class DatabaseStorageControllerNG

Implements Field API specific enhancements to the DatabaseStorageController class.

@todo: Once all entity types have been converted, merge improvements into the DatabaseStorageController class.

See the EntityNG documentation for an explanation of "NG".

Hierarchy

Expanded class hierarchy of DatabaseStorageControllerNG

See also

\Drupal\Core\EntityNG

9 files declare their use of DatabaseStorageControllerNG
CommentStorageController.php in drupal/core/modules/comment/lib/Drupal/comment/CommentStorageController.php
Definition of Drupal\comment\CommentStorageController.
CustomBlockStorageController.php in drupal/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockStorageController.php
Contains \Drupal\custom_block\CustomBlockStorageController.
EntityTestStorageController.php in drupal/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestStorageController.php
Definition of Drupal\entity_test\EntityTestStorageController.
EntityTranslationTestBase.php in drupal/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationTestBase.php
Contains \Drupal\entity\Tests\EntityTranslationTestBase.
FeedStorageController.php in drupal/core/modules/aggregator/lib/Drupal/aggregator/FeedStorageController.php
Contains \Drupal\aggregator\FeedStorageController.

... See full list

File

drupal/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php, line 31
Contains \Drupal\Core\Entity\DatabaseStorageControllerNG.

Namespace

Drupal\Core\Entity
View source
class DatabaseStorageControllerNG extends DatabaseStorageController {

  /**
   * The entity class to use.
   *
   * @var string
   */
  protected $entityClass;

  /**
   * The entity bundle key.
   *
   * @var string|bool
   */
  protected $bundleKey;

  /**
   * The table that stores properties, if the entity has multilingual support.
   *
   * @var string
   */
  protected $dataTable;

  /**
   * Overrides DatabaseStorageController::__construct().
   */
  public function __construct($entity_type, array $entity_info, Connection $database) {
    parent::__construct($entity_type, $entity_info, $database);
    $this->bundleKey = !empty($this->entityInfo['entity_keys']['bundle']) ? $this->entityInfo['entity_keys']['bundle'] : FALSE;
    $this->entityClass = $this->entityInfo['class'];

    // Check if the entity type has a dedicated table for properties.
    if (!empty($this->entityInfo['data_table'])) {
      $this->dataTable = $this->entityInfo['data_table'];
    }

    // Work-a-round to let load() get stdClass storage records without having to
    // override it. We map storage records to entities in
    // DatabaseStorageControllerNG:: mapFromStorageRecords().
    // @todo: Remove this once this is moved in the main controller.
    unset($this->entityInfo['class']);
  }

  /**
   * Overrides DatabaseStorageController::create().
   *
   * @param array $values
   *   An array of values to set, keyed by field name. The value has to be
   *   the plain value of an entity field, i.e. an array of field items.
   *   If no numerically indexed array is given, the value will be set for the
   *   first field item. For example, to set the first item of a 'name'
   *   field one can pass:
   *   @code
   *     $values = array('name' => array(0 => array('value' => 'the name')));
   *   @endcode
   *   or
   *   @code
   *     $values = array('name' => array('value' => 'the name'));
   *   @endcode
   *   If the 'name' field is a defined as 'string_item' which supports
   *   setting its value by a string, it's also possible to just pass the name
   *   string:
   *   @code
   *     $values = array('name' => 'the name');
   *   @endcode
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   A new entity object.
   */
  public function create(array $values) {

    // We have to determine the bundle first.
    $bundle = FALSE;
    if ($this->bundleKey) {
      if (!isset($values[$this->bundleKey])) {
        throw new EntityStorageException(t('Missing bundle for entity type @type', array(
          '@type' => $this->entityType,
        )));
      }
      $bundle = $values[$this->bundleKey];
    }
    $entity = new $this->entityClass(array(), $this->entityType, $bundle);

    // Set all other given values.
    foreach ($values as $name => $value) {
      $entity->{$name} = $value;
    }

    // Assign a new UUID if there is none yet.
    if ($this->uuidKey && !isset($entity->{$this->uuidKey}->value)) {
      $uuid = new Uuid();
      $entity->{$this->uuidKey} = $uuid
        ->generate();
    }

    // Modules might need to add or change the data initially held by the new
    // entity object, for instance to fill-in default values.
    $this
      ->invokeHook('create', $entity);
    return $entity;
  }

  /**
   * Builds an entity query.
   *
   * @param \Drupal\Core\Entity\Query\QueryInterface $entity_query
   *   EntityQuery instance.
   * @param array $values
   *   An associative array of properties of the entity, where the keys are the
   *   property names and the values are the values those properties must have.
   */
  protected function buildPropertyQuery(QueryInterface $entity_query, array $values) {
    if ($this->dataTable) {

      // @todo We should not be using a condition to specify whether conditions
      //   apply to the default language. See http://drupal.org/node/1866330.
      // Default to the original entity language if not explicitly specified
      // otherwise.
      if (!array_key_exists('default_langcode', $values)) {
        $values['default_langcode'] = 1;
      }
      elseif ($values['default_langcode'] === NULL) {
        unset($values['default_langcode']);
      }
    }
    parent::buildPropertyQuery($entity_query, $values);
  }

  /**
   * {@inheritdoc}
   */
  protected function buildQuery($ids, $revision_id = FALSE) {
    $query = $this->database
      ->select($this->entityInfo['base_table'], 'base');
    $is_revision_query = $this->revisionKey && ($revision_id || !$this->dataTable);
    $query
      ->addTag($this->entityType . '_load_multiple');
    if ($revision_id) {
      $query
        ->join($this->revisionTable, 'revision', "revision.{$this->idKey} = base.{$this->idKey} AND revision.{$this->revisionKey} = :revisionId", array(
        ':revisionId' => $revision_id,
      ));
    }
    elseif ($is_revision_query) {
      $query
        ->join($this->revisionTable, 'revision', "revision.{$this->revisionKey} = base.{$this->revisionKey}");
    }

    // Add fields from the {entity} table.
    $entity_fields = drupal_schema_fields_sql($this->entityInfo['base_table']);
    if ($is_revision_query) {

      // Add all fields from the {entity_revision} table.
      $entity_revision_fields = drupal_map_assoc(drupal_schema_fields_sql($this->entityInfo['revision_table']));

      // The ID field is provided by entity, so remove it.
      unset($entity_revision_fields[$this->idKey]);

      // Remove all fields from the base table that are also fields by the same
      // name in the revision table.
      $entity_field_keys = array_flip($entity_fields);
      foreach ($entity_revision_fields as $key => $name) {
        if (isset($entity_field_keys[$name])) {
          unset($entity_fields[$entity_field_keys[$name]]);
        }
      }
      $query
        ->fields('revision', $entity_revision_fields);

      // Compare revision ID of the base and revision table, if equal then this
      // is the default revision.
      $query
        ->addExpression('base.' . $this->revisionKey . ' = revision.' . $this->revisionKey, 'isDefaultRevision');
    }
    $query
      ->fields('base', $entity_fields);
    if ($ids) {
      $query
        ->condition("base.{$this->idKey}", $ids, 'IN');
    }
    return $query;
  }

  /**
   * Overrides DatabaseStorageController::attachLoad().
   *
   * Added mapping from storage records to entities.
   */
  protected function attachLoad(&$queried_entities, $load_revision = FALSE) {

    // Map the loaded stdclass records into entity objects and according fields.
    $queried_entities = $this
      ->mapFromStorageRecords($queried_entities, $load_revision);
    if ($this->entityInfo['fieldable']) {
      if ($load_revision) {
        field_attach_load_revision($this->entityType, $queried_entities);
      }
      else {
        field_attach_load($this->entityType, $queried_entities);
      }
    }

    // Call hook_entity_load().
    foreach (module_implements('entity_load') as $module) {
      $function = $module . '_entity_load';
      $function($queried_entities, $this->entityType);
    }

    // Call hook_TYPE_load(). The first argument for hook_TYPE_load() are
    // always the queried entities, followed by additional arguments set in
    // $this->hookLoadArguments.
    $args = array_merge(array(
      $queried_entities,
    ), $this->hookLoadArguments);
    foreach (module_implements($this->entityType . '_load') as $module) {
      call_user_func_array($module . '_' . $this->entityType . '_load', $args);
    }
  }

  /**
   * Maps from storage records to entity objects.
   *
   * @param array $records
   *   Associative array of query results, keyed on the entity ID.
   * @param boolean $load_revision
   *   (optional) TRUE if the revision should be loaded, defaults to FALSE.
   *
   * @return array
   *   An array of entity objects implementing the EntityInterface.
   */
  protected function mapFromStorageRecords(array $records, $load_revision = FALSE) {
    $entities = array();
    foreach ($records as $id => $record) {
      $entities[$id] = array();
      foreach ($record as $name => $value) {

        // Skip the item delta and item value levels but let the field assign
        // the value as suiting. This avoids unnecessary array hierarchies and
        // saves memory here.
        $entities[$id][$name][Language::LANGCODE_DEFAULT] = $value;
      }

      // If we have no multilingual values we can instantiate entity objecs
      // right now, otherwise we need to collect all the field values first.
      if (!$this->dataTable) {
        $bundle = $this->bundleKey ? $record->{$this->bundleKey} : FALSE;

        // Turn the record into an entity class.
        $entities[$id] = new $this->entityClass($entities[$id], $this->entityType, $bundle);
      }
    }
    $this
      ->attachPropertyData($entities, $load_revision);
    return $entities;
  }

  /**
   * Attaches property data in all languages for translatable properties.
   *
   * @param array &$entities
   *   Associative array of entities, keyed on the entity ID.
   * @param int $revision_id
   *   (optional) The revision to be loaded. Defaults to FALSE.
   */
  protected function attachPropertyData(array &$entities, $revision_id = FALSE) {
    if ($this->dataTable) {

      // If a revision table is available, we need all the properties of the
      // latest revision. Otherwise we fall back to the data table.
      $table = $this->revisionTable ?: $this->dataTable;
      $query = $this->database
        ->select($table, 'data', array(
        'fetch' => PDO::FETCH_ASSOC,
      ))
        ->fields('data')
        ->condition($this->idKey, array_keys($entities))
        ->orderBy('data.' . $this->idKey);
      if ($this->revisionTable) {
        if ($revision_id) {
          $query
            ->condition($this->revisionKey, $revision_id);
        }
        else {

          // Get the revision IDs.
          $revision_ids = array();
          foreach ($entities as $id => $values) {
            $revision_ids[] = $values[$this->revisionKey];
          }
          $query
            ->condition($this->revisionKey, $revision_ids);
        }
      }
      $data = $query
        ->execute();
      $field_definition = $this
        ->getFieldDefinitions(array());
      if ($this->revisionTable) {
        $data_fields = array_flip(array_diff(drupal_schema_fields_sql($this->entityInfo['revision_table']), drupal_schema_fields_sql($this->entityInfo['base_table'])));
      }
      else {
        $data_fields = array_flip(drupal_schema_fields_sql($this->entityInfo['data_table']));
      }
      foreach ($data as $values) {
        $id = $values[$this->idKey];

        // Field values in default language are stored with
        // Language::LANGCODE_DEFAULT as key.
        $langcode = empty($values['default_langcode']) ? $values['langcode'] : Language::LANGCODE_DEFAULT;
        foreach ($field_definition as $name => $definition) {

          // Set only translatable properties, unless we are dealing with a
          // revisable entity, in which case we did not load the untranslatable
          // data before.
          $translatable = !empty($definition['translatable']);
          if (isset($data_fields[$name]) && ($this->revisionTable || $translatable)) {
            $entities[$id][$name][$langcode] = $values[$name];
          }
        }
      }
      foreach ($entities as $id => $values) {
        $bundle = $this->bundleKey ? $values[$this->bundleKey][Language::LANGCODE_DEFAULT] : FALSE;

        // Turn the record into an entity class.
        $entities[$id] = new $this->entityClass($values, $this->entityType, $bundle);
      }
    }
  }

  /**
   * Overrides DatabaseStorageController::save().
   *
   * Added mapping from entities to storage records before saving.
   */
  public function save(EntityInterface $entity) {
    $transaction = $this->database
      ->startTransaction();
    try {

      // Ensure we are dealing with the actual entity.
      $entity = $entity
        ->getNGEntity();

      // Sync the changes made in the fields array to the internal values array.
      $entity
        ->updateOriginalValues();

      // Load the stored entity, if any.
      if (!$entity
        ->isNew() && !isset($entity->original)) {
        $entity->original = entity_load_unchanged($this->entityType, $entity
          ->id());
      }
      $this
        ->preSave($entity);
      $this
        ->invokeHook('presave', $entity);

      // Create the storage record to be saved.
      $record = $this
        ->mapToStorageRecord($entity);
      if (!$entity
        ->isNew()) {
        if ($entity
          ->isDefaultRevision()) {
          $return = drupal_write_record($this->entityInfo['base_table'], $record, $this->idKey);
        }
        else {

          // @todo, should a different value be returned when saving an entity
          // with $isDefaultRevision = FALSE?
          $return = FALSE;
        }
        if ($this->revisionKey) {
          $record->{$this->revisionKey} = $this
            ->saveRevision($entity);
        }
        if ($this->dataTable) {
          $this
            ->savePropertyData($entity);
        }
        $this
          ->resetCache(array(
          $entity
            ->id(),
        ));
        $this
          ->postSave($entity, TRUE);
        $this
          ->invokeHook('update', $entity);
      }
      else {
        $return = drupal_write_record($this->entityInfo['base_table'], $record);
        $entity->{$this->idKey}->value = $record->{$this->idKey};
        if ($this->revisionKey) {
          $record->{$this->revisionKey} = $this
            ->saveRevision($entity);
        }
        $entity->{$this->idKey}->value = $record->{$this->idKey};
        if ($this->dataTable) {
          $this
            ->savePropertyData($entity);
        }

        // Reset general caches, but keep caches specific to certain entities.
        $this
          ->resetCache(array());
        $entity
          ->enforceIsNew(FALSE);
        $this
          ->postSave($entity, FALSE);
        $this
          ->invokeHook('insert', $entity);
      }

      // Ignore slave server temporarily.
      db_ignore_slave();
      unset($entity->original);
      return $return;
    } catch (\Exception $e) {
      $transaction
        ->rollback();
      watchdog_exception($this->entityType, $e);
      throw new EntityStorageException($e
        ->getMessage(), $e
        ->getCode(), $e);
    }
  }

  /**
   * Saves an entity revision.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   *
   * @return integer
   *   The revision id.
   */
  protected function saveRevision(EntityInterface $entity) {
    $return = $entity
      ->id();
    $default_langcode = $entity
      ->language()->langcode;
    if (!$entity
      ->isNewRevision()) {

      // Delete to handle removed values.
      $this->database
        ->delete($this->revisionTable)
        ->condition($this->idKey, $entity
        ->id())
        ->condition($this->revisionKey, $entity
        ->getRevisionId())
        ->execute();
    }
    $languages = $this->dataTable ? $entity
      ->getTranslationLanguages(TRUE) : array(
      $default_langcode => $entity
        ->language(),
    );
    foreach ($languages as $langcode => $language) {
      $translation = $entity
        ->getTranslation($langcode, FALSE);
      $record = $this
        ->mapToRevisionStorageRecord($translation);
      $record->langcode = $langcode;
      $record->default_langcode = $langcode == $default_langcode;

      // When saving a new revision, set any existing revision ID to NULL so as
      // to ensure that a new revision will actually be created.
      if ($entity
        ->isNewRevision() && isset($record->{$this->revisionKey})) {
        $record->{$this->revisionKey} = NULL;
      }
      $this
        ->preSaveRevision($record, $entity);
      if ($entity
        ->isNewRevision()) {
        drupal_write_record($this->revisionTable, $record);
        if ($entity
          ->isDefaultRevision()) {
          $this->database
            ->update($this->entityInfo['base_table'])
            ->fields(array(
            $this->revisionKey => $record->{$this->revisionKey},
          ))
            ->condition($this->idKey, $record->{$this->idKey})
            ->execute();
        }
        $entity
          ->setNewRevision(FALSE);
      }
      else {

        // @todo Use multiple insertions to improve performance.
        drupal_write_record($this->revisionTable, $record);
      }

      // Make sure to update the new revision key for the entity.
      $entity->{$this->revisionKey}->value = $record->{$this->revisionKey};
      $return = $record->{$this->revisionKey};
    }
    return $return;
  }

  /**
   * Stores the entity property language-aware data.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   */
  protected function savePropertyData(EntityInterface $entity) {

    // Delete and insert to handle removed values.
    $this->database
      ->delete($this->dataTable)
      ->condition($this->idKey, $entity
      ->id())
      ->execute();
    $query = $this->database
      ->insert($this->dataTable);
    foreach ($entity
      ->getTranslationLanguages() as $langcode => $language) {
      $record = $this
        ->mapToDataStorageRecord($entity, $langcode);
      $values = (array) $record;
      $query
        ->fields(array_keys($values))
        ->values($values);
    }
    $query
      ->execute();
  }

  /**
   * Overrides DatabaseStorageController::invokeHook().
   *
   * Invokes field API attachers with a BC entity.
   */
  protected function invokeHook($hook, EntityInterface $entity) {
    $function = 'field_attach_' . $hook;

    // @todo: field_attach_delete_revision() is named the wrong way round,
    // consider renaming it.
    if ($function == 'field_attach_revision_delete') {
      $function = 'field_attach_delete_revision';
    }
    if (!empty($this->entityInfo['fieldable']) && function_exists($function)) {
      $function($entity);
    }

    // Invoke the hook.
    module_invoke_all($this->entityType . '_' . $hook, $entity);

    // Invoke the respective entity-level hook.
    module_invoke_all('entity_' . $hook, $entity, $this->entityType);
  }

  /**
   * Maps from an entity object to the storage record of the base table.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   *
   * @return \stdClass
   *   The record to store.
   */
  protected function mapToStorageRecord(EntityInterface $entity) {
    $record = new \stdClass();
    foreach (drupal_schema_fields_sql($this->entityInfo['base_table']) as $name) {
      $record->{$name} = $entity->{$name}->value;
    }
    return $record;
  }

  /**
   * Maps from an entity object to the storage record of the revision table.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   *
   * @return \stdClass
   *   The record to store.
   */
  protected function mapToRevisionStorageRecord(ComplexDataInterface $entity) {
    $record = new \stdClass();
    $definitions = $entity
      ->getPropertyDefinitions();
    foreach (drupal_schema_fields_sql($this->entityInfo['revision_table']) as $name) {
      if (isset($definitions[$name]) && isset($entity->{$name}->value)) {
        $record->{$name} = $entity->{$name}->value;
      }
    }
    return $record;
  }

  /**
   * Maps from an entity object to the storage record of the data table.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   * @param $langcode
   *   The language code of the translation to get.
   *
   * @return \stdClass
   *   The record to store.
   */
  protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) {
    $default_langcode = $entity
      ->language()->langcode;

    // Don't use strict mode, this way there's no need to do checks here, as
    // non-translatable properties are replicated for each language.
    $translation = $entity
      ->getTranslation($langcode, FALSE);
    $definitions = $translation
      ->getPropertyDefinitions();
    $schema = drupal_get_schema($this->entityInfo['data_table']);
    $record = new \stdClass();
    foreach (drupal_schema_fields_sql($this->entityInfo['data_table']) as $name) {
      $info = $schema['fields'][$name];
      $value = isset($definitions[$name]) && isset($translation->{$name}->value) ? $translation->{$name}->value : NULL;
      $record->{$name} = drupal_schema_get_field_value($info, $value);
    }
    $record->langcode = $langcode;
    $record->default_langcode = intval($default_langcode == $langcode);
    return $record;
  }

  /**
   * Overwrites \Drupal\Core\Entity\DatabaseStorageController::delete().
   */
  public function delete(array $entities) {
    if (!$entities) {

      // If no IDs or invalid IDs were passed, do nothing.
      return;
    }
    $transaction = $this->database
      ->startTransaction();
    try {

      // Ensure we are dealing with the actual entities.
      foreach ($entities as $id => $entity) {
        $entities[$id] = $entity
          ->getNGEntity();
      }
      $this
        ->preDelete($entities);
      foreach ($entities as $id => $entity) {
        $this
          ->invokeHook('predelete', $entity);
      }
      $ids = array_keys($entities);
      $this->database
        ->delete($this->entityInfo['base_table'])
        ->condition($this->idKey, $ids)
        ->execute();
      if ($this->revisionKey) {
        $this->database
          ->delete($this->revisionTable)
          ->condition($this->idKey, $ids)
          ->execute();
      }
      if ($this->dataTable) {
        $this->database
          ->delete($this->dataTable)
          ->condition($this->idKey, $ids)
          ->execute();
      }

      // Reset the cache as soon as the changes have been applied.
      $this
        ->resetCache($ids);
      $this
        ->postDelete($entities);
      foreach ($entities as $id => $entity) {
        $this
          ->invokeHook('delete', $entity);
      }

      // Ignore slave server temporarily.
      db_ignore_slave();
    } catch (\Exception $e) {
      $transaction
        ->rollback();
      watchdog_exception($this->entityType, $e);
      throw new EntityStorageException($e
        ->getMessage(), $e
        ->getCode(), $e);
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DatabaseStorageController::$cache protected property Whether this entity type should use the static cache. Overrides EntityStorageControllerBase::$cache
DatabaseStorageController::$database protected property Active database connection.
DatabaseStorageController::$entityFieldInfo protected property An array of field information, i.e. containing definitions.
DatabaseStorageController::$fieldDefinitions protected property Static cache of field definitions per bundle.
DatabaseStorageController::$revisionKey protected property Name of entity's revision database table field, if it supports revisions.
DatabaseStorageController::$revisionTable protected property The table that stores revisions, if the entity supports revisions.
DatabaseStorageController::baseFieldDefinitions public function Defines the base properties of the entity type. 8
DatabaseStorageController::createInstance public static function Instantiates a new instance of this entity controller. Overrides EntityControllerInterface::createInstance 2
DatabaseStorageController::deleteRevision public function Implements \Drupal\Core\Entity\EntityStorageControllerInterface::deleteRevision(). Overrides EntityStorageControllerInterface::deleteRevision
DatabaseStorageController::getFieldDefinitions public function Implements \Drupal\Core\Entity\EntityStorageControllerInterface::getFieldDefinitions(). Overrides EntityStorageControllerInterface::getFieldDefinitions
DatabaseStorageController::getQueryServiceName public function Implements \Drupal\Core\Entity\EntityStorageControllerInterface::getQueryServiceName().
DatabaseStorageController::load public function Implements \Drupal\Core\Entity\EntityStorageControllerInterface::load(). Overrides EntityStorageControllerInterface::load
DatabaseStorageController::loadByProperties public function Implements \Drupal\Core\Entity\EntityStorageControllerInterface::loadByProperties(). Overrides EntityStorageControllerInterface::loadByProperties
DatabaseStorageController::loadRevision public function Implements \Drupal\Core\Entity\EntityStorageControllerInterface::loadRevision(). Overrides EntityStorageControllerInterface::loadRevision
DatabaseStorageController::postDelete protected function Acts on deleted entities before the delete hook is invoked. 6
DatabaseStorageController::postSave protected function Acts on a saved entity before the insert or update hook is invoked. 8
DatabaseStorageController::preDelete protected function Acts on entities before they are deleted. 5
DatabaseStorageController::preSave protected function Acts on an entity before the presave hook is invoked. 6
DatabaseStorageController::preSaveRevision protected function Act on a revision before being saved. 3
DatabaseStorageControllerNG::$bundleKey protected property The entity bundle key.
DatabaseStorageControllerNG::$dataTable protected property The table that stores properties, if the entity has multilingual support.
DatabaseStorageControllerNG::$entityClass protected property The entity class to use.
DatabaseStorageControllerNG::attachLoad protected function Overrides DatabaseStorageController::attachLoad(). Overrides DatabaseStorageController::attachLoad 6
DatabaseStorageControllerNG::attachPropertyData protected function Attaches property data in all languages for translatable properties.
DatabaseStorageControllerNG::buildPropertyQuery protected function Builds an entity query. Overrides DatabaseStorageController::buildPropertyQuery 1
DatabaseStorageControllerNG::buildQuery protected function Builds the query to load the entity. Overrides DatabaseStorageController::buildQuery 1
DatabaseStorageControllerNG::create public function Overrides DatabaseStorageController::create(). Overrides DatabaseStorageController::create 7
DatabaseStorageControllerNG::delete public function Overwrites \Drupal\Core\Entity\DatabaseStorageController::delete(). Overrides DatabaseStorageController::delete
DatabaseStorageControllerNG::invokeHook protected function Overrides DatabaseStorageController::invokeHook(). Overrides DatabaseStorageController::invokeHook 2
DatabaseStorageControllerNG::mapFromStorageRecords protected function Maps from storage records to entity objects.
DatabaseStorageControllerNG::mapToDataStorageRecord protected function Maps from an entity object to the storage record of the data table. 1
DatabaseStorageControllerNG::mapToRevisionStorageRecord protected function Maps from an entity object to the storage record of the revision table.
DatabaseStorageControllerNG::mapToStorageRecord protected function Maps from an entity object to the storage record of the base table.
DatabaseStorageControllerNG::save public function Overrides DatabaseStorageController::save(). Overrides DatabaseStorageController::save 1
DatabaseStorageControllerNG::savePropertyData protected function Stores the entity property language-aware data.
DatabaseStorageControllerNG::saveRevision protected function Saves an entity revision. Overrides DatabaseStorageController::saveRevision
DatabaseStorageControllerNG::__construct public function Overrides DatabaseStorageController::__construct(). Overrides DatabaseStorageController::__construct 1
EntityStorageControllerBase::$entityCache protected property Static cache of entities.
EntityStorageControllerBase::$entityInfo protected property Array of information about the entity.
EntityStorageControllerBase::$entityType protected property Entity type for this controller instance.
EntityStorageControllerBase::$hookLoadArguments protected property Additional arguments to pass to hook_TYPE_load().
EntityStorageControllerBase::$idKey protected property Name of the entity's ID field in the entity database table.
EntityStorageControllerBase::$uuidKey protected property Name of entity's UUID database table field, if it supports UUIDs. 1
EntityStorageControllerBase::cacheGet protected function Gets entities from the static cache.
EntityStorageControllerBase::cacheSet protected function Stores entities in the static entity cache.
EntityStorageControllerBase::loadUnchanged public function Loads an unchanged entity from the database. Overrides EntityStorageControllerInterface::loadUnchanged
EntityStorageControllerBase::resetCache public function Resets the internal, static entity cache. Overrides EntityStorageControllerInterface::resetCache 3
EntityStorageControllerInterface::getQueryServicename public function Gets the name of the service for the query for this entity storage. 1