You are here

public function view::fix_missing_relationships in Views (for Drupal 7) 7.3

Attempt to discover if the view has handlers missing relationships.

This will try to add relationships automatically if it can, and will remove the handlers if it cannot.

1 call to view::fix_missing_relationships()
view::init_handlers in includes/view.inc
Acquire and attach all of the handlers.

File

includes/view.inc, line 623
views_objects Objects that represent a View or part of a view

Class

view
An object to contain all of the data to generate a view.

Code

public function fix_missing_relationships() {
  if (isset($this->relationships_fixed)) {
    return;
  }
  $this->relationships_fixed = TRUE;

  // Go through all of our handler types and test them to see if they
  // are missing relationships. Missing relationships can cause fatally
  // broken Views.
  $base_tables = array(
    $this->base_table => TRUE,
    '#global' => TRUE,
  );

  // For each relationship we have, make sure we mark the base it provides as
  // available.
  foreach ($this->display_handler
    ->get_option('relationships') as $id => $options) {
    $options['table'] = views_move_table($options['table']);
    $data = views_fetch_data($options['table'], FALSE);
    if (isset($data[$options['field']]['relationship']['base'])) {
      $base_tables[$data[$options['field']]['relationship']['base']] = TRUE;
    }
  }
  $base_tables = array_keys($base_tables);
  $missing_base_tables = array();
  $types = views_object_types();
  foreach ($types as $key => $info) {
    foreach ($this->display_handler
      ->get_option($info['plural']) as $id => $options) {
      $options['table'] = views_move_table($options['table']);
      $data = views_fetch_data($options['table'], FALSE);
      $valid_bases = array(
        $options['table'],
      );
      if (isset($data['table']['join'])) {
        $valid_bases = array_merge($valid_bases, array_keys($data['table']['join']));
      }

      // If the base table is missing, record it so we can try to fix it.
      if (!array_intersect($valid_bases, $base_tables)) {
        $missing_base_tables[$options['table']][] = array(
          'type' => $key,
          'id' => $id,
        );
      }
    }
  }
  if (!empty($missing_base_tables)) {

    // This will change handlers, so make sure any existing handlers get
    // tossed.
    $this->display_handler->handlers = array();
    $this->relationships_changed = TRUE;
    $this->changed = TRUE;

    // Try to fix it.
    foreach ($missing_base_tables as $table => $handlers) {
      $data = views_fetch_data($table);
      $relationship = NULL;

      // Does the missing base table have a default relationship we can
      // throw in?
      if (isset($data['table']['default_relationship'][$this->base_table])) {

        // Create the relationship.
        $info = $data['table']['default_relationship'][$this->base_table];
        $relationship_options = isset($info['options']) ? $info['options'] : array();
        $relationship = $this
          ->add_item($this->current_display, 'relationship', $info['table'], $info['field'], $relationship_options);
      }
      foreach ($handlers as $handler) {
        $options = $this->display_handler
          ->get_option($types[$handler['type']]['plural']);
        if ($relationship) {
          $options[$handler['id']]['relationship'] = $relationship;
        }
        else {
          unset($options[$handler['id']]);
        }
        $this->display_handler
          ->set_option($types[$handler['type']]['plural'], $options);
      }
    }
  }
}