ViewfieldItem.php 7.38 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\viewfield\Plugin\Field\FieldType;

jerdavis's avatar
jerdavis committed
5
use Drupal\Core\Entity\ContentEntityStorageInterface;
6 7
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
jerdavis's avatar
jerdavis committed
8
use Drupal\Core\Field\FieldDefinitionInterface;
9 10
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TypedData\DataDefinition;
11
use Drupal\Core\Field\FieldFilteredMarkup;
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
use Drupal\views\Views;

/**
 * Plugin implementation of the 'viewfield' field type.
 *
 * @FieldType(
 *   id = "viewfield",
 *   label = @Translation("Viewfield"),
 *   description = @Translation("'Defines a entity reference field type to display a view.'"),
 *   category = @Translation("Reference"),
 *   default_widget = "viewfield_select",
 *   default_formatter = "viewfield_default",
 *   list_class = "\Drupal\Core\Field\EntityReferenceFieldItemList",
 * )
 */
class ViewfieldItem extends EntityReferenceItem {

  /**
   * {@inheritdoc}
   */
  public static function defaultStorageSettings() {
33
    return [
34
      'target_type' => 'view',
jerdavis's avatar
jerdavis committed
35
    ];
36 37 38 39 40 41
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultFieldSettings() {
42
    return [
43
      'force_default' => 0,
44 45
      'allowed_views' => [],
      'allowed_display_types' => ['block' => 'block'],
jerdavis's avatar
jerdavis committed
46
    ] + parent::defaultFieldSettings();
47 48 49 50 51 52
  }

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
jerdavis's avatar
jerdavis committed
53
    $schema = parent::schema($field_definition);
54

55
    $schema['columns']['display_id'] = [
56
      'description' => 'The ID of the view display.',
57
      'type' => 'varchar_ascii',
58
      'length' => 255,
59
    ];
60

61
    $schema['columns']['arguments'] = [
62 63 64
      'description' => 'Arguments to be passed to the display.',
      'type' => 'varchar',
      'length' => 255,
65
    ];
66

67 68 69 70 71 72
    $schema['columns']['items_to_display'] = [
      'description' => 'Items to display.',
      'type' => 'varchar',
      'length' => 255,
    ];

73 74 75 76 77 78 79 80
    return $schema;
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);
81
    $properties['entity']->setDescription(t('The referenced view'));
82 83

    $properties['display_id'] = DataDefinition::create('string')
84 85
      ->setLabel(t('Display ID'))
      ->setDescription(t('The view display ID'));
86 87 88 89 90

    $properties['arguments'] = DataDefinition::create('string')
      ->setLabel(t('Arguments'))
      ->setDescription(t('An optional comma-delimited list of arguments for the display'));

91 92 93 94
    $properties['items_to_display'] = DataDefinition::create('string')
      ->setLabel(t('Items to display'))
      ->setDescription(t('Override the number of displayed items.'));

95 96 97
    return $properties;
  }

98 99 100 101 102 103 104 105 106 107 108
  /**
   * {@inheritdoc}
   */
  public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
    $element = parent::storageSettingsForm($form, $form_state, $has_data);
    // Hide entity type selection.
    $element['target_type']['#access'] = FALSE;

    return $element;
  }

109 110 111 112
  /**
   * {@inheritdoc}
   */
  public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
113
    $form = [];
114

115
    $form['force_default'] = [
116 117
      '#type' => 'checkbox',
      '#title' => $this->t('Always use default value'),
118
      '#default_value' => $this->getSetting('force_default'),
119
      '#description' => $this->t('Hides this field in entity edit forms and enforces the configured default value for all entities in the bundle, making it unnecessary to assign values individually to each one.<br>If this is checked, you must provide a default value.'),
120
    ];
121

122
    $form['allowed_views'] = [
123
      '#type' => 'checkboxes',
124
      '#options' => $this->getViewOptions(FALSE),
125
      '#title' => $this->t('Allowed views'),
126
      '#default_value' => $this->getSetting('allowed_views'),
127
      '#description' => $this->t('Views available for content authors. Leave empty to allow all.'),
128
    ];
129

130
    $form['allowed_display_types'] = [
131
      '#type' => 'checkboxes',
132
      '#options' => $this->getDisplayTypeOptions(),
133
      '#title' => $this->t('Allowed display types'),
134
      '#default_value' => $this->getSetting('allowed_display_types'),
135
      '#description' => $this->t('Display types available for content authors. Leave empty to allow all.'),
136
    ];
137

138
    $form['#element_validate'][] = [get_called_class(), 'fieldSettingsFormValidate'];
139 140 141 142 143

    return $form;
  }

  /**
144
   * Form API callback.
145 146 147 148 149 150 151 152 153 154 155 156
   *
   * Requires that field defaults be supplied when the 'force_default' option
   * is checked.
   *
   * This function is assigned as an #element_validate callback in
   * fieldSettingsForm().
   */
  public static function fieldSettingsFormValidate(array $form, FormStateInterface $form_state) {
    $settings = $form_state->getValue('settings');
    if ($settings['force_default']) {
      $default_value = $form_state->getValue('default_value_input');
      $field_name = $form_state->getFormObject()->getEntity()->getName();
157
      if (empty($default_value[$field_name][0]['target_id']) || $default_value[$field_name][0]['target_id'] == '_none') {
158
        $form_state->setErrorByName('default_value_input', t('%title requires a default value.', [
159
          '%title' => $form['force_default']['#title'],
160
        ]));
161 162 163
      }
    }
  }
164

165 166 167 168 169 170 171
  /**
   * {@inheritdoc}
   */
  public static function getPreconfiguredOptions() {
    return [];
  }

172
  /**
173
   * Get an options array of views.
174
   *
175
   * @param bool $filter
176
   *   (optional) Flag to filter the output using the 'allowed_views' setting.
177
   *
178 179 180
   * @return array
   *   The array of options.
   */
181
  public function getViewOptions($filter = TRUE) {
182 183
    $views_options = [];
    $allowed_views = $filter ? array_filter($this->getSetting('allowed_views')) : [];
184
    foreach (Views::getEnabledViews() as $key => $view) {
185 186 187
      if (empty($allowed_views) || isset($allowed_views[$key])) {
        $views_options[$key] = FieldFilteredMarkup::create($view->get('label'));
      }
188
    }
189
    natcasesort($views_options);
190 191 192 193

    return $views_options;
  }

194
  /**
195
   * Get display ID options for a view.
196 197 198
   *
   * @param string $entity_id
   *   The entity_id of the view.
199
   * @param bool $filter
200
   *   (optional) Flag to filter the output using the 'allowed_display_types'
201
   *   setting.
202 203 204 205
   *
   * @return array
   *   The array of options.
   */
206
  public function getDisplayOptions($entity_id, $filter = TRUE) {
207
    $display_options = [];
208 209
    $views = Views::getEnabledViews();
    if (isset($views[$entity_id])) {
210
      $allowed_display_types = $filter ? array_filter($this->getSetting('allowed_display_types')) : [];
211
      foreach ($views[$entity_id]->get('display') as $key => $display) {
212
        if (empty($allowed_display_types) || isset($allowed_display_types[$display['display_plugin']])) {
213
          $display_options[$key] = FieldFilteredMarkup::create($display['display_title']);
214 215
        }
      }
216
      natcasesort($display_options);
217 218
    }

219
    return $display_options;
220 221
  }

222 223 224 225 226 227
  /**
   * Get an options array of all Views display types.
   *
   * @return array
   *   The array of options.
   */
228
  public function getDisplayTypeOptions() {
229
    $display_type_options = [];
230 231
    foreach (Views::pluginList() as $key => $type) {
      if ($type['type'] == 'display') {
232
        $display_type_options[str_replace('display:', '', $key)] = FieldFilteredMarkup::create($type['title']);
233 234
      }
    }
235
    natcasesort($display_type_options);
236 237 238

    return $display_type_options;
  }
239

240
}