class JsonapiHelper in Entity Share 8
Same name and namespace in other branches
- 8.3 modules/entity_share_client/src/Service/JsonapiHelper.php \Drupal\entity_share_client\Service\JsonapiHelper
- 8.2 modules/entity_share_client/src/Service/JsonapiHelper.php \Drupal\entity_share_client\Service\JsonapiHelper
Class JsonapiHelper.
@package Drupal\entity_share_client\Service
Hierarchy
- class \Drupal\entity_share_client\Service\JsonapiHelper implements JsonapiHelperInterface uses StringTranslationTrait
Expanded class hierarchy of JsonapiHelper
1 string reference to 'JsonapiHelper'
- entity_share_client.services.yml in modules/
entity_share_client/ entity_share_client.services.yml - modules/entity_share_client/entity_share_client.services.yml
1 service uses JsonapiHelper
- entity_share_client.jsonapi_helper in modules/
entity_share_client/ entity_share_client.services.yml - Drupal\entity_share_client\Service\JsonapiHelper
File
- modules/
entity_share_client/ src/ Service/ JsonapiHelper.php, line 31
Namespace
Drupal\entity_share_client\ServiceView source
class JsonapiHelper implements JsonapiHelperInterface {
use StringTranslationTrait;
/**
* The JsonApiDocumentTopLevelNormalizer normalizer.
*
* @var \Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer
*/
protected $jsonapiDocumentTopLevelNormalizer;
/**
* The resource type repository.
*
* @var \Drupal\jsonapi\ResourceType\ResourceTypeRepository
*/
protected $resourceTypeRepository;
/**
* The bundle infos from the website.
*
* @var array
*/
protected $bundleInfos;
/**
* The entity type definitions.
*
* @var \Drupal\Core\Entity\EntityTypeInterface[]
*/
protected $entityDefinitions;
/**
* The entity definition update manager.
*
* @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
*/
protected $entityDefinitionUpdateManager;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The stream wrapper manager.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManager;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The remote manager.
*
* @var \Drupal\entity_share_client\Service\RemoteManagerInterface
*/
protected $remoteManager;
/**
* The event dispatcher service.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* A prepared HTTP client for file transfer.
*
* @var \GuzzleHttp\Client
*/
protected $fileHttpClient;
/**
* A prepared HTTP client.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;
/**
* The remote website on which to prepare the clients.
*
* @var \Drupal\entity_share_client\Entity\RemoteInterface
*/
protected $remote;
/**
* The list of the currently imported entities.
*
* @var array
*/
protected $importedEntities;
/**
* JsonapiHelper constructor.
*
* @param \Symfony\Component\Serializer\SerializerInterface $serializer
* A serializer.
* @param \Drupal\jsonapi\Normalizer\JsonApiDocumentTopLevelNormalizer $jsonapi_document_top_level_normalizer
* The JsonApiDocumentTopLevelNormalizer normalizer.
* @param \Drupal\jsonapi\ResourceType\ResourceTypeRepository $resource_type_repository
* The resource type repository.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle info service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $entity_definition_update_manager
* The entity definition update manager.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
* The stream wrapper manager.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Drupal\entity_share_client\Service\RemoteManagerInterface $remote_manager
* The remote manager service.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher service.
*/
public function __construct(SerializerInterface $serializer, JsonApiDocumentTopLevelNormalizer $jsonapi_document_top_level_normalizer, ResourceTypeRepository $resource_type_repository, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityTypeManagerInterface $entity_type_manager, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, StreamWrapperManagerInterface $stream_wrapper_manager, LanguageManagerInterface $language_manager, RemoteManagerInterface $remote_manager, EventDispatcherInterface $event_dispatcher) {
$this->jsonapiDocumentTopLevelNormalizer = $jsonapi_document_top_level_normalizer;
$this->jsonapiDocumentTopLevelNormalizer
->setSerializer($serializer);
$this->resourceTypeRepository = $resource_type_repository;
$this->bundleInfos = $entity_type_bundle_info
->getAllBundleInfo();
$this->entityDefinitions = $entity_type_manager
->getDefinitions();
$this->entityDefinitionUpdateManager = $entity_definition_update_manager;
$this->entityTypeManager = $entity_type_manager;
$this->streamWrapperManager = $stream_wrapper_manager;
$this->languageManager = $language_manager;
$this->remoteManager = $remote_manager;
$this->eventDispatcher = $event_dispatcher;
// TODO: Maybe use an API if the array is too big. State API, Tempstore or
// Cache API.
$this->importedEntities = [];
}
/**
* {@inheritdoc}
*/
public function buildEntitiesOptions(array $json_data) {
$options = [];
foreach ($this
->prepareData($json_data) as $data) {
$this
->addOptionFromJson($options, $data);
}
return $options;
}
/**
* {@inheritdoc}
*/
public function extractEntity(array $data) {
// Format JSON as in
// JsonApiDocumentTopLevelNormalizerTest::testDenormalize().
$prepared_json = [
'data' => [
'type' => $data['type'],
'attributes' => $data['attributes'],
],
];
$parsed_type = explode('--', $data['type']);
return $this->jsonapiDocumentTopLevelNormalizer
->denormalize($prepared_json, NULL, 'api_json', [
'resource_type' => $this->resourceTypeRepository
->get($parsed_type[0], $parsed_type[1]),
]);
}
/**
* {@inheritdoc}
*/
public function updateRelationships(ContentEntityInterface $entity, array $data) {
if (isset($data['relationships'])) {
$resource_type = $this->resourceTypeRepository
->get($entity
->getEntityTypeId(), $entity
->bundle());
// Reference fields.
foreach ($data['relationships'] as $field_name => $field_data) {
$field_name = $resource_type
->getInternalName($field_name);
$field = $entity
->get($field_name);
if ($this
->relationshipHandleable($field)) {
$field_values = [];
// Check that the field has data.
if ($field_data['data'] != NULL && isset($field_data['links']) && isset($field_data['links']['related'])) {
$referenced_entities_response = $this
->getHttpClient()
->get($field_data['links']['related'])
->getBody()
->getContents();
$referenced_entities_json = Json::decode($referenced_entities_response);
if (!isset($referenced_entities_json['errors'])) {
$referenced_entities_ids = $this
->importEntityListData($referenced_entities_json['data']);
$main_property = $field
->getItemDefinition()
->getMainPropertyName();
// Add field metadatas.
foreach ($this
->prepareData($field_data['data']) as $key => $field_value_data) {
// When dealing with taxonomy term entities which has a
// hierarchy, there is a virtual entity for the root. So
// $referenced_entities_ids[$key] may not exist.
// See https://www.drupal.org/node/2976856.
if (isset($referenced_entities_ids[$key])) {
$field_value = [
$main_property => $referenced_entities_ids[$key],
];
if (isset($field_value_data['meta'])) {
$field_value += $field_value_data['meta'];
}
// Allow to alter the field value with an event.
$event = new RelationshipFieldValueEvent($field, $field_value);
$this->eventDispatcher
->dispatch(RelationshipFieldValueEvent::EVENT_NAME, $event);
$field_values[] = $event
->getFieldValue();
}
}
}
}
$entity
->set($field_name, $field_values);
}
}
// Save the entity once all the references have been updated.
$entity
->save();
}
}
/**
* {@inheritdoc}
*/
public function handlePhysicalFiles(ContentEntityInterface $entity, array &$data) {
if ($entity instanceof FileInterface) {
$remote_uri = $data['attributes']['uri']['value'];
$remote_url = $data['attributes']['uri']['url'];
$stream_wrapper = $this->streamWrapperManager
->getViaUri($remote_uri);
$directory_uri = $stream_wrapper
->dirname($remote_uri);
// Create the destination folder.
if (file_prepare_directory($directory_uri, FILE_CREATE_DIRECTORY)) {
// TODO: Check the case of large files.
// TODO: Transfer file only if necessary.
try {
$file_content = $this
->getFileHttpClient()
->get($remote_url)
->getBody()
->getContents();
file_put_contents($remote_uri, $file_content);
} catch (ClientException $e) {
drupal_set_message($this
->t('Missing file: %url', [
'%url' => $remote_url,
]), 'warning');
}
}
else {
drupal_set_message($this
->t('Impossible to write in the directory %directory', [
'%directory' => $directory_uri,
]), 'error');
}
}
}
/**
* {@inheritdoc}
*/
public function setRemote(RemoteInterface $remote) {
$this->remote = $remote;
}
/**
* {@inheritdoc}
*/
public function importEntityListData(array $entity_list_data) {
$imported_entity_ids = [];
foreach ($this
->prepareData($entity_list_data) as $entity_data) {
$parsed_type = explode('--', $entity_data['type']);
$entity_type = $this->entityDefinitionUpdateManager
->getEntityType($parsed_type[0]);
$entity_keys = $entity_type
->getKeys();
$this
->prepareEntityData($entity_data, $entity_keys);
$data_langcode = $entity_data['attributes'][$entity_keys['langcode']];
// Prepare entity label.
if (isset($entity_keys['label'])) {
$entity_label = $entity_data['attributes'][$entity_keys['label']];
}
else {
// Use the entity type if there is no label.
$entity_label = $parsed_type[0];
}
if (!$this
->dataLanguageExists($data_langcode, $entity_label)) {
continue;
}
// Check if an entity already exists.
$existing_entities = $this->entityTypeManager
->getStorage($parsed_type[0])
->loadByProperties([
'uuid' => $entity_data['attributes'][$entity_keys['uuid']],
]);
// Here is the supposition that we are importing a list of content
// entities. Currently this is ensured by the fact that it is not possible
// to make a channel on config entities and on users. And that in the
// relationshipHandleable() method we prevent handling config entities and
// users relationships.
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $this
->extractEntity($entity_data);
// New entity.
if (empty($existing_entities)) {
$entity
->save();
$imported_entity_ids[] = $entity
->id();
// Prevent the entity of being reimported.
$this->importedEntities[] = $entity
->uuid();
$this
->updateRelationships($entity, $entity_data);
$this
->handlePhysicalFiles($entity, $entity_data);
// Change the entity "changed" time because it could have been altered
// with relationship save by example.
if (method_exists($entity, 'setChangedTime')) {
$entity
->setChangedTime($entity_data['attributes']['changed']);
}
$entity
->save();
}
else {
/** @var \Drupal\Core\Entity\ContentEntityInterface $existing_entity */
$existing_entity = array_shift($existing_entities);
$imported_entity_ids[] = $existing_entity
->id();
if (!in_array($existing_entity
->uuid(), $this->importedEntities)) {
// Prevent the entity of being reimported.
$this->importedEntities[] = $existing_entity
->uuid();
$has_translation = $existing_entity
->hasTranslation($data_langcode);
// Update the existing translation.
if ($has_translation) {
$resource_type = $this->resourceTypeRepository
->get($entity
->getEntityTypeId(), $entity
->bundle());
$existing_translation = $existing_entity
->getTranslation($data_langcode);
foreach ($entity_data['attributes'] as $field_name => $value) {
$field_name = $resource_type
->getInternalName($field_name);
$existing_translation
->set($field_name, $entity
->get($field_name)
->getValue());
}
$existing_translation
->save();
}
else {
$translation = $entity
->toArray();
$existing_entity
->addTranslation($data_langcode, $translation);
$existing_entity
->save();
$existing_translation = $existing_entity
->getTranslation($data_langcode);
}
$this
->updateRelationships($existing_translation, $entity_data);
$this
->handlePhysicalFiles($existing_translation, $entity_data);
// Change the entity "changed" time because it could have been altered
// with relationship save by example.
if (method_exists($existing_translation, 'setChangedTime')) {
$existing_translation
->setChangedTime($entity_data['attributes']['changed']);
}
$existing_translation
->save();
}
}
}
return $imported_entity_ids;
}
/**
* Helper function to add an option.
*
* @param array $options
* The array of options for the tableselect form type element.
* @param array $data
* An array of data.
* @param int $level
* The level of indentation.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \InvalidArgumentException
*/
protected function addOptionFromJson(array &$options, array $data, $level = 0) {
// Format JSON as in
// JsonApiDocumentTopLevelNormalizerTest::testDenormalize().
$prepared_json = [
'data' => [
'type' => $data['type'],
'attributes' => $data['attributes'],
],
];
$parsed_type = explode('--', $data['type']);
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $this->jsonapiDocumentTopLevelNormalizer
->denormalize($prepared_json, NULL, 'api_json', [
'resource_type' => $this->resourceTypeRepository
->get($parsed_type[0], $parsed_type[1]),
]);
$this
->addOption($options, $entity, $parsed_type[0], $parsed_type[1], $level);
}
/**
* Helper function to add an option.
*
* @param array $options
* The array of options for the tableselect form type element.
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* An unserialized entity.
* @param string $entity_type_id
* The entity type ID of the entity.
* @param string $bundle_id
* The bundle id of the entity.
* @param int $level
* The level of indentation.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \InvalidArgumentException
*/
protected function addOption(array &$options, ContentEntityInterface $entity, $entity_type_id, $bundle_id, $level = 0) {
$indentation = '';
for ($i = 1; $i <= $level; $i++) {
$indentation .= '<div class="indentation"> </div>';
}
$label = new FormattableMarkup($indentation . '@label', [
'@label' => $entity
->label(),
]);
$status_info = $this
->getStatusInfo($entity, $entity_type_id);
$options[$entity
->uuid()] = [
'label' => $label,
'type' => $entity
->getEntityType()
->getLabel(),
'bundle' => $this->bundleInfos[$entity_type_id][$bundle_id]['label'],
'language' => $this
->getEntityLanguageLabel($entity),
'status' => $status_info['label'],
'#attributes' => [
'class' => [
$status_info['class'],
],
],
];
}
/**
* {@inheritdoc}
*/
public function prepareData(array $data) {
if ($this
->isNumericArray($data)) {
return $data;
}
else {
return [
$data,
];
}
}
/**
* Check if a array is numeric.
*
* @param array $array
* The array to check.
*
* @return bool
* TRUE if the array is numeric. FALSE in case of associative array.
*/
protected function isNumericArray(array $array) {
foreach ($array as $a => $b) {
if (!is_int($a)) {
return FALSE;
}
}
return TRUE;
}
/**
* Check if a relationship is handleable.
*
* Filter on fields not targeting config entities or users.
*
* @param \Drupal\Core\Field\FieldItemListInterface $field
* The field item list.
*
* @return bool
* TRUE if the relationship is handleable.
*/
protected function relationshipHandleable(FieldItemListInterface $field) {
$relationship_handleable = FALSE;
if ($field instanceof EntityReferenceFieldItemListInterface) {
$settings = $field
->getItemDefinition()
->getSettings();
// TODO: Other field types that inherit from entity reference should be
// handled automatically or using a plugin/event system if possible.
// Entity reference and Entity reference revisions.
if (isset($settings['target_type'])) {
$relationship_handleable = !$this
->isUserOrConfigEntity($settings['target_type']);
}
elseif (isset($settings['entity_type_ids'])) {
foreach ($settings['entity_type_ids'] as $entity_type_id) {
$relationship_handleable = !$this
->isUserOrConfigEntity($entity_type_id);
if (!$relationship_handleable) {
break;
}
}
}
}
return $relationship_handleable;
}
/**
* Helper function to get the language from an extracted entity.
*
* We can't use $entity->language() because if the entity is in a language not
* enabled, it is the site default language that is returned.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* An unserialized entity.
*
* @return string
* The language of the entity.
*/
protected function getEntityLanguageLabel(ContentEntityInterface $entity) {
$langcode = $entity
->get('langcode')->value;
$language = $this->languageManager
->getLanguage($langcode);
// Check if the entity is in an enabled language.
if (is_null($language)) {
$language_list = LanguageManager::getStandardLanguageList();
if (isset($language_list[$langcode])) {
$entity_language = $language_list[$langcode][0] . ' ' . $this
->t('(not enabled)', [], [
'context' => 'language',
]);
}
else {
$entity_language = $this
->t('Entity in an unsupported language.');
}
}
else {
$entity_language = $language
->getName();
}
return $entity_language;
}
/**
* Helper function to get the File Http Client.
*
* @return \GuzzleHttp\Client
* A HTTP client to retrieve files.
*/
protected function getFileHttpClient() {
if (!$this->fileHttpClient) {
$this->fileHttpClient = $this->remoteManager
->prepareClient($this->remote);
}
return $this->fileHttpClient;
}
/**
* Helper function to get the Http Client.
*
* @return \GuzzleHttp\Client
* A HTTP client to request JSONAPI endpoints.
*/
protected function getHttpClient() {
if (!$this->httpClient) {
$this->httpClient = $this->remoteManager
->prepareJsonApiClient($this->remote);
}
return $this->httpClient;
}
/**
* Prepare the data array before extracting the entity.
*
* Used to remove some data.
*
* @param array $data
* An array of data.
* @param array $entity_keys
* An array of entity keys.
*/
protected function prepareEntityData(array &$data, array $entity_keys) {
// Removes some ids.
unset($data['attributes'][$entity_keys['id']]);
if (isset($entity_keys['revision']) && !empty($entity_keys['revision'])) {
unset($data['attributes'][$entity_keys['revision']]);
}
// Remove the default_langcode boolean to be able to import content not
// necessarily in the default language.
// TODO: Handle content_translation_source?
unset($data['attributes'][$entity_keys['default_langcode']]);
// To avoid side effects and as currently JSONAPI send null for the path
// we remove the path attribute.
if (isset($data['attributes']['path'])) {
unset($data['attributes']['path']);
}
}
/**
* Check if we try to import an entity in a disabled language.
*
* @param string $langcode
* The langcode of the language to check.
* @param string $entity_label
* The entity label.
*
* @return bool
* FALSE if the data is not in an enabled language.
*/
protected function dataLanguageExists($langcode, $entity_label) {
if (is_null($this->languageManager
->getLanguage($langcode))) {
drupal_set_message($this
->t('Trying to import an entity (%entity_label) in a disabled language.', [
'%entity_label' => $entity_label,
]), 'error');
return FALSE;
}
return TRUE;
}
/**
* Check if an entity already exists or not and compare revision timestamp.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The distant entity to check.
* @param string $entity_type_id
* The entity type id.
*
* @return array
* Returns an array of info:
* - class: to add a class on a row.
* - label: the label to display.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \InvalidArgumentException
*/
protected function getStatusInfo(ContentEntityInterface $entity, $entity_type_id) {
$status_info = [
'label' => $this
->t('Undefined'),
'class' => 'entity-share-undefined',
];
// Check if an entity already exists.
$existing_entities = $this->entityTypeManager
->getStorage($entity_type_id)
->loadByProperties([
'uuid' => $entity
->uuid(),
]);
if (empty($existing_entities)) {
$status_info = [
'label' => $this
->t('New entity'),
'class' => 'entity-share-new',
];
}
elseif (method_exists($entity, 'getChangedTime')) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $existing_entity */
$existing_entity = array_shift($existing_entities);
$entity_language_id = $entity
->language()
->getId();
// Entity has the translation.
if ($existing_entity
->hasTranslation($entity_language_id)) {
$existing_translation = $existing_entity
->getTranslation($entity_language_id);
$entity_changed_time = $entity
->getChangedTime();
$existing_entity_changed_time = $existing_translation
->getChangedTime();
// Existing entity.
if ($entity_changed_time != $existing_entity_changed_time) {
$status_info = [
'label' => $this
->t('Entities not synchronized'),
'class' => 'entity-share-changed',
];
}
else {
$status_info = [
'label' => $this
->t('Entities synchronized'),
'class' => 'entity-share-up-to-date',
];
}
}
else {
$status_info = [
'label' => $this
->t('New translation'),
'class' => 'entity-share-new',
];
}
}
return $status_info;
}
/**
* Helper function to check if an entity type id is a user or a config entity.
*
* @param string $entity_type_id
* The entity type id.
*
* @return bool
* TRUE if the entity type is user or a config entity. FALSE otherwise.
*/
protected function isUserOrConfigEntity($entity_type_id) {
if ($entity_type_id == 'user') {
return TRUE;
}
elseif ($this->entityDefinitions[$entity_type_id]
->getGroup() == 'configuration') {
return TRUE;
}
return FALSE;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
JsonapiHelper:: |
protected | property | The bundle infos from the website. | |
JsonapiHelper:: |
protected | property | The entity type definitions. | |
JsonapiHelper:: |
protected | property | The entity definition update manager. | |
JsonapiHelper:: |
protected | property | The entity type manager. | |
JsonapiHelper:: |
protected | property | The event dispatcher service. | |
JsonapiHelper:: |
protected | property | A prepared HTTP client for file transfer. | |
JsonapiHelper:: |
protected | property | A prepared HTTP client. | |
JsonapiHelper:: |
protected | property | The list of the currently imported entities. | |
JsonapiHelper:: |
protected | property | The JsonApiDocumentTopLevelNormalizer normalizer. | |
JsonapiHelper:: |
protected | property | The language manager. | |
JsonapiHelper:: |
protected | property | The remote website on which to prepare the clients. | |
JsonapiHelper:: |
protected | property | The remote manager. | |
JsonapiHelper:: |
protected | property | The resource type repository. | |
JsonapiHelper:: |
protected | property | The stream wrapper manager. | |
JsonapiHelper:: |
protected | function | Helper function to add an option. | |
JsonapiHelper:: |
protected | function | Helper function to add an option. | |
JsonapiHelper:: |
public | function |
Prepare entities from an URI to request. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
protected | function | Check if we try to import an entity in a disabled language. | |
JsonapiHelper:: |
public | function |
Helper function to unserialize an entity from the JSON API response. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
protected | function | Helper function to get the language from an extracted entity. | |
JsonapiHelper:: |
protected | function | Helper function to get the File Http Client. | |
JsonapiHelper:: |
protected | function | Helper function to get the Http Client. | |
JsonapiHelper:: |
protected | function | Check if an entity already exists or not and compare revision timestamp. | |
JsonapiHelper:: |
public | function |
Create or update the entity reference field values of an entity. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
public | function |
Use data from the JSONAPI to import content. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
protected | function | Check if a array is numeric. | |
JsonapiHelper:: |
protected | function | Helper function to check if an entity type id is a user or a config entity. | |
JsonapiHelper:: |
public | function |
Uniformize JSON data in case of single value. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
protected | function | Prepare the data array before extracting the entity. | |
JsonapiHelper:: |
protected | function | Check if a relationship is handleable. | |
JsonapiHelper:: |
public | function |
Set the remote to get content from. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
public | function |
Create or update the entity reference field values of an entity. Overrides JsonapiHelperInterface:: |
|
JsonapiHelper:: |
public | function | JsonapiHelper constructor. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |