class EntityManager in Acquia Content Hub 8
Provides a service for managing entity actions for Content Hub.
@todo To be renamed to "ExportEntityManager".
Hierarchy
- class \Drupal\acquia_contenthub\EntityManager
Expanded class hierarchy of EntityManager
9 files declare their use of EntityManager
- ContentEntityCdfNormalizer.php in src/
Normalizer/ ContentEntityCdfNormalizer.php - ContentHubEntityExportController.php in src/
Controller/ ContentHubEntityExportController.php - ContentHubEntityRequestHandler.php in src/
Controller/ ContentHubEntityRequestHandler.php - ContentHubExportQueueBase.php in src/
Plugin/ QueueWorker/ ContentHubExportQueueBase.php - ContentHubSubscriberController.php in acquia_contenthub_subscriber/
src/ Controller/ ContentHubSubscriberController.php
1 string reference to 'EntityManager'
1 service uses EntityManager
File
- src/
EntityManager.php, line 30
Namespace
Drupal\acquia_contenthubView source
class EntityManager {
// Possible actions that the Entity Manager can queue entities for.
const EXPORT = 'EXPORT';
const UNEXPORT = 'UNEXPORT';
/**
* Base root.
*
* @var string
*/
private $baseRoot;
/**
* Logger.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
private $loggerFactory;
/**
* Content Hub Client Manager.
*
* @var \Drupal\acquia_contenthub\Client\ClientManager
*/
private $clientManager;
/**
* The Content Hub Entities Tracking Service.
*
* @var \Drupal\acquia_contenthub\ContentHubEntitiesTracking
*/
private $contentHubEntitiesTracking;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
private $entityTypeManager;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
private $entityTypeBundleInfoManager;
/**
* The list of candidate entities for next bulk export.
*
* @var array
*/
private $candidateEntities = [
self::EXPORT => [],
self::UNEXPORT => [],
];
/**
* The "shutdown function is registered" flag.
*
* @var bool
*/
private $shutdownFunctionRegistered = FALSE;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('logger.factory'), $container
->get('config.factory'), $container
->get('acquia_contenthub.client_manager'), $container
->get('acquia_contenthub.acquia_contenthub_entities_tracking'), $container
->get('entity_type.manager'), $container
->get('entity_type.bundle.info'));
}
/**
* Constructs an EntityManager object.
*
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\acquia_contenthub\Client\ClientManagerInterface $client_manager
* The client manager.
* @param \Drupal\acquia_contenthub\ContentHubEntitiesTracking $acquia_contenthub_entities_tracking
* The Content Hub Entities Tracking.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The Entity Type Manager.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info_manager
* The Entity Type Bundle Info Manager.
*/
public function __construct(LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory, ClientManagerInterface $client_manager, ContentHubEntitiesTracking $acquia_contenthub_entities_tracking, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info_manager) {
$this->baseRoot = isset($GLOBALS['base_root']) ? $GLOBALS['base_root'] : '';
$this->loggerFactory = $logger_factory;
$this->clientManager = $client_manager;
$this->contentHubEntitiesTracking = $acquia_contenthub_entities_tracking;
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleInfoManager = $entity_type_bundle_info_manager;
// Get the content hub config settings.
$this->config = $config_factory
->get('acquia_contenthub.admin_settings');
}
/**
* Get candidate entities.
*
* @return array
* The list of candidate entities of a specific action.
*/
public function getExportCandidateEntities() {
return $this->candidateEntities[self::EXPORT];
}
/**
* Enqueue an entity with an operation to be performed on Content Hub.
*
* @param object $entity
* The Drupal Entity object.
* @param bool $do_export
* TRUE if the entity action is 'EXPORT'; FALSE, if it is 'UNEXPORT'.
*/
public function enqueueCandidateEntity($entity, $do_export = TRUE) {
// Early return, if entity is not eligible.
if (!$this
->isEligibleEntity($entity)) {
return;
}
// Register shutdown function.
$this
->registerShutdownFunction();
$unexporting_entities = [];
$exporting_entities = [];
// Only care about the case where entity is 1) node, and 2) updating.
if ($entity instanceof NodeInterface && isset($entity->original)) {
// We also know the $do_export at this point should be TRUE.
$old_is_published = $entity->original
->isPublished();
$new_is_published = $this
->isPublished($entity);
if (!$new_is_published) {
$do_export = FALSE;
}
// If "published to unpublished", unexport it and its old descendants.
if ($old_is_published && !$new_is_published) {
$unexporting_entities += $this
->getReferencedEntities($entity->original);
}
}
// Only add references to be exported if the entity is to be exported. In
// the case of unexporting/deletion, references should not be exported.
if ($do_export) {
$exporting_entities += $this
->getReferencedEntities($entity);
}
// If "to published", we have to move any disassociated entities exporting
// list to unexporting list.
if ($do_export && $entity instanceof EntityInterface && isset($entity->original)) {
// Find all UUIDs of the exported entities.
$exporting_entities_uuids = [];
foreach ($exporting_entities as $exporting_entity) {
$exporting_entities_uuids[$exporting_entity
->uuid()] = TRUE;
}
$exported_entities = $this
->getReferencedEntities($entity->original);
// For each exported entity, check if it still remains associated.
foreach ($exported_entities as $key => $exported_entity) {
// If remain associated, leave it alone.
if (isset($exporting_entities_uuids[$exported_entity
->uuid()])) {
continue;
}
// Otherwise, if disassociated, move it from export to unexport queue.
$unexporting_entities[] = $exported_entity;
unset($exported_entities[$key]);
}
}
// Enqueue unexport and export entities separately.
$this
->enqueueQualifiedEntities($unexporting_entities, FALSE);
$this
->enqueueQualifiedEntities($exporting_entities, TRUE);
$action = $do_export ? self::EXPORT : self::UNEXPORT;
$this->candidateEntities[$action][$entity
->uuid()] = $entity;
}
/**
* Enqueue array of entities with an operation to be performed on Content Hub.
*
* @param array $entities
* A list of entities.
* @param bool $do_export
* TRUE if the entity action is 'EXPORT'; FALSE, if it is 'UNEXPORT'.
*/
private function enqueueQualifiedEntities(array $entities, $do_export) {
foreach ($entities as $entity) {
// @todo Paragraphs' handling is hardcoded in Export Entity Manager right
// now, but need to be refactored out of this class in the future.
if (!$entity instanceof ParagraphInterface) {
continue;
}
$this
->enqueueCandidateParagraph($entity, $do_export);
}
}
/**
* Enqueue a paragraph with an operation to be performed on Content Hub.
*
* @param \Drupal\paragraphs\ParagraphInterface $paragraph
* The Paragraph object.
* @param bool $do_export
* TRUE if the entity action is 'EXPORT'; FALSE, if it is 'UNEXPORT'.
*/
private function enqueueCandidateParagraph(ParagraphInterface $paragraph, $do_export) {
// Early return, if entity is not eligible.
if (!$this
->isEligibleEntity($paragraph)) {
return;
}
$referenced_entities = $paragraph
->referencedEntities();
$this
->enqueueQualifiedEntities($referenced_entities, $do_export);
$action = $do_export ? self::EXPORT : self::UNEXPORT;
$this->candidateEntities[$action][$paragraph
->uuid()] = $paragraph;
}
/**
* Register shutdown function.
*/
private function registerShutdownFunction() {
if ($this->shutdownFunctionRegistered) {
return;
}
// Register shutdown function to send/delete entities to/from Content Hub.
drupal_register_shutdown_function('acquia_contenthub_bulk_export');
$this->shutdownFunctionRegistered = TRUE;
}
/**
* Tracks the number of entities that fail to bulk upload.
*
* @param string $num
* Number of failed entities added to the pool.
*
* @return string
* The total number of entities that failed to bulk upload.
*/
private function entityFailures($num = NULL) {
$total =& drupal_static(__METHOD__);
if (!isset($total)) {
$total = is_int($num) ? $num : 0;
}
else {
$total = is_int($num) ? $total + $num : $total;
}
return $total;
}
/**
* Sends the entities for update to Content Hub.
*
* @param string $resource_url
* The Resource Url.
*
* @return bool|mixed
* Returns the response or FALSE otherwise.
*/
public function updateRemoteEntities($resource_url) {
$response = $this->clientManager
->createRequest('updateEntities', [
$resource_url,
]);
if (method_exists($response, 'getBody')) {
$response = Json::decode($response
->getBody());
}
return $response;
}
/**
* PUT entities for update to Content Hub, without site callback.
*
* @param mixed $entities
* An array of entities.
*
* @return bool
* TRUE if request succeeds, FALSE otherwise.
*/
public function putRemoteEntities($entities) {
if (!isset($entities['entities'])) {
$entities = [
'entities' => $entities,
];
}
if ($response = $this->clientManager
->createRequest('putEntities', [
$entities,
])) {
$response = Json::decode($response
->getBody());
}
return !empty($response['success']);
}
/**
* Bulk-export all the enqueued entities.
*/
public function bulkExport() {
$this
->unexportDisqualifiedExportCandidateEntities();
$this
->unexportCandidateEntities();
}
/**
* Delete entities from Content Hub that are explicitly un-exported.
*/
private function unexportCandidateEntities() {
$candidate_entites = $this->candidateEntities[self::UNEXPORT];
foreach ($candidate_entites as $uuid => $candidate_entity) {
$this
->deleteRemoteEntity($candidate_entity);
unset($this->candidateEntities[self::UNEXPORT][$uuid]);
}
}
/**
* Delete entities from Content Hub that are disqualified of exporting.
*/
private function unexportDisqualifiedExportCandidateEntities() {
$candidate_entites = $this->candidateEntities[self::EXPORT];
foreach ($candidate_entites as $uuid => $candidate_entity) {
$root_ancestor_entity = $this
->findRootAncestorEntity($candidate_entity);
// If root ancestor is not published, delete the current entity.
if ($root_ancestor_entity instanceof NodeInterface && !$this
->isPublished($root_ancestor_entity)) {
$this->candidateEntities[self::UNEXPORT][$uuid] = $candidate_entity;
unset($this->candidateEntities[self::EXPORT][$uuid]);
}
}
}
/**
* Delete an entity from Content Hub.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The Content Hub Entity.
*/
private function deleteRemoteEntity(EntityInterface $entity) {
// Check if the entity was never exported first, to avoid sending a DELETE
// request to the Content Hub service.
if ($this->contentHubEntitiesTracking
->loadExportedByUuid($entity
->uuid()) === FALSE) {
return;
}
/** @var \Drupal\acquia_contenthub\Client\ClientManagerInterface $client_manager */
try {
$client = $this->clientManager
->getConnection();
} catch (ContentHubException $e) {
$this->loggerFactory
->get('acquia_contenthub')
->error($e
->getMessage());
return;
}
$resource_url = $this
->getResourceUrl($entity);
$args = [
'@type' => $entity
->getEntityTypeId(),
'@uuid' => $entity
->uuid(),
'@id' => $entity
->id(),
];
if (!$resource_url) {
$this->loggerFactory
->get('acquia_contenthub')
->error('Error trying to form a unique resource Url for @type with uuid @uuid and id @id', $args);
return;
}
try {
$uuid = $entity
->uuid();
$response = $client
->deleteEntity($uuid);
$args = [
'@uuid' => $uuid,
'@type' => $entity
->getEntityTypeId(),
'@id' => $entity
->id(),
];
$log_msg = 'Deleting remote entity with UUID = @uuid (@type, @id)';
$contents = Json::decode($response
->getBody()
->getContents());
if (isset($contents['request_id'])) {
$log_msg .= ' (Request ID: @request_id.)';
$args += [
'@request_id' => $contents['request_id'],
];
}
$this->loggerFactory
->get('acquia_contenthub')
->debug($log_msg, $args);
$exported_entity = $this->contentHubEntitiesTracking
->loadExportedByUuid($uuid);
if ($exported_entity) {
$exported_entity
->delete();
}
} catch (RequestException $e) {
$args['@error'] = $e
->getMessage();
$this->loggerFactory
->get('acquia_contenthub')
->error('Error trying to post the resource url for @type with uuid @uuid and id @id with a response from the API: @error', $args);
return;
} catch (\RuntimeException $e) {
$this->loggerFactory
->get('acquia_contenthub')
->error('Error trying to read response contents: @error', $e
->getMessage() . $e
->getTraceAsString());
return;
}
// Make sure it is within the 2XX range. Expected response is a 202.
$status_code = $response
->getStatusCode();
if (substr($status_code, 0, 2) !== '20') {
$this->loggerFactory
->get('acquia_contenthub')
->error('Error trying to post the resource url for @type with uuid @uuid and id @id: Response status code was not 20X as expected.', $args);
}
}
/**
* Returns the local Resource URL.
*
* This is an absolute URL, which base_url can be overwritten with the
* variable 'acquia_contenthub_rewrite_localdomain', which is especially
* useful in cases where the Content Hub module is installed in a Drupal site
* that is running locally (not from the public internet).
*
* @return string|bool
* The absolute resource URL, if it can be generated, FALSE otherwise.
*/
private function getResourceUrl(EntityInterface $entity, $include_references = 'true') {
// Check if there are link templates defined for the entity type and
// use the path from the route instead of the default.
$entity_type_id = $entity
->getEntityTypeId();
$route_name = 'acquia_contenthub.entity.' . $entity_type_id . '.GET.acquia_contenthub_cdf';
$url_options = [
'entity_type' => $entity_type_id,
$entity_type_id => $entity
->id(),
'_format' => 'acquia_contenthub_cdf',
'include_references' => $include_references,
];
return $this
->getResourceUrlByRouteName($route_name, $url_options);
}
/**
* Returns the route's resource URL.
*
* @param string $route_name
* Route name.
* @param array $url_options
* Bulk-upload Url query params.
*
* @return string
* returns URL.
*/
private function getResourceUrlByRouteName($route_name, array $url_options = []) {
$url = Url::fromRoute($route_name, $url_options);
$path = $url
->toString();
// Get the content hub config settings.
$rewrite_localdomain = $this->config
->get('rewrite_domain');
if (UrlHelper::isExternal($path)) {
// If for some reason the $path is an external URL, do not further
// prefix a domain, and do not overwrite the given domain.
$full_path = $path;
}
elseif ($rewrite_localdomain) {
$full_path = $rewrite_localdomain . $path;
}
else {
$full_path = $this->baseRoot . $path;
}
$url = Url::fromUri($full_path);
return $url
->toUriString();
}
/**
* Builds the bulk-upload url to make a single request.
*
* @param array $url_options
* Bulk-upload Url query params.
*
* @return string
* returns URL.
*/
public function getBulkResourceUrl(array $url_options = []) {
$route_name = 'acquia_contenthub.acquia_contenthub_bulk_cdf';
return $this
->getResourceUrlByRouteName($route_name, $url_options);
}
/**
* Checks whether the current entity should be transferred to Content Hub.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The Drupal entity.
*
* @return bool
* True if it can be parsed, False if it not a suitable entity for sending
* to content hub.
*/
public function isEligibleEntity(EntityInterface $entity) {
// Early return, if already sync'ing.
if (!empty($entity->__contenthub_entity_syncing)) {
return FALSE;
}
// Currently Content Hub does not support configuration entities to be
// exported. Only content entities can be exported to Content Hub.
if ($entity instanceof ConfigEntityInterface) {
return FALSE;
}
// If access to the entity is not allowed, then it is not eligible.
if ($entity instanceof FileInterface) {
$account = new ContentHubUserSession(\Drupal::config('acquia_contenthub.entity_config')
->get('user_role'));
$entity_access = $entity
->access('view', $account, TRUE);
if (!$entity_access
->isAllowed()) {
return FALSE;
}
}
$entity_type_id = $entity
->getEntityTypeId();
/** @var \Drupal\acquia_contenthub\ContentHubEntityTypeConfigInterface $entity_type_config */
$entity_type_config = $this
->getContentHubEntityTypeConfigurationEntity($entity_type_id);
$bundle_id = $entity
->bundle();
if (empty($entity_type_config) || empty($entity_type_config
->isEnableIndex($bundle_id))) {
return FALSE;
}
// If this is a file with status = 0 (TEMPORARY FILE) do not export it.
// This is a check to avoid exporting temporary files.
if ($entity instanceof FileInterface && $entity
->isTemporary()) {
return FALSE;
}
$tracking_entity = $this->contentHubEntitiesTracking
->loadExportedByUuid($entity
->uuid());
if ($tracking_entity) {
$entity_origin = $tracking_entity
->getOrigin();
$site_origin = $this->contentHubEntitiesTracking
->getSiteOrigin();
if ($entity_origin !== $site_origin) {
$this->loggerFactory
->get('acquia_contenthub')
->warning('Site origin id (@site) and origin id in the tracking table (@entity) does not match', [
'@entity' => $entity_origin,
'@site' => $site_origin,
]);
return FALSE;
}
}
// If the entity has been imported before, then it didn't originate from
// this site and shouldn't be exported.
$entity_id = $entity
->id();
if ($this->contentHubEntitiesTracking
->loadImportedByDrupalEntity($entity_type_id, $entity_id) !== FALSE) {
// Is this an entity that does not belong to this site? Has it been
// previously imported from Content Hub?
$uuid = $entity
->uuid();
// We cannot bulk upload this entity because it does not belong to this
// site. Add it to the pool of failed entities.
if (isset($uuid)) {
$this
->entityFailures(1);
// We can use this pool of failed entities to display a message to the
// user about the entities that failed to export.
// $args = [
// '@type' => $entity_type_id,
// '@uuid' => $uuid,
// ];
// $message = new FormattableMarkup('Cannot export @type entity with
// UUID = @uuid to Content Hub because it was previously imported
// (did not originate from this site).', $args);
// $this->loggerFactory->get('acquia_contenthub')->error($message);
}
return FALSE;
}
$status = $entity
->getEntityType()
->hasKey("status") ? $entity
->getEntityType()
->getKey("status") : NULL;
$revision_col = $entity
->getEntityType()
->hasKey("revision") ? $entity
->getEntityType()
->getKey("revision") : NULL;
if ($status && $revision_col && $entity instanceof RevisionableInterface) {
$definition = $entity
->getFieldDefinition($status);
$property = $definition
->getFieldStorageDefinition()
->getMainPropertyName();
$value = $entity
->get($status)->{$property};
if (!$value) {
$table = $entity
->getEntityType()
->getBaseTable();
$id_col = $entity
->getEntityType()
->getKey("id");
$query = \Drupal::database()
->select($table)
->fields($table, [
$revision_col,
]);
$query
->condition("{$table}.{$id_col}", $entity
->id());
$revision_id = $query
->execute()
->fetchField();
if ($revision_id != $entity
->getRevisionId()) {
return FALSE;
}
}
}
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
$module_handler = \Drupal::getContainer()
->get("module_handler");
$results = $module_handler
->invokeAll('acquia_contenthub_is_eligible_entity', [
$entity,
]);
foreach ($results as $result) {
if ($result === FALSE) {
return FALSE;
}
}
return TRUE;
}
/**
* Checks whether the current dependency should be transferred to Content Hub.
*
* Dependencies have an additional check as to whether they should be trans-
* ferred to Content Hub. If they have been previously exported then they do
* not need to be exported again. Dependent entities are those which are
* referenced from an entity that has been fired through entity hooks.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity object.
*
* @return bool
* TRUE if it is eligible for export to Content Hub, FALSE otherwise.
*/
public function isEligibleDependency(EntityInterface $entity) {
if ($this
->isEligibleEntity($entity)) {
if ($entity_tracking = $this->contentHubEntitiesTracking
->loadExportedByUuid($entity
->uuid())) {
if ($entity_tracking
->isExported()) {
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
/**
* Returns the list of enabled entity types for Content Hub.
*
* @return string[]
* A list of enabled entity type IDs.
*/
public function getContentHubEnabledEntityTypeIds() {
/** @var \Drupal\acquia_contenthub\Entity\ContentHubEntityTypeConfig[] $entity_type_ids */
$entity_type_ids = $this
->getContentHubEntityTypeConfigurationEntities();
$enabled_entity_type_ids = [];
foreach ($entity_type_ids as $entity_type_id => $entity_type_config) {
$bundles = $entity_type_config
->getBundles();
// For a type to be enabled, it must at least have one bundle enabled.
if (!empty(array_filter(array_column($bundles, 'enable_index')))) {
$enabled_entity_type_ids[] = $entity_type_id;
}
}
return $enabled_entity_type_ids;
}
/**
* Returns the Content Hub configuration entity for this entity type.
*
* @param string $entity_type_id
* The Entity type ID.
*
* @return bool|\Drupal\acquia_contenthub\ContentHubEntityTypeConfigInterface
* The Configuration entity if exists, FALSE otherwise.
*/
public function getContentHubEntityTypeConfigurationEntity($entity_type_id) {
/** @var \Drupal\rest\RestResourceConfigInterface $contenthub_entity_config_storage */
$contenthub_entity_config_storage = $this->entityTypeManager
->getStorage('acquia_contenthub_entity_config');
/** @var \Drupal\acquia_contenthub\ContentHubEntityTypeConfigInterface[] $contenthub_entity_config_ids */
$contenthub_entity_config_ids = $contenthub_entity_config_storage
->loadMultiple([
$entity_type_id,
]);
$contenthub_entity_config_id = isset($contenthub_entity_config_ids[$entity_type_id]) ? $contenthub_entity_config_ids[$entity_type_id] : FALSE;
return $contenthub_entity_config_id;
}
/**
* Returns the list of configured Content Hub configuration entities.
*
* @return \Drupal\acquia_contenthub\ContentHubEntityTypeConfigInterface[]
* An array of Content Hub Configuration entities
*/
public function getContentHubEntityTypeConfigurationEntities() {
/** @var \Drupal\Core\Entity\EntityStorageInterface $contenthub_entity_config_storage */
$contenthub_entity_config_storage = $this->entityTypeManager
->getStorage('acquia_contenthub_entity_config');
/** @var \Drupal\acquia_contenthub\ContentHubEntityTypeConfigInterface[] $contenthub_entity_config_ids */
$contenthub_entity_config_ids = $contenthub_entity_config_storage
->loadMultiple();
return $contenthub_entity_config_ids;
}
/**
* Obtains the list of entity types.
*/
public function getAllowedEntityTypes() {
// List of entities that are excluded from displaying on
// entity configuration page and will not be pushed to Content Hub.
$excluded_types = $this
->getExcludedContentEntityTypeIds();
$types = $this->entityTypeManager
->getDefinitions();
$entity_types = [];
foreach ($types as $type => $entity) {
// We only support content entity types at the moment, since config
// entities don't implement \Drupal\Core\TypedData\ComplexDataInterface.
if ($entity instanceof ContentEntityTypeInterface) {
// Skip excluded types.
if (in_array($type, $excluded_types)) {
continue;
}
$bundles = $this->entityTypeBundleInfoManager
->getBundleInfo($type);
// Here we need to load all the different bundles?
if (isset($bundles) && count($bundles) > 0) {
foreach ($bundles as $key => $bundle) {
$entity_types[$type][$key] = $bundle['label'];
}
}
}
}
$entity_types = array_diff_key($entity_types, $excluded_types);
return $entity_types;
}
/**
* List of Content Entity Type Ids that are excluded from Content Hub.
*
* @return array
* List of content entity type IDs.
*/
private function getExcludedContentEntityTypeIds() {
return [
'comment',
'contact_message',
'crop',
'menu_link_content',
'scheduled_update',
'search_api_task',
'shortcut',
'user',
];
}
/**
* Checks whether the current entity is supported by Content Hub.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity.
*
* @return bool
* TRUE if it is a supported entity, FALSE otherwise.
*/
public function isSupportedContentHubEntity(EntityInterface $entity) {
// If the entity is not a Content Entity then it is not supported.
if (!$entity instanceof ContentEntityInterface) {
return FALSE;
}
// From all content entities, some of them are excluded.
$excluded_types = $this
->getExcludedContentEntityTypeIds();
if (in_array($entity
->getEntityTypeId(), $excluded_types)) {
return FALSE;
}
return TRUE;
}
/**
* Obtains a list of referenced eligible Content Hub Entities.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* An entity to check for references.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* An array of all the referenced entities
*/
private function getReferencedEntities(EntityInterface $entity) {
$referenced_entities = $entity
->referencedEntities();
foreach ($referenced_entities as $key => $referenced_entity) {
if (!$this
->isSupportedContentHubEntity($referenced_entity)) {
unset($referenced_entities[$key]);
}
}
return $referenced_entities;
}
/**
* Returns the entity's root ancestor.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The current (child) entity.
*
* @return \Drupal\Core\Entity\EntityInterface
* The root ancestor entity.
*/
private function findRootAncestorEntity(EntityInterface $entity) {
if (!$entity || !method_exists($entity, 'getParentEntity')) {
return $entity;
}
return $this
->findRootAncestorEntity($entity
->getParentEntity());
}
/**
* Detect the publishing status of a particular entity.
*
* If the entity is translatable and has at least one published translation
* then the resulting publishing status will be TRUE.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The Content Entity.
*
* @return bool
* TRUE if at least one published translation, FALSE otherwise.
*/
public function isPublished(ContentEntityInterface $entity) {
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
$module_handler = \Drupal::getContainer()
->get("module_handler");
if ($module_handler
->moduleExists('content_translation')) {
/** @var \Drupal\content_translation\ContentTranslationManagerInterface $translation_manager */
$translation_manager = \Drupal::getContainer()
->get("content_translation.manager");
// If we are using content_translation module and this is a 'translatable'
// entity, then check if at least one translation is published.
if ($translation_manager
->isEnabled($entity
->getEntityTypeId(), $entity
->bundle())) {
// Check whether this entity has at least one published translation.
$languages = $entity
->getTranslationLanguages();
foreach ($languages as $language) {
$langcode = $language
->getId();
$localized_entity = $entity
->getTranslation($langcode);
/** @var \Drupal\content_translation\ContentTranslationMetadataWrapperInterface $translation_metadata */
$translation_metadata = $translation_manager
->getTranslationMetadata($localized_entity);
if ($translation_metadata
->isPublished()) {
return TRUE;
}
}
return FALSE;
}
}
return $entity instanceof NodeInterface ? $entity
->isPublished() : TRUE;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
EntityManager:: |
private | property | Base root. | |
EntityManager:: |
private | property | The list of candidate entities for next bulk export. | |
EntityManager:: |
private | property | Content Hub Client Manager. | |
EntityManager:: |
private | property | The Content Hub Entities Tracking Service. | |
EntityManager:: |
private | property | The entity manager. | |
EntityManager:: |
private | property | The entity manager. | |
EntityManager:: |
private | property | Logger. | |
EntityManager:: |
private | property | The "shutdown function is registered" flag. | |
EntityManager:: |
public | function | Bulk-export all the enqueued entities. | |
EntityManager:: |
public static | function | ||
EntityManager:: |
private | function | Delete an entity from Content Hub. | |
EntityManager:: |
public | function | Enqueue an entity with an operation to be performed on Content Hub. | |
EntityManager:: |
private | function | Enqueue a paragraph with an operation to be performed on Content Hub. | |
EntityManager:: |
private | function | Enqueue array of entities with an operation to be performed on Content Hub. | |
EntityManager:: |
private | function | Tracks the number of entities that fail to bulk upload. | |
EntityManager:: |
constant | |||
EntityManager:: |
private | function | Returns the entity's root ancestor. | |
EntityManager:: |
public | function | Obtains the list of entity types. | |
EntityManager:: |
public | function | Builds the bulk-upload url to make a single request. | |
EntityManager:: |
public | function | Returns the list of enabled entity types for Content Hub. | |
EntityManager:: |
public | function | Returns the list of configured Content Hub configuration entities. | |
EntityManager:: |
public | function | Returns the Content Hub configuration entity for this entity type. | |
EntityManager:: |
private | function | List of Content Entity Type Ids that are excluded from Content Hub. | |
EntityManager:: |
public | function | Get candidate entities. | |
EntityManager:: |
private | function | Obtains a list of referenced eligible Content Hub Entities. | |
EntityManager:: |
private | function | Returns the local Resource URL. | |
EntityManager:: |
private | function | Returns the route's resource URL. | |
EntityManager:: |
public | function | Checks whether the current dependency should be transferred to Content Hub. | |
EntityManager:: |
public | function | Checks whether the current entity should be transferred to Content Hub. | |
EntityManager:: |
public | function | Detect the publishing status of a particular entity. | |
EntityManager:: |
public | function | Checks whether the current entity is supported by Content Hub. | |
EntityManager:: |
public | function | PUT entities for update to Content Hub, without site callback. | |
EntityManager:: |
private | function | Register shutdown function. | |
EntityManager:: |
constant | |||
EntityManager:: |
private | function | Delete entities from Content Hub that are explicitly un-exported. | |
EntityManager:: |
private | function | Delete entities from Content Hub that are disqualified of exporting. | |
EntityManager:: |
public | function | Sends the entities for update to Content Hub. | |
EntityManager:: |
public | function | Constructs an EntityManager object. |