updated admin_menu, entity_translation, addressfield, addressfield_token, autocomplete_deluxe

This commit is contained in:
2019-05-13 17:41:56 +02:00
parent 472762edfa
commit 33210e10f2
65 changed files with 3124 additions and 700 deletions

View File

@@ -1,13 +1,13 @@
<?php
/**
* @file
* Webform Component information for an address field type
* Webform Component information for an address field type.
*/
/**
* Specify the default properties of a component.
*
* @return
* @return array
* An array defining the default structure of a component.
*/
function _webform_defaults_addressfield() {
@@ -23,6 +23,8 @@ function _webform_defaults_addressfield() {
'attributes' => array(),
'description' => '',
'available_countries' => array(),
'default_country' => '',
'format_handlers' => array(),
'csv_separate' => 0,
),
);
@@ -30,21 +32,22 @@ function _webform_defaults_addressfield() {
/**
* Generate the form for editing a component.
*
* Create a set of form elements to be displayed on the form for editing this
* component. Use care naming the form items, as this correlates directly to the
* database schema. The component "Name" and "Description" fields are added to
* every component type and are not necessary to specify here (although they
* may be overridden if desired).
*
* @param $component
* @param mixed $component
* A Webform component array.
*
* @return
* @return array
* An array of form items to be displayed on the edit component page
*/
function _webform_edit_addressfield($component) {
$form = array();
$form['extra']['available_countries'] = array(
'#type' => 'select',
'#multiple' => TRUE,
@@ -53,6 +56,21 @@ function _webform_edit_addressfield($component) {
'#options' => _addressfield_country_options_list(),
'#default_value' => $component['extra']['available_countries'],
);
$form['extra']['default_country'] = array(
'#type' => 'select',
'#multiple' => FALSE,
'#title' => t('Default country'),
'#description' => t('Select which country should be selected as the default.'),
'#options' => array_merge(array(0 => t('- None -')), _addressfield_country_options_list()),
'#default_value' => $component['extra']['default_country'],
);
$form['extra']['format_handlers'] = array(
'#type' => 'checkboxes',
'#title' => t('Format handlers'),
'#options' => addressfield_format_plugins_options(),
'#required' => TRUE,
'#default_value' => !empty($component['extra']['format_handlers']) ? $component['extra']['format_handlers'] : array('address'),
);
$form['extra']['csv_separate'] = array(
'#type' => 'radios',
'#title' => t('CSV download'),
@@ -69,18 +87,21 @@ function _webform_edit_addressfield($component) {
/**
* Render a Webform component to be part of a form.
*
* @param $component
* @param mixed $component
* A Webform component array.
* @param $value
* @param mixed $value
* If editing an existing submission or resuming a draft, this will contain
* an array of values to be shown instead of the default in the component
* configuration. This value will always be an array, keyed numerically for
* each value saved in this field.
* @param $filter
* @param bool $filter
* Whether or not to filter the contents of descriptions and values when
* rendering the component. Values need to be unfiltered to be editable by
* Form Builder.
*
* @return array
* Form element.
*
* @see _webform_client_form_add_component()
*/
function _webform_render_addressfield($component, $value = NULL, $filter = TRUE) {
@@ -98,55 +119,98 @@ function _webform_render_addressfield($component, $value = NULL, $filter = TRUE)
'description',
),
);
$available = !empty($component['extra']['available_countries']) ? $component['extra']['available_countries'] : NULL;
// Get the current address
if (!empty($value[0])) {
if (is_string($value[0])) {
$address = unserialize($value[0]);
// Get the current address.
$address = _addressfield_tokens_expand_value($value);
if (empty($address)) {
if (!empty($component['value'])) {
$address = $component['value'];
}
else {
$address = $value[0];
$address = _webform_addressfield($component['cid']);
}
}
elseif (!empty($component['value'])) {
$address = $component['value'];
}
else {
$address = _webform_addressfield($component['cid']);
}
if (empty($address)) {
$address = addressfield_default_values($available);
$address = _webform_addressfield_default_values($available, $component);
}
// Generate the address form.
$context = array(
'mode' => 'form',
'instance' => array(
'required' => $component['required'],
),
'form_key' => $component['form_key'],
);
$element += addressfield_generate($address, array('address'), $context);
if (!empty($available)) {
$element['country']['#options'] = array_intersect_key($element['country']['#options'], $available);
$handlers = !empty($component['extra']['format_handlers']) ? $component['extra']['format_handlers'] : array('address');
$element += addressfield_generate($address, $handlers, $context);
if (empty($address['country'])) {
$element['street_block']['#access'] = FALSE;
$element['locality_block']['#access'] = FALSE;
}
$element['country']['#element_validate'] = array('_webform_addressfield_country_validate');
$element['country']['#cid'] = $component['cid'];
$element['country']['#limit_validation_errors'] = array();
if (isset($element['country'])) {
if (!empty($available)) {
$element['country']['#options'] = array_intersect_key($element['country']['#options'], $available);
// Hide the country element only if there is one option and the whole field
// is required, otherwise there will always be an additional None option.
// @see addressfield_format_address_hide_country()
if (!empty($handlers['address-hide-country']) && count($element['country']['#options']) == 1 && $component['required']) {
$element['country']['#access'] = FALSE;
}
}
$element['country']['#default_value'] = $address['country'];
$element['country']['#element_validate'] = array('_webform_addressfield_country_validate');
$element['country']['#cid'] = $component['cid'];
$element['country']['#limit_validation_errors'] = array();
}
$form_state = array();
drupal_alter('field_widget_addressfield_standard_form', $element, $form_state, $context);
drupal_alter('field_widget_addressfield_standard_form', $element, $form_state, $context);
return $element;
}
function _webform_addressfield_default_values($available, $component) {
$default_country = !empty($component['extra']['default_country'])
? $component['extra']['default_country']
: addressfield_tokens_default_country();
$default_values = array(
'country' => $default_country,
'name_line' => '',
'first_name' => '',
'last_name' => '',
'organisation_name' => '',
'administrative_area' => '',
'sub_administrative_area' => '',
'locality' => '',
'dependent_locality' => '',
'postal_code' => '',
'thoroughfare' => '',
'premise' => '',
'sub_premise' => '',
'data' => '',
);
return ($default_values);
}
/**
* Stores an addressfield submitted in a webform component. Ideally we should store
* it in the $form_state instead, but there appears to be no way to get it to actually
* pass through to _webform_render_addressfield().
*
* @param $cid integer The ID of the webform component.
* @param $address array If set, this address will be stored with the given $cid.
* @return array The address stored with the given $cid, if there is one; otherwise, NULL.
* Stores an addressfield submitted in a webform component.
*
* Ideally store it in the $form_state instead, but there appears to be no way
* to get it to actually pass through to _webform_render_addressfield().
*
* @param int $cid
* The ID of the webform component.
* @param mixed $address
* If set, this address will be stored with the given $cid.
*
* @return array
* The address stored with the given $cid, if there is one; otherwise, NULL.
*/
function _webform_addressfield($cid, $address = NULL) {
$out = &drupal_static(__FUNCTION__, array());
@@ -160,40 +224,41 @@ function _webform_addressfield($cid, $address = NULL) {
}
/**
* Validates a country, and if it changes, rebuilds the form for the new country
* Validates a country, and if changed, rebuilds the form for the new country.
*/
function _webform_addressfield_country_validate(&$element, &$form_state) {
// If the country was changed, rebuild the form.
if ($element['#default_value'] != $element['#value']) {
if (!isset($element['#default_value']) || $element['#default_value'] != $element['#value']) {
$form_state['rebuild'] = TRUE;
}
$cid = $element['#cid'];
$parents = $element['#parents'];
array_pop($parents);
// Search through the form values to find the current address.
$address = drupal_array_get_nested_value($form_state['values'], $parents);
_webform_addressfield($cid, $address);
}
/**
* Display the result of a submission for a component.
*
* The output of this function will be displayed under the "Results" tab then
* "Submissions". This should output the saved data in some reasonable manner.
*
* @param $component
* @param mixed $component
* A Webform component array.
* @param $value
* @param mixed $value
* An array of information containing the submission result, directly
* correlating to the webform_submitted_data database table schema.
* @param $format
* @param string $format
* Either 'html' or 'text'. Defines the format that the content should be
* returned as. Make sure that returned content is run through check_plain()
* or other filtering functions when returning HTML.
*
* @return
* @return array
* A renderable element containing at the very least these properties:
* - #title
* - #weight
@@ -205,27 +270,23 @@ function _webform_addressfield_country_validate(&$element, &$form_state) {
* (such as wrapping the text) or as HTML (ensuring consistent output).
*/
function _webform_display_addressfield($component, $value, $format = 'html') {
$address = NULL;
if (isset($value[0])) {
$address = $value[0];
if (is_string($address)) {
$address = unserialize($address);
}
}
$address = _addressfield_tokens_expand_value($value);
return array(
'#title' => $component['name'],
'#weight' => $component['weight'],
'#theme' => $format == 'html' ? 'addressfield_formatter' : 'addressfield_formatter__linear',
'#theme_wrappers' => $format == 'html' ? array('webform_element' ) : array('webform_element_text'),
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'),
'#post_render' => array('webform_element_wrapper'),
'#component' => $component,
'#format' => $format,
'#address' => $address,
'#address' => $address ? $address : NULL,
'#handlers' => $component['extra']['format_handlers'],
);
}
/**
* A hook for changing the input values before saving to the database.
*
* Webform expects a component to consist of a single field, or a single array
* of fields. If you have a component that requires a deeper form tree
* you must flatten the data into a single array using this callback
@@ -234,12 +295,12 @@ function _webform_display_addressfield($component, $value, $format = 'html') {
* Note that Webform will save the result of this function directly into the
* database.
*
* @param $component
* @param mixed $component
* A Webform component array.
* @param $value
* @param mixed $value
* The POST data associated with the user input.
*
* @return
* @return array
* An array of values to be saved into the database. Note that this should be
* a numerically keyed array.
*/
@@ -249,88 +310,92 @@ function _webform_submit_addressfield($component, $value) {
/**
* Calculate and returns statistics about results for this component.
*
* This takes into account all submissions to this webform. The output of this
* function will be displayed under the "Results" tab then "Analysis".
*
* @param $component
* @param mixed $component
* An array of information describing the component, directly correlating to
* the webform_component database schema.
* @param $sids
* @param mixed $sids
* An optional array of submission IDs (sid). If supplied, the analysis will
* be limited to these sids.
* @param $single
* @param bool $single
* Boolean flag determining if the details about a single component are being
* shown. May be used to provided detailed information about a single
* component's analysis, such as showing "Other" options within a select list.
*
* @return
* @return array
* An array of data rows, each containing a statistic for this component's
* submissions.
*/
function _webform_analysis_addressfield($component, $sids = array(), $single = FALSE) {
// TODO Update this function
// @todo Update this function
// Generate the list of options and questions.
$query = db_select('webform_submitted_data', 'wsd')
->fields('wsd', array('data'))
->condition('nid', $component['nid'])
->condition('cid', $component['cid']);
if ( count($sids) ) {
if (count($sids)) {
$query->condition('sid', $sids, 'IN');
}
$non_blanks = 0;
$submissions = 0;
$results = $query->execute();
foreach ($results as $row) {
if ( drupal_strlen(trim($row->data)) > 0 ) {
if (drupal_strlen(trim($row->data)) > 0) {
$non_blanks++;
}
$submissions++;
}
$rows[0] = array(
t('Left Blank'),
( $submissions - $non_blanks )
($submissions - $non_blanks),
);
$rows[1] = array(
t('User entered value'),
$non_blanks
$non_blanks,
);
return $rows;
return array('table_rows' => $rows);
}
/**
* Return the result of a component value for display in a table.
*
* The output of this function will be displayed under the "Results" tab then
* "Table".
*
* @param $component
* @param mixed $component
* A Webform component array.
* @param $value
* @param mixed $value
* An array of information containing the submission result, directly
* correlating to the webform_submitted_data database schema.
*
* @return
* @return string
* Textual output formatted for human reading.
*/
function _webform_table_addressfield($component, $value) {
if (!empty($value[0])) {
return theme('addressfield_formatter', array( 'address' => $value[0] ));
$address = _addressfield_tokens_expand_value($value);
if ($address) {
return theme('addressfield_formatter', array('address' => $address));
}
return '';
}
/**
* Return the header for this component to be displayed in a CSV file.
*
* The output of this function will be displayed under the "Results" tab then
* "Download".
*
* @param $component
* @param mixed $component
* A Webform component array.
* @param $export_options
* @param mixed $export_options
* An array of options that may configure export of this field.
*
* @return
* @return array
* An array of data to be displayed in the first three rows of a CSV file, not
* including either prefixed or trailing commas.
*/
@@ -340,7 +405,6 @@ function _webform_csv_headers_addressfield($component, $export_options) {
$header[0] = array();
$header[1] = array();
$header[2] = array();
foreach (addressfield_tokens_property_names() as $key => $name) {
$header[0][] = '';
$header[1][] = (empty($header[1])) ? $component['name'] : '';
@@ -349,7 +413,7 @@ function _webform_csv_headers_addressfield($component, $export_options) {
}
else {
$header[0] = array('');
$header[1] = array();
$header[1] = array('');
$header[2] = array($component['name']);
}
return $header;
@@ -357,34 +421,56 @@ function _webform_csv_headers_addressfield($component, $export_options) {
/**
* Format the submitted data of a component for CSV downloading.
*
* The output of this function will be displayed under the "Results" tab then
* "Download".
*
* @param $component
* @param mixed $component
* A Webform component array.
* @param $export_options
* @param mixed $export_options
* An array of options that may configure export of this field.
* @param $value
* @param mixed $value
* An array of information containing the submission result, directly
* correlating to the webform_submitted_data database schema.
*
* @return
* @return array
* An array of items to be added to the CSV file. Each value within the array
* will be another column within the file. This function is called once for
* every row of data.
*/
function _webform_csv_data_addressfield($component, $export_options, $value) {
$address = _addressfield_tokens_expand_value($value);
if (!empty($component['extra']['csv_separate']) && $component['extra']['csv_separate'] == 1) {
// Each address component should be in a separate column.
$return = array();
foreach (addressfield_tokens_property_names() as $key => $name) {
$return[] = (isset($value[0][$key])) ? $value[0][$key] : '';
$return[] = (isset($address[$key])) ? $address[$key] : '';
}
return $return;
}
else {
if (!empty($value[0])) {
return theme('addressfield_formatter__linear', array( 'address' => $value[0] ));
// The entire address should be displayed in the one column.
if ($address) {
return theme('addressfield_formatter__linear', array('address' => $address));
}
return '';
}
}
/**
* Expand a raw address submission as loaded from the database to an array.
*
* @param string $value
* An array of information containing the submission result, directly
* correlating to the {webform_submitted_data} database schema.
*
* @return array|false
* An associative array of address fields, or FALSE on failure.
*/
function _addressfield_tokens_expand_value($value) {
if (isset($value[0]) && is_string($value[0])) {
return unserialize($value[0]);
}
return FALSE;
}

View File

@@ -1,16 +1,13 @@
name = Address Field Tokens
description = Creates tokens for address fields, adds new addressfield renders, and adds webform integration.
core = 7.x
package = Fields
dependencies[] = addressfield
dependencies[] = entity_token
dependencies[] = token
name = Address Field Tokens
description = Creates tokens for address fields, adds new addressfield renders, and adds webform integration.
core = 7.x
package = Fields
dependencies[] = addressfield
dependencies[] = entity_token
dependencies[] = token
; Information added by Drupal.org packaging script on 2014-10-29
version = "7.x-1.5"
; Information added by Drupal.org packaging script on 2018-10-11
version = "7.x-1.13"
core = "7.x"
project = "addressfield_tokens"
datestamp = "1414599829"
datestamp = "1539260884"

View File

@@ -4,9 +4,12 @@
* Main components.
*/
/**
* Implements hook_menu().
*/
function addressfield_tokens_menu() {
$items = array();
$items['admin/config/regional/address'] = array(
'title' => 'Addresses',
'description' => 'Settings for address fields and tokens',
@@ -16,7 +19,7 @@ function addressfield_tokens_menu() {
'file' => 'addressfield_tokens.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
@@ -34,19 +37,31 @@ function addressfield_tokens_theme($existing, $type, $theme, $path) {
'file' => 'addressfield_tokens.theme.inc',
),
'addressfield_formatter__linear' => array(
'variables' => array('address' => NULL, 'premise' => TRUE, 'organisation_name' => TRUE, 'name_line' => TRUE),
'variables' => array(
'address' => NULL,
'premise' => TRUE,
'organisation_name' => TRUE,
'name_line' => TRUE,
),
'file' => 'addressfield_tokens.theme.inc',
),
'addressfield_formatter__components' => array(
'variables' => array(
'address' => NULL,
'components' => array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country'),
'components' => array(
'thoroughfare',
'premise',
'locality',
'administrative_area',
'postal_code',
'country',
),
'separator' => ', ',
),
'file' => 'addressfield_tokens.theme.inc',
),
);
return $theme;
}
@@ -75,7 +90,14 @@ function addressfield_tokens_field_formatter_info() {
'label' => t('Address components'),
'field types' => array('addressfield'),
'settings' => array(
'components' => array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country'),
'components' => array(
'thoroughfare',
'premise',
'locality',
'administrative_area',
'postal_code',
'country',
),
'separator' => ', ',
),
),
@@ -103,14 +125,13 @@ function addressfield_tokens_field_formatter_settings_form($field, $instance, $v
$element['separator'] = array(
'#type' => 'textfield',
'#title' => t('Separator'),
'#description' => t('The separator to use between components. Use \n for a line break.'),
'#description' => t('The separator to use between components. Use br tag for a line break.'),
'#default_value' => $settings['separator'],
);
}
return $element;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
@@ -132,7 +153,7 @@ function addressfield_tokens_field_formatter_settings_summary($field, $instance,
*/
function addressfield_tokens_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'addressfield_citystate':
$theme = array('addressfield_formatter__citystate', 'addressfield_formatter');
@@ -147,7 +168,7 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
);
}
break;
case 'addressfield_linear':
$theme = array('addressfield_formatter__linear', 'addressfield_formatter');
@@ -161,7 +182,7 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
);
}
break;
case 'addressfield_country':
foreach ($items as $delta => $item) {
if (!empty($item['country'])) {
@@ -175,11 +196,11 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
}
}
break;
case 'addressfield_state':
foreach ($items as $delta => $item) {
if (!empty($item['country']) && !empty($item['administrative_area'])) {
$state = _addressfield_tokens_state($item['country'], $item['administrative_area']);
$state = addressfield_tokens_state($item['country'], $item['administrative_area']);
$element[$delta] = array(
'#type' => 'markup',
'#markup' => filter_xss($state),
@@ -189,19 +210,19 @@ function addressfield_tokens_field_formatter_view($entity_type, $entity, $field,
}
}
break;
case 'addressfield_components':
$theme = array('addressfield_formatter__components', 'addressfield_formatter');
$settings = $display['settings'];
foreach ($items as $delta => $item) {
if (!empty($item['country'])) {
array_unshift($theme, 'addressfield_formatter__components__' . $item['country']);
}
}
$element[$delta] = array(
'#theme' => $theme,
'#address' => array_map('filter_xss', $item),
'#components' => $settings['components'],
'#separator' => filter_xss($settings['separator']),
'#separator' => filter_xss($settings['separator'], array('br')),
);
}
break;
@@ -230,11 +251,31 @@ function addressfield_tokens_property_names() {
return $names;
}
/**
* Generates token components.
*
* @return mixed
* Array of components.
*/
function addressfield_tokens_components() {
$comps = &drupal_static(__FUNCTION__, array());
if (empty($comps)) {
$names = addressfield_tokens_property_names();
foreach (array('first_name', 'last_name', 'name_line', 'organisation_name', 'thoroughfare', 'premise', 'locality', 'dependent_locality', 'administrative_area', 'sub_administrative_area', 'postal_code', 'country') as $key) {
$fields = array(
'first_name',
'last_name',
'name_line',
'organisation_name',
'thoroughfare',
'premise',
'locality',
'dependent_locality',
'administrative_area',
'sub_administrative_area',
'postal_code',
'country',
);
foreach ($fields as $key) {
$comps[$key] = $names[$key];
if (in_array($key, array('administrative_area', 'country'))) {
$comps[$key . '_full'] = t('@name (full)', array(
@@ -248,14 +289,15 @@ function addressfield_tokens_components() {
/**
* Gets the list of countries from the locale settings in Drupal.
*
* @return array An array of countries. The keys are the 2-letter
*
* @return array
* An array of countries. The keys are the 2-letter
* abbreviations and the values are the full country names.
*/
function _addressfield_tokens_countries() {
$countries = &drupal_static(__FUNCTION__);
if (empty($countries)) {
include_once('includes/locale.inc');
require_once DRUPAL_ROOT . '/includes/locale.inc';
$countries = country_get_list();
}
return $countries;
@@ -263,14 +305,17 @@ function _addressfield_tokens_countries() {
/**
* Gets the name of the country with the given abbreviation.
*
* @param string $country The 2-letter abbreviation of the country.
* @return string The name of the country, or FALSE.
*
* @param string $country
* The 2-letter abbreviation of the country.
*
* @return string
* The name of the country, or FALSE.
*/
function _addressfield_tokens_country($country) {
$countries = _addressfield_tokens_countries();
// Country abbreviations will always be two uppercase letters.
// Country abbreviations will always be two uppercase letters.
$country = drupal_strtoupper($country);
if (!empty($country) && isset($countries[$country])) {
return check_plain($countries[$country]);
@@ -279,11 +324,12 @@ function _addressfield_tokens_country($country) {
}
/**
* Gets the abbreviation of the country with the given name
*
* @param string
* Gets the abbreviation of the country with the given name.
*
* @param string $country
* The name of the country.
* @return string $country
*
* @return string
* The 2-letter abbreviation of the country, or FALSE.
*/
function _addressfield_tokens_country_abbr($country) {
@@ -297,55 +343,63 @@ function _addressfield_tokens_country_abbr($country) {
/**
* Gets the list of states in the given country.
*
* @param string $country The 2-letter abbreviation of the country.
*
* @return array An array of countries. The keys are the 2-letter
*
* @param string $country
* The 2-letter abbreviation of the country.
*
* @return array
* An array of countries. The keys are the 2-letter
* abbreviations and the values are the full country names.
*/
function _addressfield_tokens_states($country) {
function addressfield_tokens_states($country) {
global $language;
$langcode = $language->language;
$states = &drupal_static(__FUNCTION__);
$country = drupal_strtoupper($country);
if (!isset($states[$country])) {
$cache = cache_get('addressfield_tokens_states');
$cache = cache_get('addressfield_tokens_states:' . $langcode);
if ($cache) {
$states = $cache->data;
}
}
if (!isset($states[$country])) {
$format = addressfield_generate(array('country' => $country), array('address'), array('mode' => 'render'));
if (isset($format['locality_block']['administrative_area']['#options'])) {
$states[$country] = $format['locality_block']['administrative_area']['#options'];
}
else {
$states[$country] = array();
}
cache_set('addressfield_tokens_states', $states);
cache_set('addressfield_tokens_states:' . $langcode, $states);
}
return $states[$country];
}
/**
* Gets the name of the state with the given abbreviation.
*
* @param string $country The 2-letter abbreviation of the country.
* @param string $state The 2-letter abbreviation of the state.
* @return string The name of the state, or FALSE.
*
* @param string $country
* The 2-letter abbreviation of the country.
* @param string $state
* The 2-letter abbreviation of the state.
*
* @return string
* The name of the state, or FALSE.
*/
function _addressfield_tokens_state($country, $state) {
$states = _addressfield_tokens_states($country);
// State abbreviations will usually be two uppercase letters.
$state = drupal_strtoupper($state);
if (!empty($state) && !empty($states[$state])) {
function addressfield_tokens_state($country, $state) {
$states = addressfield_tokens_states($country);
// State abbreviations will usually be two uppercase letters.
$state_upper = drupal_strtoupper($state);
if (!empty($state_upper) && !empty($states[$state_upper])) {
return check_plain($states[$state]);
}
return check_plain($state);
}
/**
* Implements hook_webform_component_info().
/**
* Implements hook_webform_component_info().
*/
function addressfield_tokens_webform_component_info() {
$components = array();
@@ -387,6 +441,15 @@ function addressfield_tokens_webform_component_info() {
return $components;
}
/**
* Retrieves node components based on Node ID.
* @param int $nid
* Node ID.
*
* @return mixed
* Components.
*/
function _addressfield_tokens_webform_components($nid) {
$components = &drupal_static(__FUNCTION__, array());
if (!isset($components[$nid])) {
@@ -402,13 +465,14 @@ function _addressfield_tokens_webform_components($nid) {
/**
* Implements hook_webform_submission_load().
*/
* Commented out to solve issue https://www.drupal.org/project/addressfield_tokens/issues/2674752
*
function addressfield_tokens_webform_submission_load(&$submissions) {
$submissions_reset = reset($submissions);
$nid = $submissions_reset->nid;
$components = _addressfield_tokens_webform_components($nid);
foreach ($submissions as $sid => $submission) {
foreach ($components as $cid => $component) {
if (!empty($submission->data[$cid])) {
@@ -421,17 +485,40 @@ function addressfield_tokens_webform_submission_load(&$submissions) {
$data = empty($data) ? array() : unserialize($data);
$addresses[$delta] = $data;
}
drupal_array_set_nested_value($submission->data, $parents, $addresses);
if (count($addresses)) {
drupal_array_set_nested_value($submission->data, $parents, $addresses);
}
}
}
}
}
**/
/**
* Implements hook_webform_validator_alter().
/**
* Implements hook_webform_validator_alter().
*/
function addressfield_tokens_webform_validator_alter(&$validators) {
$validators['unique']['component_types'][] = 'addressfield';
$validators['oneoftwo']['component_types'][] = 'addressfield';
$validators['oneofseveral']['component_types'][] = 'addressfield';
}
/**
* Implements hook_webform_hints_element_alter().
*/
function addressfield_tokens_webform_hints_element_alter(&$element, &$required_label)
{
if ($element['#type'] == 'addressfield_container' || $element['#type'] == 'fieldset') {
$addressfield_tokens_fields_info = addressfield_tokens_field_formatter_info();
foreach ($addressfield_tokens_fields_info['addressfield_components']['settings']['components'] as $component) {
if (isset($element[$component])) {
if (isset($element[$component]['#options'])) {
$element[$component]['#empty_option'] = '- ' . $element[$component]['#title'] . $required_label . ' -';
}
$element[$component]['#attributes']['placeholder'] = $element[$component]['#title'] . $required_label;
$element[$component]['#title_display'] = 'invisible';
}
}
}
}

View File

@@ -11,7 +11,13 @@
*/
function theme_addressfield_formatter($vars) {
$address = $vars['address'];
if (isset($address['addressfield'])) {
$address = $address['addressfield'];
}
$handlers = $vars['handlers'];
if (empty($handlers)) {
$handlers = array('address');
}
$out = addressfield_generate($address, $handlers, array('mode' => 'render'));
return '<div class="addressfield">' . render($out) . '</div>';
@@ -39,7 +45,7 @@ function theme_addressfield_formatter__citystate($vars) {
// If there's no location, render an alternate
if (empty($out)) {
$out[] = 'Undefined';
return '';
}
// Render the location components
@@ -56,6 +62,18 @@ function theme_addressfield_formatter__citystate($vars) {
function theme_addressfield_formatter__linear($vars) {
$loc = $vars['address'];
// If single line name is empty, construct it from first and last name.
if (empty($loc['name_line'])) {
$parts = array();
if (!empty($loc['first_name'])) {
$parts[] = $loc['first_name'];
}
if (!empty($loc['last_name'])) {
$parts[] = $loc['last_name'];
}
$loc['name_line'] = join(' ', $parts);
}
// Determine which location components to render
$out = array();
if (!empty($loc['name_line']) && $vars['name_line']) {
@@ -103,9 +121,9 @@ function theme_addressfield_formatter__components($vars) {
$out[$key] = _addressfield_tokens_country($loc['country']);
}
elseif ($key == 'administrative_area_full' && !empty($loc['country']) && !empty($loc['administrative_area'])) {
$out[$key] = _addressfield_tokens_state($loc['country'], $loc['administrative_area']);
$out[$key] = addressfield_tokens_state($loc['country'], $loc['administrative_area']);
}
}
return implode($separator, $out);
}
}

View File

@@ -1,36 +1,37 @@
<?php
/**
* @file Provides token replacements for address fields.
*/
* @file
* Provides token replacements for address fields.
*/
/**
* Implements hook_token_info_alter().
*
* Attaches tokens to all addressfield properties. The default names of each
* addressfield component can be altered by administrators according to the site's locale.
*
* @param array $info The existing token info.
*
* Attaches tokens to all addressfield properties. The default names of each
* addressfield component can be altered by administrators according to the
* site's locale.
*/
function addressfield_tokens_token_info_alter(&$info) {
// Define the address field token types
// Define the address field token types.
$info['types']['addressfield'] = array(
'name' => t('Address field'),
'description' => t('An address associated with an entity.'),
'needs-data' => 'addressfield',
);
// Add tokens for each component of the address
$info['tokens'] += array( 'addressfield' => array() );
// Add tokens for each component of the address.
$info['tokens'] += array('addressfield' => array());
$props = addressfield_data_property_info();
$names = addressfield_tokens_property_names();
$params = array(
'@default_country' => addressfield_tokens_default_country(),
);
foreach ($props as $field => $data) {
$fieldtoken = str_replace('_', '-', $field);
if (!empty($names[$field])) {
$name = $names[$field];
$descr = $data['label'];
@@ -38,7 +39,7 @@ function addressfield_tokens_token_info_alter(&$info) {
else {
$name = $data['label'];
$descr = $name;
$matches = array();
if (preg_match('/^(.*)\s+\(i\.e\.\s+(.*)\)$/', $name, $matches)) {
$name = $matches[1];
@@ -54,7 +55,7 @@ function addressfield_tokens_token_info_alter(&$info) {
}
$info['tokens']['addressfield']['administrative-area']['name'] .= ' (abbreviation)';
$info['tokens']['addressfield']['country']['name'] .= ' (abbreviation)';
// Add tokens for the formatted address and text-only version.
$info['tokens']['addressfield'] += array(
'full' => array(
@@ -83,7 +84,7 @@ function addressfield_tokens_token_info_alter(&$info) {
'type' => 'text',
),
);
// Add user tokens that are useful for MailChimp.
if (module_exists('mailchimp')) {
$info['tokens']['addressfield'] += array(
@@ -95,9 +96,23 @@ function addressfield_tokens_token_info_alter(&$info) {
);
}
// Attach tokens to all address fields
// Add extra text to webform submission values help.
if (array_key_exists('submission', $info['tokens'])) {
$info['tokens']['submission']['values']['description'] .= '
<div>
' . t('For addressfield components you can also choose individual elements of the address using the syntax field_key:element, For example:') . '
<ul>
<li>[submission:values:address:thoroughfare]</li>
<li>[submission:values:address:locality]</li>
<li>[submission:values:address:administrative_area]</li>
<li>[submission:values:address:postal_code]</li>
<li>[submission:values:address:country]</li>
</ul>
</div>';
}
// Attach tokens to all address fields.
$valid_types = entity_token_types();
$entity_info = entity_get_info();
foreach ($valid_types as $token_type => $type) {
foreach (entity_get_all_property_info($type) as $name => $property) {
@@ -116,14 +131,6 @@ function addressfield_tokens_token_info_alter(&$info) {
/**
* Implements hook_tokens().
*
* @param string $type The type of tokens to replace. We are looking for 'addressfield', but can also chain
* addressfields onto entities that have addressfields as properties.
* @param array $tokens The tokens to replace.
* @param array $data The data to use as replacements. We are looking for an 'addressfield' property.
* @param array $options Additional options for the tokenizer.
*
* @return array The replaced values.
*/
function addressfield_tokens_tokens($type, $tokens, array $data = array(), array $options = array()) {
$url_options = array();
@@ -140,27 +147,49 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
$replacements = array();
$last_original = NULL;
// Process address field tokens
if ($type == 'addressfield' && !empty($data['addressfield'])) {
// Process webform submission addressfield tokens.
if ($type == 'submission' && !empty($data['webform-submission'])) {
$submission = $data['webform-submission'];
$node = isset($data['node']) ? $data['node'] : node_load($submission->nid);
$value_tokens = token_find_with_prefix($tokens, 'values');
// Loop through the components of the webform looking for addressfield
// components with the expected form_key.
foreach ($node->webform['components'] as $cid => $component) {
if ($component['type'] == 'addressfield' && isset($submission->data[$cid][0])) {
$address = $submission->data[$cid][0];
if (is_string($address)) {
$address = unserialize($address);
}
$address_tokens = token_find_with_prefix($value_tokens, $component['form_key']);
foreach ($address_tokens as $token => $original) {
if (isset($address[$token])) {
$replacements[$original] = $sanitize ? filter_xss($address[$token]) : $address[$token];
}
}
}
}
}
// Process address field tokens.
elseif ($type == 'addressfield' && !empty($data['addressfield'])) {
foreach ($tokens as $name => $original) {
$last_original = $original;
$name = str_replace('-', '_', $name);
$address = $data['addressfield'];
// If the address field exists, use it.
if (isset($address[$name])) {
$replacements[$original] = $sanitize ? filter_xss($address[$name]) : $address[$name];
}
else {
// Otherwise, it's a special token
// Otherwise, it's a special token.
switch ($name) {
case 'full':
$render = addressfield_generate($address, array('address'), array(
'mode' => 'render',
'mode' => 'render',
));
$replacements[$original] = $sanitize ? filter_xss(drupal_render($render)) : drupal_render($render);
break;
case 'text':
$out = array();
if (!empty($address['thoroughfare'])) {
@@ -182,7 +211,7 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
}
$replacements[$original] = $sanitize ? filter_xss(implode("\n", $out)) : implode("\n", $out);
break;
case 'city_state':
$out = array();
if (!empty($address['locality'])) {
@@ -194,20 +223,20 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
if (!empty($address['country']) && $address['country'] != addressfield_tokens_default_country()) {
$out[] = _addressfield_tokens_country($address['country']);
}
$replacements[$original] = $sanitize ? filter_xss(implode(", ", $out)) : implode(", ", $out);
$replacements[$original] = $sanitize ? filter_xss(implode(", ", $out)) : implode(", ", $out);
break;
case 'state_name':
if (!empty($address['administrative_area']) && !empty($address['country'])) {
if ($sanitize) {
$replacements[$original] = filter_xss(_addressfield_tokens_state($address['country'], $address['administrative_area']));
$replacements[$original] = filter_xss(addressfield_tokens_state($address['country'], $address['administrative_area']));
}
else {
$replacements[$original] = _addressfield_tokens_state($address['country'], $address['administrative_area']);
$replacements[$original] = addressfield_tokens_state($address['country'], $address['administrative_area']);
}
}
break;
case 'country_name':
if (!empty($address['country'])) {
if ($sanitize) {
@@ -218,16 +247,23 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
}
}
break;
case 'mc_address':
$address_components = array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country');
$address_components = array(
'thoroughfare',
'premise',
'locality',
'administrative_area',
'postal_code',
'country',
);
$mc_address = array();
foreach ($address_components as $component) {
if (!empty($address[$component])) {
$mc_address[] = check_plain($address[$component]);
}
}
// MailChimp requires the address to be a string of double-space
// MailChimp requires the address to be a string of double-space
// delimited address fields. (http://kb.mailchimp.com/article/how-do-i-set-up-the-address-field-type-for-import)
$replacements[$original] = !empty($mc_address) ? implode(' ', $mc_address) : '';
break;
@@ -242,7 +278,7 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
$token_types = entity_token_types();
$info = token_info();
if (isset($info['tokens'][$type])) {
// Otherwise, chain address fields attached to other entities
// Otherwise, chain address fields attached to other entities.
foreach ($info['tokens'][$type] as $name => $token_info) {
if (isset($token_info['type']) && $token_info['type'] == 'addressfield') {
if ($chained_tokens = token_find_with_prefix($tokens, $name)) {
@@ -261,6 +297,6 @@ function addressfield_tokens_tokens($type, $tokens, array $data = array(), array
}
}
}
return $replacements;
}
}