You are here

function views_crosstab_table::options_validate in Views Crosstab 7

Same name and namespace in other branches
  1. 6 views_crosstab_table.inc \views_crosstab_table::options_validate()

Validate the options form.

Parameters

array $form: Reference to the form array we're building.

array $form_state: Reference to the form state.

Overrides views_plugin_style::options_validate

File

plugins/views_crosstab_table.inc, line 167
Plugin functions

Class

views_crosstab_table
Style plugin to transform a linear query into a crosstab table.

Code

function options_validate(&$form, &$form_state) {
  parent::options_validate($form, $form_state);

  // Get machine_names (keys) of crosstab field options.
  $crosstab_options = array_keys(views_crosstab_field_options());

  // Ensure that the user has not picked the same field for more than
  // crosstab option.  Do this by looping over the three crosstab options
  // (rows, columns, data) twice.
  foreach ($crosstab_options as $crosstab_option) {

    // Perform nested loop over same crosstab options array.
    foreach ($crosstab_options as $crosstab_option_compare) {

      // Only compare different options.
      if ($crosstab_option != $crosstab_option_compare) {

        // Get field name used in each of the two options being compared.
        $crosstab_option_field_name = $form_state['values']['style_options'][$crosstab_option];
        $crosstab_option_compare_field_name = $form_state['values']['style_options'][$crosstab_option_compare];

        // If the field names are the same, then the user has picked the same
        // field for two different crosstab options and the query will likely
        // not work or produce unintended results.
        // TODO: check that this test doesn't return false positive errors
        // due to same field name from two different sources.
        if ($crosstab_option_field_name == $crosstab_option_compare_field_name) {

          // Define placeholders for error message.
          $error_items = array(
            '%field_display_value' => $form['info'][$crosstab_option_field_name]['name']['#markup'],
            '%crosstab_option' => $crosstab_option,
            '%crosstab_option_compare' => $crosstab_option_compare,
          );

          // Report the error.
          $error_message = 'You cannot set the same field (%field_display_value) ';
          $error_message .= 'to be a source for <strong>both</strong> ';
          $error_message .= '%crosstab_option and %crosstab_option_compare.';
          form_error($form[$crosstab_option][$crosstab_option_field_name], t($error_message, $error_items));

          // Break out of nested loop and outer loop.
          break 2;
        }
      }
    }
  }

  // Ensure that the field type selected for aggregation options is valid for
  // the chosen aggregation operation.
  // Get the aggregation operation.
  $crosstab_operation = $form_state['values']['style_options']['crosstab_operation'];

  // Define field types that can be aggregated.
  $field_types_that_can_be_aggregated = array(
    'SUM' => array(
      'serial',
      'int',
      'float',
      'numeric',
    ),
    'AVG' => array(
      'serial',
      'int',
      'float',
      'numeric',
    ),
    'MIN' => array(
      'serial',
      'int',
      'float',
      'numeric',
      'varchar',
      'char',
      'text',
    ),
    'MAX' => array(
      'serial',
      'int',
      'float',
      'numeric',
      'varchar',
      'char',
      'text',
    ),
  );

  // Assume all field types can be COUNTed and do not need to be included
  // in this validation check.
  if ($crosstab_operation != "COUNT") {

    // Get field handlers for the current display.
    $field_handlers = $this->display->handler->handlers['field'];
    if ($field_handlers) {

      // Loop over the field handlers.
      foreach ($field_handlers as $handler) {

        // Get the table name and field associated with
        // the handler of the field.
        $table_name = $handler->table;
        $field_name = $handler->field;

        // Get crosstab option field name.
        $crosstab_data_field_name = $form_state['values']['style_options']['crosstab_data'];

        // Check if the crosstab data field name matches the handler field.
        if ($crosstab_data_field_name == $field_name) {

          // Check the field exists - this should be a redundant check.
          $field_exists = db_field_exists($table_name, $field_name);
          if ($field_exists) {

            // Get the database schema for the field's table.
            $schema = drupal_get_schema($table_name);

            // Get the drupal database field type for the field.
            $field_type = $schema['fields'][$field_name]['type'];

            // Look for a matching field type for the aggregation operation.
            if (!in_array($field_type, $field_types_that_can_be_aggregated[$crosstab_operation])) {

              // Define placeholders for error message.
              $error_items = array(
                '%crosstab_data_field_name' => $crosstab_data_field_name,
                '%field_type' => $field_type,
                '%operation' => $crosstab_operation,
              );

              // Report the error.
              form_error($form['crosstab_data'][$crosstab_data_field_name], t('The field selected for the crosstab data (%crosstab_data_field_name)
                has a %field_type, which cannot be used in a %operation operation.', $error_items));
            }
          }
        }
      }
    }
  }
}