Version 1
[yaffs-website] / web / modules / contrib / diff / src / Plugin / diff / Layout / SplitFieldsDiffLayout.php
diff --git a/web/modules/contrib/diff/src/Plugin/diff/Layout/SplitFieldsDiffLayout.php b/web/modules/contrib/diff/src/Plugin/diff/Layout/SplitFieldsDiffLayout.php
new file mode 100644 (file)
index 0000000..6316b0a
--- /dev/null
@@ -0,0 +1,281 @@
+<?php
+
+namespace Drupal\diff\Plugin\diff\Layout;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Datetime\DateFormatter;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\diff\DiffEntityComparison;
+use Drupal\diff\DiffEntityParser;
+use Drupal\diff\DiffLayoutBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Provides Split fields diff layout.
+ *
+ * @DiffLayoutBuilder(
+ *   id = "split_fields",
+ *   label = @Translation("Split fields"),
+ *   description = @Translation("Field based layout, displays revision comparison side by side."),
+ * )
+ */
+class SplitFieldsDiffLayout extends DiffLayoutBase {
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The diff entity comparison service.
+   *
+   * @var \Drupal\diff\DiffEntityComparison
+   */
+  protected $entityComparison;
+
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * Constructs a SplitFieldsDiffLayout object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config
+   *   The configuration factory object.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\diff\DiffEntityParser $entity_parser
+   *   The entity parser.
+   * @param \Drupal\Core\DateTime\DateFormatter $date
+   *   The date service.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   * @param \Drupal\diff\DiffEntityComparison $entity_comparison
+   *   The diff entity comparison service.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, DiffEntityParser $entity_parser, DateFormatter $date, RendererInterface $renderer, DiffEntityComparison $entity_comparison, RequestStack $request_stack) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $config, $entity_type_manager, $entity_parser, $date);
+    $this->renderer = $renderer;
+    $this->entityComparison = $entity_comparison;
+    $this->requestStack = $request_stack;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('entity_type.manager'),
+      $container->get('diff.entity_parser'),
+      $container->get('date.formatter'),
+      $container->get('renderer'),
+      $container->get('diff.entity_comparison'),
+      $container->get('request_stack')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  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';
+    $build['controls']['filter'] = [
+      '#type' => 'item',
+      '#title' => $this->t('Filter'),
+      '#wrapper_attributes' => ['class' => 'diff-controls__item'],
+      'options' => $this->buildFilterNavigation($entity, $left_revision, $right_revision, 'split_fields', $active_filter),
+    ];
+
+    // Build the diff comparison table.
+    $diff_header = $this->buildTableHeader($left_revision, $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 = [];
+    $raw_active = $active_filter == 'raw';
+    foreach ($fields as $field) {
+      $field_label_row = '';
+      if (!empty($field['#name'])) {
+        $field_label_row = [
+          'data' => $field['#name'],
+          'colspan' => 8,
+          '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']);
+        }
+        // In case the settings are not loaded correctly use drupal_html_to_text
+        // to avoid any possible notices when a user clicks on markdown.
+        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']
+      );
+
+      // EXPERIMENTAL: Deal with magic thumbnail image data.
+      if (isset($field['#data']['#left_thumbnail'])) {
+        $field_diff_rows['#thumbnail'][1] = [
+          'data' => $field['#data']['#left_thumbnail'],
+          'class' => '',
+        ];
+      }
+      if (isset($field['#data']['#right_thumbnail'])) {
+        $field_diff_rows['#thumbnail'][3] = [
+          'data' => $field['#data']['#right_thumbnail'],
+          'class' => '',
+        ];
+      }
+
+      $final_diff = [];
+      $row_count_left = NULL;
+      $row_count_right = NULL;
+
+      foreach ($field_diff_rows as $key => $value) {
+        $show_left = FALSE;
+        $show_right = FALSE;
+        if (isset($field_diff_rows[$key][1]['data'])) {
+          $show_left = TRUE;
+          $row_count_left++;
+        }
+        if (isset($field_diff_rows[$key][3]['data'])) {
+          $show_right = TRUE;
+          $row_count_right++;
+        }
+        $final_diff[] = [
+          'left-line-number' => [
+            'data' => $show_left ? $row_count_left : NULL,
+            'class' => [
+              'diff-line-number',
+              isset($field_diff_rows[$key][1]['data']) ? $field_diff_rows[$key][1]['class'] : NULL,
+            ],
+          ],
+          'left-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,
+              isset($field_diff_rows[$key][1]['data']) ? $field_diff_rows[$key][1]['class'] : NULL,
+            ],
+          ],
+          'left-row-data' => [
+            'data' => isset($field_diff_rows[$key][1]['data']) ? $field_diff_rows[$key][1]['data'] : NULL,
+            'class' => isset($field_diff_rows[$key][1]['data']) ? $field_diff_rows[$key][1]['class'] : NULL,
+          ],
+          'right-line-number' => [
+            'data' => $show_right ? $row_count_right : NULL,
+            'class' => [
+              'diff-line-number',
+              isset($field_diff_rows[$key][3]['data']) ? $field_diff_rows[$key][3]['class'] : NULL,
+            ],
+          ],
+          'right-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,
+              isset($field_diff_rows[$key][3]['data']) ? $field_diff_rows[$key][3]['class'] : NULL,
+            ],
+          ],
+          'right-row-data' => [
+            'data' => isset($field_diff_rows[$key][3]['data']) ? $field_diff_rows[$key][3]['data'] : NULL,
+            'class' => isset($field_diff_rows[$key][3]['data']) ? $field_diff_rows[$key][3]['class'] : NULL,
+          ],
+        ];
+      }
+
+      // 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;
+    }
+
+    $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.double_column';
+    $build['#attached']['library'][] = 'diff/diff.colors';
+    return $build;
+  }
+
+  /**
+   * Build the header for the diff table.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $left_revision
+   *   Revision from the left hand side.
+   * @param \Drupal\Core\Entity\ContentEntityInterface $right_revision
+   *   Revision from the right hand side.
+   *
+   * @return array
+   *   Header for Diff table.
+   */
+  protected function buildTableHeader(ContentEntityInterface $left_revision, ContentEntityInterface $right_revision) {
+    $header = [];
+    $header[] = [
+      'data' => ['#markup' => $this->buildRevisionLink($left_revision)],
+      'colspan' => 3,
+    ];
+    $header[] = [
+      'data' => ['#markup' => $this->buildRevisionLink($right_revision)],
+      'colspan' => 3,
+    ];
+
+    return $header;
+  }
+
+}