| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |