diff --git a/src/DiffEntityComparison.php b/src/DiffEntityComparison.php index 8184326..b291bff 100644 --- a/src/DiffEntityComparison.php +++ b/src/DiffEntityComparison.php @@ -90,18 +90,19 @@ class DiffEntityComparison { $result[$left_key] = [ '#name' => (isset($compare_settings['settings']['show_header']) && $compare_settings['settings']['show_header'] == 0) ? '' : $values['label'], '#settings' => $compare_settings, + '#data' => [], ]; // Fields which exist on the right entity also. if (isset($right_values[$left_key])) { - $result[$left_key] += $this->combineFields($left_values[$left_key], $right_values[$left_key]); + $result[$left_key]['#data'] += $this->combineFields($left_values[$left_key], $right_values[$left_key]); // Unset the field from the right entity so that we know if the right // entity has any fields that left entity doesn't have. unset($right_values[$left_key]); } // This field exists only on the left entity. else { - $result[$left_key] += $this->combineFields($left_values[$left_key], []); + $result[$left_key]['#data'] += $this->combineFields($left_values[$left_key], []); } } @@ -113,41 +114,22 @@ class DiffEntityComparison { '#name' => (isset($compare_settings['settings']['show_header']) && $compare_settings['settings']['show_header'] == 0) ? '' : $values['label'], '#settings' => $compare_settings, ]; - $result[$right_key] += $this->combineFields([], $right_values[$right_key]); + $result[$right_key]['#data'] += $this->combineFields([], $right_values[$right_key]); } // Field rows. Recurse through all child elements. foreach (Element::children($result) as $key) { - $result[$key]['#states'] = array(); // Ensure that the element follows the #states format. - if (isset($result[$key]['#left'])) { + if (isset($result[$key]['#data']['#left'])) { // We need to trim spaces and new lines from the end of the string // otherwise in some cases we have a blank not needed line. - $result[$key]['#states']['raw']['#left'] = trim($result[$key]['#left']); - unset($result[$key]['#left']); + $result[$key]['#data']['#left'] = trim($result[$key]['#data']['#left']); } - if (isset($result[$key]['#right'])) { - $result[$key]['#states']['raw']['#right'] = trim($result[$key]['#right']); - unset($result[$key]['#right']); - } - $field_settings = $result[$key]['#settings']; - - if (!empty($field_settings['settings']['markdown'])) { - $result[$key]['#states']['raw_plain']['#left'] = $this->applyMarkdown($field_settings['settings']['markdown'], $result[$key]['#states']['raw']['#left']); - $result[$key]['#states']['raw_plain']['#right'] = $this->applyMarkdown($field_settings['settings']['markdown'], $result[$key]['#states']['raw']['#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 { - $result[$key]['#states']['raw_plain']['#left'] = $this->applyMarkdown('drupal_html_to_text', $result[$key]['#states']['raw']['#left']); - $result[$key]['#states']['raw_plain']['#right'] = $this->applyMarkdown('drupal_html_to_text', $result[$key]['#states']['raw']['#right']); + if (isset($result[$key]['#data']['#right'])) { + $result[$key]['#data']['#right'] = trim($result[$key]['#data']['#right']); } } - // Process the array (split the strings into single line strings) - // and get line counts per field. - array_walk($result, array($this, 'processStateLine')); - return $result; } @@ -231,57 +213,25 @@ class DiffEntityComparison { * @param $diff * Array of strings. */ - protected function processStateLine(&$diff) { - foreach ($diff['#states'] as $state => $data) { - if (isset($data['#left'])) { - if (is_string($data['#left'])) { - $diff['#states'][$state]['#left'] = explode("\n", $data['#left']); - } - $diff['#states'][$state]['#count_left'] = count($diff['#states'][$state]['#left']); - } - else { - $diff['#states'][$state]['#count_left'] = 0; - } - if (isset($data['#right'])) { - if (is_string($data['#right'])) { - $diff['#states'][$state]['#right'] = explode("\n", $data['#right']); - } - $diff['#states'][$state]['#count_right'] = count($diff['#states'][$state]['#right']); - } - else { - $diff['#states'][$state]['#count_right'] = 0; + public function processStateLine(&$diff) { + $data = $diff['#data']; + if (isset($data['#left'])) { + if (is_string($data['#left'])) { + $diff['#data']['#left'] = explode("\n", $data['#left']); } + $diff['#data']['#count_left'] = count($diff['#data']['#left']); } - } - - /** - * Applies a markdown function to a string. - * - * @param $markdown - * Key of the markdown function to be applied to the items. - * One of drupal_html_to_text, filter_xss, filter_xss_all. - * @param $items - * String to be processed. - * - * @return array|string - * Result after markdown was applied on $items. - */ - protected function applyMarkdown($markdown, $items) { - if (!$markdown) { - return $items; - } - - if ($markdown == 'drupal_html_to_text') { - return trim(MailFormatHelper::htmlToText($items), "\n"); - } - elseif ($markdown == 'filter_xss') { - return trim(Xss::filter($items), "\n"); + else { + $diff['#data']['#count_left'] = 0; } - elseif ($markdown == 'filter_xss_all') { - return trim(Xss::filter($items, array()), "\n"); + if (isset($data['#right'])) { + if (is_string($data['#right'])) { + $diff['#data']['#right'] = explode("\n", $data['#right']); + } + $diff['#data']['#count_right'] = count($diff['#data']['#right']); } else { - return $items; + $diff['#data']['#count_right'] = 0; } } diff --git a/src/DiffLayoutBase.php b/src/DiffLayoutBase.php index 4f9f9f3..8f67beb 100644 --- a/src/DiffLayoutBase.php +++ b/src/DiffLayoutBase.php @@ -77,21 +77,21 @@ abstract class DiffLayoutBase extends PluginBase implements DiffLayoutInterface, * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - // TODO: Implement buildConfigurationForm() method. + // @todo Implement buildConfigurationForm() method. } /** * {@inheritdoc} */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { - // TODO: Implement validateConfigurationForm() method. + // @todo Implement validateConfigurationForm() method. } /** * {@inheritdoc} */ public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { - // TODO: Implement submitConfigurationForm() method. + // @todo Implement submitConfigurationForm() method. } /** @@ -105,14 +105,14 @@ abstract class DiffLayoutBase extends PluginBase implements DiffLayoutInterface, * {@inheritdoc} */ public function getConfiguration() { - return $this->configFactory->getEditable('diff.layout_plugins'); + // @todo Implement getConfiguration() method. } /** * {@inheritdoc} */ public function setConfiguration(array $configuration) { - $config = $this->configFactory->getEditable('diff.layout_plugins'); + // @todo Implement setConfiguration() method. } /** diff --git a/src/DiffLayoutInterface.php b/src/DiffLayoutInterface.php index b3393e9..dcfccc5 100644 --- a/src/DiffLayoutInterface.php +++ b/src/DiffLayoutInterface.php @@ -10,36 +10,25 @@ use Drupal\Core\Routing\RouteMatchInterface; interface DiffLayoutInterface extends PluginFormInterface, ConfigurablePluginInterface { /** - * Builds an array of strings. + * Builds a diff comparison between two revisions. * - * This method is responsible for transforming a FieldItemListInterface object - * into an array of strings. The resulted array of strings is then compared by - * the Diff component with another such array of strings and the result - * represents the difference between two entity fields. + * 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. * - * Example of FieldItemListInterface built into an array of strings: - * @code - * array( - * 0 => "This is an example string", - * 1 => "Field values or properties", - * ) - * @endcode - * - * @see \Drupal\diff\Plugin\Diff\TextFieldBuilder + * @see \Drupal\diff\Plugin\Layout\ClassicDiffLayout * * @param array $build - * Represents an entity field. + * A renderable array of data. * @param \Drupal\Core\Entity\EntityInterface $left_revision * The left revision. * @param \Drupal\Core\Entity\EntityInterface $right_revision * The right revision. * @param \Drupal\Core\Entity\EntityInterface $entity - * The route match. + * The entity. * * @return mixed - * An array of strings to be compared. If an empty array is returned it - * means that a field is either empty or no properties need to be compared - * for that field. + * The modified build array that the plugin builds. */ public function build(array $build, EntityInterface $left_revision, EntityInterface $right_revision, EntityInterface $entity); } diff --git a/src/DiffLayoutManager.php b/src/DiffLayoutManager.php index e0e6aa8..9d3f781 100644 --- a/src/DiffLayoutManager.php +++ b/src/DiffLayoutManager.php @@ -14,7 +14,7 @@ use Drupal\Core\Plugin\DefaultPluginManager; /** * Plugin type manager for field diff builders. * - * @ingroup field_diff_builder + * @ingroup diff_layout_builder */ class DiffLayoutManager extends DefaultPluginManager { @@ -36,7 +36,7 @@ class DiffLayoutManager extends DefaultPluginManager { protected $layoutPluginsConfig; /** - * Constructs a FieldDiffBuilderManager object. + * Constructs a DiffLayoutManager object. * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths diff --git a/src/Plugin/Layout/ClassicDiffLayout.php b/src/Plugin/Layout/ClassicDiffLayout.php index c750036..9afeb2e 100644 --- a/src/Plugin/Layout/ClassicDiffLayout.php +++ b/src/Plugin/Layout/ClassicDiffLayout.php @@ -2,15 +2,12 @@ namespace Drupal\diff\Plugin\Layout; -use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Xss; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Render\RendererInterface; -use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; use Drupal\diff\DiffEntityComparison; use Drupal\diff\DiffEntityParser; @@ -100,35 +97,40 @@ class ClassicDiffLayout extends DiffLayoutBase { foreach ($fields as $field) { $field_label_row = ''; if (!empty($field['#name'])) { - $field_label_row = array( + $field_label_row = [ 'data' => $this->t('%name', ['%name' => $field['#name']]), 'colspan' => 4, - 'class' => array('field-name'), - ); + 'class' => ['field-name'], + ]; } + + // 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['#states']['raw']['#left'], - $field['#states']['raw']['#right'] + $field['#data']['#left'], + $field['#data']['#right'] ); // Add the field label to the table only if there are changes to that field. if (!empty($field_diff_rows) && !empty($field_label_row)) { - $diff_rows[] = array($field_label_row); + $diff_rows[] = [$field_label_row]; } // Add field diff rows to the table rows. $diff_rows = array_merge($diff_rows, $field_diff_rows); } - $build['diff'] = array( + $build['diff'] = [ '#type' => 'table', '#header' => $diff_header, '#rows' => $diff_rows, '#empty' => $this->t('No visible changes'), - '#attributes' => array( - 'class' => array('diff'), - ), - ); + '#attributes' => [ + 'class' => ['diff'], + ], + ]; $build['#attached']['library'][] = 'diff/diff.github'; return $build; @@ -180,10 +182,6 @@ class ClassicDiffLayout extends DiffLayoutBase { elseif ($revision instanceof NodeInterface) { $revision_log = $revision->revision_log->value; } - $username = [ - '#theme' => 'username', - '#account' => $revision->uid->entity, - ]; $revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short'); $route_name = $entity_type_id != 'node' ? "entity.$entity_type_id.revisions_diff" : 'entity.node.revision'; $revision_link = $this->t($revision_log . '@date', [ diff --git a/src/Plugin/Layout/MarkdownDiffLayout.php b/src/Plugin/Layout/MarkdownDiffLayout.php index 799b93d..4d2d6a4 100644 --- a/src/Plugin/Layout/MarkdownDiffLayout.php +++ b/src/Plugin/Layout/MarkdownDiffLayout.php @@ -2,15 +2,13 @@ namespace Drupal\diff\Plugin\Layout; -use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Xss; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Mail\MailFormatHelper; use Drupal\Core\Render\RendererInterface; -use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; use Drupal\diff\DiffEntityComparison; use Drupal\diff\DiffEntityParser; @@ -100,35 +98,51 @@ class MarkdownDiffLayout extends DiffLayoutBase { foreach ($fields as $field) { $field_label_row = ''; if (!empty($field['#name'])) { - $field_label_row = array( + $field_label_row = [ 'data' => $this->t('%name', ['%name' => $field['#name']]), 'colspan' => 4, - 'class' => array('field-name'), - ); + 'class' => ['field-name'], + ]; } + $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['#states']['raw_plain']['#left'], - $field['#states']['raw_plain']['#right'] + $field['#data']['#left'], + $field['#data']['#right'] ); // Add the field label to the table only if there are changes to that field. if (!empty($field_diff_rows) && !empty($field_label_row)) { - $diff_rows[] = array($field_label_row); + $diff_rows[] = [$field_label_row]; } // Add field diff rows to the table rows. $diff_rows = array_merge($diff_rows, $field_diff_rows); } - $build['diff'] = array( + $build['diff'] = [ '#type' => 'table', '#header' => $diff_header, '#rows' => $diff_rows, '#empty' => $this->t('No visible changes'), - '#attributes' => array( - 'class' => array('diff'), - ), - ); + '#attributes' => [ + 'class' => ['diff'], + ], + ]; $build['#attached']['library'][] = 'diff/diff.github'; return $build; @@ -180,10 +194,6 @@ class MarkdownDiffLayout extends DiffLayoutBase { elseif ($revision instanceof NodeInterface) { $revision_log = $revision->revision_log->value; } - $username = [ - '#theme' => 'username', - '#account' => $revision->uid->entity, - ]; $revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short'); $route_name = $entity_type_id != 'node' ? "entity.$entity_type_id.revisions_diff" : 'entity.node.revision'; $revision_link = $this->t($revision_log . '@date', [ @@ -199,4 +209,36 @@ class MarkdownDiffLayout extends DiffLayoutBase { return $revision_link; } + + /** + * Applies a markdown function to a string. + * + * @param $markdown + * Key of the markdown function to be applied to the items. + * One of drupal_html_to_text, filter_xss, filter_xss_all. + * @param $items + * String to be processed. + * + * @return array|string + * Result after markdown was applied on $items. + */ + protected function applyMarkdown($markdown, $items) { + if (!$markdown) { + return $items; + } + + if ($markdown == 'drupal_html_to_text') { + return trim(MailFormatHelper::htmlToText($items), "\n"); + } + elseif ($markdown == 'filter_xss') { + return trim(Xss::filter($items), "\n"); + } + elseif ($markdown == 'filter_xss_all') { + return trim(Xss::filter($items, []), "\n"); + } + else { + return $items; + } + } + }