123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599 |
- <?php
- /**
- * @file
- * Webform Localization i18n_string integration.
- */
- /**
- * Provides interface with the i18n_string module.
- * Based in patch http://drupal.org/node/245424#comment-5244256
- * by Calin Marian. Further development sponsored by Riot Games.
- *
- * @author German Martin <gmartin.php@gmail.com>
- */
- /**
- * Translates the component properties that are translatable.
- *
- * These are found in under 'translated_strings' in the 'extra' array of the
- * component, which is build when the component is inserted / updated, or
- * when all webform strings are updated from
- * admin/config/regional/translate/i18n_string.
- *
- * @param array $element
- * The FAPI renderable array of the component instance.
- * @param array $component
- * The component.
- */
- function _webform_localization_translate_component(&$element, $component) {
- if (isset($component['extra']['translated_strings']) && is_array($component['extra']['translated_strings'])) {
- foreach ($component['extra']['translated_strings'] as $name) {
- $name_list = explode(':', $name);
- $current_element = &$element;
- if (strpos($name_list[3], '[') !== FALSE) {
- // The property is deeper in the renderable array, we must extract the
- // the place where it is.
- list ($children, $property) = explode(']#', $name_list[3]);
- // Remove the '[' from the begining of the string.
- $children = drupal_substr($children, 1);
- $children_array = explode('][', $children);
- foreach ($children_array as $child) {
- if (isset($current_element[$child])) {
- $current_element = &$current_element[$child];
- }
- else {
- continue;
- }
- }
- }
- else {
- // Remove the '#' from the begining of the property, for consistency.
- $property = drupal_substr($name_list[3], 1);
- }
- if (strpos($property, '-') !== FALSE) {
- // If property is array, we extract the key from the property.
- list ($property, $key) = explode('-', $property);
- if (isset($current_element['#' . $property][$key])) {
- $current_element['#' . $property][$key] = i18n_string($name, $current_element['#' . $property][$key], array('sanitize' => FALSE));
- }
- }
- else {
- // If we are dealing with option groups.
- if (isset($name_list[4]) && strpos($name_list[4], '/-') !== FALSE) {
- $option_group = str_replace('/-', '', $name_list[4]);
- // If it's a element.
- if (isset($name_list[5])) {
- $current_element['#' . $property][$option_group][$name_list[5]] = i18n_string($name, $current_element['#' . $property][$option_group][$name_list[5]]);
- }
- else {
- // If it's a option group we translate the key.
- $translated_option_group = i18n_string($name, $option_group);
- if ($translated_option_group != $option_group) {
- _webform_localization_array_key_replace($current_element['#' . $property], $option_group, $translated_option_group);
- }
- }
- }
- else {
- // Else we can treat the property as string.
- if (isset($current_element['#' . $property])) {
- if ($property == 'markup' && $current_element['#type'] == 'markup') {
- $current_element['#' . $property] = i18n_string($name, $current_element['#' . $property], array('format' => $current_element['#format']));
- }
- elseif ($property == 'description') {
- $current_element['#' . $property] = i18n_string($name, $current_element['#' . $property], array('format' => I18N_STRING_FILTER_XSS));
- }
- else {
- $current_element['#' . $property] = i18n_string($name, $current_element['#' . $property]);
- }
- }
- }
- }
- }
- }
- }
- /**
- * Translates the analysis component properties that are translatable.
- *
- * These are found in under 'translated_strings' in the 'extra' array of the
- * component, which is build when the component is inserted / updated, or
- * when all webform strings are updated from
- * admin/config/regional/translate/i18n_string.
- *
- * @param array $data
- * The data array of component results.
- * @param array $component
- * The component.
- */
- function _webform_localization_translate_analysis_component(&$data, &$component) {
- if (!isset($component['extra']['translated_strings']) || !is_array($component['extra']['translated_strings'])) {
- return;
- }
- // Attempt to translate select options.
- if ($component['type'] == 'select') {
- $item_key_lookup = _webform_localization_string_to_key($component['extra']['items']);
- }
- // Attempt to translate grid options / questions.
- if ($component['type'] == 'grid') {
- $options_key_lookup = _webform_localization_string_to_key($component['extra']['options']);
- $questions_key_lookup = _webform_localization_string_to_key($component['extra']['questions']);
- }
- foreach ($component['extra']['translated_strings'] as $name) {
- $name_list = explode(':', $name);
- // Translate component name from title property.
- if ($name_list[3] == '#title') {
- $component['name'] = i18n_string($name, $component['name']);
- continue;
- }
- // Translate options for select elements.
- if ($component['type'] == 'select' && strpos($name_list[3], '-') !== FALSE) {
- list (, $key) = explode('-', $name_list[3]);
- if (isset($item_key_lookup[$key])) {
- foreach ($data['table_rows'] as $index => $row) {
- if ($row[0] == $item_key_lookup[$key]) {
- $data['table_rows'][$index][0] = i18n_string($name, $row[0]);
- }
- }
- }
- }
- // Translate options / questions for grid elements.
- if ($component['type'] == 'grid' && $name_list[3] !== '#title') {
- list (, $key) = explode('-', $name_list[3]);
- if (strpos($name_list[3], 'grid_options')) {
- if (isset($options_key_lookup[$key])) {
- foreach ($data['table_header'] as $index => $row) {
- if ($row == $options_key_lookup[$key]) {
- $data['table_header'][$index] = i18n_string($name, $row);
- }
- }
- }
- }
- if (strpos($name_list[3], 'grid_questions')) {
- if (isset($questions_key_lookup[$key])) {
- foreach ($data['table_rows'] as $index => $row) {
- if (trim($row[0]) == trim($questions_key_lookup[$key])) {
- $data['table_rows'][$index][0] = i18n_string($name, $row[0]);
- }
- }
- }
- }
- }
- }
- }
- /**
- * Update / create translation source for all the translatable poperties.
- *
- * @param array $component
- * A webform component.
- */
- function webform_localization_component_update_translation_strings(&$component) {
- // Fill in the the default values for the missing properties.
- module_load_include('inc', 'webform', 'includes/webform.components');
- webform_component_defaults($component);
- // Render the 'render' FAPI array for the component.
- $element = webform_component_invoke($component['type'], 'render', $component, NULL, 'html');
- // Parse the renderable array to find the translatable properties and
- // update / create translation source for them.
- $component['extra']['translated_strings'] = _webform_localization_component_translation_parse($element, $component);
- // Render the 'display' FAPI array for the component.
- $element = webform_component_invoke($component['type'], 'display', $component, NULL, 'html');
- // Parse the renderable array to find the translatable properties and
- // update / create translation source for them.
- $component['extra']['translated_strings'] = array_merge($component['extra']['translated_strings'], array_diff(_webform_localization_component_translation_parse($element, $component), $component['extra']['translated_strings']));
- }
- /**
- * Parse a component renderable array to find the translatable properties.
- *
- * Create / update or remove translation source for translatable properties
- * of a webform component.
- *
- * @param array $element
- * The renderable array to be parsed.
- * @param array $component
- * The component which was rendered.
- * @return
- * An array of translatabled webform properties.
- *
- */
- function _webform_localization_component_translation_parse($element, $component) {
- $translated_properies = array();
- if (!isset($element['#parents'])) {
- $element['#parents'] = array();
- }
- if (isset($element['#translatable']) && is_array($element['#translatable'])) {
- foreach ($element['#translatable'] as $key) {
- if (isset($element['#' . $key]) && $element['#' . $key] != '') {
- if (isset($element['#parents']) && count($element['#parents'])) {
- $property = '[' . implode('][', $element['#parents']) . ']#' . $key;
- }
- else {
- $property = '#' . $key;
- }
- if (is_array($element['#' . $key])) {
- // If the translatable property is an array, we translate the
- // children.
- foreach ($element['#' . $key] as $elem_key => $elem_value) {
- // If the child if an array, we translate the elements.
- if (is_array($elem_value)) {
- foreach ($elem_value as $k => $v) {
- $name = webform_localization_i18n_string_name($component['nid'], $component['cid'], $property, '/-' . $elem_key . '/-', $k);
- $translated_properies[] = $name;
- i18n_string($name, $v, array('update' => TRUE));
- }
- $name = webform_localization_i18n_string_name($component['nid'], $component['cid'], $property, '/-' . $elem_key . '/-');
- $translated_properies[] = $name;
- i18n_string($name, $elem_key, array('update' => TRUE));
- }
- else {
- // If the child is not an array.
- $name = webform_localization_i18n_string_name($component['nid'], $component['cid'], $property . '-' . $elem_key);
- $translated_properies[] = $name;
- i18n_string($name, $elem_value, array('update' => TRUE));
- }
- }
- }
- else {
- /**
- * If the translatable property is not an array,
- * it can be treated as a string.
- */
- $name = webform_localization_i18n_string_name($component['nid'], $component['cid'], $property);
- $translated_properies[] = $name;
- i18n_string($name, $element['#' . $key], array('update' => TRUE));
- }
- }
- }
- }
- // Recursevly call the function on the children, after adding the children
- // name to its #parents array.
- foreach (element_children($element) as $child) {
- $element[$child]['#parents'] = $element['#parents'];
- $element[$child]['#parents'][] = $child;
- // Add the translated propertied to the list.
- $translated_properies = array_merge(
- $translated_properies,
- _webform_localization_component_translation_parse($element[$child], $component)
- );
- }
- return $translated_properies;
- }
- /**
- * Utility function to create i18n string name.
- *
- * Additional arguments can be passed to add more depth to context
- *
- * @param int $node_identifier
- * webform nid
- *
- * @return string
- * i18n string name grouped by nid or uuid if module is available
- */
- function webform_localization_i18n_string_name($node_identifier) {
- if (module_exists('uuid')) {
- $node_identifier = current(entity_get_uuid_by_id('node', array($node_identifier)));
- }
- $name = array('webform', $node_identifier);
- $args = func_get_args();
- // Remove $node_identifier from args
- array_shift($args);
- foreach ($args as $arg) {
- $name[] = $arg;
- }
- return implode(':', $name);
- }
- /**
- * Delete translation source for all the translatable poperties
- *
- * Process components matching webforms configuration.
- */
- function webform_localization_delete_all_strings() {
- $query = db_select('webform_component', 'wc');
- $query->fields('wc');
- $query->condition('wl.expose_strings', 0, '=');
- $query->innerJoin('webform_localization', 'wl', 'wc.nid = wl.nid');
- $components = $query->execute()->fetchAllAssoc('cid');
- foreach ($components as $component) {
- $component = (array) $component;
- $component['extra'] = unserialize($component['extra']);
- webform_localization_component_delete_translation_strings($component);
- $component['extra'] = serialize($component['extra']);
- drupal_write_record('webform_component', $component, array('nid', 'cid'));
- }
- }
- /**
- * Remove translation source for all the translatable poperties.
- *
- * @param array $component
- * A webform component array.
- */
- function webform_localization_component_delete_translation_strings($component) {
- if (isset($component['extra']['translated_strings'])) {
- foreach ($component['extra']['translated_strings'] as $name) {
- i18n_string_remove($name);
- }
- }
- }
- /**
- * Update / create translation source for general webform poperties.
- *
- * @param array $properties
- * The form_state values that have been saved.
- */
- function webform_localization_update_translation_strings($properties) {
- if (!empty($properties['confirmation']['value'])) {
- $name = webform_localization_i18n_string_name($properties['nid'], 'confirmation');
- i18n_string($name, $properties['confirmation']['value'], array('update' => TRUE));
- }
- if (!empty($properties['submit_text'])) {
- $name = webform_localization_i18n_string_name($properties['nid'], 'submit_text');
- i18n_string($name, $properties['submit_text'], array('update' => TRUE));
- }
- // Allow to translate the redirect url if it's not set to none or the
- // default confirmation page.
- if (!in_array($properties['redirect_url'], array('<confirmation>', '<none>'))) {
- $name = webform_localization_i18n_string_name($properties['nid'], 'redirect_url');
- i18n_string($name, $properties['redirect_url'], array('update' => TRUE));
- }
- }
- /**
- * Translate general webform properties.
- *
- * @param $node
- * A node object.
- */
- function webform_localization_translate_strings(&$node, $update = FALSE) {
- $option = array('update' => $update, 'sanitize' => FALSE);
- $name = webform_localization_i18n_string_name($node->webform['nid'], 'confirmation');
- $node->webform['confirmation'] = i18n_string(
- $name,
- $node->webform['confirmation'],
- $option);
- $name = webform_localization_i18n_string_name($node->webform['nid'], 'submit_text');
- $node->webform['submit_text'] = i18n_string(
- $name,
- $node->webform['submit_text'],
- $option);
- // Allow to translate the redirect url if it's not set to none or the
- // default confirmation page.
- if (!in_array($node->webform['redirect_url'], array('<confirmation>', '<none>'))) {
- $name = webform_localization_i18n_string_name($node->webform['nid'], 'redirect_url');
- $node->webform['redirect_url'] = i18n_string($name, $node->webform['redirect_url'], $option);
- }
- }
- /**
- * Update / create translation source for webform email poperties.
- *
- * @param array $properties
- * The form_state values that have been saved.
- */
- function webform_localization_emails_update_translation_string($properties) {
- $nid = $properties['node']->webform['nid'];
- $eid = $properties['eid'];
- if (!empty($properties['subject_custom'])) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'subject_custom');
- i18n_string($name, $properties['subject_custom'], array('update' => TRUE));
- }
- // Allow to translate the mail recipients if not based on a component.
- if (!empty($properties['email']) && !is_numeric($properties['email'])) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'email');
- i18n_string($name, $properties['email'], array('update' => TRUE));
- }
- if (!empty($properties['from_name_custom'])) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'from_name_custom');
- i18n_string($name, $properties['from_name_custom'], array('update' => TRUE));
- }
- if (!empty($properties['template'])) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'template');
- i18n_string($name, $properties['template'], array('update' => TRUE));
- }
- }
- /**
- * Update / create translation source for webform email poperties.
- *
- * @param $emails
- * An array of webform emails.
- * @param $nid
- * The node Id of the webform.
- */
- function webform_localization_emails_translation_string_refresh($emails, $nid) {
- foreach ($emails as $email) {
- $eid = $email['eid'];
- if (!empty($email['subject']) && $email['subject'] != 'default') {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'subject_custom');
- i18n_string($name, $email['subject'], array('update' => TRUE));
- }
- // Allow to translate the mail recipients if not based on a component.
- if (!empty($email['email']) && !is_numeric($email['email'])) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'email');
- i18n_string($name, $email['email'], array('update' => TRUE));
- }
- if (!empty($email['from_name']) && $email['from_name'] != 'default') {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'from_name_custom');
- i18n_string($name, $email['from_name'], array('update' => TRUE));
- }
- if (!empty($email['template']) && $email['template'] != 'default') {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'template');
- i18n_string($name, $email['template'], array('update' => TRUE));
- }
- }
- }
- /**
- * Translate webform email poperties.
- *
- * @param $node
- * A node object.
- */
- function webform_localization_email_translate_strings(&$node) {
- $nid = $node->webform['nid'];
- foreach ($node->webform['emails'] as $eid => &$email) {
- if (!empty($email['subject']) && $email['subject'] != 'default') {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'subject_custom');
- $email['subject'] = i18n_string($name, $email['subject']);
- }
- // Allow to translate the mail recipients if not based on a component.
- if (!empty($email['email']) && !is_numeric($email['email'])) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'email');
- $email['email'] = i18n_string($name, $email['email']);
- }
- if (!empty($email['from_name']) && $email['from_name'] != 'default') {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'from_name_custom');
- $email['from_name'] = i18n_string($name, $email['from_name']);
- }
- if (!empty($email['template']) && $email['template'] != 'default') {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'template');
- $email['template'] = i18n_string($name, $email['template']);
- }
- }
- }
- /**
- * Remove translation source for webform email poperties.
- *
- * @param $eid
- * A webform email Id.
- * @param $nid
- * A node Id.
- */
- function webform_localization_emails_delete_translation_string($eid, $nid) {
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'subject_custom');
- i18n_string_remove($name);
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'from_name_custom');
- i18n_string_remove($name);
- $name = webform_localization_i18n_string_name($nid, 'email', $eid, 'template');
- i18n_string_remove($name);
- }
- /**
- * Translate general webform poperties.
- *
- * @param $node
- * A node object.
- */
- function webform_localization_delete_translate_strings($node) {
- $name = webform_localization_i18n_string_name($node->webform['nid'], 'confirmation');
- i18n_string_remove($name);
- $name = webform_localization_i18n_string_name($node->webform['nid'], 'submit_text');
- i18n_string_remove($name);
- foreach ($node->webform['emails'] as $eid => $value) {
- webform_localization_emails_delete_translation_string($eid, $node->nid);
- }
- }
- /**
- * Update i18n string contexts if uuid module is enabled/disabled.
- *
- */
- function webform_localization_uuid_update_strings($disabling_uuid = FALSE) {
- module_load_install('i18n_string');
- $old_ids = db_query('SELECT distinct type FROM {i18n_string} WHERE textgroup = :webform', array(
- ':webform' => 'webform'
- ))->fetchCol();
- variable_set('webform_localization_using_uuid', !$disabling_uuid);
- if (empty($old_ids)) {
- return;
- }
- if (!$disabling_uuid) {
- $old_context_ids = entity_get_uuid_by_id('node', array($old_ids));
- }
- else {
- // entity_get_id_by_uuid() do not work properly on hook_disable.
- $old_context_ids = webform_localization_get_id_by_uuid('node', array($old_ids));
- }
- foreach ($old_context_ids as $old_id => $new_id) {
- $old_context = 'webform:' . $old_id . ':*';
- $new_context = 'webform:' . $new_id . ':*';
- i18n_string_install_update_context($old_context, $new_context);
- }
- }
- /**
- * Helper function that retrieves entity IDs by their UUIDs.
- *
- *
- * @param $entity_type
- * The entity type we should be dealing with.
- * @param $uuids
- * An array of UUIDs for which we should find their entity IDs. If $revision
- * is TRUE this should be revision UUIDs instead.
- * @return
- * Array of entity IDs keyed by their UUIDs. If $revision is TRUE revision
- * IDs and UUIDs are returned instead.
- */
- function webform_localization_get_id_by_uuid($entity_type, $uuids) {
- if (empty($uuids)) {
- return array();
- }
- $info = entity_get_info($entity_type);
- $table = $info['base table'];
- $id_key = $info['entity keys']['id'];
- // The uuid key is not available at hook_disable.
- $core_info = uuid_get_core_entity_info();
- $uuid_key = $core_info['node']['entity keys']['uuid'];
- // Get all UUIDs in one query.
- return db_select($table, 't')
- ->fields('t', array($uuid_key, $id_key))
- ->condition($uuid_key, array_values($uuids), 'IN')
- ->execute()
- ->fetchAllKeyed();
- }
- /**
- * Helper function to replace an array key and its content.
- *
- * @param $array
- * Array To process.
- * @param $old_key
- * Array key to be replaced.
- * @param $new_key
- * The new array key.
- *
- */
- function _webform_localization_array_key_replace(&$array, $old_key, $new_key) {
- $keys = array_keys($array);
- $values = array_values($array);
- foreach ($keys as $k => $v) {
- if ($v == $old_key) {
- $keys[$k] = $new_key;
- }
- }
- $array = array_combine($keys, $values);
- }
- /**
- * Helper function to convert select / grid strings to array.
- *
- * @param $string_array
- * Array To process.
- *
- */
- function _webform_localization_string_to_key($string_array) {
- $key_array = array();
- $items = explode("\n", trim($string_array));
- foreach ($items as $item) {
- $item_data = explode('|', $item);
- $key_array[$item_data[0]] = $item_data[1];
- }
- return $key_array;
- }
|