View source
<?php
namespace Drupal\gatsby_instantpreview;
use GuzzleHttp\ClientInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\node\NodeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityRepository;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\gatsby\GatsbyPreview;
use Drupal\jsonapi_extras\EntityToJsonApi;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
class GatsbyInstantPreview extends GatsbyPreview {
private $entityToJsonApi;
private $entityRepository;
private $innerService;
public function __construct(GatsbyPreview $inner_service, ClientInterface $http_client, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, LoggerChannelFactoryInterface $logger, EntityToJsonApi $entity_to_json_api, EntityRepository $entity_repository) {
$this->innerService = $inner_service;
$this->entityToJsonApi = $entity_to_json_api;
$this->entityRepository = $entity_repository;
parent::__construct($http_client, $config, $entity_type_manager, $logger);
}
public function gatsbyPrepareData(ContentEntityInterface $entity = NULL, string $action = 'update') {
$json = $this
->getJson($entity);
if (!$json) {
return;
}
$json['id'] = $entity
->uuid();
$json['action'] = $action;
$settings = $this->configFactory
->get('gatsby.settings');
if ($settings
->get('secret_key')) {
$json['secret'] = $settings
->get('secret_key');
}
$preview_url = $settings
->get('preview_callback_url');
if ($preview_url) {
$json = $this
->bundleData('preview', $preview_url, $json);
$this
->updateData('preview', $preview_url, $json);
}
$incrementalbuild_url = $settings
->get('incrementalbuild_url');
if (!$incrementalbuild_url) {
return;
}
if ($settings
->get('build_published')) {
if (!$entity instanceof NodeInterface || !$entity
->isPublished()) {
return;
}
if (empty($json['data']['relationships'])) {
return;
}
$entity_data = [];
$included_types = $settings
->get('preview_entity_types') ?: [];
$this
->buildRelationshipJson($json['data']['relationships'], $entity_data, array_values($included_types));
if (!empty($entity_data)) {
$entity_data = array_values($entity_data);
$original_data = $json['data'];
$entity_data[] = $original_data;
$json['data'] = $entity_data;
}
}
$json = $this
->bundleData('incrementalbuild', $incrementalbuild_url, $json);
$this
->updateData('incrementalbuild', $incrementalbuild_url, $json);
}
public function gatsbyPrepareDelete(ContentEntityInterface $entity = NULL) {
$json = [
'id' => $entity
->uuid(),
'action' => 'delete',
'type' => $entity
->getEntityType()
->id() . '--' . $entity
->bundle(),
'attributes' => [
'langcode' => $entity
->language()
->getId(),
'drupal_internal__revision_id' => $entity
->getRevisionId(),
],
];
$settings = $this->configFactory
->get('gatsby.settings');
$json['data'] = $json;
if ($settings
->get('secret_key')) {
$json['secret'] = $settings
->get('secret_key');
}
$preview_url = $settings
->get('preview_callback_url');
if ($preview_url) {
$preview_json = $this
->bundleData('preview', $preview_url, $json);
$this
->updateData('preview', $preview_url, $preview_json);
}
$incrementalbuild_url = $settings
->get('incrementalbuild_url');
if ($incrementalbuild_url) {
$json = $this
->bundleData('incrementalbuild', $incrementalbuild_url, $json);
$this
->updateData('incrementalbuild', $incrementalbuild_url, $json);
}
}
public function bundleData($key, $url, $json) {
$updated =& self::$updateData;
if (empty($updated)) {
return $json;
}
if (!empty($updated[$key][$url]['json'])) {
if (!empty($updated[$key][$url]['json']['data']['type'])) {
$json['data'] = [
$updated[$key][$url]['json']['data'],
$json['data'],
];
}
else {
foreach ($updated[$key][$url]['json']['data'] as $index => $entity) {
if ($entity['id'] == $json['id']) {
$updated[$key][$url]['json']['data'][$index] = $json['data'];
$json['data'] = $updated[$key][$url]['json']['data'];
return $json;
}
}
$updated[$key][$url]['json']['data'][] = $json['data'];
$json['data'] = $updated[$key][$url]['json']['data'];
}
}
return $json;
}
public function buildRelationshipJson($relationships, &$entity_data, $included_types = []) {
foreach ($relationships as $data) {
if (empty($data['data'])) {
continue;
}
$related_items = $data['data'];
if (!empty($data['data']['type'])) {
$related_items = [
$data['data'],
];
}
foreach ($related_items as $related_data) {
$entityType = !empty($related_data['type']) ? explode('--', $related_data['type']) : "";
if (!empty($entityType) && (!$included_types || in_array($entityType[0], $included_types, TRUE))) {
if (!empty($entity_data[$related_data['id']])) {
continue;
}
$related_entity = $this->entityRepository
->loadEntityByUuid($entityType[0], $related_data['id']);
if (empty($related_entity) || !$related_entity instanceof ContentEntityInterface) {
continue;
}
$related_json = $this
->getJson($related_entity);
if (!$related_json) {
continue;
}
$entity_data[$related_data['id']] = $related_json['data'];
if (!empty($related_json['data']['relationships'])) {
$this
->buildRelationshipJson($related_json['data']['relationships'], $entity_data, $included_types);
}
}
}
}
}
public function getJson(ContentEntityInterface $entity) {
try {
return $this->entityToJsonApi
->normalize($entity);
} catch (RouteNotFoundException $e) {
return NULL;
}
}
}