Issue #1615236 by Berdir, aspilicious: Merge entity controller interfaces, document and add default entity class definition.
parent
c1f05ae409
commit
2bfb9b0415
|
@ -7,16 +7,16 @@
|
|||
|
||||
namespace Drupal\Core\File;
|
||||
|
||||
use Drupal\entity\EntityDatabaseStorageController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
use Drupal\entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* File storage controller for files.
|
||||
*/
|
||||
class FileStorageController extends EntityDatabaseStorageController {
|
||||
class FileStorageController extends DatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::create().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::create().
|
||||
*/
|
||||
public function create(array $values) {
|
||||
// Automatically detect filename if not set.
|
||||
|
@ -32,7 +32,7 @@ class FileStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::presave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::presave().
|
||||
*/
|
||||
protected function preSave(EntityInterface $entity) {
|
||||
$entity->timestamp = REQUEST_TIME;
|
||||
|
@ -47,7 +47,7 @@ class FileStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::preDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::preDelete().
|
||||
*/
|
||||
public function preDelete($entities) {
|
||||
foreach ($entities as $entity) {
|
||||
|
|
|
@ -8,18 +8,18 @@
|
|||
namespace Drupal\comment;
|
||||
|
||||
use Drupal\entity\EntityInterface;
|
||||
use Drupal\entity\EntityDatabaseStorageController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
|
||||
/**
|
||||
* Defines the controller class for comments.
|
||||
*
|
||||
* This extends the Drupal\entity\EntityDatabaseStorageController class, adding
|
||||
* This extends the Drupal\entity\DatabaseStorageController class, adding
|
||||
* required special handling for comment entities.
|
||||
*/
|
||||
class CommentStorageController extends EntityDatabaseStorageController {
|
||||
class CommentStorageController extends DatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::buildQuery().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::buildQuery().
|
||||
*/
|
||||
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
|
||||
$query = parent::buildQuery($ids, $conditions, $revision_id);
|
||||
|
@ -33,7 +33,7 @@ class CommentStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::attachLoad().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$comments, $revision_id = FALSE) {
|
||||
// Set up standard comment properties.
|
||||
|
@ -47,7 +47,7 @@ class CommentStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::preSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::preSave().
|
||||
*
|
||||
* @see comment_int_to_alphadecimal()
|
||||
* @see comment_increment_alphadecimal()
|
||||
|
@ -129,7 +129,7 @@ class CommentStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postSave().
|
||||
*/
|
||||
protected function postSave(EntityInterface $comment, $update) {
|
||||
// Update the {node_comment_statistics} table prior to executing the hook.
|
||||
|
@ -140,7 +140,7 @@ class CommentStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postDelete().
|
||||
*/
|
||||
protected function postDelete($comments) {
|
||||
// Delete the comments' replies.
|
||||
|
|
|
@ -21,20 +21,24 @@
|
|||
* An array whose keys are entity type names and whose values identify
|
||||
* properties of those types that the system needs to know about:
|
||||
* - label: The human-readable name of the type.
|
||||
* - entity class: The name of the entity class, defaults to
|
||||
* Drupal\entity\Entity. The entity class must implement EntityInterface.
|
||||
* - controller class: The name of the class that is used to load the objects.
|
||||
* The class has to implement the Drupal\entity\EntityControllerInterface
|
||||
* interface. Leave blank to use the Drupal\entity\EntityController
|
||||
* implementation.
|
||||
* - base table: (used by Drupal\entity\EntityController) The name of the
|
||||
* entity type's base table.
|
||||
* - static cache: (used by Drupal\entity\EntityController) FALSE to disable
|
||||
* static caching of entities during a page request. Defaults to TRUE.
|
||||
* The class has to implement the
|
||||
* Drupal\entity\EntityStorageControllerInterface interface. Leave blank
|
||||
* to use the Drupal\entity\DatabaseStorageController implementation.
|
||||
* - base table: (used by Drupal\entity\DatabaseStorageController) The
|
||||
* name of the entity type's base table.
|
||||
* - static cache: (used by Drupal\entity\DatabaseStorageController)
|
||||
* FALSE to disable static caching of entities during a page request.
|
||||
* Defaults to TRUE.
|
||||
* - field cache: (used by Field API loading and saving of field data) FALSE
|
||||
* to disable Field API's persistent cache of field data. Only recommended
|
||||
* if a higher level persistent cache is available for the entity type.
|
||||
* Defaults to TRUE.
|
||||
* - load hook: The name of the hook which should be invoked by
|
||||
* Drupal\entity\EntityController::attachLoad(), for example 'node_load'.
|
||||
* Drupal\entity\DatabaseStorageController::attachLoad(), for example
|
||||
* 'node_load'.
|
||||
* - uri callback: A function taking an entity as argument and returning the
|
||||
* uri elements of the entity, e.g. 'path' and 'options'. The actual entity
|
||||
* uri can be constructed by passing these elements to url().
|
||||
|
@ -131,7 +135,8 @@ function hook_entity_info() {
|
|||
$return = array(
|
||||
'node' => array(
|
||||
'label' => t('Node'),
|
||||
'controller class' => 'NodeController',
|
||||
'entity class' => 'Drupal\node\Node',
|
||||
'controller class' => 'Drupal\node\NodeStorageController',
|
||||
'base table' => 'node',
|
||||
'revision table' => 'node_revision',
|
||||
'uri callback' => 'node_uri',
|
||||
|
@ -211,8 +216,8 @@ function hook_entity_info() {
|
|||
*/
|
||||
function hook_entity_info_alter(&$entity_info) {
|
||||
// Set the controller class for nodes to an alternate implementation of the
|
||||
// Drupal\entity\EntityController interface.
|
||||
$entity_info['node']['controller class'] = 'Drupal\mymodule\MyCustomNodeController';
|
||||
// Drupal\entity\EntityStorageControllerInterface interface.
|
||||
$entity_info['node']['controller class'] = 'Drupal\mymodule\MyCustomNodeStorageController';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -68,7 +68,8 @@ function entity_get_info($entity_type = NULL) {
|
|||
foreach ($entity_info as $name => $data) {
|
||||
$entity_info[$name] += array(
|
||||
'fieldable' => FALSE,
|
||||
'controller class' => 'Drupal\entity\EntityController',
|
||||
'entity class' => 'Drupal\entity\Entity',
|
||||
'controller class' => 'Drupal\entity\DatabaseStorageController',
|
||||
'static cache' => TRUE,
|
||||
'field cache' => TRUE,
|
||||
'load hook' => $name . '_load',
|
||||
|
@ -92,7 +93,7 @@ function entity_get_info($entity_type = NULL) {
|
|||
$entity_info[$name]['bundles'] = array($name => array('label' => $entity_info[$name]['label']));
|
||||
}
|
||||
// Prepare entity schema fields SQL info for
|
||||
// Drupal\entity\EntityControllerInterface::buildQuery().
|
||||
// Drupal\entity\DatabaseStorageControllerInterface::buildQuery().
|
||||
if (isset($entity_info[$name]['base table'])) {
|
||||
$entity_info[$name]['schema_fields_sql']['base table'] = drupal_schema_fields_sql($entity_info[$name]['base table']);
|
||||
if (isset($entity_info[$name]['revision table'])) {
|
||||
|
@ -206,8 +207,8 @@ function entity_create_stub_entity($entity_type, $ids) {
|
|||
*
|
||||
* @see hook_entity_info()
|
||||
* @see entity_load_multiple()
|
||||
* @see Drupal\entity\EntityControllerInterface
|
||||
* @see Drupal\entity\EntityController
|
||||
* @see Drupal\entity\EntityStorageControllerInterface
|
||||
* @see Drupal\entity\DatabaseStorageController
|
||||
* @see Drupal\entity\EntityFieldQuery
|
||||
*/
|
||||
function entity_load($entity_type, $id, $reset = FALSE) {
|
||||
|
@ -223,13 +224,14 @@ function entity_load($entity_type, $id, $reset = FALSE) {
|
|||
* database access if loaded again during the same page request.
|
||||
*
|
||||
* The actual loading is done through a class that has to implement the
|
||||
* Drupal\entity\EntityControllerInterface interface. By default,
|
||||
* Drupal\entity\EntityController is used. Entity types can specify
|
||||
* that a different class should be used by setting the 'controller class' key
|
||||
* in hook_entity_info(). These classes can either implement the
|
||||
* Drupal\entity\EntityControllerInterface interface, or, most
|
||||
* commonly, extend the Drupal\entity\EntityController class. See
|
||||
* node_entity_info() and the NodeController in node.module as an example.
|
||||
* Drupal\entity\EntityStorageControllerInterface interface. By default,
|
||||
* Drupal\entity\DatabaseStorageController is used. Entity types can
|
||||
* specify that a different class should be used by setting the
|
||||
* 'controller class' key in hook_entity_info(). These classes can either
|
||||
* implement the Drupal\entity\EntityStorageControllerInterface interface, or,
|
||||
* most commonly, extend the Drupal\entity\DatabaseStorageController
|
||||
* class. See node_entity_info() and the NodeStorageController in node.module as
|
||||
* an example.
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type to load, e.g. node or user.
|
||||
|
@ -249,8 +251,8 @@ function entity_load($entity_type, $id, $reset = FALSE) {
|
|||
* @todo Remove $conditions in Drupal 8.
|
||||
*
|
||||
* @see hook_entity_info()
|
||||
* @see Drupal\entity\EntityControllerInterface
|
||||
* @see Drupal\entity\EntityController
|
||||
* @see Drupal\entity\EntityStorageControllerInterface
|
||||
* @see Drupal\entity\DatabaseStorageController
|
||||
* @see Drupal\entity\EntityFieldQuery
|
||||
*/
|
||||
function entity_load_multiple($entity_type, $ids = FALSE, $conditions = array(), $reset = FALSE) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\entity\EntityController.
|
||||
* Definition of Drupal\entity\DatabaseStorageController.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity;
|
||||
|
@ -12,12 +12,12 @@ use PDO;
|
|||
/**
|
||||
* Defines a base entity controller class.
|
||||
*
|
||||
* Default implementation of Drupal\entity\EntityControllerInterface.
|
||||
* Default implementation of Drupal\entity\DatabaseStorageControllerInterface.
|
||||
*
|
||||
* This class can be used as-is by most simple entity types. Entity types
|
||||
* requiring special handling can extend the class.
|
||||
*/
|
||||
class EntityController implements EntityControllerInterface {
|
||||
class DatabaseStorageController implements EntityStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Static cache of entities.
|
||||
|
@ -45,7 +45,7 @@ class EntityController implements EntityControllerInterface {
|
|||
/**
|
||||
* Additional arguments to pass to hook_TYPE_load().
|
||||
*
|
||||
* Set before calling Drupal\entity\EntityController::attachLoad().
|
||||
* Set before calling Drupal\entity\DatabaseStorageController::attachLoad().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
@ -84,7 +84,7 @@ class EntityController implements EntityControllerInterface {
|
|||
protected $cache;
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityController::__construct().
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::__construct().
|
||||
*
|
||||
* Sets basic variables.
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ class EntityController implements EntityControllerInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityControllerInterface::resetCache().
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::resetCache().
|
||||
*/
|
||||
public function resetCache(array $ids = NULL) {
|
||||
if (isset($ids)) {
|
||||
|
@ -123,7 +123,7 @@ class EntityController implements EntityControllerInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityControllerInterface::load().
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::load().
|
||||
*/
|
||||
public function load($ids = array(), $conditions = array()) {
|
||||
$entities = array();
|
||||
|
@ -356,4 +356,144 @@ class EntityController implements EntityControllerInterface {
|
|||
protected function cacheSet($entities) {
|
||||
$this->entityCache += $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::create().
|
||||
*/
|
||||
public function create(array $values) {
|
||||
$class = isset($this->entityInfo['entity class']) ? $this->entityInfo['entity class'] : 'Drupal\entity\Entity';
|
||||
return new $class($values, $this->entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::delete().
|
||||
*/
|
||||
public function delete($ids) {
|
||||
$entities = $ids ? $this->load($ids) : FALSE;
|
||||
if (!$entities) {
|
||||
// If no IDs or invalid IDs were passed, do nothing.
|
||||
return;
|
||||
}
|
||||
$transaction = db_transaction();
|
||||
|
||||
try {
|
||||
$this->preDelete($entities);
|
||||
foreach ($entities as $id => $entity) {
|
||||
$this->invokeHook('predelete', $entity);
|
||||
}
|
||||
$ids = array_keys($entities);
|
||||
|
||||
db_delete($this->entityInfo['base table'])
|
||||
->condition($this->idKey, $ids, 'IN')
|
||||
->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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::save().
|
||||
*/
|
||||
public function save(EntityInterface $entity) {
|
||||
$transaction = db_transaction();
|
||||
try {
|
||||
// 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);
|
||||
|
||||
if (!$entity->isNew()) {
|
||||
$return = drupal_write_record($this->entityInfo['base table'], $entity, $this->idKey);
|
||||
$this->resetCache(array($entity->{$this->idKey}));
|
||||
$this->postSave($entity, TRUE);
|
||||
$this->invokeHook('update', $entity);
|
||||
}
|
||||
else {
|
||||
$return = drupal_write_record($this->entityInfo['base table'], $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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acts on an entity before the presave hook is invoked.
|
||||
*
|
||||
* Used before the entity is saved and before invoking the presave hook.
|
||||
*/
|
||||
protected function preSave(EntityInterface $entity) { }
|
||||
|
||||
/**
|
||||
* Acts on a saved entity before the insert or update hook is invoked.
|
||||
*
|
||||
* Used after the entity is saved, but before invoking the insert or update
|
||||
* hook.
|
||||
*
|
||||
* @param $update
|
||||
* (bool) TRUE if the entity has been updated, or FALSE if it has been
|
||||
* inserted.
|
||||
*/
|
||||
protected function postSave(EntityInterface $entity, $update) { }
|
||||
|
||||
/**
|
||||
* Acts on entities before they are deleted.
|
||||
*
|
||||
* Used before the entities are deleted and before invoking the delete hook.
|
||||
*/
|
||||
protected function preDelete($entities) { }
|
||||
|
||||
/**
|
||||
* Acts on deleted entities before the delete hook is invoked.
|
||||
*
|
||||
* Used after the entities are deleted but before invoking the delete hook.
|
||||
*/
|
||||
protected function postDelete($entities) { }
|
||||
|
||||
/**
|
||||
* Invokes a hook on behalf of the entity.
|
||||
*
|
||||
* @param $hook
|
||||
* One of 'presave', 'insert', 'update', 'predelete', or 'delete'.
|
||||
* @param $entity
|
||||
* The entity object.
|
||||
*/
|
||||
protected function invokeHook($hook, EntityInterface $entity) {
|
||||
if (!empty($this->entityInfo['fieldable']) && function_exists($function = 'field_attach_' . $hook)) {
|
||||
$function($this->entityType, $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);
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\entity\EntityControllerInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity;
|
||||
|
||||
/**
|
||||
* Defines a common interface for entity controller classes.
|
||||
*
|
||||
* All entity controller classes specified via the 'controller class' key
|
||||
* returned by hook_entity_info() or hook_entity_info_alter() have to implement
|
||||
* this interface.
|
||||
*
|
||||
* Most simple, SQL-based entity controllers will do better by extending
|
||||
* Drupal\entity\EntityController instead of implementing this interface
|
||||
* directly.
|
||||
*/
|
||||
interface EntityControllerInterface {
|
||||
|
||||
/**
|
||||
* Constructs a new Drupal\entity\EntityControllerInterface object.
|
||||
*
|
||||
* @param $entityType
|
||||
* The entity type for which the instance is created.
|
||||
*/
|
||||
public function __construct($entityType);
|
||||
|
||||
/**
|
||||
* Resets the internal, static entity cache.
|
||||
*
|
||||
* @param $ids
|
||||
* (optional) If specified, the cache is reset for the entities with the
|
||||
* given ids only.
|
||||
*/
|
||||
public function resetCache(array $ids = NULL);
|
||||
|
||||
/**
|
||||
* Loads one or more entities.
|
||||
*
|
||||
* @param $ids
|
||||
* An array of entity IDs, or FALSE to load all entities.
|
||||
* @param $conditions
|
||||
* An array of conditions in the form 'field' => $value.
|
||||
*
|
||||
* @return
|
||||
* An array of entity objects indexed by their ids.
|
||||
*/
|
||||
public function load($ids = array(), $conditions = array());
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\entity\EntityDatabaseStorageController.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity;
|
||||
|
||||
/**
|
||||
* Implements the entity storage controller interface for the database.
|
||||
*/
|
||||
class EntityDatabaseStorageController extends EntityController implements EntityStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::create().
|
||||
*/
|
||||
public function create(array $values) {
|
||||
$class = isset($this->entityInfo['entity class']) ? $this->entityInfo['entity class'] : 'Drupal\entity\Entity';
|
||||
return new $class($values, $this->entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::delete().
|
||||
*/
|
||||
public function delete($ids) {
|
||||
$entities = $ids ? $this->load($ids) : FALSE;
|
||||
if (!$entities) {
|
||||
// If no IDs or invalid IDs were passed, do nothing.
|
||||
return;
|
||||
}
|
||||
$transaction = db_transaction();
|
||||
|
||||
try {
|
||||
$this->preDelete($entities);
|
||||
foreach ($entities as $id => $entity) {
|
||||
$this->invokeHook('predelete', $entity);
|
||||
}
|
||||
$ids = array_keys($entities);
|
||||
|
||||
db_delete($this->entityInfo['base table'])
|
||||
->condition($this->idKey, $ids, 'IN')
|
||||
->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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityStorageControllerInterface::save().
|
||||
*/
|
||||
public function save(EntityInterface $entity) {
|
||||
$transaction = db_transaction();
|
||||
try {
|
||||
// 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);
|
||||
|
||||
if (!$entity->isNew()) {
|
||||
$return = drupal_write_record($this->entityInfo['base table'], $entity, $this->idKey);
|
||||
$this->resetCache(array($entity->{$this->idKey}));
|
||||
$this->postSave($entity, TRUE);
|
||||
$this->invokeHook('update', $entity);
|
||||
}
|
||||
else {
|
||||
$return = drupal_write_record($this->entityInfo['base table'], $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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acts on an entity before the presave hook is invoked.
|
||||
*
|
||||
* Used before the entity is saved and before invoking the presave hook.
|
||||
*/
|
||||
protected function preSave(EntityInterface $entity) { }
|
||||
|
||||
/**
|
||||
* Acts on a saved entity before the insert or update hook is invoked.
|
||||
*
|
||||
* Used after the entity is saved, but before invoking the insert or update
|
||||
* hook.
|
||||
*
|
||||
* @param $update
|
||||
* (bool) TRUE if the entity has been updated, or FALSE if it has been
|
||||
* inserted.
|
||||
*/
|
||||
protected function postSave(EntityInterface $entity, $update) { }
|
||||
|
||||
/**
|
||||
* Acts on entities before they are deleted.
|
||||
*
|
||||
* Used before the entities are deleted and before invoking the delete hook.
|
||||
*/
|
||||
protected function preDelete($entities) { }
|
||||
|
||||
/**
|
||||
* Acts on deleted entities before the delete hook is invoked.
|
||||
*
|
||||
* Used after the entities are deleted but before invoking the delete hook.
|
||||
*/
|
||||
protected function postDelete($entities) { }
|
||||
|
||||
/**
|
||||
* Invokes a hook on behalf of the entity.
|
||||
*
|
||||
* @param $hook
|
||||
* One of 'presave', 'insert', 'update', 'predelete', or 'delete'.
|
||||
* @param $entity
|
||||
* The entity object.
|
||||
*/
|
||||
protected function invokeHook($hook, EntityInterface $entity) {
|
||||
if (!empty($this->entityInfo['fieldable']) && function_exists($function = 'field_attach_' . $hook)) {
|
||||
$function($this->entityType, $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);
|
||||
}
|
||||
}
|
|
@ -8,9 +8,47 @@
|
|||
namespace Drupal\entity;
|
||||
|
||||
/**
|
||||
* Defines a common interface for entity storage controllers.
|
||||
* Defines a common interface for entity controller classes.
|
||||
*
|
||||
* All entity controller classes specified via the 'controller class' key
|
||||
* returned by hook_entity_info() or hook_entity_info_alter() have to implement
|
||||
* this interface.
|
||||
*
|
||||
* Most simple, SQL-based entity controllers will do better by extending
|
||||
* Drupal\entity\DatabaseStorageController instead of implementing this
|
||||
* interface directly.
|
||||
*/
|
||||
interface EntityStorageControllerInterface extends EntityControllerInterface {
|
||||
interface EntityStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Constructs a new Drupal\entity\EntityStorageControllerInterface object.
|
||||
*
|
||||
* @param $entityType
|
||||
* The entity type for which the instance is created.
|
||||
*/
|
||||
public function __construct($entityType);
|
||||
|
||||
/**
|
||||
* Resets the internal, static entity cache.
|
||||
*
|
||||
* @param $ids
|
||||
* (optional) If specified, the cache is reset for the entities with the
|
||||
* given ids only.
|
||||
*/
|
||||
public function resetCache(array $ids = NULL);
|
||||
|
||||
/**
|
||||
* Loads one or more entities.
|
||||
*
|
||||
* @param $ids
|
||||
* An array of entity IDs, or FALSE to load all entities.
|
||||
* @param $conditions
|
||||
* An array of conditions in the form 'field' => $value.
|
||||
*
|
||||
* @return
|
||||
* An array of entity objects indexed by their ids.
|
||||
*/
|
||||
public function load($ids = array(), $conditions = array());
|
||||
|
||||
/**
|
||||
* Constructs a new entity object, without permanently saving it.
|
||||
|
|
|
@ -52,6 +52,6 @@ class EntityApiInfoTest extends WebTestBase {
|
|||
module_enable(array('entity_cache_test'));
|
||||
$info = variable_get('entity_cache_test');
|
||||
$this->assertEqual($info['label'], 'Entity Cache Test', 'Entity info label is correct.');
|
||||
$this->assertEqual($info['controller class'], 'Drupal\entity\EntityController', 'Entity controller class info is correct.');
|
||||
$this->assertEqual($info['controller class'], 'Drupal\entity\DatabaseStorageController', 'Entity controller class info is correct.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ function entity_test_entity_info() {
|
|||
$items['entity_test'] = array(
|
||||
'label' => t('Test entity'),
|
||||
'entity class' => 'Drupal\entity\Entity',
|
||||
'controller class' => 'Drupal\entity\EntityDatabaseStorageController',
|
||||
'controller class' => 'Drupal\entity\DatabaseStorageController',
|
||||
'base table' => 'entity_test',
|
||||
'fieldable' => TRUE,
|
||||
'entity keys' => array(
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
|
||||
namespace Drupal\field_test;
|
||||
|
||||
use Drupal\entity\EntityController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
|
||||
/**
|
||||
* Controller class for the test_entity_bundle entity type.
|
||||
*
|
||||
* This extends the Drupal\entity\EntityController class, adding
|
||||
* This extends the Drupal\entity\DatabaseStorageController class, adding
|
||||
* required special handling for bundles (since they are not stored in the
|
||||
* database).
|
||||
*/
|
||||
class TestEntityBundleController extends EntityController {
|
||||
class TestEntityBundleController extends DatabaseStorageController {
|
||||
|
||||
protected function attachLoad(&$entities, $revision_id = FALSE) {
|
||||
// Add bundle information.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\entity\EntityDatabaseStorageController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
use Drupal\entity\EntityInterface;
|
||||
use Drupal\entity\EntityStorageException;
|
||||
use Exception;
|
||||
|
@ -15,13 +15,13 @@ use Exception;
|
|||
/**
|
||||
* Controller class for nodes.
|
||||
*
|
||||
* This extends the Drupal\entity\EntityDatabaseStorageController class, adding
|
||||
* This extends the Drupal\entity\DatabaseStorageController class, adding
|
||||
* required special handling for node entities.
|
||||
*/
|
||||
class NodeStorageController extends EntityDatabaseStorageController {
|
||||
class NodeStorageController extends DatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::create().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::create().
|
||||
*/
|
||||
public function create(array $values) {
|
||||
$node = parent::create($values);
|
||||
|
@ -35,7 +35,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::delete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::delete().
|
||||
*/
|
||||
public function delete($ids) {
|
||||
$entities = $ids ? $this->load($ids) : FALSE;
|
||||
|
@ -80,7 +80,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::save().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::save().
|
||||
*/
|
||||
public function save(EntityInterface $entity) {
|
||||
$transaction = db_transaction();
|
||||
|
@ -152,7 +152,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityController::attachLoad().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$nodes, $revision_id = FALSE) {
|
||||
// Create an array of nodes for each content type and pass this to the
|
||||
|
@ -177,7 +177,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityController::buildQuery().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::buildQuery().
|
||||
*/
|
||||
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
|
||||
// Ensure that uid is taken from the {node} table,
|
||||
|
@ -192,7 +192,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::invokeHook().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::invokeHook().
|
||||
*/
|
||||
protected function invokeHook($hook, EntityInterface $node) {
|
||||
if ($hook == 'insert' || $hook == 'update') {
|
||||
|
@ -241,7 +241,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::preSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::preSave().
|
||||
*/
|
||||
protected function preSave(EntityInterface $node) {
|
||||
// Before saving the node, set changed and revision times.
|
||||
|
@ -257,14 +257,14 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postSave().
|
||||
*/
|
||||
function postSave(EntityInterface $node, $update) {
|
||||
node_access_acquire_grants($node, $update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::preDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::preDelete().
|
||||
*/
|
||||
function preDelete($entities) {
|
||||
if (module_exists('search')) {
|
||||
|
@ -275,7 +275,7 @@ class NodeStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postDelete().
|
||||
*/
|
||||
protected function postDelete($nodes) {
|
||||
// Delete values from other tables also referencing this node.
|
||||
|
|
|
@ -529,7 +529,7 @@ function hook_node_insert(Drupal\node\Node $node) {
|
|||
* Act on nodes being loaded from the database.
|
||||
*
|
||||
* This hook is invoked during node loading, which is handled by entity_load(),
|
||||
* via classes NodeController and Drupal\entity\EntityController.
|
||||
* via classes NodeController and Drupal\entity\DatabaseStorageController.
|
||||
* After the node information is read from the database or the entity cache,
|
||||
* hook_load() is invoked on the node's content type module, then
|
||||
* field_attach_node_revision() or field_attach_load() is called, then
|
||||
|
@ -1158,7 +1158,7 @@ function hook_insert(Drupal\node\Node $node) {
|
|||
* (use hook_node_load() to respond to all node loads).
|
||||
*
|
||||
* This hook is invoked during node loading, which is handled by entity_load(),
|
||||
* via classes NodeController and Drupal\entity\EntityController.
|
||||
* via classes NodeController and Drupal\entity\DatabaseStorageController.
|
||||
* After the node information is read from the database or the entity cache,
|
||||
* hook_load() is invoked on the node's content type module, then
|
||||
* field_attach_node_revision() or field_attach_load() is called, then
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
namespace Drupal\taxonomy;
|
||||
|
||||
use Drupal\entity\EntityInterface;
|
||||
use Drupal\entity\EntityDatabaseStorageController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
|
||||
/**
|
||||
* Defines a Controller class for taxonomy terms.
|
||||
*/
|
||||
class TermStorageController extends EntityDatabaseStorageController {
|
||||
class TermStorageController extends DatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::create().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::create().
|
||||
*
|
||||
* @param array $values
|
||||
* An array of values to set, keyed by property name. A value for the
|
||||
|
@ -40,7 +40,7 @@ class TermStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::buildQuery().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::buildQuery().
|
||||
*/
|
||||
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
|
||||
$query = parent::buildQuery($ids, $conditions, $revision_id);
|
||||
|
@ -63,7 +63,7 @@ class TermStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::cacheGet().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::cacheGet().
|
||||
*/
|
||||
protected function cacheGet($ids, $conditions = array()) {
|
||||
$terms = parent::cacheGet($ids, $conditions);
|
||||
|
@ -78,7 +78,7 @@ class TermStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postDelete().
|
||||
*/
|
||||
protected function postDelete($entities) {
|
||||
// See if any of the term's children are about to be become orphans.
|
||||
|
@ -109,7 +109,7 @@ class TermStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postSave().
|
||||
*/
|
||||
protected function postSave(EntityInterface $entity, $update) {
|
||||
if (isset($entity->parent)) {
|
||||
|
@ -131,7 +131,7 @@ class TermStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\EntityControllerInterface::resetCache().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::resetCache().
|
||||
*/
|
||||
public function resetCache(array $ids = NULL) {
|
||||
drupal_static_reset('taxonomy_term_count_nodes');
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
namespace Drupal\taxonomy;
|
||||
|
||||
use Drupal\entity\EntityInterface;
|
||||
use Drupal\entity\EntityDatabaseStorageController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
|
||||
/**
|
||||
* Defines a controller class for taxonomy vocabularies.
|
||||
*/
|
||||
class VocabularyStorageController extends EntityDatabaseStorageController {
|
||||
class VocabularyStorageController extends DatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::buildQuery().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::buildQuery().
|
||||
*/
|
||||
protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
|
||||
$query = parent::buildQuery($ids, $conditions, $revision_id);
|
||||
|
@ -27,7 +27,7 @@ class VocabularyStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postSave().
|
||||
*/
|
||||
protected function postSave(EntityInterface $entity, $update) {
|
||||
if (!$update) {
|
||||
|
@ -39,7 +39,7 @@ class VocabularyStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::preDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::preDelete().
|
||||
*/
|
||||
protected function preDelete($entities) {
|
||||
// Only load terms without a parent, child terms will get deleted too.
|
||||
|
@ -48,7 +48,7 @@ class VocabularyStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postDelete().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postDelete().
|
||||
*/
|
||||
protected function postDelete($entities) {
|
||||
// Load all Taxonomy module fields and delete those which use only this
|
||||
|
@ -79,7 +79,7 @@ class VocabularyStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\entity\DrupalEntityControllerInterface::resetCache().
|
||||
* Overrides Drupal\entity\DrupalDatabaseStorageController::resetCache().
|
||||
*/
|
||||
public function resetCache(array $ids = NULL) {
|
||||
drupal_static_reset('taxonomy_vocabulary_get_names');
|
||||
|
|
|
@ -9,18 +9,18 @@ namespace Drupal\user;
|
|||
|
||||
use Drupal\entity\EntityInterface;
|
||||
use Drupal\entity\EntityMalformedException;
|
||||
use Drupal\entity\EntityDatabaseStorageController;
|
||||
use Drupal\entity\DatabaseStorageController;
|
||||
|
||||
/**
|
||||
* Controller class for users.
|
||||
*
|
||||
* This extends the Drupal\entity\EntityDatabaseStorageController class, adding
|
||||
* This extends the Drupal\entity\DatabaseStorageController class, adding
|
||||
* required special handling for user objects.
|
||||
*/
|
||||
class UserStorageController extends EntityDatabaseStorageController {
|
||||
class UserStorageController extends DatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::attachLoad().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::attachLoad().
|
||||
*/
|
||||
function attachLoad(&$queried_users, $revision_id = FALSE) {
|
||||
// Build an array of user picture IDs so that these can be fetched later.
|
||||
|
@ -60,7 +60,7 @@ class UserStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::create().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::create().
|
||||
*/
|
||||
public function create(array $values) {
|
||||
if (!isset($values['created'])) {
|
||||
|
@ -73,7 +73,7 @@ class UserStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::save().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::save().
|
||||
*/
|
||||
public function save(EntityInterface $entity) {
|
||||
if (empty($entity->uid)) {
|
||||
|
@ -84,7 +84,7 @@ class UserStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::preSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::preSave().
|
||||
*/
|
||||
protected function preSave(EntityInterface $entity) {
|
||||
// Update the user password if it has changed.
|
||||
|
@ -158,7 +158,7 @@ class UserStorageController extends EntityDatabaseStorageController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\EntityDatabaseStorageController::postSave().
|
||||
* Overrides Drupal\entity\DatabaseStorageController::postSave().
|
||||
*/
|
||||
protected function postSave(EntityInterface $entity, $update) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue