Content Hub

Content Hub events

Important

Content Hub 2.x will reach end-of-life on December 31, 2024. Acquia recommends that you update your Content Hub version to Content Hub 3.x by using the composer require instructions available on the acquia_contenthub project page.

Content Hub has an event-driven architecture. To interact with it, you must write event subscribers, which subscribe to the appropriate event. This document provides an overview of Content Hub events and their example implementation. The Content Hub events are present in the \Drupal\acquia_contenthub\AcquiaContentHubEvents class and are listed as follows:

Getting settings

The external PHP library for Content Hub provides the settings object within Content Hub. It is a class containing the credentials for connecting to the Content Hub service, and you can instantiate it in multiple ways. While primarily used for Acquia’s purposes, it provides an example for understanding how the class works.

The Drupal\acquia_contenthub\Client\ClientFactory::populateSettings method dispatches an event to retrieve the Settings object. Subscribers can choose to resolve this request in their own way. The core Content Hub module provides code that stores and retrieves the settings from the normal Drupal configuration if no other Settings object is present before the method is called. This enables the configuration form to work, while locking the form when another event subscriber provides a Settings object.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::GET_SETTINGS
Dispatched eventDrupal\acquia_contenthub\Event\AcquiaContentHubSettingsEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\GetSettings\GetSettingsFromCoreConfig

Drupal\acquia_contenthub\EventSubscriber\GetSettings\GetSettingsFromCoreSettings

Creating a CDF object

Common Data Format (CDF) objects are designed to be a robust format that supports useful data faceting, and a form of serialization to assist efficiently syndicating data between publishing and subscribing websites. Content Hub handles all Drupal entities by default, but the default handling may lack features you need.

Content Hub provides default handlers for the Content, Configuration, and File entities. These are separate event subscribers, but File entities are acted upon by both the File and Content handlers. The Content handler performs most of the necessary work, and the File handler adds specific attributes to the CDF object for file handling, retrieval, and saving.

Any CDF handler will:

  • Create a CDF object (CDFObject)
  • Add appropriate attributes to that object using the Acquia\ContentHubClient\CDFObject::addAttribute method
  • Interact with the attributes and metadata as necessary to support their data

If you are creating a new data type, ensure that you type that data with your own custom string. For content entities in the current Drupal version, Content Hub uses the string drupal8_content_entity. You can do similar with your type. Ensure that the namespace doesn’t conflict with anything else. For details on creating your own CDF object, refer to the CDFObject class.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::CREATE_CDF_OBJECT
Dispatched eventDrupal\acquia_contenthub\Event\CreateCDFEntityEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\CDF\ContentEntityHandler

Drupal\acquia_contenthub\EventSubscriber\CDF\FileEntityHandler

Drupal\acquia_contenthub\EventSubscriber\CDF\ConfigEntityHandler

Related classes:

  • Acquia\ContentHubClient\CDFObject
  • Acquia\ContentHubClient\CDFAttribute

Creating global CDF attributes

When creating your own CDF object and type, you can add custom CDF attributes. For example, you may need to affect CDF attribute generation across multiple CDF data types. You can use the Content Hub module to add custom CDF attributes, elevating attributes such as entity type, bundle, label, hash value, and other attributes used to expose data to user interfaces or search criteria.

Any attribute added to a CDF object is indexed by the Content Hub service, so data placed at this layer can be queried against. In addition, while the event is intended to allow for customization of attributes, events can also alter the CDF object’s metadata. Metadata is not indexed.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::POPULATE_CDF_ATTRIBUTES
Dispatched eventDrupal\acquia_contenthub\Event\CDFAttributesEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\CDFAttributes\EntityTagsCDFAttribute

Drupal\acquia_contenthub\EventSubscriber\CDFAttributes\HashCDFAttribute

Parsing a CDF Object

As discussed in Creating a CDF object, CDF supports custom data types. Content Hub provides support for the Configuration, Content and File entities as part of its Drupal integration. Developer can also establish their own serialization types both inside and outside of Drupal.

For example, you can write code in an eCommerce system that sends your system’s products to Content Hub, and writes a corresponding CDF parser in your Drupal website to interpret and import the Magento data. With a custom CDF parser, you can target specific kinds of CDF objects to act upon, then decode the data in the CDF and import it.

The Content Hub module enables you to link subscription of this event to the CREATE_CDF_OBJECT event. While not strictly necessary, it is helpful when the originator and consumer of the data are both Drupal. When importing non-Drupal data, subscribing to this event enables you to access the data and define how to import it.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::POPULATE_CDF_ATTRIBUTES
Dispatched eventDrupal\acquia_contenthub\Event\ParseCDFEntityEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\CDF\ContentEntityHandler

Drupal\acquia_contenthub\EventSubscriber\CDF\FileEntityHandler

Drupal\acquia_contenthub\EventSubscriber\CDF\ConfigEntityHandler

Handling field data

Field data requires special handling and has its own set of events, which you can dispatch to serialize and unserialize the field data. In addition to the normal serialization and unserialization processes, these events can suppress field data from export. For example, Content Hub excludes the native serial IDs associated to content entities for id` and ``revision_id before publishing to the hub so the content can be assigned new serial IDs on the subscriber website.

When working with field data exports, you should:

  • Consider all possible languages.
  • Track entity references in all forms. If a field implicitly or explicitly references another entity, ensure the dependency tracking is aware, and use the entity’s UUID for export.
  • Ensure that data can be turned back into field-level data during import.

These events are useful when working with fields Content Hub does not support, such as:

  • Field types you have created
  • Field types created from a contributed module that does not yet have Content Hub support

Content Hub’s General and Fallback handlers handle most fields. Only special fields with unusual formats or entity reference implications should need special handling.

Exclude Content field from serialization

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::EXCLUDE_CONTENT_ENTITY_FIELD
Dispatched eventDrupal\acquia_contenthub\Event\ExcludeEntityFieldEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\ExcludeContentField\RemovePathAliasField

Drupal\acquia_contenthub\EventSubscriber\ExcludeContentField\RemoveRevisionField

Serializing data

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::SERIALIZE_CONTENT_ENTITY_FIELD
Dispatched eventDrupal\acquia_contenthub\Event\SerializeCDFEntityField
Example implementation

Drupal\acquia_contenthub\EventSubscriber\SerializeContentField\EntityReferenceFieldSerializer

Drupal\acquia_contenthub\EventSubscriber\SerializeContentField\TextItemFieldSerializer

For more examples of field serialization, see the files in acquia_contenthub/src/EventSubscriber/SerializeContentField.

Unserializing data

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::UNSERIALIZE_CDF_ATTRIBUTE
Dispatched eventDrupal\acquia_contenthub\Event\UnserializeCDFAttributeEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\UnserializeCDFAttribute\EntityReferenceField

Drupal\acquia_contenthub\EventSubscriber\UnserializeCDFAttribute\EntityLanguage

Drupal\acquia_contenthub\EventSubscriber\UnserializeCDFAttribute\TextItemField

For more examples of field unserialization, see the files in acquia_contenthub/src/EventSubscriber/UnserializeCDFAttribute.

Tampering with data

Many import or migration processes, including Content Hub, offer methods of data tampering. The data to be imported is made available for various types of manipulation, such as:

  • Remapping data from one entity bundle into another, while updating or removing data needed to support that action
  • Removing data from import, if it is unchanged since the previous import

For example, the Content Hub Subscriber module implements the second scenario by comparing the entity’s current and previous hash values. If the hash is unchanged, Content Hub loads the local version of the entity and adds it to the DependencyStack object, preventing the CDF representation from being processed for import.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::ENTITY_DATA_TAMPER
Dispatched eventDrupal\acquia_contenthub\Event\EntityDataTamperEvent
Example implementation

Drupal\acquia_contenthub\EventSubscriber\EntityDataTamper\DefaultLanguage

Drupal\acquia_contenthub\EventSubscriber\EntityDataTamper\AnonymousUser

Importing or updating entities

All transformations needed for proper entity functioning should be performed when saving the entity, but this best practice is not always feasible. To enable you to import entities of all types, Content Hub dispatches events corresponding to initial saves and updates. These events enable you to implement logic from other areas, such as form submit methods.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::ENTITY_IMPORT_NEW Drupal\acquia_contenthub\AcquiaContentHubEvents::ENTITY_IMPORT_UPDATE
Dispatched eventDrupal\acquia_contenthub\Event\EntityImportEvent
Example implementationDrupal\acquia_contenthub\EventSubscriber\EntityImport\ContentLanguageSettings

Pruning data

Content Hub requests all required content from the Content Hub service before performing an import operation. In this operation, data not relevant to the importing website may be discarded.

For example, rendered_entity data is used by Personalization, but is not used by subscribing websites. The Content Hub modules do not subscribe to this event. This event is optional, but can help speed the processing of queued entities that may never need to be imported.

The prune event happens before other processing of the CDF, including the enabling of modules. It can discard data where the supporting modules are not present.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::PRUNE_CDF
Dispatched eventDrupal\acquia_contenthub\Event\PruneCDFEntitiesEvent

Handling webhooks

Webhooks dispatch to publishers and subscribers as part of the interaction patterns with the Content Hub service. The Content Hub service sends webhooks that inform sites about new or updated content to import, and all incoming webhooks arrive at the same route within Drupal.

Webhook handling dispatches an event to allow the incoming data to be inspected and acted upon. Modules can add their own custom handling to Content Hub’s baseline handling of these incoming webhooks.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::HANDLE_WEBHOOK
Dispatched eventDrupal\acquia_contenthub\Event\HandleWebhookEvent
Example implementationDrupal\acquia_contenthub\EventSubscriber\HandleWebhook\RegisterWebhook

Handling import failures

The vast majority of failures within Content Hub happen during the import process. Content Hub dispatches an event when it detects a failure.

When Content Hub cannot proceed with an import process, it dispatches an event containing the following:

  • The CDF document being processed
  • The current state of the DependencyStack
  • A count of items processed.

These items provide insight into the failure, and may assist with error handling to help you finish a failed import.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::IMPORT_FAILURE
Dispatched eventDrupal\acquia_contenthub\Event\FailedImportEvent

Executing tasks after a queue item is processed

After a queue item is processed, a new event is fired. This event runs certain tasks that require the imported entities to be in the database and record them in the tracking tables. The event receives the queue name, the original queue item, which might contain multiple entity UUIDs, and the result of the process function.

DescriptionPath
To use this event, subscribe toDrupal\acquia_contenthub\AcquiaContentHubEvents::QUEUE_ITEM_PROCESS_FINISHED
Dispatched eventDrupal\acquia_contenthub\Event\Queue\QueueItemProcessFinishedEvent
Example implementationDrupal\acquia_contenthub\EventSubscriber\ParseCdf\File::onQueueFinished

Swapping the entity ID and the entity UUID during import and export

During the View export process, the entity ID referenced in the View filter plugin is local to the site. Therefore, you must replace the entity ID with the entity UUID.

Use the following tabulated events to:

  • Replace the entity ID with the entity UUID during export.
  • Replace the entity UUID with the entity ID during import.
DescriptionPath
To replace the entity ID with the entity UUIDDrupal\acquia_contenthub_publisher::REPLACE_ENTITY_ID_WITH_UUID
Dispatched eventDrupal\acquia_contenthub_publisher\Event\ViewFilterPluginReplaceEntityIdWithUuidEvent
Example implementationDrupal\acquia_contenthub_publisher\EventSubscriber\ReplaceEntityIdWithUuid\ViewFilterPluginReplaceEntityIdWithUuidBase
To replace the entity UUID with the entity IDDrupal\acquia_contenthub_subscriber::REPLACE_ENTITY_UUID_WITH_ID
Dispatched eventDrupal\acquia_contenthub_subscriber\Event\ViewFilterPluginReplaceEntityUuidWithIdEvent
Example implementationDrupal\acquia_contenthub_subscriber\EventSubscriber\ReplaceEntityUuidWithId\ViewFilterPluginReplaceEntityUuidWithIdBase