You are here

public function UnifiedFieldsDiffLayout::build in Diff 8

Builds a diff comparison between two revisions.

This method is responsible for building the diff comparison between revisions of the same entity. It can build a table, navigation links and headers of a diff comparison.

Parameters

\Drupal\Core\Entity\ContentEntityInterface $left_revision: The left revision.

\Drupal\Core\Entity\ContentEntityInterface $right_revision: The right revision.

\Drupal\Core\Entity\ContentEntityInterface $entity: The entity.

Return value

array The modified build array that the plugin builds.

Overrides DiffLayoutInterface::build

File

src/Plugin/diff/Layout/UnifiedFieldsDiffLayout.php, line 101

Class

UnifiedFieldsDiffLayout
Provides Unified fields diff layout.

Namespace

Drupal\diff\Plugin\diff\Layout

Code

public function build(ContentEntityInterface $left_revision, ContentEntityInterface $right_revision, ContentEntityInterface $entity) {

  // Build the revisions data.
  $build = $this
    ->buildRevisionsData($left_revision, $right_revision);
  $active_filter = $this->requestStack
    ->getCurrentRequest()->query
    ->get('filter') ?: 'raw';
  $raw_active = $active_filter == 'raw';
  $build['controls']['filter'] = [
    '#type' => 'item',
    '#title' => $this
      ->t('Filter'),
    '#wrapper_attributes' => [
      'class' => 'diff-controls__item',
    ],
    'options' => $this
      ->buildFilterNavigation($entity, $left_revision, $right_revision, 'unified_fields', $active_filter),
  ];

  // Build the diff comparison table.
  $diff_header = $this
    ->buildTableHeader($right_revision);

  // Perform comparison only if both entity revisions loaded successfully.
  $fields = $this->entityComparison
    ->compareRevisions($left_revision, $right_revision);

  // Build the diff rows for each field and append the field rows
  // to the table rows.
  $diff_rows = [];
  foreach ($fields as $field) {
    $field_label_row = '';
    if (!empty($field['#name'])) {
      $field_label_row = [
        'data' => $field['#name'],
        'colspan' => 4,
        'class' => [
          'field-name',
        ],
      ];
    }
    if (!$raw_active) {
      $field_settings = $field['#settings'];
      if (!empty($field_settings['settings']['markdown'])) {
        $field['#data']['#left'] = $this
          ->applyMarkdown($field_settings['settings']['markdown'], $field['#data']['#left']);
        $field['#data']['#right'] = $this
          ->applyMarkdown($field_settings['settings']['markdown'], $field['#data']['#right']);
      }
      else {
        $field['#data']['#left'] = $this
          ->applyMarkdown('drupal_html_to_text', $field['#data']['#left']);
        $field['#data']['#right'] = $this
          ->applyMarkdown('drupal_html_to_text', $field['#data']['#right']);
      }
    }

    // Process the array (split the strings into single line strings)
    // and get line counts per field.
    $this->entityComparison
      ->processStateLine($field);
    $field_diff_rows = $this->entityComparison
      ->getRows($field['#data']['#left'], $field['#data']['#right']);
    $final_diff = [];
    $row_count_left = NULL;
    $row_count_right = NULL;
    foreach ($field_diff_rows as $key => $value) {
      $show = FALSE;
      if (isset($field_diff_rows[$key][1]['data'])) {
        if ($field_diff_rows[$key][1] == $field_diff_rows[$key][3]) {
          $show = TRUE;
          $row_count_right++;
        }
        $row_count_left++;
        $final_diff[] = [
          'left-line-number' => [
            'data' => $row_count_left,
            'class' => [
              'diff-line-number',
              $field_diff_rows[$key][1]['class'],
            ],
          ],
          'right-line-number' => [
            'data' => $show ? $row_count_right : NULL,
            'class' => [
              'diff-line-number',
              $field_diff_rows[$key][1]['class'],
            ],
          ],
          'row-sign' => [
            'data' => isset($field_diff_rows[$key][0]['data']) ? $field_diff_rows[$key][0]['data'] : NULL,
            'class' => [
              isset($field_diff_rows[$key][0]['class']) ? $field_diff_rows[$key][0]['class'] : NULL,
              $field_diff_rows[$key][1]['class'],
            ],
          ],
          'row-data' => [
            'data' => $field_diff_rows[$key][1]['data'],
            'colspan' => 2,
            'class' => $field_diff_rows[$key][1]['class'],
          ],
        ];
      }
      if ($field_diff_rows[$key][1] != $field_diff_rows[$key][3]) {
        if (isset($field_diff_rows[$key][3]['data'])) {
          $row_count_right++;
          $final_diff[] = [
            'left-line-number' => [
              'data' => NULL,
              'class' => [
                'diff-line-number',
                $field_diff_rows[$key][3]['class'],
              ],
            ],
            'right-line-number' => [
              'data' => $row_count_right,
              'class' => [
                'diff-line-number',
                $field_diff_rows[$key][3]['class'],
              ],
            ],
            'row-sign' => [
              'data' => isset($field_diff_rows[$key][2]['data']) ? $field_diff_rows[$key][2]['data'] : NULL,
              'class' => [
                isset($field_diff_rows[$key][2]['class']) ? $field_diff_rows[$key][2]['class'] : NULL,
                $field_diff_rows[$key][3]['class'],
              ],
            ],
            'row-data' => [
              'data' => $field_diff_rows[$key][3]['data'],
              'colspan' => 2,
              'class' => $field_diff_rows[$key][3]['class'],
            ],
          ];
        }
      }
    }

    // Add field label to the table only if there are changes to that field.
    if (!empty($final_diff) && !empty($field_label_row)) {
      $diff_rows[] = [
        $field_label_row,
      ];
    }

    // Add field diff rows to the table rows.
    $diff_rows = array_merge($diff_rows, $final_diff);
  }
  if (!$raw_active) {

    // Remove line numbers.
    foreach ($diff_rows as $i => $row) {
      unset($diff_rows[$i]['left-line-number']);
      unset($diff_rows[$i]['right-line-number']);
    }

    // Reduce the colspan.
    $diff_header[0]['colspan'] = 2;
    $diff_rows[0][0]['colspan'] = 2;
  }
  $build['diff'] = [
    '#type' => 'table',
    '#header' => $diff_header,
    '#rows' => $diff_rows,
    '#weight' => 10,
    '#empty' => $this
      ->t('No visible changes'),
    '#attributes' => [
      'class' => [
        'diff',
      ],
    ],
  ];
  $build['#attached']['library'][] = 'diff/diff.single_column';
  $build['#attached']['library'][] = 'diff/diff.colors';
  return $build;
}