You are here

public function RssFields::render in Views RSS 8.2

Same name in this branch
  1. 8.2 src/Plugin/views/style/RssFields.php \Drupal\views_rss\Plugin\views\style\RssFields::render()
  2. 8.2 src/Plugin/views/row/RssFields.php \Drupal\views_rss\Plugin\views\row\RssFields::render()
Same name and namespace in other branches
  1. 8.3 src/Plugin/views/row/RssFields.php \Drupal\views_rss\Plugin\views\row\RssFields::render()

Function render.

Overrides RowPluginBase::render

File

src/Plugin/views/row/RssFields.php, line 214

Class

RssFields
Renders an RSS item based on fields.

Namespace

Drupal\views_rss\Plugin\views\row

Code

public function render($row) {
  static $row_index;
  if (!isset($row_index)) {
    $row_index = 0;
  }
  $item_elements = views_rss_get('item_elements');
  $item_data = $this
    ->mapRow($row);

  // Preprocess whole item array before preprocessing separate elements.
  $hook = 'views_rss_preprocess_item';
  $modules = \Drupal::moduleHandler()
    ->getImplementations($hook);
  $item_variables = array(
    'item' => &$item_data,
    'view' => $this->view,
  );

  // Add raw row if generated based on raw item values provided by field formatter.
  if (!empty($this->view->views_rss['raw_items'][$row->index])) {
    $item_variables['raw'] = $this->view->views_rss['raw_items'][$row->index];
  }
  foreach ($modules as $module) {
    \Drupal::moduleHandler()
      ->invoke($module, $hook, array(
      $item_variables,
    ));
  }
  $item = new \stdClass();
  $item->elements = array();

  // Process each element separately.
  foreach ($item_data as $module => $module_item_elements) {
    foreach ($module_item_elements as $element => $value) {

      // Avoid double encoding: the $value might be already encoded here,
      // depending on the field configuration/processing, and because we know
      // it will be encoded again when the whole feed array will be passed to
      // Drupal render, let's make sure we decode it here first.
      if (is_string($value)) {
        $value = htmlspecialchars_decode($value, ENT_QUOTES);
      }

      // Start building XML element array compatible with Drupal render.
      // TODO review this to ensure that no warnings are generated.
      $rss_elements = array(
        array(
          'key' => $element,
          'value' => $value,
        ),
      );

      // Preprocess element initial value if required.
      if (isset($item_elements[$module][$element]['preprocess functions']) && is_array($item_elements[$module][$element]['preprocess functions'])) {
        foreach ($item_elements[$module][$element]['preprocess functions'] as $preprocess_function) {
          if (function_exists($preprocess_function)) {
            $item_variables = array(
              'elements' => &$rss_elements,
              'item' => $item_data,
              'view' => $this->view,
            );

            // Add raw item if provided by field formatter.
            if (!empty($this->view->views_rss['raw_items'][$row->index][$module][$element])) {
              $item_variables['raw'] = $this->view->views_rss['raw_items'][$row->index][$module][$element];
            }
            $preprocess_function($item_variables);
          }
        }
      }

      // If there is no value and no attributes (in case of self-closing elements)
      // already set for the element at this stage, it is not going to be set
      // at any point further, so the element should not be added to the feed.
      foreach ($rss_elements as $key => $rss_element) {
        if (empty($rss_element['value']) && empty($rss_element['attributes'])) {
          unset($rss_elements[$key]);
        }
      }
      if (empty($rss_elements)) {
        continue;
      }

      // Special processing for title, description and link elements, as these
      // are hardcoded both in template_preprocess_views_view_row_rss() and in
      // views-view-row-rss.html.twig, and we try to keep the compatibility.
      if ($element === 'title' || $element === 'link') {
        $rss_element = reset($rss_elements);
        $item->{$element} = $rss_element['value'];
      }
      elseif ($element === 'description') {
        $rss_element = reset($rss_elements);
        if (is_string($rss_element['value'])) {
          $item->{$element} = [
            '#markup' => $rss_element['value'],
          ];
        }
        else {
          $item->{$element} = $rss_element['value'];
        }
      }
      else {
        $item->elements = array_merge($item->elements, $rss_elements);
      }
    }
  }

  // Merge RDF namespaces in the XML namespaces in case they are used
  // further in the RSS content.
  if (function_exists('rdf_get_namespaces') && !empty($this->view->style_plugin->options['namespaces']['add_rdf_namespaces'])) {
    $xml_rdf_namespaces = array();
    foreach (rdf_get_namespaces() as $prefix => $uri) {
      $xml_rdf_namespaces['xmlns:' . $prefix] = $uri;
    }
    $this->view->style_plugin->namespaces += $xml_rdf_namespaces;
  }
  $build = [
    '#theme' => $this
      ->themeFunctions(),
    '#view' => $this->view,
    '#options' => $this->options,
    '#row' => $item,
    '#field_alias' => isset($this->field_alias) ? $this->field_alias : '',
  ];
  return $build;
}