124cc8bf71067fbc0147c34aadd01c9eadb6d2d6
[yaffs-website] / web / modules / contrib / diff / src / Plugin / diff / Layout / VisualInlineDiffLayout.php
1 <?php
2
3 namespace Drupal\diff\Plugin\diff\Layout;
4
5 use Drupal\Core\Config\ConfigFactoryInterface;
6 use Drupal\Core\Datetime\DateFormatter;
7 use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
8 use Drupal\Core\Entity\ContentEntityInterface;
9 use Drupal\Core\Entity\EntityTypeManagerInterface;
10 use Drupal\Core\PhpStorage\PhpStorageFactory;
11 use Drupal\Core\Render\RendererInterface;
12 use Drupal\diff\Controller\PluginRevisionController;
13 use Drupal\diff\DiffEntityComparison;
14 use Drupal\diff\DiffEntityParser;
15 use Drupal\diff\DiffLayoutBase;
16 use Symfony\Component\DependencyInjection\ContainerInterface;
17 use HtmlDiffAdvancedInterface;
18 use Symfony\Component\HttpFoundation\RequestStack;
19
20 /**
21  * Provides Visual Inline diff layout.
22  *
23  * @DiffLayoutBuilder(
24  *   id = "visual_inline",
25  *   label = @Translation("Visual Inline"),
26  *   description = @Translation("Visual layout, displays revision comparison using the entity type view mode."),
27  * )
28  */
29 class VisualInlineDiffLayout extends DiffLayoutBase {
30
31   /**
32    * The renderer.
33    *
34    * @var \Drupal\Core\Render\RendererInterface
35    */
36   protected $renderer;
37
38   /**
39    * The diff entity comparison service.
40    *
41    * @var \Drupal\diff\DiffEntityComparison
42    */
43   protected $entityComparison;
44
45   /**
46    * The html diff service.
47    *
48    * @var \HtmlDiffAdvancedInterface
49    */
50   protected $htmlDiff;
51
52   /**
53    * The request stack.
54    *
55    * @var \Symfony\Component\HttpFoundation\RequestStack
56    */
57   protected $requestStack;
58
59   /**
60    * The entity display repository.
61    *
62    * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
63    */
64   protected $entityDisplayRepository;
65
66   /**
67    * Constructs a VisualInlineDiffLayout object.
68    *
69    * @param array $configuration
70    *   A configuration array containing information about the plugin instance.
71    * @param string $plugin_id
72    *   The plugin_id for the plugin instance.
73    * @param mixed $plugin_definition
74    *   The plugin implementation definition.
75    * @param \Drupal\Core\Config\ConfigFactoryInterface $config
76    *   The configuration factory object.
77    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
78    *   The entity type manager.
79    * @param \Drupal\diff\DiffEntityParser $entity_parser
80    *   The entity parser.
81    * @param \Drupal\Core\DateTime\DateFormatter $date
82    *   The date service.
83    * @param \Drupal\Core\Render\RendererInterface $renderer
84    *   The renderer.
85    * @param \Drupal\diff\DiffEntityComparison $entity_comparison
86    *   The diff entity comparison service.
87    * @param \HtmlDiffAdvancedInterface $html_diff
88    *   The html diff service.
89    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
90    *   The request stack.
91    * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
92    *   The entity display repository.
93    */
94   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, HtmlDiffAdvancedInterface $html_diff, RequestStack $request_stack, EntityDisplayRepositoryInterface $entity_display_repository) {
95     parent::__construct($configuration, $plugin_id, $plugin_definition, $config, $entity_type_manager, $entity_parser, $date);
96     $this->renderer = $renderer;
97     $this->entityComparison = $entity_comparison;
98     $storage = PhpStorageFactory::get('html_purifier_serializer');
99     if (!$storage->exists('cache.php')) {
100       $storage->save('cache.php', 'dummy');
101     }
102     $html_diff->getConfig()->setPurifierCacheLocation(dirname($storage->getFullPath('cache.php')));
103     $this->htmlDiff = $html_diff;
104     $this->requestStack = $request_stack;
105     $this->entityDisplayRepository = $entity_display_repository;
106   }
107
108   /**
109    * {@inheritdoc}
110    */
111   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
112     return new static(
113       $configuration,
114       $plugin_id,
115       $plugin_definition,
116       $container->get('config.factory'),
117       $container->get('entity_type.manager'),
118       $container->get('diff.entity_parser'),
119       $container->get('date.formatter'),
120       $container->get('renderer'),
121       $container->get('diff.entity_comparison'),
122       $container->get('diff.html_diff'),
123       $container->get('request_stack'),
124       $container->get('entity_display.repository')
125     );
126   }
127
128   /**
129    * {@inheritdoc}
130    */
131   public function build(ContentEntityInterface $left_revision, ContentEntityInterface $right_revision, ContentEntityInterface $entity) {
132     // Build the revisions data.
133     $build = $this->buildRevisionsData($left_revision, $right_revision);
134
135     $this->entityTypeManager->getStorage($entity->getEntityTypeId())->resetCache([$entity->id()]);
136     // Build the view modes filter.
137     $options = [];
138     // Get all view modes for entity type.
139     $view_modes = $this->entityDisplayRepository->getViewModeOptionsByBundle($entity->getEntityTypeId(), $entity->bundle());
140     foreach ($view_modes as $view_mode => $view_mode_info) {
141       // Skip view modes that are not used in the front end.
142       if (in_array($view_mode, ['rss', 'search_index'])) {
143         continue;
144       }
145       $options[$view_mode] = [
146         'title' => $view_mode_info,
147         'url' => PluginRevisionController::diffRoute($entity,
148           $left_revision->getRevisionId(),
149           $right_revision->getRevisionId(),
150           'visual_inline',
151           ['view_mode' => $view_mode]
152         ),
153       ];
154     }
155
156     $active_option = array_keys($options);
157     $active_view_mode = $this->requestStack->getCurrentRequest()->query->get('view_mode') ?: reset($active_option);
158
159     $filter = $options[$active_view_mode];
160     unset($options[$active_view_mode]);
161     array_unshift($options, $filter);
162
163     $build['controls']['view_mode'] = [
164       '#type' => 'item',
165       '#title' => $this->t('View mode'),
166       '#wrapper_attributes' => ['class' => 'diff-controls__item'],
167       'filter' => [
168         '#type' => 'operations',
169         '#links' => $options,
170       ],
171     ];
172
173     $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
174     // Trigger exclusion of interactive items like on preview.
175     $left_revision->in_preview = TRUE;
176     $right_revision->in_preview = TRUE;
177     $left_view = $view_builder->view($left_revision, $active_view_mode);
178     $right_view = $view_builder->view($right_revision, $active_view_mode);
179
180     // Avoid render cache from being built.
181     unset($left_view['#cache']);
182     unset($right_view['#cache']);
183
184     $html_1 = $this->renderer->render($left_view);
185     $html_2 = $this->renderer->render($right_view);
186
187     $this->htmlDiff->setOldHtml($html_1);
188     $this->htmlDiff->setNewHtml($html_2);
189     $this->htmlDiff->build();
190
191     $build['diff'] = [
192       '#markup' => $this->htmlDiff->getDifference(),
193       '#weight' => 10,
194     ];
195
196     $build['#attached']['library'][] = 'diff/diff.visual_inline';
197     return $build;
198   }
199
200 }