You are here

function slickgrid_preprocess_views_view_slickgrid in Slickgrid 6

Same name and namespace in other branches
  1. 7.2 theme/theme.inc \slickgrid_preprocess_views_view_slickgrid()
  2. 7 theme/theme.inc \slickgrid_preprocess_views_view_slickgrid()

Preprocessor for views-view-slickgrid.tpl.php Repurpose the views result for slickgrid

File

./slickgrid.module, line 279

Code

function slickgrid_preprocess_views_view_slickgrid(&$vars) {
  global $user;

  // We'll need node.pages so the node forms can be pseudo-rendered
  module_load_include('inc', 'node', 'node.pages');
  $view = $vars['view'];

  // Get any view settings
  $view->style_plugin->options['settings'] = (array) slickgrid_get_settings($user->uid, $view->name) + (array) $view->style_plugin->options['settings'];

  // Set header height default
  $view->style_plugin->options['headerHeight'] = 42;

  // Add some extra slickgrid options here
  $view->style_plugin->options['enableCellNavigation'] = $view->style_plugin->options['editable'];
  $view->style_plugin->options['enableAddRow'] = false;

  // Overide view height option if it's been set by user
  if (is_numeric($view->style_plugin->options['settings']['viewport_height'])) {
    $view->style_plugin->options['viewport_height'] = $view->style_plugin->options['settings']['viewport_height'];
  }

  // Overide forceFitColumns option if it's been set by user
  if (isset($view->style_plugin->options['settings']['forceFitColumns'])) {
    $view->style_plugin->options['forceFitColumns'] = (int) $view->style_plugin->options['settings']['forceFitColumns'];
  }
  $result = $vars['rows'];
  $handler = $view->style_plugin;
  $handlers = $view->style_plugin->display->handler
    ->get_handlers('field');
  $fields =& $view->field;
  $ordered_columns = array();
  $unordered_columns = array();

  // Build the slickgrid columns
  foreach ($handlers as $field => $handler) {

    // If this field is ecluded from the display, continue to the next one
    if ($handler->options['exclude']) {
      continue;
    }
    if (!($name = $handler
      ->label())) {
      $name = $handler
        ->ui_name();
    }
    $handler->content_field['field_name'] ? $field_name = $handler->content_field['field_name'] : ($field_name = $field);

    // Get the column width
    if ($view->style_plugin->options['settings']['column_width'][$field]) {

      // UI column resized
      $column_width = $view->style_plugin->options['settings']['column_width'][$field];
    }
    elseif ($view->style_plugin->options['columns'][$field]['width']) {

      // width set from within the view
      $column_width = $view->style_plugin->options['columns'][$field]['width'];
    }
    else {
      $column_width = 100;

      // default width for all unset columns
    }
    $column = array(
      'id' => $field,
      // The ID of the field from the view
      'name' => $name,
      // Column title / label
      'field' => $field_name,
      // The CCK / Node field name - data values match the field
      'width' => $column_width,
      'cssClass' => 'cell-title',
      'resizable' => $view->style_plugin->options['enableColumnResize'] ? 1 : 0,
    );

    // Is this a taxonomy term field?
    if (is_array($handler->options['vids']) && ($vid = slickgrid_taxonomy_field_get_vid($handler))) {
      $column['vid'] = $vid;
    }

    // Is this field being filtered?
    // If any fields require filtering, we need to let the JS know
    if ($view->style_plugin->options['columns'][$field]['filter']) {
      $view->style_plugin->options['has_filters'] = TRUE;

      // Add a header row for the filters
      // Don't add a headerRow if the filter is set on a taxonomy filter field - this won't require a header row
      if ($view->style_plugin->options['collapsible_taxonomy_field'] != $field) {
        $view->style_plugin->options['showHeaderRow'] = TRUE;
      }
    }

    // Loop through all the plugin types and see if it's been set for this column
    foreach (array_keys(slickgrid_get_plugin_types()) as $plugin_type) {

      // Is there an plugin defined for this column
      if ($view->style_plugin->options['columns'][$field][$plugin_type]) {
        $column[$plugin_type] = $view->style_plugin->options['columns'][$field][$plugin_type];

        // If just one column is editable, turn on editable & cell navigation for the grid
        if ($plugin_type == 'editor') {
          $view->style_plugin->options['editable'] = TRUE;
          $view->style_plugin->options['enableCellNavigation'] = TRUE;
        }
      }
    }

    // Is this field sortable?
    // If any fields are sortable, set style option so we can access it in the js
    // DO NOT turn on sortable columns if collapsible_taxonomy_field is set - they are not compatible
    if ($view->style_plugin->options['columns'][$field]['sortable'] & !$view->style_plugin->options['collapsible_taxonomy_field']) {
      $view->style_plugin->options['sortable_columns'] = TRUE;
      $column['sortable'] = 1;
    }

    // Is this using the collapsible tree formatter plugin?
    if ($view->style_plugin->options['collapsible_taxonomy_field'] == $field) {

      // Set the filters & formatters for the collapsible field column
      $view->style_plugin->options['columns'][$field]['filter'] = $column['filter'] = 'collapsibleFilter';
      $view->style_plugin->options['columns'][$field]['formatter'] = $column['formatter'] = 'collapsibleFormatter';
      $view->style_plugin->options['has_filters'] = true;
    }

    // We need to know the column label for the group by function in JS
    // Add it to the views plugin options so we can access it efficiantly (otherwise I'll need to loop thru columns array)
    $view->style_plugin->options['columns'][$field]['label'] = $name;
    if (is_array($view->style_plugin->options['settings']['ordered_columns']) && is_numeric($ordered_column_position = array_search($field, $view->style_plugin->options['settings']['ordered_columns']))) {

      // This is an ordered column
      $ordered_columns[$ordered_column_position] = $column;
    }
    else {

      // There is no ordering for this column
      $unordered_columns[] = $column;
    }
  }
  ksort($ordered_columns);

  // Merge ordered & unordered columns
  // Any unordered columns are added to the end to allow for new columns added through the view
  $columns = array_merge($ordered_columns, $unordered_columns);

  // Allow other modules to change the columns before they're output as a slickgrid
  drupal_alter('slickgrid', $data, 'columns', $view);

  // Construct the slickgrid data array
  $keys = array_keys($view->field);
  $parents = array();

  // array of tid => array(nid => nid, indent => indent) so we can retrive the nid & indentation of a parent node
  $data = array();
  if (is_array($result)) {

    // Keep a record of all ids & trigger an error on duplication
    $ids = array();
    foreach ($result as $count => $row) {

      // Has this already been added to the data grid?
      if (in_array($row->nid, $ids)) {
        drupal_set_message(t('There are duplicate nodes in this grid - each row must be unique.'), 'error');
        watchdog('slickgrid', t('Duplicate nodes - @id is not unique.'), array(
          '@id' => $row->{$view->base_field},
        ), WATCHDOG_ERROR);
        break;
      }
      else {

        // Add the data fields
        foreach ($columns as $column) {
          if (!$view->field[$column['field']]->options['exclude']) {
            $data[$count][$column['field']] = $view->field[$column['id']]
              ->theme($row);
          }
        }
        $data[$count]['id'] = $row->nid;

        // If this has collapsible_taxonomy_field set, we will have added slickgrid_parent_tid & slickgrid_tid in hook_views_pre_view
        // These are aliased in $row so get the field aliases
        if (property_exists($row, $view->field['slickgrid_tid']->field_alias) && ($slickgrid_tid = $row->{$view->field['slickgrid_tid']->field_alias})) {
          if ($parent = $parents[$row->{$view->field['slickgrid_parent_tid']->field_alias}]) {

            // If we can find a parent, set the parent nid & indentation++
            $data[$count]['indent'] = $parent['indent'] + 1;
            $data[$count]['parent'] = $parent['nid'];
          }
          else {

            // Otherwise set indent & parent to 0 - this breaks if left blank
            $data[$count]['indent'] = 0;
            $data[$count]['parent'] = 0;
          }

          // Store the indent & nid so then can be used to calculate child term indentation
          $parents[$slickgrid_tid] = array(
            'nid' => $row->nid,
            'indent' => $data[$count]['indent'],
          );
        }
      }
    }
  }

  // Allow other modules to change the data before it's output as a slickgrid
  drupal_alter('slickgrid', $data, 'data', $view);
  $vars['slickgrid'] = theme('slickgrid', $view->style_plugin->options, $columns, $data, $view);
}