class CiviEntityStorage in CiviCRM Entity 8.3
Defines entity class for external CiviCRM entities.
Hierarchy
- class \Drupal\Core\Entity\EntityHandlerBase uses DependencySerializationTrait, StringTranslationTrait
- class \Drupal\Core\Entity\EntityStorageBase implements EntityHandlerInterface, EntityStorageInterface
- class \Drupal\Core\Entity\ContentEntityStorageBase implements ContentEntityStorageInterface, DynamicallyFieldableEntityStorageInterface uses DeprecatedServicePropertyTrait
- class \Drupal\Core\Entity\Sql\SqlContentEntityStorage implements EntityBundleListenerInterface, DynamicallyFieldableEntityStorageSchemaInterface, SqlEntityStorageInterface
- class \Drupal\civicrm_entity\CiviEntityStorage
- class \Drupal\Core\Entity\Sql\SqlContentEntityStorage implements EntityBundleListenerInterface, DynamicallyFieldableEntityStorageSchemaInterface, SqlEntityStorageInterface
- class \Drupal\Core\Entity\ContentEntityStorageBase implements ContentEntityStorageInterface, DynamicallyFieldableEntityStorageInterface uses DeprecatedServicePropertyTrait
- class \Drupal\Core\Entity\EntityStorageBase implements EntityHandlerInterface, EntityStorageInterface
Expanded class hierarchy of CiviEntityStorage
3 files declare their use of CiviEntityStorage
- civicrm_entity.module in ./
civicrm_entity.module - Module file for the CiviCRM Entity module.
- civicrm_entity.views.inc in ./
civicrm_entity.views.inc - UserCreate.php in src/
Plugin/ RulesAction/ UserCreate.php
File
- src/
CiviEntityStorage.php, line 23
Namespace
Drupal\civicrm_entityView source
class CiviEntityStorage extends SqlContentEntityStorage {
/**
* The CiviCRM API.
*
* @var \Drupal\civicrm_entity\CiviCrmApi
*/
protected $civicrmApi;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Gets the CiviCRM API
*
* @return \Drupal\civicrm_entity\CiviCrmApiInterface
* The CiviCRM APi.
*/
private function getCiviCrmApi() {
if (!$this->civicrmApi) {
$this->civicrmApi = \Drupal::service('civicrm_entity.api');
}
return $this->civicrmApi;
}
/**
* Gets the config factory.
*
* @return \Drupal\Core\Config\ConfigFactoryInterface
* The configuration factory service.
*/
private function getConfigFactory() {
if (!$this->configFactory) {
$this->configFactory = \Drupal::configFactory();
}
return $this->configFactory;
}
/**
* Get the entity field manager.
*
* This is a BC layer for Drupal 8.6 entity.manager and
* Drupal 8.7 entity_field.manager properties.
*
* @return \Drupal\Core\Entity\EntityFieldManagerInterface
* The entity field manager.
*/
private function getEntityFieldManager() {
if (property_exists(static::class, 'entityManager')) {
return $this->entityManager;
}
return $this->entityFieldManager;
}
/**
* Initializes table name variables.
*/
protected function initTableLayout() {
$this->tableMapping = NULL;
$this->revisionKey = NULL;
$this->revisionTable = NULL;
$this->dataTable = NULL;
$this->revisionDataTable = NULL;
}
/**
* {@inheritdoc}
*/
protected function doDelete($entities) {
/** @var \Drupal\Core\Entity\EntityInterface $entity */
foreach ($entities as $entity) {
try {
$params['id'] = $entity
->id();
$this
->getCiviCrmApi()
->delete($this->entityType
->get('civicrm_entity'), $params);
} catch (\Exception $e) {
throw $e;
}
}
$this
->doDeleteFieldItems($entities);
}
/**
* {@inheritdoc}
*/
protected function doDeleteFieldItems($entities) {
$table_mapping = $this
->getTableMapping();
foreach ($entities as $entity) {
foreach ($this
->getEntityFieldManager()
->getFieldDefinitions($entity
->getEntityTypeId(), $entity
->bundle()) as $field_definition) {
$storage_definition = $field_definition
->getFieldStorageDefinition();
if (!$table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
continue;
}
$table_name = $table_mapping
->getDedicatedDataTableName($storage_definition);
$this->database
->delete($table_name)
->condition('entity_id', $entity
->id())
->execute();
}
}
}
/**
* {@inheritdoc}
*/
protected function doSave($id, EntityInterface $entity) {
/** @var \Drupal\civicrm_entity\Entity\CivicrmEntity $entity */
$return = $entity
->isNew() ? SAVED_NEW : SAVED_UPDATED;
$params = $entity
->civicrmApiNormalize();
$non_base_fields = array_filter($entity
->getFieldDefinitions(), function (FieldDefinitionInterface $definition) {
return !$definition
->getFieldStorageDefinition()
->isBaseField();
});
$non_base_fields = array_map(function (FieldDefinitionInterface $definition) {
return $definition
->getName();
}, $non_base_fields);
$result = $this
->getCiviCrmApi()
->save($this->entityType
->get('civicrm_entity'), $params);
if ($entity
->isNew()) {
$entity->{$this->idKey} = (string) $result['id'];
}
$this
->doSaveFieldItems($entity, $non_base_fields);
return $return;
}
/**
* {@inheritdoc}
*
* @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
*/
protected function doLoadMultiple(array $ids = NULL) {
$entities = [];
if ($ids === NULL) {
$civicrm_entities = $this
->getCiviCrmApi()
->get($this->entityType
->get('civicrm_entity'));
foreach ($civicrm_entities as $civicrm_entity) {
$civicrm_entity = reset($civicrm_entity);
$entity = $this
->prepareLoadedEntity($civicrm_entity);
$entities[$entity
->id()] = $entity;
}
}
// get all the fields
$fields = $this
->getCiviCrmApi()
->getFields($this->entityType
->get('civicrm_entity'));
$field_names = [];
foreach ($fields as $field) {
$field_names[] = $field['name'];
}
foreach ($ids as $id) {
$options = [
'id' => $id,
];
$options['return'] = $field_names;
if ($this->entityType
->get('civicrm_entity') === 'participant') {
unset($options['return']);
}
$civicrm_entity = $this
->getCiviCrmApi()
->get($this->entityType
->get('civicrm_entity'), $options);
$civicrm_entity = reset($civicrm_entity);
if ($civicrm_entity) {
if ($this->entityType
->get('civicrm_entity') === 'participant') {
// Massage the values.
$temporary = [];
foreach ($civicrm_entity as $key => $value) {
if (strpos($key, 'participant_') === 0) {
$temporary[str_replace('participant_', '', $key)] = $value;
}
else {
$temporary[$key] = $value;
}
}
$civicrm_entity = $temporary;
}
$entity = $this
->prepareLoadedEntity($civicrm_entity);
$entities[$entity
->id()] = $entity;
}
}
return $entities;
}
/**
* Prepares a loaded entity.
*
* @param array $civicrm_entity
* The entity data.
*
* @return \Drupal\civicrm_entity\Entity\CivicrmEntity
* The prepared entity.
*
* @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
*/
protected function prepareLoadedEntity(array $civicrm_entity) {
$this
->loadFromDedicatedTables($civicrm_entity);
$bundle = FALSE;
if ($this->bundleKey) {
$bundle_property = $this->entityType
->get('civicrm_bundle_property');
if (!isset($civicrm_entity[$bundle_property])) {
throw new EntityStorageException('Missing bundle for entity type ' . $this->entityTypeId);
}
$bundle_value = $civicrm_entity[$bundle_property];
$options = $this->civicrmApi
->getOptions($this->entityType
->get('civicrm_entity'), $bundle_property);
$bundle = $options[$bundle_value];
$transliteration = \Drupal::transliteration();
$bundle = SupportedEntities::optionToMachineName($bundle, $transliteration);
}
$entity = new $this->entityClass([], $this->entityTypeId, $bundle);
// Use initFieldValues to fix CiviCRM data array to Drupal.
$this
->initFieldValues($entity, $civicrm_entity);
return $entity;
}
/**
* {@inheritdoc}
*/
protected function getQueryServiceName() {
return 'entity.query.civicrm_entity';
}
/**
* {@inheritdoc}
*
* @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
*/
public function countFieldData($storage_definition, $as_bool = FALSE) {
// The table mapping contains stale data during a request when a field
// storage definition is added, so bypass the internal storage definitions
// and fetch the table mapping using the passed in storage definition.
// @todo Fix this in https://www.drupal.org/node/2705205.
$table_mapping = $this
->getTableMapping();
if ($table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
$is_deleted = $storage_definition instanceof FieldStorageConfigInterface && $storage_definition
->isDeleted();
$table_name = $table_mapping
->getDedicatedDataTableName($storage_definition, $is_deleted);
$query = $this->database
->select($table_name, 't');
$or = $query
->orConditionGroup();
foreach ($storage_definition
->getColumns() as $column_name => $data) {
$or
->isNotNull($table_mapping
->getFieldColumnName($storage_definition, $column_name));
}
$query
->condition($or);
if (!$as_bool) {
$query
->fields('t', [
'entity_id',
])
->distinct(TRUE);
}
}
// @todo Find a way to count field data also for fields having custom
// storage. See https://www.drupal.org/node/2337753.
$count = 0;
if (isset($query)) {
// If we are performing the query just to check if the field has data
// limit the number of rows.
if ($as_bool) {
$query
->range(0, 1)
->addExpression('1');
}
else {
// Otherwise count the number of rows.
$query = $query
->countQuery();
}
$count = $query
->execute()
->fetchField();
}
return $as_bool ? (bool) $count : (int) $count;
}
/**
* {@inheritdoc}
*/
public function hasData() {
if (($component = $this->entityType
->get('component')) !== NULL) {
$components = $this
->getCiviCrmApi()
->getValue('Setting', [
'name' => 'enable_components',
]);
return !in_array($component, $components) ? FALSE : $this
->getCiviCrmApi()
->getCount($this->entityType
->get('civicrm_entity')) > 0;
}
return $this
->getCiviCrmApi()
->getCount($this->entityType
->get('civicrm_entity')) > 0;
}
/**
* {@inheritdoc}
*/
protected function doLoadRevisionFieldItems($revision_id) {
}
/**
* {@inheritdoc}
*/
protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = []) {
$update = !$entity
->isNew();
$table_mapping = $this
->getTableMapping();
$storage_definitions = $this
->getEntityFieldManager()
->getFieldStorageDefinitions($this->entityTypeId);
$dedicated_table_fields = [];
// Collect the name of fields to be written in dedicated tables and check
// whether shared table records need to be updated.
foreach ($names as $name) {
$storage_definition = $storage_definitions[$name];
if ($table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
$dedicated_table_fields[] = $name;
}
}
// Update dedicated table records if necessary.
if ($dedicated_table_fields) {
$names = is_array($dedicated_table_fields) ? $dedicated_table_fields : [];
$this
->saveToDedicatedTables($entity, $update, $names);
}
}
/**
* {@inheritdoc}
*/
protected function doDeleteRevisionFieldItems(ContentEntityInterface $revision) {
}
/**
* {@inheritdoc}
*/
public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) {
$this
->wrapSchemaException(function () use ($storage_definition) {
$this
->getStorageSchema()
->onFieldStorageDefinitionCreate($storage_definition);
});
}
/**
* {@inheritdoc}
*/
public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
$table_mapping = $this
->getTableMapping($this
->getEntityFieldManager()
->getActiveFieldStorageDefinitions($this->entityType
->id()));
if ($storage_definition instanceof FieldStorageConfigInterface && $table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
// Mark all data associated with the field for deletion.
$table = $table_mapping
->getDedicatedDataTableName($storage_definition);
$this->database
->update($table)
->fields([
'deleted' => 1,
])
->execute();
}
// Update the field schema.
$this
->wrapSchemaException(function () use ($storage_definition) {
$this
->getStorageSchema()
->onFieldStorageDefinitionDelete($storage_definition);
});
}
/**
* {@inheritdoc}
*
* Provide any additional processing of values from CiviCRM API.
*/
protected function initFieldValues(ContentEntityInterface $entity, array $values = [], array $field_names = []) {
parent::initFieldValues($entity, $values, $field_names);
$civicrm_entity_settings = $this
->getConfigFactory()
->get('civicrm_entity.settings');
$field_definitions = $entity
->getFieldDefinitions();
foreach ($field_definitions as $definition) {
$items = $entity
->get($definition
->getName());
if ($items
->isEmpty()) {
continue;
}
$main_property_name = $definition
->getFieldStorageDefinition()
->getMainPropertyName();
// Set a default format for text fields.
if ($definition
->getType() === 'text_long') {
$filter_format = $civicrm_entity_settings
->get('filter_format') ?: filter_fallback_format();
$item_values = $items
->getValue();
foreach ($item_values as $delta => $item) {
$item_values[$delta]['format'] = $filter_format;
}
$items
->setValue($item_values);
}
elseif ($definition
->getType() === 'datetime') {
$item_values = $items
->getValue();
foreach ($item_values as $delta => $item) {
// On Contribution entities, there are dates sometimes set to the
// string value of 'null'.
if ($item[$main_property_name] === 'null') {
$item_values[$delta][$main_property_name] = NULL;
}
elseif (is_numeric($item[$main_property_name])) {
$item_values[$delta][$main_property_name] = (new \DateTime())
->setTimestamp($item[$main_property_name])
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
}
else {
$datetime_format = $definition
->getSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE ? DateTimeItemInterface::DATE_STORAGE_FORMAT : DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
// CiviCRM gives us the datetime in the users timezone (or no
// timezone at all) but Drupal expects it in UTC. So, we need to
// convert from the users timezone into UTC.
$datetime_value = (new \DateTime($item[$main_property_name], new \DateTimeZone(date_default_timezone_get())))
->setTimezone(new \DateTimeZone('UTC'))
->format($datetime_format);
$item_values[$delta][$main_property_name] = $datetime_value;
}
}
$items
->setValue($item_values);
}
}
// Handle special cases for field definitions.
foreach ($field_definitions as $definition) {
if (($field_metadata = $definition
->getSetting('civicrm_entity_field_metadata')) && isset($field_metadata['custom_group_id']) && $field_metadata['data_type'] === 'File') {
$items = $entity
->get($definition
->getName());
$item_values = $items
->getValue();
if (!empty($item_values)) {
$ret = [];
foreach ($item_values as $value) {
if (!isset($value['fid'])) {
continue;
}
$ret[] = [
'value' => $value['fid'],
];
}
if (!empty($ret)) {
$items
->setValue($ret);
}
}
}
}
}
/**
* {@inheritdoc}
*/
public function getTableMapping(array $storage_definitions = NULL) {
$table_mapping = $this->tableMapping;
if ($table_mapping) {
return $table_mapping;
}
$table_mapping_class = DefaultTableMapping::class;
$definitions = $this
->getEntityFieldManager()
->getFieldStorageDefinitions($this->entityTypeId);
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping|\Drupal\Core\Entity\Sql\TemporaryTableMapping $table_mapping */
$table_mapping = new $table_mapping_class($this->entityType, $definitions);
// Add dedicated tables.
$dedicated_table_definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
return $table_mapping
->requiresDedicatedTableStorage($definition);
});
$extra_columns = [
'bundle',
'deleted',
'entity_id',
'revision_id',
'langcode',
'delta',
];
foreach ($dedicated_table_definitions as $field_name => $definition) {
$tables = [
$table_mapping
->getDedicatedDataTableName($definition),
];
foreach ($tables as $table_name) {
$table_mapping
->setFieldNames($table_name, [
$field_name,
]);
$table_mapping
->setExtraColumns($table_name, $extra_columns);
}
}
$this->tableMapping = $table_mapping;
return $table_mapping;
}
/**
* Loads values of fields stored in dedicated tables for a group of entities.
*
* @param array &$values
* An array of values keyed by entity ID.
* defaults to FALSE.
*
* @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
*/
protected function loadFromDedicatedTables(array &$values, $load_from_revision = FALSE) {
if (empty($values)) {
return;
}
// Collect impacted fields.
$storage_definitions = [];
$table_mapping = $this
->getTableMapping();
$definitions = $this
->getEntityFieldManager()
->getFieldDefinitions($this->entityTypeId, $this->entityTypeId);
foreach ($definitions as $field_name => $field_definition) {
$storage_definition = $field_definition
->getFieldStorageDefinition();
if ($table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
$storage_definitions[$field_name] = $storage_definition;
}
}
// Load field data.
$langcodes = array_keys($this->languageManager
->getLanguages(LanguageInterface::STATE_ALL));
foreach ($storage_definitions as $field_name => $storage_definition) {
$table = $table_mapping
->getDedicatedDataTableName($storage_definition);
// Ensure that only values having valid languages are retrieved. Since we
// are loading values for multiple entities, we cannot limit the query to
// the available translations.
$results = $this->database
->select($table, 't')
->fields('t')
->condition('entity_id', [
$values[$this
->getEntityType()
->getKey('id')],
], 'IN')
->condition('deleted', 0)
->condition('langcode', $langcodes, 'IN')
->orderBy('delta')
->execute();
foreach ($results as $row) {
if (!isset($values[$field_name])) {
$values[$field_name] = [];
}
if ($storage_definition
->getCardinality() == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || count($values[$field_name]) < $storage_definition
->getCardinality()) {
$item = [];
// For each column declared by the field, populate the item from the
// prefixed database column.
foreach ($storage_definition
->getColumns() as $column => $attributes) {
$column_name = $table_mapping
->getFieldColumnName($storage_definition, $column);
// Unserialize the value if specified in the column schema.
$item[$column] = !empty($attributes['serialize']) ? unserialize($row->{$column_name}) : $row->{$column_name};
}
// Add the item to the field values for the entity.
$values[$field_name][] = $item;
}
}
}
}
/**
* {@inheritdoc}
*/
public function requiresEntityStorageSchemaChanges(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
// The entity base table is managed by CiviCRM.
return FALSE;
}
/**
* {@inheritdoc}
*/
public function requiresEntityDataMigration(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
// The entity base table is managed by CiviCRM.
return FALSE;
}
/**
* Saves values of fields that use dedicated tables.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity.
* @param bool $update
* TRUE if the entity is being updated, FALSE if it is being inserted.
* @param string[] $names
* (optional) The names of the fields to be stored. Defaults to all the
* available fields.
*
* @throws \Drupal\Core\Entity\Sql\SqlContentEntityStorageException
*/
protected function saveToDedicatedTables(ContentEntityInterface $entity, $update = TRUE, $names = []) {
$vid = $entity
->getRevisionId();
$id = $entity
->id();
$bundle = $entity
->bundle();
$entity_type = $entity
->getEntityTypeId();
$default_langcode = $entity
->getUntranslated()
->language()
->getId();
$translation_langcodes = array_keys($entity
->getTranslationLanguages());
$table_mapping = $this
->getTableMapping();
if (!isset($vid)) {
$vid = $id;
}
$original = !empty($entity->original) ? $entity->original : NULL;
// Determine which fields should be actually stored.
$definitions = $this
->getEntityFieldManager()
->getFieldDefinitions($entity_type, $bundle);
if ($names) {
$definitions = array_intersect_key($definitions, array_flip($names));
}
foreach ($definitions as $field_name => $field_definition) {
$storage_definition = $field_definition
->getFieldStorageDefinition();
if (!$table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
continue;
}
// When updating an existing revision, keep the existing records if the
// field values did not change.
if (!$entity
->isNewRevision() && $original && !$this
->hasFieldValueChanged($field_definition, $entity, $original)) {
continue;
}
$table_name = $table_mapping
->getDedicatedDataTableName($storage_definition);
$revision_name = $table_mapping
->getDedicatedRevisionTableName($storage_definition);
// Delete and insert, rather than update, in case a value was added.
if ($update) {
// Only overwrite the field's base table if saving the default revision
// of an entity.
if ($entity
->isDefaultRevision()) {
$this->database
->delete($table_name)
->condition('entity_id', $id)
->execute();
}
if ($this->entityType
->isRevisionable()) {
$this->database
->delete($revision_name)
->condition('entity_id', $id)
->condition('revision_id', $vid)
->execute();
}
}
// Prepare the multi-insert query.
$do_insert = FALSE;
$columns = [
'entity_id',
'revision_id',
'bundle',
'delta',
'langcode',
];
foreach ($storage_definition
->getColumns() as $column => $attributes) {
$columns[] = $table_mapping
->getFieldColumnName($storage_definition, $column);
}
$query = $this->database
->insert($table_name)
->fields($columns);
if ($this->entityType
->isRevisionable()) {
$revision_query = $this->database
->insert($revision_name)
->fields($columns);
}
$langcodes = $field_definition
->isTranslatable() ? $translation_langcodes : [
$default_langcode,
];
foreach ($langcodes as $langcode) {
$delta_count = 0;
$items = $entity
->getTranslation($langcode)
->get($field_name);
$items
->filterEmptyItems();
foreach ($items as $delta => $item) {
// We now know we have something to insert.
$do_insert = TRUE;
$record = [
'entity_id' => $id,
'revision_id' => $vid,
'bundle' => $bundle,
'delta' => $delta,
'langcode' => $langcode,
];
foreach ($storage_definition
->getColumns() as $column => $attributes) {
$column_name = $table_mapping
->getFieldColumnName($storage_definition, $column);
// Serialize the value if specified in the column schema.
$value = $item->{$column};
if (!empty($attributes['serialize'])) {
$value = serialize($value);
}
$record[$column_name] = SqlContentEntityStorageSchema::castValue($attributes, $value);
}
$query
->values($record);
if ($this->entityType
->isRevisionable()) {
$revision_query
->values($record);
}
if ($storage_definition
->getCardinality() != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && ++$delta_count == $storage_definition
->getCardinality()) {
break;
}
}
}
// Execute the query if we have values to insert.
if ($do_insert) {
// Only overwrite the field's base table if saving the default revision
// of an entity.
if ($entity
->isDefaultRevision()) {
$query
->execute();
}
if ($this->entityType
->isRevisionable()) {
$revision_query
->execute();
}
}
}
}
/**
* Allows CiviCRM hook to invoke presave.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity to save.
*
* @throws \Drupal\Core\Entity\EntityStorageException
* If the entity identifier is invalid.
*
* @see \Drupal\Core\Entity\ContentEntityStorageBase::doPreSave
*/
public function civiPreSave(EntityInterface $entity) {
if (!empty($entity->drupal_crud)) {
return;
}
$this
->doPreSave($entity);
}
/**
* Allows CiviCRM hook to invoke postsave.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The saved entity.
* @param $update
* Specifies whether the entity is being updated or created.
*
* @see \Drupal\Core\Entity\ContentEntityStorageBase::doPostSave
*/
public function civiPostSave(EntityInterface $entity, $update) {
if (!empty($entity->drupal_crud)) {
return;
}
$this
->doPostSave($entity, $update);
}
/**
* Allows CiviCRM hook to invoke predelete.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity to be deleted.
*
* @see \Drupal\Core\Entity\EntityStorageInterface::delete
*/
public function civiPreDelete(EntityInterface $entity) {
if (!empty($entity->drupal_crud)) {
return;
}
CivicrmEntity::preDelete($this, [
$entity,
]);
$this
->invokeHook('predelete', $entity);
}
/**
* Allows CiviCRM hook to invoke delete.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity deleted.
*
* @see \Drupal\Core\Entity\EntityStorageInterface::delete
*/
public function civiPostDelete(EntityInterface $entity) {
if (!empty($entity->drupal_crud)) {
return;
}
$this
->doDeleteFieldItems([
$entity,
]);
$this
->resetCache([
$entity
->id(),
]);
CivicrmEntity::postDelete($this, [
$entity,
]);
$this
->invokeHook('delete', $entity);
}
/**
* Loads the EntityTag ID.
*
* When saving EntityTag objects, the 'id' that's passed to CiviCRM hooks is
* not the ID of the EntityTag, but rather the object to which the EntityTag
* applies. This provides the lookup to determing the ID of the EntityTag
* object itself.
*
* @param $entityId
* The entity ID.
* @param $entityTable
* The entity table.
*
* @return int|null
* The EntityTag object's ID, or NULL if not found.
*/
public function getEntityTagEntityId($entityId, $entityTable) {
$api_params = [
'sequential' => 1,
'entity_id' => $entityId,
'entity_table' => $entityTable,
];
$api_results = civicrm_api3('EntityTag', 'get', $api_params);
if (!empty($api_results['values'])) {
foreach ($api_results['values'] as $delta => $result) {
if ($result['entity_id'] == $entityId) {
return $result['id'];
}
}
}
}
/**
* {@inheritdoc}
*/
public function onEntityTypeDelete(EntityTypeInterface $entity_type) {
// Don't do anything.
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CiviEntityStorage:: |
protected | property | The CiviCRM API. | |
CiviEntityStorage:: |
protected | property | The config factory. | |
CiviEntityStorage:: |
public | function | Allows CiviCRM hook to invoke delete. | |
CiviEntityStorage:: |
public | function | Allows CiviCRM hook to invoke postsave. | |
CiviEntityStorage:: |
public | function | Allows CiviCRM hook to invoke predelete. | |
CiviEntityStorage:: |
public | function | Allows CiviCRM hook to invoke presave. | |
CiviEntityStorage:: |
public | function |
Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Performs storage-specific entity deletion. Overrides ContentEntityStorageBase:: |
|
CiviEntityStorage:: |
protected | function |
Deletes entity field values from the storage. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Deletes field values of an entity revision from the storage. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Actually loads revision field item values from the storage. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Performs storage-specific saving of the entity. Overrides ContentEntityStorageBase:: |
|
CiviEntityStorage:: |
protected | function |
Writes entity field values to the storage. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
private | function | Gets the CiviCRM API | |
CiviEntityStorage:: |
private | function | Gets the config factory. | |
CiviEntityStorage:: |
private | function | Get the entity field manager. | |
CiviEntityStorage:: |
public | function | Loads the EntityTag ID. | |
CiviEntityStorage:: |
protected | function |
Gets the name of the service for the query for this entity storage. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
public | function |
Gets a table mapping for the entity's SQL tables. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
public | function |
Determines if the storage contains any data. Overrides EntityStorageBase:: |
|
CiviEntityStorage:: |
protected | function |
Provide any additional processing of values from CiviCRM API. Overrides ContentEntityStorageBase:: |
|
CiviEntityStorage:: |
protected | function |
Initializes table name variables. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Loads values of fields stored in dedicated tables for a group of entities. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
public | function |
Reacts to the deletion of the entity type. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
public | function |
Reacts to the creation of a field storage definition. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
public | function |
Reacts to the deletion of a field storage definition. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function | Prepares a loaded entity. | |
CiviEntityStorage:: |
public | function |
Checks if existing data would be lost if the schema changes were applied. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
public | function |
Checks if the changes to the entity type requires storage schema changes. Overrides SqlContentEntityStorage:: |
|
CiviEntityStorage:: |
protected | function |
Saves values of fields that use dedicated tables. Overrides SqlContentEntityStorage:: |
|
ContentEntityStorageBase:: |
protected | property | The entity bundle key. | |
ContentEntityStorageBase:: |
protected | property | Cache backend. | |
ContentEntityStorageBase:: |
protected | property | ||
ContentEntityStorageBase:: |
protected | property | The entity field manager service. | |
ContentEntityStorageBase:: |
protected | property | The entity bundle info. | |
ContentEntityStorageBase:: |
protected | property | Stores the latest revision IDs for entities. | |
ContentEntityStorageBase:: |
protected | function | Ensures integer entity key values are valid. | |
ContentEntityStorageBase:: |
public | function |
Creates a new revision starting off from the specified entity object. Overrides TranslatableRevisionableStorageInterface:: |
|
ContentEntityStorageBase:: |
public | function |
Constructs a new entity translation object, without permanently saving it. Overrides TranslatableStorageInterface:: |
|
ContentEntityStorageBase:: |
public | function |
Creates an entity with sample field values. Overrides ContentEntityStorageInterface:: |
1 |
ContentEntityStorageBase:: |
public | function |
Delete a specific entity revision. Overrides EntityStorageInterface:: |
1 |
ContentEntityStorageBase:: |
protected | function |
Performs storage-specific creation of entities. Overrides EntityStorageBase:: |
|
ContentEntityStorageBase:: |
protected | function |
Performs post save entity processing. Overrides EntityStorageBase:: |
|
ContentEntityStorageBase:: |
protected | function |
Performs presave entity processing. Overrides EntityStorageBase:: |
|
ContentEntityStorageBase:: |
protected | function | Gets entities from the persistent cache backend. | |
ContentEntityStorageBase:: |
public | function |
Returns the latest revision identifier for an entity. Overrides RevisionableStorageInterface:: |
|
ContentEntityStorageBase:: |
public | function |
Returns the latest revision affecting the specified translation. Overrides TranslatableRevisionableStorageInterface:: |
|
ContentEntityStorageBase:: |
protected | function | Returns an array of field names to skip when merging revision translations. | |
ContentEntityStorageBase:: |
protected | function | Checks whether the field values changed compared to the original entity. | |
ContentEntityStorageBase:: |
protected | function | Invokes a method on the Field objects within an entity. | |
ContentEntityStorageBase:: |
protected | function | Invokes the post save method on the Field objects within an entity. | |
ContentEntityStorageBase:: |
protected | function |
Invokes a hook on behalf of the entity. Overrides EntityStorageBase:: |
1 |
ContentEntityStorageBase:: |
protected | function | Invokes hook_entity_storage_load(). | |
ContentEntityStorageBase:: |
protected | function | Checks translation statuses and invoke the related hooks if needed. | |
ContentEntityStorageBase:: |
protected | function | Checks whether any entity revision is translated. | |
ContentEntityStorageBase:: |
protected | function | Checks whether any stored entity revision is translated. | |
ContentEntityStorageBase:: |
public | function |
Loads multiple entity revisions. Overrides RevisionableStorageInterface:: |
1 |
ContentEntityStorageBase:: |
public | function |
Load a specific entity revision. Overrides EntityStorageInterface:: |
1 |
ContentEntityStorageBase:: |
public | function |
Loads an unchanged entity from the database. Overrides EntityStorageBase:: |
|
ContentEntityStorageBase:: |
public | function |
Reacts to the creation of a field. Overrides FieldDefinitionListenerInterface:: |
|
ContentEntityStorageBase:: |
public | function |
Reacts to the update of a field. Overrides FieldDefinitionListenerInterface:: |
|
ContentEntityStorageBase:: |
protected | function | Populates the affected flag for all the revision translations. | |
ContentEntityStorageBase:: |
protected | function |
Gathers entities from a 'preload' step. Overrides EntityStorageBase:: |
|
ContentEntityStorageBase:: |
public | function |
Purges a batch of field data. Overrides FieldableEntityStorageInterface:: |
|
ContentEntityStorageBase:: |
public | function |
Resets the internal, static entity cache. Overrides EntityStorageBase:: |
1 |
ContentEntityStorageBase:: |
protected | function | Stores entities in the persistent cache backend. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
DeprecatedServicePropertyTrait:: |
public | function | Allows to access deprecated/removed properties. | |
EntityHandlerBase:: |
protected | property | The module handler to invoke hooks on. | 2 |
EntityHandlerBase:: |
protected | function | Gets the module handler. | 2 |
EntityHandlerBase:: |
public | function | Sets the module handler for this handler. | |
EntityStorageBase:: |
protected | property | Name of the entity class. | |
EntityStorageBase:: |
protected | property | Information about the entity type. | |
EntityStorageBase:: |
protected | property | Entity type ID for this storage. | |
EntityStorageBase:: |
protected | property | Name of the entity's ID field in the entity database table. | |
EntityStorageBase:: |
protected | property | The memory cache. | |
EntityStorageBase:: |
protected | property | The memory cache cache tag. | |
EntityStorageBase:: |
protected | property | Name of entity's UUID database table field, if it supports UUIDs. | 1 |
EntityStorageBase:: |
protected | property | The UUID service. | 1 |
EntityStorageBase:: |
protected | function | Builds the cache ID for the passed in entity ID. | 1 |
EntityStorageBase:: |
public | function |
Constructs a new entity object, without permanently saving it. Overrides EntityStorageInterface:: |
1 |
EntityStorageBase:: |
public | function |
Gets an aggregated query instance. Overrides EntityStorageInterface:: |
|
EntityStorageBase:: |
public | function |
Gets the entity type definition. Overrides EntityStorageInterface:: |
|
EntityStorageBase:: |
public | function |
Gets the entity type ID. Overrides EntityStorageInterface:: |
|
EntityStorageBase:: |
protected | function | Gets entities from the static cache. | |
EntityStorageBase:: |
public | function |
Gets an entity query instance. Overrides EntityStorageInterface:: |
|
EntityStorageBase:: |
public | function |
Loads one entity. Overrides EntityStorageInterface:: |
2 |
EntityStorageBase:: |
public | function |
Load entities by their property values. Overrides EntityStorageInterface:: |
3 |
EntityStorageBase:: |
public | function |
Loads one or more entities. Overrides EntityStorageInterface:: |
1 |
EntityStorageBase:: |
protected | function | Attaches data to entities upon loading. | |
EntityStorageBase:: |
protected | function | Stores entities in the static entity cache. | |
EntityStorageInterface:: |
constant | Load the most recent version of an entity's field data. | ||
EntityStorageInterface:: |
constant | Load the version of an entity's field data specified in the entity. | ||
SqlContentEntityStorage:: |
protected | property | The base table of the entity. | |
SqlContentEntityStorage:: |
protected | property | Active database connection. | |
SqlContentEntityStorage:: |
protected | property | The table that stores properties, if the entity has multilingual support. | |
SqlContentEntityStorage:: |
protected | property | The default language entity key. | |
SqlContentEntityStorage:: |
protected | property | The entity type manager. | |
SqlContentEntityStorage:: |
protected | property | The entity type's field storage definitions. | |
SqlContentEntityStorage:: |
protected | property |
The entity langcode key. Overrides EntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | property | The language manager. | |
SqlContentEntityStorage:: |
protected | property | The table that stores revision field data if the entity supports revisions. | |
SqlContentEntityStorage:: |
protected | property | Name of entity's revision database table field, if it supports revisions. | |
SqlContentEntityStorage:: |
protected | property | The table that stores revisions, if the entity supports revisions. | |
SqlContentEntityStorage:: |
protected | property | The entity type's storage schema object. | |
SqlContentEntityStorage:: |
protected | property | The mapping of field columns to SQL tables. | |
SqlContentEntityStorage:: |
protected | property | Whether this storage should use the temporary table mapping. | |
SqlContentEntityStorage:: |
protected | function |
Builds an entity query. Overrides EntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | function | Builds the query to load the entity. | |
SqlContentEntityStorage:: |
public static | function |
Instantiates a new instance of this entity handler. Overrides ContentEntityStorageBase:: |
1 |
SqlContentEntityStorage:: |
public | function |
Deletes permanently saved entities. Overrides EntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | function | Deletes values of fields in dedicated tables for all revisions. | |
SqlContentEntityStorage:: |
protected | function | Deletes values of fields in dedicated tables for all revisions. | |
SqlContentEntityStorage:: |
protected | function |
Actually loads revision field item values from the storage. Overrides ContentEntityStorageBase:: |
|
SqlContentEntityStorage:: |
public | function |
Performs final cleanup after all data of a field has been purged. Overrides ContentEntityStorageBase:: |
|
SqlContentEntityStorage:: |
public | function | Gets the base table name. | |
SqlContentEntityStorage:: |
public | function | Gets a table mapping for the specified entity type and storage definitions. | |
SqlContentEntityStorage:: |
public | function | Gets the data table name. | |
SqlContentEntityStorage:: |
public | function | Gets the base field definitions for a content entity type. | |
SqlContentEntityStorage:: |
protected | function | Gets entities from the storage. | |
SqlContentEntityStorage:: |
public | function | Gets the revision data table name. | |
SqlContentEntityStorage:: |
public | function | Gets the revision table name. | |
SqlContentEntityStorage:: |
protected | function | Gets the entity type's storage schema object. | |
SqlContentEntityStorage:: |
protected | function |
Determines if this entity already exists in storage. Overrides EntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | function | Checks whether a field column should be treated as serial. | 1 |
SqlContentEntityStorage:: |
protected | function | Loads values for fields stored in the shared data tables. | |
SqlContentEntityStorage:: |
protected | function |
Maps from storage records to entity objects, and attaches fields. Overrides EntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | function | Maps from an entity object to the storage record of the field data. | |
SqlContentEntityStorage:: |
protected | function | Maps from an entity object to the storage record. | |
SqlContentEntityStorage:: |
public | function |
Reacts to a bundle being created. Overrides EntityBundleListenerInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to a bundle being deleted. Overrides EntityBundleListenerInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to the creation of the entity type. Overrides EntityTypeListenerInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to the update of the entity type. Overrides EntityTypeListenerInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to the creation of the fieldable entity type. Overrides EntityTypeListenerInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to the update of a fieldable entity type. Overrides EntityTypeListenerInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to the deletion of a field. Overrides ContentEntityStorageBase:: |
|
SqlContentEntityStorage:: |
public | function |
Reacts to the update of a field storage definition. Overrides ContentEntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | function |
Removes field items from storage per entity during purge. Overrides ContentEntityStorageBase:: |
|
SqlContentEntityStorage:: |
protected | function |
Reads values to be purged for a single field. Overrides ContentEntityStorageBase:: |
|
SqlContentEntityStorage:: |
public | function |
Checks if existing data would be lost if the schema changes were applied. Overrides DynamicallyFieldableEntityStorageSchemaInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Checks if the changes to the storage definition requires schema changes. Overrides DynamicallyFieldableEntityStorageSchemaInterface:: |
|
SqlContentEntityStorage:: |
public | function |
Restores a previously saved entity. Overrides EntityStorageBase:: |
|
SqlContentEntityStorage:: |
public | function |
Saves the entity permanently. Overrides EntityStorageBase:: |
1 |
SqlContentEntityStorage:: |
protected | function | Saves an entity revision. | |
SqlContentEntityStorage:: |
protected | function | Saves fields that use the shared tables. | |
SqlContentEntityStorage:: |
public | function | Updates the wrapped entity type definition. | |
SqlContentEntityStorage:: |
public | function | Updates the internal list of field storage definitions. | |
SqlContentEntityStorage:: |
public | function | Sets the wrapped table mapping definition. | |
SqlContentEntityStorage:: |
public | function | Changes the temporary state of the storage. | |
SqlContentEntityStorage:: |
protected | function | Determines whether the passed field has been already deleted. | |
SqlContentEntityStorage:: |
protected | function | Wraps a database schema exception into an entity storage exception. | |
SqlContentEntityStorage:: |
public | function |
Constructs a SqlContentEntityStorage object. Overrides ContentEntityStorageBase:: |
1 |
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. |