[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/options_element/ -> options_element.inc (source)

   1  <?php
   2  
   3  /**
   4   * @file
   5   * All logic for options_element form elements.
   6   */
   7  
   8  
   9  /**
  10   * Theme an options element.
  11   */
  12  function theme_options($element) {
  13    drupal_add_js('misc/tabledrag.js');
  14    drupal_add_js(drupal_get_path('module', 'options_element') .'/options_element.js');
  15    drupal_add_css(drupal_get_path('module', 'options_element') .'/options_element.css');
  16  
  17    $classes = array();
  18    if (isset($element['#attributes']['class'])) {
  19      $classes[] = $element['#attributes']['class'];
  20    }
  21  
  22    $classes[] = 'form-options';
  23    $classes[] = 'options-key-type-'. $element['#key_type'];
  24  
  25    if ($element['#key_type_toggled']) {
  26      $classes[] = 'options-key-custom';
  27    }
  28  
  29    if (isset($element['#optgroups']) && $element['#optgroups']) {
  30      $classes[] = 'options-optgroups';
  31    }
  32  
  33    if (isset($element['#multiple']) && $element['#multiple']) {
  34      $classes[] = 'options-multiple';
  35    }
  36  
  37    $options = '';
  38    $options .= drupal_render($element['options_field']);
  39    if (isset($element['default_value_field'])) {
  40      $options .= drupal_render($element['default_value_field']);
  41    }
  42    if (isset($element['default_value_pattern'])) {
  43      $options .= drupal_render($element['default_value_pattern']);
  44    }
  45  
  46    $settings = '';
  47    if (isset($element['custom_keys'])) {
  48      $settings .= drupal_render($element['custom_keys']);
  49    }
  50    if (isset($element['multiple'])) {
  51      $settings .= drupal_render($element['multiple']);
  52    }
  53    if (isset($element['option_settings'])) {
  54      $settings .= drupal_render($element['option_settings']);
  55    }
  56  
  57    $output = '';
  58    $output .= '<div class="' . implode(' ', $classes) .'">';
  59    $output .= theme('fieldset', array(
  60      '#title' => t('Options'),
  61      '#collapsible' => FALSE,
  62      '#children' => $options,
  63      '#attributes' => array('class' => 'options'),
  64    ));
  65  
  66    if (!empty($settings)) {
  67      $output .= theme('fieldset', array(
  68        '#title' => t('Option settings'),
  69        '#collapsible' => FALSE,
  70        '#children' => $settings,
  71        '#attributes' => array('class' => 'option-settings'),
  72      ));
  73    }
  74    $output .= '</div>';
  75  
  76    return $output;
  77  }
  78  
  79  /**
  80   * Logic function for form_options_expand(). Do not call directly.
  81   *
  82   * @see form_options_expand()
  83   */
  84  function _form_options_expand($element) {
  85    $element['#options'] = isset($element['#options']) ? $element['#options'] : array();
  86    $element['#multiple'] = isset($element['#multiple']) ? $element['#multiple'] : FALSE;
  87  
  88    $element['#tree'] = TRUE;
  89    $element['#theme'] = 'options';
  90  
  91    // Add the key type toggle checkbox.
  92    if (!isset($element['custom_keys']) && $element['#key_type'] != 'custom' && !empty($element['#key_type_toggle'])) {
  93      $element['custom_keys'] = array(
  94        '#title' => is_string($element['#key_type_toggle']) ? $element['#key_type_toggle'] : t('Customize keys'),
  95        '#type' => 'checkbox',
  96        '#default_value' => $element['#key_type_toggled'],
  97        '#attributes' => array('class' => 'key-type-toggle'),
  98        '#description' => t('Customizing the keys will allow you to save one value internally while showing a different option to the user.'),
  99      );
 100    }
 101  
 102    // Add the multiple value toggle checkbox.
 103    if (!isset($element['multiple']) && !empty($element['#multiple_toggle'])) {
 104      $element['multiple'] = array(
 105        '#title' => is_string($element['#multiple_toggle']) ? $element['#multiple_toggle'] : t('Allow multiple values'),
 106        '#type' => 'checkbox',
 107        '#default_value' => !empty($element['#multiple']),
 108        '#attributes' => array('class' => 'multiple-toggle'),
 109        '#description' => t('Multiple values will let users select multiple items in this list.'),
 110      );
 111    }
 112    // If the element had a custom interface for toggling whether or not multiple
 113    // values are accepted, make sure that form_type_options_value() knows to use
 114    // it.
 115    if (isset($element['multiple']) && empty($element['#multiple_toggle'])) {
 116      $element['#multiple_toggle'] = TRUE;
 117    }
 118  
 119    // Add the main textarea for adding options.
 120    if (!isset($element['options'])) {
 121      $element['options_field'] = array(
 122        '#type' => 'textarea',
 123        '#resizable' => TRUE,
 124        '#cols' => 60,
 125        '#rows' => 5,
 126        '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
 127        '#description' => t('List options one option per line.'),
 128        '#attributes' => $element['#disabled'] ? array('readonly' => 'readonly') : array(),
 129        '#wysiwyg' => FALSE, // Prevent CKeditor from trying to hijack.
 130      );
 131  
 132      // If validation fails, reload the user's text even if it's not valid.
 133      if (isset($element['#value']['text'])) {
 134        $element['options_field']['#value'] = $element['#value']['text'];
 135      }
 136      // Most of the time, we'll be converting the options array into the text.
 137      else {
 138        $element['options_field']['#value'] = isset($element['#options']) ? form_options_to_text($element['#options'], $element['#key_type']) : '';
 139      }
 140  
 141  
 142      if ($element['#key_type'] == 'mixed' || $element['#key_type'] == 'numeric' || $element['#key_type'] == 'custom') {
 143        $element['options_field']['#description'] .= ' ' . t('Key-value pairs may be specified by separating each option with pipes, such as <em>key|value</em>.');
 144      }
 145      elseif ($element['#key_type_toggle']) {
 146        $element['options_field']['#description'] .= ' ' . t('If the %toggle field is checked, key-value pairs may be specified by separating each option with pipes, such as <em>key|value</em>.', array('%toggle' => $element['custom_keys']['#title']));
 147      }
 148      if ($element['#key_type'] == 'numeric') {
 149        $element['options_field']['#description'] .= ' ' . t('This field requires all specified keys to be integers.');
 150      }
 151    }
 152  
 153    // Add the field for storing default values.
 154    if ($element['#default_value_allowed'] && !isset($element['default_value_field'])) {
 155      $element['default_value_field'] = array(
 156        '#title' => t('Default value'),
 157        '#type' => 'textfield',
 158        '#size' => 60,
 159        '#maxlength' => 1024,
 160        '#value' => isset($element['#default_value']) ? ($element['#multiple'] ? implode(', ', (array) $element['#default_value']) : $element['#default_value']) : '',
 161        '#description' => t('Specify the keys that should be selected by default.'),
 162      );
 163      if ($element['#multiple']) {
 164        $element['default_value_field']['#description'] .= ' ' . t('Multiple default values may be specified by separating keys with commas.');
 165      }
 166    }
 167  
 168    // Add the field for storing a default value pattern.
 169    if ($element['#default_value_pattern']) {
 170      $element['default_value_pattern'] = array(
 171        '#type' => 'hidden',
 172        '#value' => $element['#default_value_pattern'],
 173        '#attributes' => array('class' => 'default-value-pattern'),
 174      );
 175    }
 176  
 177    // Remove properties that will confuse the FAPI.
 178    unset($element['#options']);
 179    $element['#required'] = FALSE;
 180  
 181    return $element;
 182  }
 183  
 184  /**
 185   * Logic function for form_options_validate(). Do not call directly.
 186   *
 187   * @see form_options_validate()
 188   */
 189  function _form_options_validate($element, &$form_state) {
 190    // Convert text to an array of options.
 191    $duplicates = array();
 192    $options = form_options_from_text($element['#value']['options_text'], $element['#key_type'], empty($element['#optgroups']), $duplicates);
 193  
 194    // Check if a key is used multiple times.
 195    if (count($duplicates) == 1) {
 196      form_error($element, t('The key %key has been used multiple times. Each key must be unique to display properly.', array('%key' => reset($duplicates))));
 197    }
 198    elseif (!empty($duplicates)) {
 199      array_walk($duplicates, 'check_plain');
 200      $duplicate_list = theme('item_list', $duplicates);
 201      form_error($element, t('The following keys have been used multiple times. Each key must be unique to display properly.') . $duplicate_list);
 202    }
 203  
 204    // Add the list of duplicates to the page so that we can highlight the fields.
 205    if (!empty($duplicates)) {
 206      drupal_add_js(array('optionsElement' => array('errors' => drupal_map_assoc($duplicates))), 'setting');
 207    }
 208  
 209    // Check if no options are specified.
 210    if (empty($options) && $element['#required']) {
 211      form_error($element, t('At least one option must be specified.'));
 212    }
 213  
 214    // Check for numeric keys if needed.
 215    if ($element['#key_type'] == 'numeric') {
 216      foreach ($options as $key => $value) {
 217        if (!is_int($key)) {
 218          form_error($element, t('The keys for the %title field must be integers.', array('%title' => $element['#title'])));
 219          break;
 220        }
 221      }
 222    }
 223  
 224    // Check that the limit of options has not been exceeded.
 225    if (!empty($element['#limit'])) {
 226      $count = 0;
 227      foreach ($options as $value) {
 228        if (is_array($value)) {
 229          $count += count($value);
 230        }
 231        else {
 232          $count++;
 233        }
 234      }
 235      if ($count > $element['#limit']) {
 236        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'])));
 237      }
 238    }
 239  }
 240  
 241  /**
 242   * Logic function for form_type_options_value(). Do not call directly.
 243   *
 244   * @see form_type_options_value()
 245   */
 246  function _form_type_options_value(&$element, $edit = FALSE) {
 247    if ($edit === FALSE) {
 248       return array(
 249         'options' => isset($element['#options']) ? $element['#options'] : array(),
 250         'default_value' => isset($element['#default_value']) ? $element['#default_value'] : '',
 251       );
 252    }
 253    else {
 254      // Convert text to an array of options.
 255      $duplicates = array();
 256      $options = form_options_from_text($edit['options_field'], $element['#key_type'], empty($element['#optgroups']), $duplicates);
 257  
 258      // Convert default value.
 259      if (isset($edit['default_value_field'])) {
 260        // If the element supports toggling whether or not it will accept
 261        // multiple values, use the value that was passed in via $edit (keeping
 262        // in mind that this value may not be set, if a checkbox was used to
 263        // configure it). Otherwise, use the current setting stored with the
 264        // element itself.
 265        $multiple = !empty($element['#multiple_toggle']) ? !empty($edit['multiple']) : !empty($element['#multiple']);
 266        if ($multiple) {
 267          $default_value = array();
 268          $default_items = explode(',', $edit['default_value_field']);
 269          foreach ($default_items as $key) {
 270            $key = trim($key);
 271            $value = _form_options_search($key, $options, $element['#default_value_pattern']);
 272            if (!is_null($value)) {
 273              $default_value[] = $value;
 274            }
 275          }
 276        }
 277        else {
 278          $default_value = _form_options_search(trim($edit['default_value_field']), $options, $element['#default_value_pattern']);
 279        }
 280      }
 281      else {
 282        $default_value = NULL;
 283      }
 284  
 285      $return = array(
 286        'options' => $options,
 287        'default_value' => $default_value,
 288        'options_text' => $edit['options_field'],
 289      );
 290  
 291      if (isset($edit['default_value_field'])) {
 292        $return['default_value_text'] = $edit['default_value_field'];
 293      }
 294  
 295      return $return;
 296    }
 297  }
 298  
 299  /**
 300   * Logic function for form_options_to_text(). Do not call directly.
 301   *
 302   * @see form_options_to_text()
 303   */
 304  function _form_options_to_text($options, $key_type) {
 305    $output = '';
 306    $previous_key = false;
 307  
 308    foreach ($options as $key => $value) {
 309      // Convert groups.
 310      if (is_array($value)) {
 311        $output .= '<' . $key . '>' . "\n";
 312        foreach ($value as $subkey => $subvalue) {
 313          $output .= (($key_type == 'mixed' || $key_type == 'numeric' || $key_type == 'custom') ? $subkey . '|' : '') . $subvalue . "\n";
 314        }
 315        $previous_key = $key;
 316      }
 317      // Typical key|value pairs.
 318      else {
 319        // Exit out of any groups.
 320        if (isset($options[$previous_key]) && is_array($options[$previous_key])) {
 321          $output .= "<>\n";
 322        }
 323        // Skip empty rows.
 324        if ($options[$key] !== '') {
 325          if ($key_type == 'mixed' || $key_type == 'numeric' || $key_type == 'custom') {
 326            $output .= $key . '|' . $value . "\n";
 327          }
 328          else {
 329            $output .= $value . "\n";
 330          }
 331        }
 332        $previous_key = $key;
 333      }
 334    }
 335  
 336    return $output;
 337  }
 338  
 339  /**
 340   * Logic function for form_options_from_text(). Do not call directly.
 341   *
 342   * @see form_options_from_text()
 343   */
 344  function _form_options_from_text($text, $key_type, $flat = FALSE, &$duplicates = array()) {
 345    $keys = array();
 346    $items = array();
 347    $rows = array_filter(explode("\n", trim($text)));
 348    $group = FALSE;
 349    foreach ($rows as $row) {
 350      $row = trim($row);
 351      $matches = array();
 352  
 353      // Check for a simple empty row.
 354      if (empty($row)) {
 355        continue;
 356      }
 357      // Check if this row is a group.
 358      elseif (!$flat && preg_match('/^\<((([^>|]*)\|)?([^>]*))\>$/', $row, $matches)) {
 359        if ($matches[1] === '') {
 360          $group = FALSE;
 361        }
 362        else {
 363          $group = $matches[4] ? $matches[4] : '';
 364          $keys[] = $group;
 365        }
 366      }
 367      // Check if this row is a key|value pair.
 368      elseif (($key_type == 'mixed' || $key_type == 'custom' || $key_type == 'numeric') && preg_match('/^([^|]+)\|(.*)$/', $row, $matches)) {
 369        $key = $matches[1];
 370        $value = $matches[2];
 371        $keys[] = $key;
 372        $items[] = array(
 373          'key' => $key,
 374          'value' => $value,
 375          'group' => $group,
 376        );
 377      }
 378      // Set this this row as a straight value.
 379      else {
 380        $items[] = array(
 381          'key' => NULL,
 382          'value' => $row,
 383          'group' => $group,
 384        );
 385      }
 386    }
 387  
 388    // Expand the list into a nested array, assign keys and check duplicates.
 389    $options = array();
 390    $new_key = 1;
 391    foreach ($items as $item) {
 392      $int_key = $item['key'] * 1;
 393      if (is_int($int_key)) {
 394        $new_key = max($int_key, $new_key);
 395      }
 396    }
 397    foreach ($items as $item) {
 398      // Assign a key if needed.
 399      if ($key_type == 'none') {
 400        $item['key'] = $new_key++;
 401      }
 402      elseif (!isset($item['key'])) {
 403        while (in_array($new_key, $keys)) {
 404          $new_key++;
 405        }
 406        $keys[] = $new_key;
 407        $item['key'] = $new_key;
 408      }
 409  
 410      if ($item['group']) {
 411        if (isset($options[$item['group']][$item['key']])) {
 412          $duplicates[] = $item['key'];
 413        }
 414        $options[$item['group']][$item['key']] = $item['value'];
 415      }
 416      else {
 417        if (isset($options[$item['key']])) {
 418          $duplicates[] = $item['key'];
 419        }
 420        $options[$item['key']] = $item['value'];
 421      }
 422    }
 423  
 424    return $options;
 425  }
 426  
 427  /**
 428   * Recursive function for finding default value keys. Matches on keys or values.
 429   */
 430  function _form_options_search($needle, $haystack, $include_pattern) {
 431    if (isset($haystack[$needle])) {
 432      return $needle;
 433    }
 434    elseif ($include_pattern && preg_match('/' . $include_pattern . '/', $needle)) {
 435      return $needle;
 436    }
 437    foreach ($haystack as $key => $value) {
 438      if (is_array($value)) {
 439        return _form_options_search($needle, $value, $include_pattern);
 440      }
 441      elseif ($value == $needle) {
 442        return $key;
 443      }
 444    }
 445  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7