Serializer.php 5.49 KB
Newer Older
1 2 3 4
<?php

namespace Drupal\rest\Plugin\views\style;

5 6
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
7
use Drupal\Core\Form\FormStateInterface;
8
use Drupal\views\Plugin\views\style\StylePluginBase;
9 10
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\SerializerInterface;
11 12 13 14 15 16

/**
 * The style plugin for serialized output formats.
 *
 * @ingroup views_style_plugins
 *
17
 * @ViewsStyle(
18 19 20
 *   id = "serializer",
 *   title = @Translation("Serializer"),
 *   help = @Translation("Serializes views row data using the Serializer component."),
21
 *   display_types = {"data"}
22 23
 * )
 */
24
class Serializer extends StylePluginBase implements CacheableDependencyInterface {
25 26

  /**
27
   * {@inheritdoc}
28 29 30 31
   */
  protected $usesRowPlugin = TRUE;

  /**
32
   * {@inheritdoc}
33 34 35 36 37 38 39 40 41 42 43
   */
  protected $usesGrouping = FALSE;

  /**
   * The serializer which serializes the views result.
   *
   * @var \Symfony\Component\Serializer\Serializer
   */
  protected $serializer;

  /**
44 45 46 47 48 49
   * The available serialization formats.
   *
   * @var array
   */
  protected $formats = array();

50 51 52 53 54 55 56
  /**
   * The serialization format providers, keyed by format.
   *
   * @var string[]
   */
  protected $formatProviders;

57 58 59
  /**
   * {@inheritdoc}
   */
60
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
61 62 63 64 65
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('serializer'),
66 67
      $container->getParameter('serializer.formats'),
      $container->getParameter('serializer.format_providers')
68 69 70 71 72
    );
  }

  /**
   * Constructs a Plugin object.
73
   */
74
  public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, array $serializer_formats, array $serializer_format_providers) {
75
    parent::__construct($configuration, $plugin_id, $plugin_definition);
76

77 78 79
    $this->definition = $plugin_definition + $configuration;
    $this->serializer = $serializer;
    $this->formats = $serializer_formats;
80
    $this->formatProviders = $serializer_format_providers;
81 82 83
  }

  /**
84 85 86 87 88 89 90 91 92 93 94 95
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['formats'] = array('default' => array());

    return $options;
  }

  /**
   * {@inheritdoc}
   */
96
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
97 98 99 100
    parent::buildOptionsForm($form, $form_state);

    $form['formats'] = array(
      '#type' => 'checkboxes',
101 102
      '#title' => $this->t('Accepted request formats'),
      '#description' => $this->t('Request formats that will be allowed in responses. If none are selected all formats will be allowed.'),
103
      '#options' => $this->getFormatOptions(),
104 105 106 107 108 109 110
      '#default_value' => $this->options['formats'],
    );
  }

  /**
   * {@inheritdoc}
   */
111
  public function submitOptionsForm(&$form, FormStateInterface $form_state) {
112 113
    parent::submitOptionsForm($form, $form_state);

114 115
    $formats = $form_state->getValue(array('style_options', 'formats'));
    $form_state->setValue(array('style_options', 'formats'), array_filter($formats));
116 117 118 119
  }

  /**
   * {@inheritdoc}
120 121 122 123 124 125 126 127
   */
  public function render() {
    $rows = array();
    // If the Data Entity row plugin is used, this will be an array of entities
    // which will pass through Serializer to one of the registered Normalizers,
    // which will transform it to arrays/scalars. If the Data field row plugin
    // is used, $rows will not contain objects and will pass directly to the
    // Encoder.
128 129
    foreach ($this->view->result as $row_index => $row) {
      $this->view->row_index = $row_index;
130
      $rows[] = $this->view->rowPlugin->render($row);
131
    }
132
    unset($this->view->row_index);
133

134 135 136 137 138 139 140
    // Get the content type configured in the display or fallback to the
    // default.
    if ((empty($this->view->live_preview))) {
      $content_type = $this->displayHandler->getContentType();
    }
    else {
      $content_type = !empty($this->options['formats']) ? reset($this->options['formats']) : 'json';
141
    }
142
    return $this->serializer->serialize($rows, $content_type, ['views_style_plugin' => $this]);
143 144
  }

145 146 147 148 149 150 151 152 153 154
  /**
   * Gets a list of all available formats that can be requested.
   *
   * This will return the configured formats, or all formats if none have been
   * selected.
   *
   * @return array
   *   An array of formats.
   */
  public function getFormats() {
155
    return $this->options['formats'];
156 157
  }

158 159 160
  /**
   * {@inheritdoc}
   */
161 162
  public function getCacheMaxAge() {
    return Cache::PERMANENT;
163 164 165 166 167 168 169 170 171
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() {
    return ['request_format'];
  }

172 173 174 175 176 177 178
  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    return [];
  }

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
  /**
   * {@inheritdoc}
   */
  public function calculateDependencies() {
    $dependencies = parent::calculateDependencies();
    $formats = $this->getFormats();
    $providers = array_intersect_key($this->formatProviders, array_flip($formats));
    // The plugin always uses services from the serialization module.
    $providers[] = 'serialization';

    $dependencies += ['module' => []];
    $dependencies['module'] = array_merge($dependencies['module'], $providers);
    return $dependencies;
  }

  /**
   * Returns an array of format options
   *
   * @return string[]
   *   An array of format options. Both key and value are the same.
   */
  protected function getFormatOptions() {
    $formats = array_keys($this->formatProviders);
    return array_combine($formats, $formats);
  }

205
}