vocabularyStorage = $vocabulary_storage; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity.manager')->getStorage('taxonomy_vocabulary') ); } /** * {@inheritdoc} */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { parent::init($view, $display, $options); // @todo Remove the legacy code. // Convert legacy vids option to machine name vocabularies. if (!empty($this->options['vids'])) { $vocabularies = taxonomy_vocabulary_get_names(); foreach ($this->options['vids'] as $vid) { if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) { $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name; } } } } protected function defineOptions() { $options = parent::defineOptions(); $options['vids'] = ['default' => []]; return $options; } public function buildOptionsForm(&$form, FormStateInterface $form_state) { $vocabularies = $this->vocabularyStorage->loadMultiple(); $options = []; foreach ($vocabularies as $voc) { $options[$voc->id()] = $voc->label(); } $form['vids'] = [ '#type' => 'checkboxes', '#title' => $this->t('Vocabularies'), '#options' => $options, '#default_value' => $this->options['vids'], '#description' => $this->t('Choose which vocabularies you wish to relate. Remember that every term found will create a new record, so this relationship is best used on just one vocabulary that has only one term per node.'), ]; parent::buildOptionsForm($form, $form_state); } /** * {@inheritdoc} */ public function submitOptionsForm(&$form, FormStateInterface $form_state) { // Transform the #type = checkboxes value to a numerically indexed array, // because the config schema expects a sequence, not a mapping. $vids = $form_state->getValue(['options', 'vids']); $form_state->setValue(['options', 'vids'], array_values(array_filter($vids))); } /** * Called to implement a relationship in a query. */ public function query() { $this->ensureMyTable(); $def = $this->definition; $def['table'] = 'taxonomy_term_field_data'; if (!array_filter($this->options['vids'])) { $taxonomy_index = $this->query->addTable('taxonomy_index', $this->relationship); $def['left_table'] = $taxonomy_index; $def['left_field'] = 'tid'; $def['field'] = 'tid'; $def['type'] = empty($this->options['required']) ? 'LEFT' : 'INNER'; } else { // If vocabularies are supplied join a subselect instead $def['left_table'] = $this->tableAlias; $def['left_field'] = 'nid'; $def['field'] = 'nid'; $def['type'] = empty($this->options['required']) ? 'LEFT' : 'INNER'; $def['adjusted'] = TRUE; $query = db_select('taxonomy_term_field_data', 'td'); $query->addJoin($def['type'], 'taxonomy_index', 'tn', 'tn.tid = td.tid'); $query->condition('td.vid', array_filter($this->options['vids']), 'IN'); $query->addTag('taxonomy_term_access'); $query->fields('td'); $query->fields('tn', ['nid']); $def['table formula'] = $query; } $join = \Drupal::service('plugin.manager.views.join')->createInstance('standard', $def); // use a short alias for this: $alias = $def['table'] . '_' . $this->table; $this->alias = $this->query->addRelationship($alias, $join, 'taxonomy_term_field_data', $this->relationship); } /** * {@inheritdoc} */ public function calculateDependencies() { $dependencies = parent::calculateDependencies(); foreach ($this->options['vids'] as $vocabulary_id) { if ($vocabulary = $this->vocabularyStorage->load($vocabulary_id)) { $dependencies[$vocabulary->getConfigDependencyKey()][] = $vocabulary->getConfigDependencyName(); } } return $dependencies; } }