View source  
  <?php
namespace Drupal\viewsreference\Plugin\Field\FieldType;
use Drupal\views\Views;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\OptionsProviderInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\TypedData\DataDefinition;
class ViewsReferenceItem extends EntityReferenceItem implements OptionsProviderInterface, PreconfiguredFieldUiOptionsInterface {
  
  public static function defaultStorageSettings() {
    return [
      'target_type' => 'view',
    ] + parent::defaultStorageSettings();
  }
  
  public static function defaultFieldSettings() {
    return [
      'plugin_types' => [
        'block' => 'block',
      ],
      'preselect_views' => [],
    ] + parent::defaultFieldSettings();
  }
  
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);
    $properties['display_id'] = DataDefinition::create('string')
      ->setLabel(new TranslatableMarkup('Display Id'))
      ->setDescription(new TranslatableMarkup('The referenced display Id'));
    $properties['argument'] = DataDefinition::create('string')
      ->setLabel(new TranslatableMarkup('Argument'))
      ->setDescription(new TranslatableMarkup('An optional argument or contextual filter to apply to the View'));
    $properties['title'] = DataDefinition::create('string')
      ->setLabel(new TranslatableMarkup('Title'))
      ->setDescription(new TranslatableMarkup('Whether or not to include the View or Block title'));
    $properties['data'] = DataDefinition::create('string')
      ->setLabel(new TranslatableMarkup('Data'))
      ->setDescription(new TranslatableMarkup('Settings data for advanced use'));
    return $properties;
  }
  
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    $schema = parent::schema($field_definition);
    $target_type = $field_definition
      ->getSetting('target_type');
    $target_type_info = \Drupal::entityTypeManager()
      ->getDefinition($target_type);
    $schema['columns']['display_id'] = [
      'description' => 'The ID of the display.',
      'type' => 'varchar_ascii',
      
      'length' => $target_type_info
        ->getBundleOf() ? EntityTypeInterface::BUNDLE_MAX_LENGTH : 255,
    ];
    $schema['columns']['argument'] = [
      'description' => 'An optional argument.',
      'type' => 'varchar_ascii',
      'length' => 255,
    ];
    $schema['columns']['title'] = [
      'description' => 'Include title.',
      'type' => 'int',
      'length' => 11,
    ];
    $schema['columns']['data'] = [
      'description' => 'Serialized data.',
      'type' => 'text',
      'size' => 'big',
    ];
    $schema['indexes']['display_id'] = [
      'display_id',
    ];
    return $schema;
  }
  
  public function setValue($values, $notify = TRUE) {
    
    if (isset($values['target_id']) && is_array($values['target_id'])) {
      $values['target_id'] = isset($values['target_id'][0]['target_id']) ? $values['target_id'][0]['target_id'] : NULL;
    }
    
    if (isset($values['argument']) && $values['argument'] === '') {
      $values['argument'] = NULL;
    }
    parent::setValue($values, FALSE);
  }
  
  public function isEmpty() {
    $return = parent::isEmpty();
    
    if ($this->display_id === NULL || $this->display_id == '') {
      return TRUE;
    }
    return $return;
  }
  
  public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
    $form = parent::fieldSettingsForm($form, $form_state);
    $settings = $this
      ->getSettings();
    $preselect_views = isset($settings['preselect_views']) ? $settings['preselect_views'] : [];
    $default_plugins = isset($settings['plugin_types']) ? $settings['plugin_types'] : [];
    $display_options = $this
      ->getAllPluginList();
    $view_list = $this
      ->getAllViewsNames();
    $form['plugin_types'] = [
      '#type' => 'checkboxes',
      '#options' => $display_options,
      '#title' => $this
        ->t('View display plugins to allow'),
      '#default_value' => $default_plugins,
      '#weight' => 1,
    ];
    $form['preselect_views'] = [
      '#type' => 'checkboxes',
      '#title' => t('Preselect View Options'),
      '#options' => $view_list,
      '#default_value' => $preselect_views,
      '#weight' => 2,
    ];
    return $form;
  }
  
  public function hasNewEntity() {
    return !$this
      ->isEmpty() && $this->target_id === NULL && $this->entity
      ->isNew();
  }
  
  public static function getPreconfiguredOptions() {
    return [];
  }
  
  private function getAllPluginList() {
    $types = Views::pluginList();
    $options = [];
    foreach ($types as $key => $type) {
      if ($type['type'] == 'display') {
        $options[str_replace('display:', '', $key)] = $type['title']
          ->render();
      }
    }
    return $options;
  }
  
  private function getAllViewsNames() {
    $views = Views::getEnabledViews();
    $options = [];
    foreach ($views as $view) {
      $options[$view
        ->get('id')] = $view
        ->get('label');
    }
    return $options;
  }
}