5 use Drupal\Component\Plugin\PluginBase;
6 use Drupal\Component\Utility\Xss;
7 use Drupal\Core\Datetime\DateFormatter;
8 use Drupal\Core\Entity\ContentEntityInterface;
9 use Drupal\Core\Entity\EntityTypeManagerInterface;
10 use Drupal\Core\Entity\RevisionLogInterface;
11 use Drupal\Core\Form\FormStateInterface;
12 use Drupal\Core\Config\ConfigFactoryInterface;
13 use Drupal\Core\Mail\MailFormatHelper;
14 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
16 use Drupal\Core\StringTranslation\StringTranslationTrait;
18 use Drupal\diff\Controller\PluginRevisionController;
19 use Drupal\node\NodeInterface;
20 use Symfony\Component\DependencyInjection\ContainerInterface;
23 * Base class for diff layout plugins.
25 abstract class DiffLayoutBase extends PluginBase implements DiffLayoutInterface, ContainerFactoryPluginInterface {
27 use StringTranslationTrait;
30 * Contains the configuration object factory.
32 * @var \Drupal\Core\Config\ConfigFactoryInterface
34 protected $configFactory;
37 * The entity type manager.
39 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
41 protected $entityTypeManager;
46 * @var \Drupal\diff\DiffEntityParser
48 protected $entityParser;
53 * @var \Drupal\Core\Datetime\DateFormatter
58 * Constructs a DiffLayoutBase object.
60 * @param array $configuration
61 * A configuration array containing information about the plugin instance.
62 * @param string $plugin_id
63 * The plugin_id for the plugin instance.
64 * @param mixed $plugin_definition
65 * The plugin implementation definition.
66 * @param \Drupal\Core\Config\ConfigFactoryInterface $config
67 * The configuration factory object.
68 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
69 * The entity type manager.
70 * @param \Drupal\diff\DiffEntityParser $entity_parser
72 * @param \Drupal\Core\DateTime\DateFormatter $date
75 public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, DiffEntityParser $entity_parser, DateFormatter $date) {
76 parent::__construct($configuration, $plugin_id, $plugin_definition);
77 $this->configFactory = $config;
78 $this->entityTypeManager = $entity_type_manager;
79 $this->entityParser = $entity_parser;
81 $this->configuration += $this->defaultConfiguration();
87 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
92 $container->get('config.factory'),
93 $container->get('entity_type.manager'),
94 $container->get('diff.entity_parser'),
95 $container->get('date.formatter')
100 * Build the revision link for a revision.
102 * @param \Drupal\Core\Entity\ContentEntityInterface $revision
103 * A revision where to add a link.
105 * @return \Drupal\Core\Link
106 * Header link for a revision in the table.
108 protected function buildRevisionLink(ContentEntityInterface $revision) {
109 if ($revision instanceof RevisionLogInterface) {
110 $revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short');
111 $revision_link = Link::fromTextAndUrl($revision_date, $revision->toUrl('revision'))->toString();
114 $revision_link = Link::fromTextAndUrl($revision->label(), $revision->toUrl('revision'))
117 return $revision_link;
121 * Build the revision link for the compared revisions.
123 * @param \Drupal\Core\Entity\ContentEntityInterface $left_revision
124 * Left revision that is compared.
125 * @param \Drupal\Core\Entity\ContentEntityInterface $right_revision
126 * Right revision that is compared.
129 * Header link for a revision in the revision comparison display.
131 public function buildRevisionsData(ContentEntityInterface $left_revision, ContentEntityInterface $right_revision) {
132 $right_revision = $this->buildRevisionData($right_revision);
133 $right_revision['#prefix'] = '<div class="diff-revision__items-group">';
134 $right_revision['#suffix'] = '</div>';
136 $left_revision = $this->buildRevisionData($left_revision);
137 $left_revision['#prefix'] = '<div class="diff-revision__items-group">';
138 $left_revision['#suffix'] = '</div>';
140 // Show the revisions that are compared.
143 'diff_revisions' => [
145 '#title' => $this->t('Comparing'),
146 '#wrapper_attributes' => ['class' => 'diff-revision'],
148 '#prefix' => '<div class="diff-revision__items">',
149 '#suffix' => '</div>',
150 'right_revision' => $right_revision,
151 'left_revision' => $left_revision,
159 * Build the revision link for a revision.
161 * @param \Drupal\Core\Entity\ContentEntityInterface $revision
162 * Left revision that is compared.
165 * Revision data about author, creation date and log.
167 protected function buildRevisionData(ContentEntityInterface $revision) {
168 if ($revision instanceof RevisionLogInterface) {
169 $revision_log = Xss::filter($revision->getRevisionLogMessage());
170 $user_id = $revision->getRevisionUserId();
172 $revision_link['date'] = [
174 '#title' => $this->date->format($revision->getRevisionCreationTime(), 'short'),
175 '#url' => $revision->toUrl('revision'),
176 '#prefix' => '<div class="diff-revision__item diff-revision__item-date">',
177 '#suffix' => '</div>',
180 $revision_link['author'] = [
182 '#title' => $revision->getRevisionUser()->getDisplayName(),
183 '#url' => Url::fromUri(\Drupal::request()->getUriForPath('/user/' . $user_id)),
184 '#theme' => 'username',
185 '#account' => $revision->getRevisionUser(),
186 '#prefix' => '<div class="diff-revision__item diff-revision__item-author">',
187 '#suffix' => '</div>',
191 $revision_link['message'] = [
193 '#prefix' => '<div class="diff-revision__item diff-revision__item-message">',
194 '#suffix' => '</div>',
195 '#markup' => $revision_log,
200 $revision_link['label'] = [
202 '#title' => $revision->label(),
203 '#url' => $revision->toUrl('revision'),
204 '#prefix' => '<div class="diff-revision__item diff-revision__item-date">',
205 '#suffix' => '</div>',
208 return $revision_link;
212 * Build the filter navigation for the diff comparison.
214 * @param \Drupal\Core\Entity\ContentEntityInterface $entity
216 * @param \Drupal\Core\Entity\ContentEntityInterface $left_revision
217 * Revision from the left side.
218 * @param \Drupal\Core\Entity\ContentEntityInterface $right_revision
219 * Revision from the right side.
220 * @param string $layout
221 * The layout plugin selected.
222 * @param string $active_filter
226 * The filter options.
228 protected function buildFilterNavigation(ContentEntityInterface $entity, ContentEntityInterface $left_revision, ContentEntityInterface $right_revision, $layout, $active_filter) {
229 // Build the view modes filter.
231 'title' => $this->t('Raw'),
232 'url' => PluginRevisionController::diffRoute($entity,
233 $left_revision->getRevisionId(),
234 $right_revision->getRevisionId(),
240 $options['strip_tags'] = [
241 'title' => $this->t('Strip tags'),
242 'url' => PluginRevisionController::diffRoute($entity,
243 $left_revision->getRevisionId(),
244 $right_revision->getRevisionId(),
246 ['filter' => 'strip_tags']
250 $filter = $options[$active_filter];
251 unset($options[$active_filter]);
252 array_unshift($options, $filter);
254 $build['options'] = [
255 '#type' => 'operations',
256 '#links' => $options,
262 * Applies a markdown function to a string.
264 * @param string $markdown
265 * Key of the markdown function to be applied to the items.
266 * One of drupal_html_to_text, filter_xss, filter_xss_all.
267 * @param string $items
268 * String to be processed.
270 * @return array|string
271 * Result after markdown was applied on $items.
273 protected function applyMarkdown($markdown, $items) {
278 if ($markdown == 'drupal_html_to_text') {
279 return trim(MailFormatHelper::htmlToText($items), "\n");
281 elseif ($markdown == 'filter_xss') {
282 return trim(Xss::filter($items), "\n");
284 elseif ($markdown == 'filter_xss_all') {
285 return trim(Xss::filter($items, []), "\n");
295 public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
301 public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
307 public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
313 public function defaultConfiguration() {
320 public function getConfiguration() {
321 return $this->configFactory->getEditable('diff.layout_plugins');
327 public function setConfiguration(array $configuration) {
328 $config = $this->configFactory->getEditable('diff.layout_plugins');
329 $config->set($this->pluginId, $configuration);
336 public function calculateDependencies() {