annotate sites/all/modules/webform/components/number.inc @ 11:b0ee71395280

deleted .DS_Store files
author danieleb <danielebarchiesi@me.com>
date Mon, 28 Oct 2013 16:12:13 +0000
parents ff03f76ab3fe
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2
danielebarchiesi@0 3 /**
danielebarchiesi@0 4 * @file
danielebarchiesi@0 5 * Webform module number component.
danielebarchiesi@0 6 */
danielebarchiesi@0 7
danielebarchiesi@0 8 /**
danielebarchiesi@0 9 * Implements _webform_defaults_component().
danielebarchiesi@0 10 */
danielebarchiesi@0 11 function _webform_defaults_number() {
danielebarchiesi@0 12 return array(
danielebarchiesi@0 13 'name' => '',
danielebarchiesi@0 14 'form_key' => NULL,
danielebarchiesi@0 15 'pid' => 0,
danielebarchiesi@0 16 'weight' => 0,
danielebarchiesi@0 17 'value' => '',
danielebarchiesi@0 18 'mandatory' => 0,
danielebarchiesi@0 19 'extra' => array(
danielebarchiesi@0 20 'type' => 'textfield',
danielebarchiesi@0 21 'field_prefix' => '',
danielebarchiesi@0 22 'field_suffix' => '',
danielebarchiesi@0 23 'unique' => 0,
danielebarchiesi@0 24 'title_display' => 0,
danielebarchiesi@0 25 'description' => '',
danielebarchiesi@0 26 'attributes' => array(),
danielebarchiesi@0 27 'private' => FALSE,
danielebarchiesi@0 28 'min' => '',
danielebarchiesi@0 29 'max' => '',
danielebarchiesi@0 30 'step' => '',
danielebarchiesi@0 31 'decimals' => '',
danielebarchiesi@0 32 'point' => '.',
danielebarchiesi@0 33 'separator' => ',',
danielebarchiesi@0 34 'integer' => 0,
danielebarchiesi@0 35 'excludezero' => 0,
danielebarchiesi@0 36 ),
danielebarchiesi@0 37 );
danielebarchiesi@0 38 }
danielebarchiesi@0 39
danielebarchiesi@0 40 /**
danielebarchiesi@0 41 * Implements _webform_theme_component().
danielebarchiesi@0 42 */
danielebarchiesi@0 43 function _webform_theme_number() {
danielebarchiesi@0 44 return array(
danielebarchiesi@0 45 'webform_number' => array(
danielebarchiesi@0 46 'render element' => 'element',
danielebarchiesi@0 47 'file' => 'components/number.inc',
danielebarchiesi@0 48 ),
danielebarchiesi@0 49 'webform_display_number' => array(
danielebarchiesi@0 50 'render element' => 'element',
danielebarchiesi@0 51 'file' => 'components/number.inc',
danielebarchiesi@0 52 ),
danielebarchiesi@0 53 );
danielebarchiesi@0 54 }
danielebarchiesi@0 55
danielebarchiesi@0 56 /**
danielebarchiesi@0 57 * Implements _webform_edit_component().
danielebarchiesi@0 58 */
danielebarchiesi@0 59 function _webform_edit_number($component) {
danielebarchiesi@0 60 $form = array();
danielebarchiesi@0 61 $form['value'] = array(
danielebarchiesi@0 62 '#type' => 'textfield',
danielebarchiesi@0 63 '#title' => t('Default value'),
danielebarchiesi@0 64 '#default_value' => $component['value'],
danielebarchiesi@0 65 '#description' => t('The default value of the field.') . theme('webform_token_help'),
danielebarchiesi@0 66 '#size' => 60,
danielebarchiesi@0 67 '#maxlength' => 1024,
danielebarchiesi@0 68 '#weight' => 0,
danielebarchiesi@0 69 );
danielebarchiesi@0 70 $form['display']['type'] = array(
danielebarchiesi@0 71 '#type' => 'radios',
danielebarchiesi@0 72 '#title' => t('Element type'),
danielebarchiesi@0 73 '#options' => array(
danielebarchiesi@0 74 'textfield' => t('Text field'),
danielebarchiesi@0 75 'select' => t('Select list'),
danielebarchiesi@0 76 ),
danielebarchiesi@0 77 '#default_value' => $component['extra']['type'],
danielebarchiesi@0 78 '#description' => t('A minimum and maximum value are required if displaying as a select.'),
danielebarchiesi@0 79 '#weight' => -1,
danielebarchiesi@0 80 '#parents' => array('extra', 'type'),
danielebarchiesi@0 81 );
danielebarchiesi@0 82 $form['display']['field_prefix'] = array(
danielebarchiesi@0 83 '#type' => 'textfield',
danielebarchiesi@0 84 '#title' => t('Prefix text placed to the left of the field'),
danielebarchiesi@0 85 '#default_value' => $component['extra']['field_prefix'],
danielebarchiesi@0 86 '#description' => t('Examples: $, #, -.'),
danielebarchiesi@0 87 '#size' => 20,
danielebarchiesi@0 88 '#maxlength' => 127,
danielebarchiesi@0 89 '#weight' => 1.1,
danielebarchiesi@0 90 '#parents' => array('extra', 'field_prefix'),
danielebarchiesi@0 91 );
danielebarchiesi@0 92 $form['display']['field_suffix'] = array(
danielebarchiesi@0 93 '#type' => 'textfield',
danielebarchiesi@0 94 '#title' => t('Postfix text placed to the right of the field'),
danielebarchiesi@0 95 '#default_value' => $component['extra']['field_suffix'],
danielebarchiesi@0 96 '#description' => t('Examples: lb, kg, %.'),
danielebarchiesi@0 97 '#size' => 20,
danielebarchiesi@0 98 '#maxlength' => 127,
danielebarchiesi@0 99 '#weight' => 1.2,
danielebarchiesi@0 100 '#parents' => array('extra', 'field_suffix'),
danielebarchiesi@0 101 );
danielebarchiesi@0 102 $form['display']['decimals'] = array(
danielebarchiesi@0 103 '#type' => 'select',
danielebarchiesi@0 104 '#title' => t('Decimal places'),
danielebarchiesi@0 105 '#options' => array('' => t('Automatic')) + drupal_map_assoc(range(0, 10)),
danielebarchiesi@0 106 '#description' => t('Automatic will display up to @count decimals places if needed. A value of "2" is common to format currency amounts.', array('@count' => '4')),
danielebarchiesi@0 107 '#default_value' => $component['extra']['decimals'],
danielebarchiesi@0 108 '#weight' => 2,
danielebarchiesi@0 109 '#parents' => array('extra', 'decimals'),
danielebarchiesi@0 110 '#element_validate' => array('_webform_edit_number_validate'),
danielebarchiesi@0 111 );
danielebarchiesi@0 112 $form['display']['separator'] = array(
danielebarchiesi@0 113 '#type' => 'select',
danielebarchiesi@0 114 '#title' => t('Thousands separator'),
danielebarchiesi@0 115 '#options' => array(
danielebarchiesi@0 116 ',' => t('Comma (,)'),
danielebarchiesi@0 117 '.' => t('Period (.)'),
danielebarchiesi@0 118 ' ' => t('Space ( )'),
danielebarchiesi@0 119 '' => t('None'),
danielebarchiesi@0 120 ),
danielebarchiesi@0 121 '#default_value' => $component['extra']['separator'],
danielebarchiesi@0 122 '#weight' => 3,
danielebarchiesi@0 123 '#parents' => array('extra', 'separator'),
danielebarchiesi@0 124 '#element_validate' => array('_webform_edit_number_validate'),
danielebarchiesi@0 125 );
danielebarchiesi@0 126 $form['display']['point'] = array(
danielebarchiesi@0 127 '#type' => 'select',
danielebarchiesi@0 128 '#title' => t('Decimal point'),
danielebarchiesi@0 129 '#options' => array(
danielebarchiesi@0 130 ',' => t('Comma (,)'),
danielebarchiesi@0 131 '.' => t('Period (.)'),
danielebarchiesi@0 132 ),
danielebarchiesi@0 133 '#default_value' => $component['extra']['point'],
danielebarchiesi@0 134 '#weight' => 4,
danielebarchiesi@0 135 '#parents' => array('extra', 'point'),
danielebarchiesi@0 136 '#element_validate' => array('_webform_edit_number_validate'),
danielebarchiesi@0 137 );
danielebarchiesi@0 138 $form['validation']['unique'] = array(
danielebarchiesi@0 139 '#type' => 'checkbox',
danielebarchiesi@0 140 '#title' => t('Unique'),
danielebarchiesi@0 141 '#return_value' => 1,
danielebarchiesi@0 142 '#description' => t('Check that all entered values for this field are unique. The same value is not allowed to be used twice.'),
danielebarchiesi@0 143 '#weight' => 1,
danielebarchiesi@0 144 '#default_value' => $component['extra']['unique'],
danielebarchiesi@0 145 '#parents' => array('extra', 'unique'),
danielebarchiesi@0 146 );
danielebarchiesi@0 147 $form['validation']['integer'] = array(
danielebarchiesi@0 148 '#type' => 'checkbox',
danielebarchiesi@0 149 '#title' => t('Integer'),
danielebarchiesi@0 150 '#return_value' => 1,
danielebarchiesi@0 151 '#description' => t('Permit only integer values as input. e.g. 12.34 would be invalid.'),
danielebarchiesi@0 152 '#weight' => 1.5,
danielebarchiesi@0 153 '#default_value' => $component['extra']['integer'],
danielebarchiesi@0 154 '#parents' => array('extra', 'integer'),
danielebarchiesi@0 155 );
danielebarchiesi@0 156 $form['validation']['min'] = array(
danielebarchiesi@0 157 '#type' => 'textfield',
danielebarchiesi@0 158 '#title' => t('Minimum'),
danielebarchiesi@0 159 '#default_value' => $component['extra']['min'],
danielebarchiesi@0 160 '#description' => t('Minimum numeric value. e.g. 0 would ensure positive numbers.'),
danielebarchiesi@0 161 '#size' => 5,
danielebarchiesi@0 162 '#maxlength' => 10,
danielebarchiesi@0 163 '#weight' => 2.1,
danielebarchiesi@0 164 '#parents' => array('extra', 'min'),
danielebarchiesi@0 165 '#element_validate' => array('_webform_edit_number_validate'),
danielebarchiesi@0 166 );
danielebarchiesi@0 167 $form['validation']['max'] = array(
danielebarchiesi@0 168 '#type' => 'textfield',
danielebarchiesi@0 169 '#title' => t('Maximum'),
danielebarchiesi@0 170 '#default_value' => $component['extra']['max'],
danielebarchiesi@0 171 '#description' => t('Maximum numeric value. This may also determine the display width of your field.'),
danielebarchiesi@0 172 '#size' => 5,
danielebarchiesi@0 173 '#maxlength' => 10,
danielebarchiesi@0 174 '#weight' => 2.2,
danielebarchiesi@0 175 '#parents' => array('extra', 'max'),
danielebarchiesi@0 176 '#element_validate' => array('_webform_edit_number_validate'),
danielebarchiesi@0 177 );
danielebarchiesi@0 178 $form['validation']['step'] = array(
danielebarchiesi@0 179 '#type' => 'textfield',
danielebarchiesi@0 180 '#title' => t('Step'),
danielebarchiesi@0 181 '#default_value' => $component['extra']['step'],
danielebarchiesi@0 182 '#description' => t('Limit options to a specific increment. e.g. a step of "5" would allow values 5, 10, 15, etc.'),
danielebarchiesi@0 183 '#size' => 5,
danielebarchiesi@0 184 '#maxlength' => 10,
danielebarchiesi@0 185 '#weight' => 3,
danielebarchiesi@0 186 '#parents' => array('extra', 'step'),
danielebarchiesi@0 187 '#element_validate' => array('_webform_edit_number_validate'),
danielebarchiesi@0 188 );
danielebarchiesi@0 189 // Analysis settings.
danielebarchiesi@0 190 $form['analysis'] = array(
danielebarchiesi@0 191 '#type' => 'fieldset',
danielebarchiesi@0 192 '#title' => t('Analysis'),
danielebarchiesi@0 193 '#collapsible' => TRUE,
danielebarchiesi@0 194 '#collapsed' => FALSE,
danielebarchiesi@0 195 '#weight' => 10,
danielebarchiesi@0 196 );
danielebarchiesi@0 197 $form['analysis']['excludezero'] = array(
danielebarchiesi@0 198 '#type' => 'checkbox',
danielebarchiesi@0 199 '#title' => t('Exclude zero'),
danielebarchiesi@0 200 '#return_value' => 1,
danielebarchiesi@0 201 '#description' => t('Exclude entries of zero (or blank) when counting submissions to calculate average and standard deviation.'),
danielebarchiesi@0 202 '#weight' => 1.5,
danielebarchiesi@0 203 '#default_value' => $component['extra']['excludezero'],
danielebarchiesi@0 204 '#parents' => array('extra', 'excludezero'),
danielebarchiesi@0 205 );
danielebarchiesi@0 206 return $form;
danielebarchiesi@0 207 }
danielebarchiesi@0 208
danielebarchiesi@0 209 /**
danielebarchiesi@0 210 * Theme function to render a number component.
danielebarchiesi@0 211 */
danielebarchiesi@0 212 function theme_webform_number($variables) {
danielebarchiesi@0 213 $element = $variables['element'];
danielebarchiesi@0 214
danielebarchiesi@0 215 // This IF statement is mostly in place to allow our tests to set type="text"
danielebarchiesi@0 216 // because SimpleTest does not support type="number".
danielebarchiesi@0 217 if (!isset($element['#attributes']['type'])) {
danielebarchiesi@0 218 $element['#attributes']['type'] = 'number';
danielebarchiesi@0 219 }
danielebarchiesi@0 220
danielebarchiesi@0 221 // Step property *must* be a full number with 0 prefix if a decimal.
danielebarchiesi@0 222 if (!empty($element['#step']) && !is_int($element['#step'] * 1)) {
danielebarchiesi@0 223 $decimals = strlen($element['#step']) - strrpos($element['#step'], '.') - 1;
danielebarchiesi@0 224 $element['#step'] = sprintf('%1.' . $decimals . 'F', $element['#step']);
danielebarchiesi@0 225 }
danielebarchiesi@0 226
danielebarchiesi@0 227 // If the number is not an integer and step is undefined/empty, set the "any"
danielebarchiesi@0 228 // value to allow any decimal.
danielebarchiesi@0 229 if (empty($element['#integer']) && empty($element['#step'])) {
danielebarchiesi@0 230 $element['#step'] = 'any';
danielebarchiesi@0 231 }
danielebarchiesi@0 232 elseif ($element['#integer'] && empty($element['#step'])) {
danielebarchiesi@0 233 $element['#step'] = 1;
danielebarchiesi@0 234 }
danielebarchiesi@0 235
danielebarchiesi@0 236 // Convert properties to attributes on the element if set.
danielebarchiesi@0 237 foreach (array('id', 'name', 'value', 'size', 'min', 'max', 'step') as $property) {
danielebarchiesi@0 238 if (isset($element['#' . $property]) && $element['#' . $property] !== '') {
danielebarchiesi@0 239 $element['#attributes'][$property] = $element['#' . $property];
danielebarchiesi@0 240 }
danielebarchiesi@0 241 }
danielebarchiesi@0 242 _form_set_class($element, array('form-text', 'form-number'));
danielebarchiesi@0 243
danielebarchiesi@0 244 return '<input' . drupal_attributes($element['#attributes']) . ' />';
danielebarchiesi@0 245 }
danielebarchiesi@0 246
danielebarchiesi@0 247 /**
danielebarchiesi@0 248 * Implements _webform_render_component().
danielebarchiesi@0 249 */
danielebarchiesi@0 250 function _webform_render_number($component, $value = NULL, $filter = TRUE) {
danielebarchiesi@0 251 $node = isset($component['nid']) ? node_load($component['nid']) : NULL;
danielebarchiesi@0 252
danielebarchiesi@0 253 $element = array(
danielebarchiesi@0 254 '#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
danielebarchiesi@0 255 '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
danielebarchiesi@0 256 '#default_value' => $filter ? _webform_filter_values($component['value'], $node, NULL, NULL, FALSE) : $component['value'],
danielebarchiesi@0 257 '#required' => $component['mandatory'],
danielebarchiesi@0 258 '#weight' => $component['weight'],
danielebarchiesi@0 259 '#field_prefix' => empty($component['extra']['field_prefix']) ? NULL : ($filter ? _webform_filter_xss($component['extra']['field_prefix']) : $component['extra']['field_prefix']),
danielebarchiesi@0 260 '#field_suffix' => empty($component['extra']['field_suffix']) ? NULL : ($filter ? _webform_filter_xss($component['extra']['field_suffix']) : $component['extra']['field_suffix']),
danielebarchiesi@0 261 '#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
danielebarchiesi@0 262 '#attributes' => $component['extra']['attributes'],
danielebarchiesi@0 263 '#element_validate' => array('_webform_validate_number'),
danielebarchiesi@0 264 '#theme_wrappers' => array('webform_element'),
danielebarchiesi@0 265 '#min' => $component['extra']['min'],
danielebarchiesi@0 266 '#max' => $component['extra']['max'],
danielebarchiesi@0 267 '#step' => $component['extra']['step'] ? abs($component['extra']['step']) : '',
danielebarchiesi@0 268 '#integer' => $component['extra']['integer'],
danielebarchiesi@0 269 '#translatable' => array('title', 'description'),
danielebarchiesi@0 270 );
danielebarchiesi@0 271
danielebarchiesi@0 272 // Flip the min and max properties to make min less than max if needed.
danielebarchiesi@0 273 if ($element['#min'] !== '' && $element['#max'] !== '' && $element['#min'] > $element['#max']) {
danielebarchiesi@0 274 $max = $element['#min'];
danielebarchiesi@0 275 $element['#min'] = $element['#max'];
danielebarchiesi@0 276 $element['#max'] = $max;
danielebarchiesi@0 277 }
danielebarchiesi@0 278
danielebarchiesi@0 279 // Ensure #step starts with a zero if a decimal.
danielebarchiesi@0 280 if (!is_int($element['#step'] * 1)) {
danielebarchiesi@0 281 $decimals = strlen($element['#step']) - strrpos($element['#step'], '.') - 1;
danielebarchiesi@0 282 $element['#step'] = sprintf('%1.' . $decimals . 'F', $element['#step']);
danielebarchiesi@0 283 }
danielebarchiesi@0 284
danielebarchiesi@0 285 if ($component['extra']['type'] == 'textfield') {
danielebarchiesi@0 286 // Render as textfield.
danielebarchiesi@0 287 $element['#type'] = 'webform_number';
danielebarchiesi@0 288
danielebarchiesi@0 289 // Set the size property based on #max, to ensure consistent behavior for
danielebarchiesi@0 290 // browsers that do not support type = number.
danielebarchiesi@0 291 if ($element['#max']) {
danielebarchiesi@0 292 $element['#size'] = strlen($element['#max']) + 1;
danielebarchiesi@0 293 }
danielebarchiesi@0 294 }
danielebarchiesi@0 295 else {
danielebarchiesi@0 296 // Render as select.
danielebarchiesi@0 297 $element['#type'] = 'select';
danielebarchiesi@0 298
danielebarchiesi@0 299 // Create user-specified options list as an array.
danielebarchiesi@0 300 $element['#options'] = _webform_number_select_options($component);
danielebarchiesi@0 301
danielebarchiesi@0 302 // Add default options if using a select list with no default. This trigger's
danielebarchiesi@0 303 // Drupal 7's adding of the option for us. See form_process_select().
danielebarchiesi@0 304 if ($component['extra']['type'] == 'select' && $element['#default_value'] === '') {
danielebarchiesi@0 305 $element['#empty_value'] = '';
danielebarchiesi@0 306 }
danielebarchiesi@0 307 }
danielebarchiesi@0 308
danielebarchiesi@0 309 // Set user-entered values.
danielebarchiesi@0 310 if (isset($value[0])) {
danielebarchiesi@0 311 $element['#default_value'] = $value[0];
danielebarchiesi@0 312 }
danielebarchiesi@0 313
danielebarchiesi@0 314 // Enforce uniqueness.
danielebarchiesi@0 315 if ($component['extra']['unique']) {
danielebarchiesi@0 316 $element['#element_validate'][] = 'webform_validate_unique';
danielebarchiesi@0 317 }
danielebarchiesi@0 318
danielebarchiesi@0 319 return $element;
danielebarchiesi@0 320 }
danielebarchiesi@0 321
danielebarchiesi@0 322 /**
danielebarchiesi@0 323 * Implements _webform_display_component().
danielebarchiesi@0 324 */
danielebarchiesi@0 325 function _webform_display_number($component, $value, $format = 'html') {
danielebarchiesi@0 326 $empty = !isset($value[0]) || $value[0] === '';
danielebarchiesi@0 327 return array(
danielebarchiesi@0 328 '#title' => $component['name'],
danielebarchiesi@0 329 '#weight' => $component['weight'],
danielebarchiesi@0 330 '#theme' => 'webform_display_number',
danielebarchiesi@0 331 '#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'),
danielebarchiesi@0 332 '#field_prefix' => $empty ? '' : $component['extra']['field_prefix'],
danielebarchiesi@0 333 '#field_suffix' => $empty ? '' : $component['extra']['field_suffix'],
danielebarchiesi@0 334 '#format' => $format,
danielebarchiesi@0 335 '#value' => $empty ? '' : _webform_number_format($component, $value[0]),
danielebarchiesi@0 336 '#translatable' => array('title'),
danielebarchiesi@0 337 );
danielebarchiesi@0 338 }
danielebarchiesi@0 339
danielebarchiesi@0 340 /**
danielebarchiesi@0 341 * Format the output of data for this component.
danielebarchiesi@0 342 */
danielebarchiesi@0 343 function theme_webform_display_number($variables) {
danielebarchiesi@0 344 $element = $variables['element'];
danielebarchiesi@0 345 $prefix = $element['#format'] == 'html' ? filter_xss($element['#field_prefix']) : $element['#field_prefix'];
danielebarchiesi@0 346 $suffix = $element['#format'] == 'html' ? filter_xss($element['#field_suffix']) : $element['#field_suffix'];
danielebarchiesi@0 347 $value = $element['#format'] == 'html' ? check_plain($element['#value']) : $element['#value'];
danielebarchiesi@0 348 return $value !== '' ? ($prefix . $value . $suffix) : ' ';
danielebarchiesi@0 349 }
danielebarchiesi@0 350
danielebarchiesi@0 351 /**
danielebarchiesi@0 352 * Implements _webform_analysis_component().
danielebarchiesi@0 353 */
danielebarchiesi@0 354 function _webform_analysis_number($component, $sids = array(), $single = FALSE) {
danielebarchiesi@0 355 $advanced_stats = $single;
danielebarchiesi@0 356
danielebarchiesi@0 357 $query = db_select('webform_submitted_data', 'wsd', array('fetch' => PDO::FETCH_ASSOC))
danielebarchiesi@0 358 ->fields('wsd', array('data'))
danielebarchiesi@0 359 ->condition('nid', $component['nid'])
danielebarchiesi@0 360 ->condition('cid', $component['cid']);
danielebarchiesi@0 361
danielebarchiesi@0 362 if (count($sids)) {
danielebarchiesi@0 363 $query->condition('sid', $sids, 'IN');
danielebarchiesi@0 364 }
danielebarchiesi@0 365
danielebarchiesi@0 366 $population = array();
danielebarchiesi@0 367 $submissions = 0;
danielebarchiesi@0 368 $nonzero = 0;
danielebarchiesi@0 369 $not_empty = 0;
danielebarchiesi@0 370 $sum = 0;
danielebarchiesi@0 371
danielebarchiesi@0 372 $result = $query->execute();
danielebarchiesi@0 373 foreach ($result as $data) {
danielebarchiesi@0 374 $value = trim($data['data']);
danielebarchiesi@0 375 if ($value == '') {
danielebarchiesi@0 376 $number = 0.0;
danielebarchiesi@0 377 }
danielebarchiesi@0 378 else {
danielebarchiesi@0 379 $number = $value * 1.0;
danielebarchiesi@0 380 }
danielebarchiesi@0 381
danielebarchiesi@0 382 if ($value !== '') {
danielebarchiesi@0 383 $not_empty++;
danielebarchiesi@0 384 }
danielebarchiesi@0 385
danielebarchiesi@0 386 if ($number > 0) {
danielebarchiesi@0 387 $nonzero++;
danielebarchiesi@0 388 $sum += $number;
danielebarchiesi@0 389 }
danielebarchiesi@0 390 $population[] = $number;
danielebarchiesi@0 391 $submissions++;
danielebarchiesi@0 392 }
danielebarchiesi@0 393 sort($population, SORT_NUMERIC);
danielebarchiesi@0 394
danielebarchiesi@0 395 // Average and population count.
danielebarchiesi@0 396 if ($component['extra']['excludezero']) {
danielebarchiesi@0 397 $average = $nonzero ? ($sum / $nonzero) : 0;
danielebarchiesi@0 398 $average_title = t('Average !mu excluding zeros/blanks', array('!mu' => $advanced_stats ? '(&mu;)' : ''));
danielebarchiesi@0 399 // Sample (sub-set of total population).
danielebarchiesi@0 400 $population_count = $nonzero - 1;
danielebarchiesi@0 401 $sigma = 'sd';
danielebarchiesi@0 402 $description = t('sample');
danielebarchiesi@0 403 }
danielebarchiesi@0 404 else {
danielebarchiesi@0 405 $average = $submissions ? ($sum / $submissions) : 0;
danielebarchiesi@0 406 $average_title = t('Average !mu including zeros/blanks', array('!mu' => $advanced_stats ? '(&mu;)' : ''));
danielebarchiesi@0 407 // Population.
danielebarchiesi@0 408 $population_count = $submissions;
danielebarchiesi@0 409 $sigma = '&sigma;';
danielebarchiesi@0 410 $description = t('population');
danielebarchiesi@0 411 }
danielebarchiesi@0 412
danielebarchiesi@0 413 // Formatting.
danielebarchiesi@0 414 $average = _webform_number_format($component, $average);
danielebarchiesi@0 415 $sum = _webform_number_format($component, $sum);
danielebarchiesi@0 416
danielebarchiesi@0 417 $rows[0] = array(t('Zero/blank'), ($submissions - $nonzero));
danielebarchiesi@0 418 $rows[1] = array(t('User entered value'), $not_empty);
danielebarchiesi@0 419 $rows[2] = array(t('Sum') . ($advanced_stats ? ' (&Sigma;)' : ''), $sum);
danielebarchiesi@0 420 $rows[3] = array($average_title, $average);
danielebarchiesi@0 421
danielebarchiesi@0 422 if (!$advanced_stats && $sum != 0) {
danielebarchiesi@0 423 $rows[4] = array('', l(t('More stats »'), 'node/' . $component['nid'] . '/webform-results/analysis/' . $component['cid']));
danielebarchiesi@0 424 }
danielebarchiesi@0 425
danielebarchiesi@0 426 // Normal distribution information.
danielebarchiesi@0 427 if ($advanced_stats && $population_count && $sum != 0) {
danielebarchiesi@0 428 // Standard deviation.
danielebarchiesi@0 429 $stddev = 0;
danielebarchiesi@0 430 foreach($population as $value) {
danielebarchiesi@0 431 // Obtain the total of squared variances.
danielebarchiesi@0 432 $stddev += pow(($value - $average), 2);
danielebarchiesi@0 433 }
danielebarchiesi@0 434 if ($population_count > 0) {
danielebarchiesi@0 435 $stddev = sqrt($stddev / $population_count);
danielebarchiesi@0 436 }
danielebarchiesi@0 437 else {
danielebarchiesi@0 438 $stddev = sqrt($stddev);
danielebarchiesi@0 439 }
danielebarchiesi@0 440
danielebarchiesi@0 441 // Build normal distribution table rows.
danielebarchiesi@0 442 $count = array();
danielebarchiesi@0 443 $percent = array();
danielebarchiesi@0 444 $limit = array();
danielebarchiesi@0 445 $index = 0;
danielebarchiesi@0 446
danielebarchiesi@0 447 $count[] = 0;
danielebarchiesi@0 448 $limit[] = $average - ($stddev * 4);
danielebarchiesi@0 449 foreach ($population as $value) {
danielebarchiesi@0 450 while ($value >= $limit[$index]) {
danielebarchiesi@0 451 $percent[] = number_format($count[$index] / $population_count * 100, 2, '.', '');
danielebarchiesi@0 452 $limit[] = $limit[$index] + $stddev;
danielebarchiesi@0 453 $index += 1;
danielebarchiesi@0 454 if ($limit[$index] == $average) {
danielebarchiesi@0 455 $limit[$index] = $limit[$index] + $stddev;
danielebarchiesi@0 456 }
danielebarchiesi@0 457 $count[$index] = 0;
danielebarchiesi@0 458 }
danielebarchiesi@0 459 $count[$index] += 1;
danielebarchiesi@0 460 }
danielebarchiesi@0 461 $percent[] = number_format($count[$index] / $population_count * 100, 2, '.', '');
danielebarchiesi@0 462
danielebarchiesi@0 463 // Format normal distribution table output.
danielebarchiesi@0 464 $stddev = _webform_number_format($component, $stddev);
danielebarchiesi@0 465 $low = _webform_number_format($component, $population[0]);
danielebarchiesi@0 466 $high = _webform_number_format($component, end($population));
danielebarchiesi@0 467 foreach($limit as $key => $value) {
danielebarchiesi@0 468 $limit[$key] = _webform_number_format($component, $value);
danielebarchiesi@0 469 }
danielebarchiesi@0 470
danielebarchiesi@0 471 // Column headings (override potential theme uppercase, e.g. Seven in D7).
danielebarchiesi@0 472 $header = array(
danielebarchiesi@0 473 t('Normal Distribution'),
danielebarchiesi@0 474 array('data' => '-4' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 475 array('data' => '-3' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 476 array('data' => '-2' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 477 array('data' => '-1' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 478 array('data' => '+1' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 479 array('data' => '+2' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 480 array('data' => '+3' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 481 array('data' => '+4' . $sigma, 'style' => 'text-transform: lowercase;',),
danielebarchiesi@0 482 );
danielebarchiesi@0 483
danielebarchiesi@0 484 // Insert row labels.
danielebarchiesi@0 485 array_unshift($limit, t('Boundary'));
danielebarchiesi@0 486 array_unshift($count, t('Count'));
danielebarchiesi@0 487 array_unshift($percent, t('% of !description', array('!description' => $description)));
danielebarchiesi@0 488
danielebarchiesi@0 489 $output = theme('table', array('header' => $header, 'rows' => array($limit, $count, $percent)));
danielebarchiesi@0 490
danielebarchiesi@0 491 $rows[4] = array(t('Range'), t('!low to !high', array('!low' => $low, '!high' => $high)));
danielebarchiesi@0 492 $rows[5] = array(t('Standard deviation (!sigma)', array('!sigma' => $sigma)), $stddev);
danielebarchiesi@0 493 $rows[6] = array(array('data' => $output, 'colspan' => 2));
danielebarchiesi@0 494 }
danielebarchiesi@0 495
danielebarchiesi@0 496 return $rows;
danielebarchiesi@0 497 }
danielebarchiesi@0 498
danielebarchiesi@0 499 /**
danielebarchiesi@0 500 * Implements _webform_table_component().
danielebarchiesi@0 501 */
danielebarchiesi@0 502 function _webform_table_number($component, $value) {
danielebarchiesi@0 503 return isset($value[0]) ? _webform_number_format($component, $value[0]) : '';
danielebarchiesi@0 504 }
danielebarchiesi@0 505
danielebarchiesi@0 506 /**
danielebarchiesi@0 507 * Implements _webform_csv_headers_component().
danielebarchiesi@0 508 */
danielebarchiesi@0 509 function _webform_csv_headers_number($component, $export_options) {
danielebarchiesi@0 510 $header = array();
danielebarchiesi@0 511 $header[0] = '';
danielebarchiesi@0 512 $header[1] = '';
danielebarchiesi@0 513 $header[2] = $component['name'];
danielebarchiesi@0 514 return $header;
danielebarchiesi@0 515 }
danielebarchiesi@0 516
danielebarchiesi@0 517 /**
danielebarchiesi@0 518 * Implements _webform_csv_data_component().
danielebarchiesi@0 519 */
danielebarchiesi@0 520 function _webform_csv_data_number($component, $export_options, $value) {
danielebarchiesi@0 521 if (isset($value[0]) && is_numeric($value[0]) && $component['extra']['decimals'] !== '') {
danielebarchiesi@0 522 $value[0] = number_format($value[0], $component['extra']['decimals'], '.', '');
danielebarchiesi@0 523 }
danielebarchiesi@0 524 return isset($value[0]) ? $value[0] : '';
danielebarchiesi@0 525 }
danielebarchiesi@0 526
danielebarchiesi@0 527 /**
danielebarchiesi@0 528 * A Drupal Form API Validation function. Validates the entered values from
danielebarchiesi@0 529 * number components on the client-side form.
danielebarchiesi@0 530 *
danielebarchiesi@0 531 * @param $element
danielebarchiesi@0 532 * The form element. May either be a select or a webform_number element.
danielebarchiesi@0 533 * @param $form_state
danielebarchiesi@0 534 * The full form state for the webform.
danielebarchiesi@0 535 * @return
danielebarchiesi@0 536 * None. Calls a form_set_error if the number is not valid.
danielebarchiesi@0 537 */
danielebarchiesi@0 538 function _webform_validate_number($element, &$form_state) {
danielebarchiesi@0 539 $value = trim($element['#value']);
danielebarchiesi@0 540 form_set_value($element, $value, $form_state);
danielebarchiesi@0 541
danielebarchiesi@0 542 if ($value != '') {
danielebarchiesi@0 543 // Numeric test.
danielebarchiesi@0 544 if (is_numeric($value)) {
danielebarchiesi@0 545 // Range test.
danielebarchiesi@0 546 if ($element['#min'] != '' && $element['#max'] != '') {
danielebarchiesi@0 547 // Flip minimum and maximum if needed.
danielebarchiesi@0 548 if ($element['#max'] > $element['#min']) {
danielebarchiesi@0 549 $min = $element['#min'];
danielebarchiesi@0 550 $max = $element['#max'];
danielebarchiesi@0 551 }
danielebarchiesi@0 552 else {
danielebarchiesi@0 553 $min = $element['#max'];
danielebarchiesi@0 554 $max = $element['#min'];
danielebarchiesi@0 555 }
danielebarchiesi@0 556 if ($value > $max || $value < $min) {
danielebarchiesi@0 557 form_error($element, t('%name field value of @value should be in the range @min to @max.', array('%name' => $element['#title'], '@value' => $value, '@min' => $min, '@max' => $max)));
danielebarchiesi@0 558 }
danielebarchiesi@0 559 }
danielebarchiesi@0 560 elseif ($element['#max'] != '' && $value > $element['#max']) {
danielebarchiesi@0 561 form_error($element, t('%name field value must be less than @max.', array('%name' => $element['#title'], '@max' => $element['#max'])));
danielebarchiesi@0 562 }
danielebarchiesi@0 563 elseif ($element['#min'] != '' && $value < $element['#min']) {
danielebarchiesi@0 564 form_error($element, t('%name field value must be greater than @min.', array('%name' => $element['#title'], '@min' => $element['#min'])));
danielebarchiesi@0 565 }
danielebarchiesi@0 566
danielebarchiesi@0 567 // Integer test.
danielebarchiesi@0 568 if ($element['#integer'] && !is_int($value * 1)) {
danielebarchiesi@0 569 form_error($element, t('%name field value of @value must be an integer.', array('%name' => $element['#title'], '@value' => $value)));
danielebarchiesi@0 570 }
danielebarchiesi@0 571
danielebarchiesi@0 572 // Step test.
danielebarchiesi@0 573 $starting_number = $element['#min'] ? $element['#min'] : 0;
danielebarchiesi@0 574 if ($element['#step'] != 0 && fmod($element['#value'] - $starting_number, $element['#step']) != 0) {
danielebarchiesi@0 575 $samples = array(
danielebarchiesi@0 576 $starting_number,
danielebarchiesi@0 577 $starting_number + ($element['#step'] * 1),
danielebarchiesi@0 578 $starting_number + ($element['#step'] * 2),
danielebarchiesi@0 579 $starting_number + ($element['#step'] * 3),
danielebarchiesi@0 580 );
danielebarchiesi@0 581 if ($starting_number) {
danielebarchiesi@0 582 form_error($element, t('%name field value must be @start plus a multiple of @step. i.e. @samples, etc.', array('%name' => $element['#title'], '@start' => $element['#min'], '@step' => $element['#step'], '@samples' => implode(', ', $samples))));
danielebarchiesi@0 583 }
danielebarchiesi@0 584 else {
danielebarchiesi@0 585 form_error($element, t('%name field value must be a multiple of @step. i.e. @samples, etc.', array('%name' => $element['#title'], '@step' => $element['#step'], '@samples' => implode(', ', $samples))));
danielebarchiesi@0 586 }
danielebarchiesi@0 587 }
danielebarchiesi@0 588 }
danielebarchiesi@0 589 else {
danielebarchiesi@0 590 form_error($element, t('%name field value of @value must be numeric.', array('%name' => $element['#title'], '@value' => $value)));
danielebarchiesi@0 591 }
danielebarchiesi@0 592 }
danielebarchiesi@0 593
danielebarchiesi@0 594 }
danielebarchiesi@0 595
danielebarchiesi@0 596 /**
danielebarchiesi@0 597 * Validation of number edit form items.
danielebarchiesi@0 598 */
danielebarchiesi@0 599 function _webform_edit_number_validate($element, &$form_state) {
danielebarchiesi@0 600 // Find the value of all related fields to this element.
danielebarchiesi@0 601 $parents = $element['#parents'];
danielebarchiesi@0 602 $key = array_pop($parents);
danielebarchiesi@0 603 $values = $form_state['values'];
danielebarchiesi@0 604 foreach ($parents as $parent) {
danielebarchiesi@0 605 $values = $values[$parent];
danielebarchiesi@0 606 }
danielebarchiesi@0 607
danielebarchiesi@0 608 switch ($key) {
danielebarchiesi@0 609 case 'min':
danielebarchiesi@0 610 if ($values['min'] == '') {
danielebarchiesi@0 611 if (isset($values['type']) && $values['type'] === 'select') {
danielebarchiesi@0 612 form_error($element, t('Minimum is required when using a select list element.'));
danielebarchiesi@0 613 }
danielebarchiesi@0 614 }
danielebarchiesi@0 615 else {
danielebarchiesi@0 616 if (!is_numeric($values['min'])) {
danielebarchiesi@0 617 form_error($element, t('Minimum must be numeric.'));
danielebarchiesi@0 618 }
danielebarchiesi@0 619 if ($values['integer'] && !is_int($values['min'] * 1)) {
danielebarchiesi@0 620 form_error($element, t('Minimum must have an integer value.'));
danielebarchiesi@0 621 }
danielebarchiesi@0 622 }
danielebarchiesi@0 623 break;
danielebarchiesi@0 624 case 'max':
danielebarchiesi@0 625 if ($values['max'] == '') {
danielebarchiesi@0 626 if (isset($values['type']) && $values['type'] === 'select') {
danielebarchiesi@0 627 form_error($element, t('Maximum is required when using a select list element.'));
danielebarchiesi@0 628 }
danielebarchiesi@0 629 }
danielebarchiesi@0 630 else {
danielebarchiesi@0 631 if (!is_numeric($values['max'])) {
danielebarchiesi@0 632 form_error($element, t('Maximum must be numeric.'));
danielebarchiesi@0 633 }
danielebarchiesi@0 634 if ($values['integer'] && !is_int($values['max'] * 1)) {
danielebarchiesi@0 635 form_error($element, t('Maximum must have an integer value.'));
danielebarchiesi@0 636 }
danielebarchiesi@0 637 }
danielebarchiesi@0 638 break;
danielebarchiesi@0 639 case 'step':
danielebarchiesi@0 640 if ($values['step'] !== '') {
danielebarchiesi@0 641 if (!is_numeric($values['step'])) {
danielebarchiesi@0 642 form_error($element, t('Step must be numeric.'));
danielebarchiesi@0 643 }
danielebarchiesi@0 644 else {
danielebarchiesi@0 645 if ($values['integer'] && !is_int($values['step'] * 1)) {
danielebarchiesi@0 646 form_error($element, t('Step must have an integer value.'));
danielebarchiesi@0 647 }
danielebarchiesi@0 648 }
danielebarchiesi@0 649 }
danielebarchiesi@0 650 break;
danielebarchiesi@0 651 }
danielebarchiesi@0 652 return TRUE;
danielebarchiesi@0 653 }
danielebarchiesi@0 654
danielebarchiesi@0 655 /**
danielebarchiesi@0 656 * Generate select list options.
danielebarchiesi@0 657 */
danielebarchiesi@0 658 function _webform_number_select_options($component) {
danielebarchiesi@0 659 $options = array();
danielebarchiesi@0 660 $step = abs($component['extra']['step']);
danielebarchiesi@0 661
danielebarchiesi@0 662 // Step is optional and defaults to 1.
danielebarchiesi@0 663 $step = empty($step) ? 1 : $step;
danielebarchiesi@0 664
danielebarchiesi@0 665 // Generate list in correct direction.
danielebarchiesi@0 666 $min = $component['extra']['min'];
danielebarchiesi@0 667 $max = $component['extra']['max'];
danielebarchiesi@0 668 $flipped = FALSE;
danielebarchiesi@0 669 if ($max < $min) {
danielebarchiesi@0 670 $min = $component['extra']['max'];
danielebarchiesi@0 671 $max = $component['extra']['min'];
danielebarchiesi@0 672 $flipped = TRUE;
danielebarchiesi@0 673 }
danielebarchiesi@0 674
danielebarchiesi@0 675 for ($f = $min; $f <= $max; $f += $step) {
danielebarchiesi@0 676 $options[$f . ''] = $f . '';
danielebarchiesi@0 677 }
danielebarchiesi@0 678
danielebarchiesi@0 679 // TODO: HTML5 browsers apparently do not include the max value if it does
danielebarchiesi@0 680 // not line up with step. Restore this if needed in the future.
danielebarchiesi@0 681 // Add end limit if it's been skipped due to step.
danielebarchiesi@0 682 //if (end($options) != $max) {
danielebarchiesi@0 683 // $options[$f] = $max;
danielebarchiesi@0 684 //}
danielebarchiesi@0 685
danielebarchiesi@0 686 if ($flipped) {
danielebarchiesi@0 687 $options = array_reverse($options, TRUE);
danielebarchiesi@0 688 }
danielebarchiesi@0 689
danielebarchiesi@0 690 // Apply requisite number formatting.
danielebarchiesi@0 691 foreach ($options as $key => $value) {
danielebarchiesi@0 692 $options[$key] = _webform_number_format($component, $value);
danielebarchiesi@0 693 }
danielebarchiesi@0 694
danielebarchiesi@0 695 return $options;
danielebarchiesi@0 696 }
danielebarchiesi@0 697
danielebarchiesi@0 698 /**
danielebarchiesi@0 699 * Apply number format.
danielebarchiesi@0 700 */
danielebarchiesi@0 701 function _webform_number_format($component, $value) {
danielebarchiesi@0 702 if (!is_numeric($value)) {
danielebarchiesi@0 703 return '';
danielebarchiesi@0 704 }
danielebarchiesi@0 705 // If no decimal places are specified, do a best guess length of decimals.
danielebarchiesi@0 706 $decimals = $component['extra']['decimals'];
danielebarchiesi@0 707 if ($decimals === '') {
danielebarchiesi@0 708 // If it's an integer, no decimals needed.
danielebarchiesi@0 709 if (is_int(($value . '') * 1)) {
danielebarchiesi@0 710 $decimals = 0;
danielebarchiesi@0 711 }
danielebarchiesi@0 712 else {
danielebarchiesi@0 713 $decimals = strlen($value) - strrpos($value, '.') - 1;
danielebarchiesi@0 714 }
danielebarchiesi@0 715 if ($decimals > 4) {
danielebarchiesi@0 716 $decimals = 4;
danielebarchiesi@0 717 }
danielebarchiesi@0 718 }
danielebarchiesi@0 719
danielebarchiesi@0 720 return number_format($value, $decimals, $component['extra']['point'], $component['extra']['separator']);
danielebarchiesi@0 721 }