- <?php
- * @file
- * All logic for options form elements.
- */
-
- * Logic function for form_options_expand(). Do not call directly.
- *
- * @see form_options_expand()
- */
- function _form_options_expand($element) {
- $element['#options'] = isset($element['#options']) ? $element['#options'] : array();
- $element['#multiple'] = isset($element['#multiple']) ? $element['#multiple'] : FALSE;
-
- $element['#tree'] = TRUE;
- $element['#theme'] = 'options';
-
- $path = backdrop_get_path('module', 'options');
- $element['#attached']['library'] = array(
- array('options', 'options'),
- );
-
-
- if (!isset($element['custom_keys']) && $element['#key_type'] != 'custom' && !empty($element['#key_type_toggle'])) {
- $element['custom_keys'] = array(
- '#title' => is_string($element['#key_type_toggle']) ? $element['#key_type_toggle'] : t('Customize keys'),
- '#type' => 'checkbox',
- '#default_value' => $element['#key_type_toggled'],
- '#attributes' => array('class' => array('key-type-toggle')),
- '#description' => t('Customizing the keys will allow you to save one value internally while showing a different option to the user.'),
- );
- }
-
-
- if (!isset($element['multiple']) && !empty($element['#multiple_toggle'])) {
- $element['multiple'] = array(
- '#title' => is_string($element['#multiple_toggle']) ? $element['#multiple_toggle'] : t('Allow multiple values'),
- '#type' => 'checkbox',
- '#default_value' => !empty($element['#multiple']),
- '#attributes' => array('class' => array('multiple-toggle')),
- '#description' => t('Multiple values will let users select multiple items in this list.'),
- );
- }
-
-
-
- if (isset($element['multiple']) && empty($element['#multiple_toggle'])) {
- $element['#multiple_toggle'] = TRUE;
- }
-
-
- if (!isset($element['options'])) {
- $element['options_field'] = array(
- '#type' => 'textarea',
- '#resizable' => 'vertical',
- '#cols' => 60,
- '#rows' => 5,
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
- '#description' => t('List options one option per line.'),
- '#attributes' => $element['#options_readonly'] ? array('readonly' => 'readonly') : array(),
- '#wysiwyg' => FALSE,
- );
-
-
- if (isset($element['#value']['options_text'])) {
- $element['options_field']['#value'] = $element['#value']['options_text'];
- }
-
- else {
- $element['options_field']['#value'] = isset($element['#options']) ? form_options_to_text($element['#options'], $element['#key_type']) : '';
- }
-
-
- if ($element['#key_type'] == 'mixed' || $element['#key_type'] == 'numeric' || $element['#key_type'] == 'custom') {
- $element['options_field']['#description'] .= ' ' . t('Key-label pairs may be specified by separating each option with pipes, such as <em>key|label</em>.');
- }
- elseif ($element['#key_type_toggle']) {
- $element['options_field']['#description'] .= ' ' . t('If the %toggle field is checked, key-label pairs may be specified by separating each option with pipes, such as <em>key|label</em>.', array('%toggle' => $element['custom_keys']['#title']));
- }
- if ($element['#key_type'] == 'numeric') {
- $element['options_field']['#description'] .= ' ' . t('This field requires all specified keys to be integers.');
- $element['options_field']['#description'] .= ' ' . t('The label is optional: if a line contains a single number, it will be used as key and label.');
- }
- $element['options_field']['#description'] .= ' ' . t('Customizing the keys will allow you to save one value internally while showing a different option to the user.');
- }
-
-
- if ($element['#default_value_allowed'] && !isset($element['default_value_field'])) {
- $element['default_value_field'] = array(
- '#title' => t('Default value'),
- '#type' => 'textfield',
- '#size' => 60,
- '#maxlength' => 1024,
- '#value' => isset($element['#default_value']) ? ($element['#multiple'] ? implode(', ', (array) $element['#default_value']) : $element['#default_value']) : '',
- '#description' => t('Specify the keys that should be selected by default.'),
- );
- if ($element['#multiple']) {
- $element['default_value_field']['#description'] .= ' ' . t('Multiple default values may be specified by separating keys with commas.');
- }
- }
-
-
- if ($element['#default_value_pattern']) {
- $element['default_value_pattern'] = array(
- '#type' => 'hidden',
- '#value' => $element['#default_value_pattern'],
- '#attributes' => array('class' => array('default-value-pattern')),
- );
- }
-
-
- $element['#attached']['js'][] = array(
- 'type' => 'setting',
- 'data' => array('optionsElement' => array('allowedtags' => '<div class="description">' . t('Allowed HTML tags in labels: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '</div>')),
- );
-
-
- unset($element['#options']);
-
- return $element;
- }
-
- * Logic function for form_options_validate(). Do not call directly.
- *
- * @see form_options_validate()
- */
- function _form_options_validate($element, &$form_state) {
-
-
- $duplicates = array();
- $options = form_options_from_text($element['#value']['options_text'], $element['#key_type'], empty($element['#optgroups']), $duplicates);
-
-
- if (count($duplicates) == 1) {
- form_error($element, t('The key %key has been used multiple times. Each key must be unique to display properly.', array('%key' => reset($duplicates))));
- }
- elseif (!empty($duplicates)) {
- array_walk($duplicates, 'check_plain');
- $duplicate_list = theme('item_list', array('items' => $duplicates));
- form_error($element, t('The following keys have been used multiple times. Each key must be unique to display properly.') . $duplicate_list);
- }
-
-
- if (!empty($duplicates)) {
- backdrop_add_js(array('optionsElement' => array('errors' => backdrop_map_assoc($duplicates))), 'setting');
- }
-
-
- if (empty($options) && $element['#required']) {
- form_error($element, t('At least one option must be specified.'));
- }
-
-
- if ($element['#key_type'] == 'numeric') {
- foreach ($options as $key => $value) {
- if (!is_int($key)) {
- form_error($element, t('The keys for the %title field must be integers.', array('%title' => $element['#title'])));
- break;
- }
- }
- }
-
-
- if (!empty($element['#limit'])) {
- $count = 0;
- foreach ($options as $value) {
- if (is_array($value)) {
- $count += count($value);
- }
- else {
- $count++;
- }
- }
- if ($count > $element['#limit']) {
- form_error($element, t('The %title field supports a maximum of @count options. Please reduce the number of options.', array('%title' => $element['#title'], '@count' => $element['#limit'])));
- }
- }
- }
-
- * Logic function for form_type_options_value(). Do not call directly.
- *
- * @see form_type_options_value()
- */
- function _form_type_options_value(&$element, $edit = FALSE) {
- if ($edit === FALSE) {
- return array(
- 'options' => isset($element['#options']) ? $element['#options'] : array(),
- 'default_value' => isset($element['#default_value']) ? $element['#default_value'] : '',
- );
- }
- else {
-
- $duplicates = array();
- $options = form_options_from_text($edit['options_field'], $element['#key_type'], empty($element['#optgroups']), $duplicates);
-
-
- if (isset($edit['default_value_field'])) {
-
-
-
-
-
- $multiple = !empty($element['#multiple_toggle']) ? !empty($edit['multiple']) : !empty($element['#multiple']);
- if ($multiple) {
- $default_value = array();
- $default_items = explode(',', $edit['default_value_field']);
- foreach ($default_items as $key) {
- $key = trim($key);
- $value = _form_options_search($key, $options, $element['#default_value_pattern']);
- if (!is_null($value)) {
- $default_value[] = $value;
- }
- }
- }
- else {
- $default_value = _form_options_search(trim($edit['default_value_field']), $options, $element['#default_value_pattern']);
- }
- }
- else {
- $default_value = NULL;
- }
-
- $return = array(
- 'options' => $options,
- 'default_value' => $default_value,
- 'options_text' => $edit['options_field'],
- );
-
- if (isset($edit['default_value_field'])) {
- $return['default_value_text'] = $edit['default_value_field'];
- }
-
- return $return;
- }
- }
-
- * Logic function for form_options_to_text(). Do not call directly.
- *
- * @see form_options_to_text()
- */
- function _form_options_to_text($options, $key_type) {
- $output = '';
- $previous_key = false;
-
- foreach ($options as $key => $value) {
-
- if (is_array($value)) {
- $output .= '<' . $key . '>' . "\n";
- foreach ($value as $subkey => $subvalue) {
- $output .= (($key_type == 'mixed' || $key_type == 'numeric' || $key_type == 'custom') ? $subkey . '|' : '') . $subvalue . "\n";
- }
- $previous_key = $key;
- }
-
- else {
-
- if (isset($options[$previous_key]) && is_array($options[$previous_key])) {
- $output .= "<>\n";
- }
-
- if ($options[$key] !== '') {
- if ($key_type == 'mixed' || $key_type == 'numeric' || $key_type == 'custom') {
- $output .= $key . '|' . $value . "\n";
- }
- else {
- $output .= $value . "\n";
- }
- }
- $previous_key = $key;
- }
- }
-
- return $output;
- }
-
- * Logic function for form_options_from_text(). Do not call directly.
- *
- * @see form_options_from_text()
- */
- function _form_options_from_text($text, $key_type, $flat = FALSE, &$duplicates = array()) {
- $keys = array();
- $items = array();
- $rows = array_filter(explode("\n", trim($text)), 'strlen');
- $group = FALSE;
- foreach ($rows as $row) {
- $row = trim($row);
- $matches = array();
-
-
- if (!strlen($row)) {
- continue;
- }
-
- elseif (!$flat && preg_match('/^\<((([^>|]*)\|)?([^>]*))\>$/', $row, $matches)) {
- if ($matches[1] === '') {
- $group = FALSE;
- }
- else {
- $group = $matches[4] ? $matches[4] : '';
- $keys[] = $group;
- }
- }
-
- elseif (($key_type == 'mixed' || $key_type == 'custom' || $key_type == 'numeric') && preg_match('/^([^|]+)\|(.*)$/', $row, $matches)) {
- $key = $matches[1];
- $value = $matches[2];
- $keys[] = $key;
- $items[] = array(
- 'key' => $key,
- 'value' => $value,
- 'group' => $group,
- );
- }
-
- else {
- $items[] = array(
- 'key' => NULL,
- 'value' => $row,
- 'group' => $group,
- );
- }
- }
-
-
- $options = array();
- $new_key = 1;
- foreach ($items as $item) {
- if (!is_numeric($item['key'])) {
- continue;
- }
- $int_key = (int) $item['key'];
- if (is_int($int_key)) {
- $new_key = max($int_key, $new_key);
- }
- }
- foreach ($items as $item) {
-
- if ($key_type == 'none') {
- $item['key'] = $new_key++;
- }
- elseif (!isset($item['key'])) {
- while (in_array($new_key, $keys)) {
- $new_key++;
- }
- $keys[] = $new_key;
- $item['key'] = $new_key;
- }
-
- if ($item['group']) {
- if (isset($options[$item['group']][$item['key']])) {
- $duplicates[] = $item['key'];
- }
- $options[$item['group']][$item['key']] = $item['value'];
- }
- else {
- if (isset($options[$item['key']])) {
- $duplicates[] = $item['key'];
- }
- $options[$item['key']] = $item['value'];
- }
- }
-
- return $options;
- }
-
- * Recursive function for finding default value keys. Matches on keys or values.
- */
- function _form_options_search($needle, $haystack, $include_pattern) {
- if (isset($haystack[$needle])) {
- return $needle;
- }
- elseif ($include_pattern && preg_match('/' . $include_pattern . '/', $needle)) {
- return $needle;
- }
- foreach ($haystack as $key => $value) {
- if (is_array($value)) {
- return _form_options_search($needle, $value, $include_pattern);
- }
- elseif ($value == $needle) {
- return $key;
- }
- }
- }