RelationshipPluginBase.php 5.32 KB
Newer Older
merlinofchaos's avatar
merlinofchaos committed
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\views\Plugin\views\relationship\RelationshipPluginBase.
merlinofchaos's avatar
merlinofchaos committed
6 7
 */

8
namespace Drupal\views\Plugin\views\relationship;
9

10
use Drupal\views\ViewExecutable;
11
use Drupal\views\Plugin\views\display\DisplayPluginBase;
12
use Drupal\views\Plugin\views\HandlerBase;
13
use Drupal\views\Join;
14
use Drupal\views\Views;
15

merlinofchaos's avatar
merlinofchaos committed
16 17 18
/**
 * @defgroup views_relationship_handlers Views relationship handlers
 * @{
19 20 21
 * Plugins for handling views relationships.
 *
 * Relationship handlers extend
22
 * \Drupal\views\Plugin\views\relationship\RelationshipPluginBase. They must
23 24 25 26 27
 * be annotated with \Drupal\views\Annotation\ViewsRelationship annotation,
 * and they must be in namespace directory Plugin\views\relationship.
 *
 * @ingroup views_plugins
 * @see plugin_api
merlinofchaos's avatar
merlinofchaos committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
 */

/**
 * Simple relationship handler that allows a new version of the primary table
 * to be linked in.
 *
 * The base relationship handler can only handle a single join. Some relationships
 * are more complex and might require chains of joins; for those, you must
 * utilize a custom relationship handler.
 *
 * Definition items:
 * - base: The new base table this relationship will be adding. This does not
 *   have to be a declared base table, but if there are no tables that
 *   utilize this base table, it won't be very effective.
 * - base field: The field to use in the relationship; if left out this will be
 *   assumed to be the primary field.
 * - relationship table: The actual table this relationship operates against.
 *   This is analogous to using a 'table' override.
 * - relationship field: The actual field this relationship operates against.
 *   This is analogous to using a 'real field' override.
 * - label: The default label to provide for this relationship, which is
 *   shown in parentheses next to any field/sort/filter/argument that uses
 *   the relationship.
 *
 * @ingroup views_relationship_handlers
 */
54
abstract class RelationshipPluginBase extends HandlerBase {
dawehner's avatar
dawehner committed
55

merlinofchaos's avatar
merlinofchaos committed
56
  /**
57 58
   * Overrides \Drupal\views\Plugin\views\HandlerBase::init().
   *
merlinofchaos's avatar
merlinofchaos committed
59 60 61
   * Init handler to let relationships live on tables other than
   * the table they operate on.
   */
62 63 64
  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    parent::init($view, $display, $options);

merlinofchaos's avatar
merlinofchaos committed
65 66 67 68
    if (isset($this->definition['relationship table'])) {
      $this->table = $this->definition['relationship table'];
    }
    if (isset($this->definition['relationship field'])) {
69 70 71
      // Set both realField and field so custom handler can rely on the old
      // field value.
      $this->realField = $this->field = $this->definition['relationship field'];
merlinofchaos's avatar
merlinofchaos committed
72 73 74
    }
  }

75 76 77 78 79 80 81 82 83 84
  /**
   * {@inheritdoc}
   */
  public function usesGroupBy() {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
85 86
  protected function defineOptions() {
    $options = parent::defineOptions();
merlinofchaos's avatar
merlinofchaos committed
87 88 89

    // Relationships definitions should define a default label, but if they aren't get another default value.
    if (!empty($this->definition['label'])) {
90 91 92
      // Cast the label to a string since it is an object.
      // @see \Drupal\Core\StringTranslation\TranslationWrapper
      $label = (string) $this->definition['label'];
merlinofchaos's avatar
merlinofchaos committed
93 94 95 96 97
    }
    else {
      $label = !empty($this->definition['field']) ? $this->definition['field'] : $this->definition['base field'];
    }

98
    $options['admin_label']['default'] = $label;
merlinofchaos's avatar
merlinofchaos committed
99 100 101 102 103 104
    $options['required'] = array('default' => FALSE, 'bool' => TRUE);

    return $options;
  }

  /**
105
   * {@inheritdoc}
merlinofchaos's avatar
merlinofchaos committed
106
   */
107 108
  public function buildOptionsForm(&$form, &$form_state) {
    parent::buildOptionsForm($form, $form_state);
109 110 111

    unset($form['admin_label']['#fieldset']);
    $form['admin_label']['#weight'] = -1;
merlinofchaos's avatar
merlinofchaos committed
112 113 114 115 116 117 118 119 120 121

    $form['required'] = array(
      '#type' => 'checkbox',
      '#title' => t('Require this relationship'),
      '#description' => t('Enable to hide items that do not contain this relationship'),
      '#default_value' => !empty($this->options['required']),
    );
  }

  /**
122
   * {@inheritdoc}
merlinofchaos's avatar
merlinofchaos committed
123
   */
124
  public function query() {
merlinofchaos's avatar
merlinofchaos committed
125
    // Figure out what base table this relationship brings to the party.
126
    $table_data = Views::viewsData()->get($this->definition['base']);
merlinofchaos's avatar
merlinofchaos committed
127 128
    $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];

129
    $this->ensureMyTable();
merlinofchaos's avatar
merlinofchaos committed
130 131 132 133

    $def = $this->definition;
    $def['table'] = $this->definition['base'];
    $def['field'] = $base_field;
134 135
    $def['left_table'] = $this->tableAlias;
    $def['left_field'] = $this->realField;
136
    $def['adjusted'] = TRUE;
merlinofchaos's avatar
merlinofchaos committed
137 138 139 140 141 142 143 144
    if (!empty($this->options['required'])) {
      $def['type'] = 'INNER';
    }

    if (!empty($this->definition['extra'])) {
      $def['extra'] = $this->definition['extra'];
    }

145 146
    if (!empty($def['join_id'])) {
      $id = $def['join_id'];
merlinofchaos's avatar
merlinofchaos committed
147 148
    }
    else {
149
      $id = 'standard';
merlinofchaos's avatar
merlinofchaos committed
150
    }
151
    $join = Views::pluginManager('join')->createInstance($id, $def);
merlinofchaos's avatar
merlinofchaos committed
152 153 154 155

    // use a short alias for this:
    $alias = $def['table'] . '_' . $this->table;

156
    $this->alias = $this->query->addRelationship($alias, $join, $this->definition['base'], $this->relationship);
merlinofchaos's avatar
merlinofchaos committed
157 158 159 160

    // Add access tags if the base table provide it.
    if (empty($this->query->options['disable_sql_rewrite']) && isset($table_data['table']['base']['access query tag'])) {
      $access_tag = $table_data['table']['base']['access query tag'];
161
      $this->query->addTag($access_tag);
merlinofchaos's avatar
merlinofchaos committed
162 163 164 165 166 167 168 169
    }
  }

}

/**
 * @}
 */