Issue #2095283 by Berdir, chx, amateescu, vladan.me: Remove non-storage logic from the storage controllers.
parent
f392d38ee8
commit
65be82a128
|
@ -141,11 +141,11 @@ class ConfigStorageController extends EntityStorageControllerBase {
|
|||
$queried_entities = $this->buildQuery($ids);
|
||||
}
|
||||
|
||||
// Pass all entities loaded from the database through $this->attachLoad(),
|
||||
// Pass all entities loaded from the database through $this->postLoad(),
|
||||
// which calls the
|
||||
// entity type specific load callback, for example hook_node_type_load().
|
||||
if (!empty($queried_entities)) {
|
||||
$this->attachLoad($queried_entities);
|
||||
$this->postLoad($queried_entities);
|
||||
$entities += $queried_entities;
|
||||
}
|
||||
|
||||
|
@ -285,38 +285,6 @@ class ConfigStorageController extends EntityStorageControllerBase {
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches data to entities upon loading.
|
||||
*
|
||||
* This will attach fields, if the entity is fieldable. It calls
|
||||
* hook_entity_load() for modules which need to add data to all entities.
|
||||
* It also calls hook_TYPE_load() on the loaded entities. For example
|
||||
* hook_node_load() or hook_user_load(). If your hook_TYPE_load()
|
||||
* expects special parameters apart from the queried entities, you can set
|
||||
* $this->hookLoadArguments prior to calling the method.
|
||||
* See Drupal\node\NodeStorageController::attachLoad() for an example.
|
||||
*
|
||||
* @param $queried_entities
|
||||
* Associative array of query results, keyed on the entity ID.
|
||||
* @param $revision_id
|
||||
* ID of the revision that was loaded, or FALSE if the most current revision
|
||||
* was loaded.
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
|
||||
// Call hook_entity_load().
|
||||
foreach (\Drupal::moduleHandler()->getImplementations('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 (\Drupal::moduleHandler()->getImplementations($this->entityType . '_load') as $module) {
|
||||
call_user_func_array($module . '_' . $this->entityType . '_load', $args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Drupal\Core\Entity\EntityStorageControllerInterface::create().
|
||||
*/
|
||||
|
|
|
@ -142,11 +142,11 @@ class DatabaseStorageController extends EntityStorageControllerBase {
|
|||
$queried_entities = $query_result->fetchAllAssoc($this->idKey);
|
||||
}
|
||||
|
||||
// Pass all entities loaded from the database through $this->attachLoad(),
|
||||
// Pass all entities loaded from the database through $this->postLoad(),
|
||||
// which attaches fields (if supported by the entity type) and calls the
|
||||
// entity type specific load callback, for example hook_node_load().
|
||||
if (!empty($queried_entities)) {
|
||||
$this->attachLoad($queried_entities);
|
||||
$this->postLoad($queried_entities);
|
||||
$entities += $queried_entities;
|
||||
}
|
||||
|
||||
|
@ -244,22 +244,6 @@ class DatabaseStorageController extends EntityStorageControllerBase {
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches data to entities upon loading.
|
||||
*
|
||||
* @param $queried_entities
|
||||
* Associative array of query results, keyed on the entity ID.
|
||||
* @param $load_revision
|
||||
* (optional) TRUE if the revision should be loaded, defaults to FALSE.
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
|
||||
// Call hook_entity_load().
|
||||
foreach (\Drupal::moduleHandler()->getImplementations('entity_load') as $module) {
|
||||
$function = $module . '_entity_load';
|
||||
$function($queried_entities, $this->entityType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -356,7 +356,7 @@ abstract class Entity implements EntityInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array $entities) {
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -207,14 +207,14 @@ interface EntityInterface extends AccessibleInterface {
|
|||
public static function postDelete(EntityStorageControllerInterface $storage_controller, array $entities);
|
||||
|
||||
/**
|
||||
* Acts on loaded entities before the load hook is invoked.
|
||||
* Acts on loaded entities.
|
||||
*
|
||||
* @param EntityStorageControllerInterface $storage_controller
|
||||
* The entity storage controller object.
|
||||
* @param array $entities
|
||||
* An array of entities.
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array $entities);
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities);
|
||||
|
||||
/**
|
||||
* Creates a duplicate of the entity.
|
||||
|
|
|
@ -44,15 +44,6 @@ abstract class EntityStorageControllerBase implements EntityStorageControllerInt
|
|||
*/
|
||||
protected $entityInfo;
|
||||
|
||||
/**
|
||||
* Additional arguments to pass to hook_TYPE_load().
|
||||
*
|
||||
* Set before calling Drupal\Core\Entity\DatabaseStorageController::attachLoad().
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hookLoadArguments = array();
|
||||
|
||||
/**
|
||||
* Name of the entity's ID field in the entity database table.
|
||||
*
|
||||
|
@ -84,6 +75,20 @@ abstract class EntityStorageControllerBase implements EntityStorageControllerInt
|
|||
$this->cache = !empty($this->entityInfo['static_cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityType() {
|
||||
return $this->entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityInfo() {
|
||||
return $this->entityInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -152,4 +157,25 @@ abstract class EntityStorageControllerBase implements EntityStorageControllerInt
|
|||
module_invoke_all('entity_' . $hook, $entity, $this->entityType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches data to entities upon loading.
|
||||
*
|
||||
* @param array $queried_entities
|
||||
* Associative array of query results, keyed on the entity ID.
|
||||
*/
|
||||
protected function postLoad(array &$queried_entities) {
|
||||
$entity_class = $this->entityInfo['class'];
|
||||
$entity_class::postLoad($this, $queried_entities);
|
||||
// Call hook_entity_load().
|
||||
foreach (\Drupal::moduleHandler()->getImplementations('entity_load') as $module) {
|
||||
$function = $module . '_entity_load';
|
||||
$function($queried_entities, $this->entityType);
|
||||
}
|
||||
// Call hook_TYPE_load().
|
||||
foreach (\Drupal::moduleHandler()->getImplementations($this->entityType . '_load') as $module) {
|
||||
$function = $module . '_' . $this->entityType . '_load';
|
||||
$function($queried_entities);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -150,7 +150,24 @@ interface EntityStorageControllerInterface {
|
|||
* Gets the name of the service for the query for this entity storage.
|
||||
*
|
||||
* @return string
|
||||
* The name of the service for the query for this entity storage.
|
||||
*/
|
||||
public function getQueryServicename();
|
||||
|
||||
/**
|
||||
* Returns the entity type.
|
||||
*
|
||||
* @return string
|
||||
* The entity type.
|
||||
*/
|
||||
public function entityType();
|
||||
|
||||
/**
|
||||
* Returns the entity info.
|
||||
*
|
||||
* @return string
|
||||
* The entity info.
|
||||
*/
|
||||
public function entityInfo();
|
||||
|
||||
}
|
||||
|
|
|
@ -229,11 +229,11 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
$queried_entities = $query_result->fetchAllAssoc($this->idKey);
|
||||
}
|
||||
|
||||
// Pass all entities loaded from the database through $this->attachLoad(),
|
||||
// Pass all entities loaded from the database through $this->postLoad(),
|
||||
// which attaches fields (if supported by the entity type) and calls the
|
||||
// entity type specific load callback, for example hook_node_load().
|
||||
if (!empty($queried_entities)) {
|
||||
$this->attachLoad($queried_entities);
|
||||
$this->postLoad($queried_entities);
|
||||
$entities += $queried_entities;
|
||||
}
|
||||
|
||||
|
@ -271,13 +271,11 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
*
|
||||
* @param array $records
|
||||
* Associative array of query results, keyed on the entity ID.
|
||||
* @param bool $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) {
|
||||
protected function mapFromStorageRecords(array $records) {
|
||||
$entities = array();
|
||||
foreach ($records as $id => $record) {
|
||||
$entities[$id] = array();
|
||||
|
@ -305,7 +303,7 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
$entities[$id] = new $this->entityClass($entities[$id], $this->entityType, $bundle);
|
||||
}
|
||||
}
|
||||
$this->attachPropertyData($entities, $load_revision);
|
||||
$this->attachPropertyData($entities);
|
||||
return $entities;
|
||||
}
|
||||
|
||||
|
@ -314,10 +312,8 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
*
|
||||
* @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) {
|
||||
protected function attachPropertyData(array &$entities) {
|
||||
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.
|
||||
|
@ -328,17 +324,12 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
->orderBy('data.' . $this->idKey);
|
||||
|
||||
if ($this->revisionDataTable) {
|
||||
if ($revision_id) {
|
||||
$query->condition($this->revisionKey, $revision_id);
|
||||
}
|
||||
else {
|
||||
// Get the revision IDs.
|
||||
$revision_ids = array();
|
||||
foreach ($entities as $values) {
|
||||
$revision_ids[] = $values[$this->revisionKey][Language::LANGCODE_DEFAULT];
|
||||
}
|
||||
$query->condition($this->revisionKey, $revision_ids);
|
||||
// Get the revision IDs.
|
||||
$revision_ids = array();
|
||||
foreach ($entities as $values) {
|
||||
$revision_ids[] = is_object($values) ? $values->getRevisionId() : $values[$this->revisionKey][Language::LANGCODE_DEFAULT];
|
||||
}
|
||||
$query->condition($this->revisionKey, $revision_ids);
|
||||
}
|
||||
|
||||
$data = $query->execute();
|
||||
|
@ -397,11 +388,11 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
$query_result = $this->buildQuery(array(), $revision_id)->execute();
|
||||
$queried_entities = $query_result->fetchAllAssoc($this->idKey);
|
||||
|
||||
// Pass the loaded entities from the database through $this->attachLoad(),
|
||||
// Pass the loaded entities from the database through $this->postLoad(),
|
||||
// which attaches fields (if supported by the entity type) and calls the
|
||||
// entity type specific load callback, for example hook_node_load().
|
||||
if (!empty($queried_entities)) {
|
||||
$this->attachLoad($queried_entities, $revision_id);
|
||||
$this->postLoad($queried_entities);
|
||||
}
|
||||
return reset($queried_entities);
|
||||
}
|
||||
|
@ -544,30 +535,17 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
*
|
||||
* @param $queried_entities
|
||||
* Associative array of query results, keyed on the entity ID.
|
||||
* @param $load_revision
|
||||
* (optional) TRUE if the revision should be loaded, defaults to FALSE.
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
|
||||
protected function postLoad(array &$queried_entities) {
|
||||
// Map the loaded records into entity objects and according fields.
|
||||
$queried_entities = $this->mapFromStorageRecords($queried_entities, $load_revision);
|
||||
$queried_entities = $this->mapFromStorageRecords($queried_entities);
|
||||
|
||||
// Attach field values.
|
||||
if ($this->entityInfo['fieldable']) {
|
||||
$this->loadFieldItems($queried_entities, $load_revision ? static::FIELD_LOAD_REVISION : static::FIELD_LOAD_CURRENT);
|
||||
$this->loadFieldItems($queried_entities);
|
||||
}
|
||||
|
||||
// Call hook_entity_load().
|
||||
foreach (\Drupal::moduleHandler()->getImplementations('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 (\Drupal::moduleHandler()->getImplementations($this->entityType . '_load') as $module) {
|
||||
call_user_func_array($module . '_' . $this->entityType . '_load', $args);
|
||||
}
|
||||
parent::postLoad($queried_entities);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,17 +27,20 @@ abstract class FieldableEntityStorageControllerBase extends EntityStorageControl
|
|||
*
|
||||
* @param array $entities
|
||||
* An array of entities keyed by entity ID.
|
||||
* @param int $age
|
||||
* EntityStorageControllerInterface::FIELD_LOAD_CURRENT to load the most
|
||||
* recent revision for all fields, or
|
||||
* EntityStorageControllerInterface::FIELD_LOAD_REVISION to load the version
|
||||
* indicated by each entity.
|
||||
*/
|
||||
protected function loadFieldItems(array $entities, $age) {
|
||||
protected function loadFieldItems(array $entities) {
|
||||
if (empty($entities)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$age = static::FIELD_LOAD_CURRENT;
|
||||
foreach ($entities as $entity) {
|
||||
if (!$entity->isDefaultRevision()) {
|
||||
$age = static::FIELD_LOAD_REVISION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only the most current revision of non-deleted fields for cacheable entity
|
||||
// types can be cached.
|
||||
$load_current = $age == static::FIELD_LOAD_CURRENT;
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\custom_block\CustomBlockStorageController.
|
||||
*/
|
||||
|
||||
namespace Drupal\custom_block;
|
||||
|
||||
use Drupal\Core\Entity\FieldableDatabaseStorageController;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
|
||||
/**
|
||||
* Controller class for custom blocks.
|
||||
*
|
||||
* This extends the Drupal\Core\Entity\DatabaseStorageController class,
|
||||
* adding required special handling for custom block entities.
|
||||
*/
|
||||
class CustomBlockStorageController extends FieldableDatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Entity\DatabaseStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$blocks, $load_revision = FALSE) {
|
||||
// Create an array of block types for passing as a load argument.
|
||||
// Note that blocks at this point are still \StdClass objects returned from
|
||||
// the database.
|
||||
foreach ($blocks as $entity) {
|
||||
$types[$entity->type] = $entity->type;
|
||||
}
|
||||
|
||||
// Besides the list of blocks, pass one additional argument to
|
||||
// hook_custom_block_load(), containing a list of block types that were
|
||||
// loaded.
|
||||
$this->hookLoadArguments = array($types);
|
||||
parent::attachLoad($blocks, $load_revision);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@ use Drupal\custom_block\CustomBlockInterface;
|
|||
* label = @Translation("Custom Block"),
|
||||
* bundle_label = @Translation("Custom Block type"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\custom_block\CustomBlockStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "access" = "Drupal\custom_block\CustomBlockAccessController",
|
||||
* "list" = "Drupal\custom_block\CustomBlockListController",
|
||||
* "view_builder" = "Drupal\custom_block\CustomBlockViewBuilder",
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\custom_block\Tests\CustomBlockLoadHooksTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\custom_block\Tests;
|
||||
|
||||
/**
|
||||
* Tests for the hooks invoked during custom_block_load().
|
||||
*/
|
||||
class CustomBlockLoadHooksTest extends CustomBlockTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('custom_block_test');
|
||||
|
||||
/**
|
||||
* Declares test information.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Custom Block load hooks',
|
||||
'description' => 'Test the hooks invoked when a custom block is being loaded.',
|
||||
'group' => 'Custom Block',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that hook_custom_block_load() is invoked correctly.
|
||||
*/
|
||||
public function testHookCustomBlockLoad() {
|
||||
$other_bundle = $this->createCustomBlockType('other');
|
||||
// Create some sample articles and pages.
|
||||
$custom_block1 = $this->createCustomBlock();
|
||||
$custom_block2 = $this->createCustomBlock();
|
||||
$custom_block3 = $this->createCustomBlock();
|
||||
$custom_block4 = $this->createCustomBlock(FALSE, $other_bundle->id());
|
||||
|
||||
// Check that when a set of custom blocks that only contains basic blocks is
|
||||
// loaded, the properties added to the custom block by
|
||||
// custom_block_test_load_custom_block() correctly reflect the expected
|
||||
// values.
|
||||
$custom_blocks = entity_load_multiple_by_properties('custom_block', array('type' => 'basic'));
|
||||
$loaded_custom_block = end($custom_blocks);
|
||||
$this->assertEqual($loaded_custom_block->custom_block_test_loaded_ids, array(
|
||||
$custom_block1->id(),
|
||||
$custom_block2->id(),
|
||||
$custom_block3->id(),
|
||||
), 'hook_custom_block_load() received the correct list of custom_block IDs the first time it was called.');
|
||||
$this->assertEqual($loaded_custom_block->custom_block_test_loaded_types, array('basic'), 'hook_custom_block_load() received the correct list of custom block types the first time it was called.');
|
||||
|
||||
// Now, as part of the same page request, load a set of custom_blocks that contain
|
||||
// both basic and other bundle, and make sure the parameters passed to
|
||||
// custom_block_test_custom_block_load() are correctly updated.
|
||||
$custom_blocks = entity_load_multiple('custom_block', \Drupal::entityQuery('custom_block')->execute(), TRUE);
|
||||
$loaded_custom_block = end($custom_blocks);
|
||||
$this->assertEqual($loaded_custom_block->custom_block_test_loaded_ids, array(
|
||||
$custom_block1->id(),
|
||||
$custom_block2->id(),
|
||||
$custom_block3->id(),
|
||||
$custom_block4->id(),
|
||||
), 'hook_custom_block_load() received the correct list of custom_block IDs the second time it was called.');
|
||||
$this->assertEqual($loaded_custom_block->custom_block_test_loaded_types, array('basic', 'other'), 'hook_custom_block_load() received the correct list of custom_block types the second time it was called.');
|
||||
}
|
||||
}
|
|
@ -10,22 +10,6 @@
|
|||
|
||||
use Drupal\custom_block\Entity\CustomBlock;
|
||||
|
||||
/**
|
||||
* Implements hook_custom_block_load().
|
||||
*/
|
||||
function custom_block_test_custom_block_load($custom_blocks, $types) {
|
||||
// Add properties to each loaded custom_block which record the parameters that
|
||||
// were passed in to this function, so the tests can check that (a) this hook
|
||||
// was called, and (b) the parameters were what we expected them to be.
|
||||
$ids = array_keys($custom_blocks);
|
||||
ksort($ids);
|
||||
sort($types);
|
||||
foreach ($custom_blocks as $custom_block) {
|
||||
$custom_block->custom_block_test_loaded_ids = $ids;
|
||||
$custom_block->custom_block_test_loaded_types = $types;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_custom_block_view().
|
||||
*/
|
||||
|
|
|
@ -435,7 +435,7 @@ function book_children($book_link) {
|
|||
/**
|
||||
* Implements hook_node_load().
|
||||
*/
|
||||
function book_node_load($nodes, $types) {
|
||||
function book_node_load($nodes) {
|
||||
$result = db_query("SELECT * FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid IN (:nids)", array(':nids' => array_keys($nodes)), array('fetch' => PDO::FETCH_ASSOC));
|
||||
foreach ($result as $record) {
|
||||
$nodes[$record['nid']]->book = $record;
|
||||
|
|
|
@ -39,12 +39,12 @@ class CommentStorageController extends FieldableDatabaseStorageController implem
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function attachLoad(&$records, $load_revision = FALSE) {
|
||||
protected function postLoad(array &$queried_entities) {
|
||||
// Prepare standard comment fields.
|
||||
foreach ($records as &$record) {
|
||||
foreach ($queried_entities as &$record) {
|
||||
$record->name = $record->uid ? $record->registered_name : $record->name;
|
||||
}
|
||||
parent::attachLoad($records, $load_revision);
|
||||
parent::postLoad($queried_entities);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -575,6 +575,42 @@ class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
|
|||
_menu_clear_page_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc}
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
|
||||
parent::postLoad($storage_controller, $entities);
|
||||
|
||||
$routes = array();
|
||||
foreach ($entities as $menu_link) {
|
||||
$menu_link->options = unserialize($menu_link->options);
|
||||
$menu_link->route_parameters = unserialize($menu_link->route_parameters);
|
||||
|
||||
// Use the weight property from the menu link.
|
||||
$menu_link->router_item['weight'] = $menu_link->weight;
|
||||
|
||||
// By default use the menu_name as type.
|
||||
$menu_link->bundle = $menu_link->menu_name;
|
||||
|
||||
// For all links that have an associated route, load the route object now
|
||||
// and save it on the object. That way we avoid a select N+1 problem later.
|
||||
if ($menu_link->route_name) {
|
||||
$routes[$menu_link->id()] = $menu_link->route_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Now mass-load any routes needed and associate them.
|
||||
if ($routes) {
|
||||
$route_objects = \Drupal::service('router.route_provider')->getRoutesByNames($routes);
|
||||
foreach ($routes as $entity_id => $route) {
|
||||
// Not all stored routes will be valid on load.
|
||||
if (isset($route_objects[$route])) {
|
||||
$entities[$entity_id]->setRouteObject($route_objects[$route]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -105,46 +105,6 @@ class MenuLinkStorageController extends DatabaseStorageController implements Men
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides DatabaseStorageController::attachLoad().
|
||||
*
|
||||
* @todo Don't call parent::attachLoad() at all because we want to be able to
|
||||
* control the entity load hooks.
|
||||
*/
|
||||
protected function attachLoad(&$menu_links, $load_revision = FALSE) {
|
||||
$routes = array();
|
||||
|
||||
foreach ($menu_links as &$menu_link) {
|
||||
$menu_link->options = unserialize($menu_link->options);
|
||||
$menu_link->route_parameters = unserialize($menu_link->route_parameters);
|
||||
|
||||
// Use the weight property from the menu link.
|
||||
$menu_link->router_item['weight'] = $menu_link->weight;
|
||||
|
||||
// By default use the menu_name as type.
|
||||
$menu_link->bundle = $menu_link->menu_name;
|
||||
|
||||
// For all links that have an associated route, load the route object now
|
||||
// and save it on the object. That way we avoid a select N+1 problem later.
|
||||
if ($menu_link->route_name) {
|
||||
$routes[$menu_link->id()] = $menu_link->route_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Now mass-load any routes needed and associate them.
|
||||
if ($routes) {
|
||||
$route_objects = $this->routeProvider->getRoutesByNames($routes);
|
||||
foreach ($routes as $entity_id => $route) {
|
||||
// Not all stored routes will be valid on load.
|
||||
if (isset($route_objects[$route])) {
|
||||
$menu_links[$entity_id]->setRouteObject($route_objects[$route]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::attachLoad($menu_links, $load_revision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides DatabaseStorageController::save().
|
||||
*/
|
||||
|
|
|
@ -22,7 +22,7 @@ use Drupal\node\NodeInterface;
|
|||
* label = @Translation("Content"),
|
||||
* bundle_label = @Translation("Content type"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\node\NodeStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "view_builder" = "Drupal\node\NodeViewBuilder",
|
||||
* "access" = "Drupal\node\NodeAccessController",
|
||||
* "form" = {
|
||||
|
@ -77,6 +77,17 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
return $this->get('vid')->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) {
|
||||
parent::preCreate($storage_controller, $values);
|
||||
// @todo Handle this through property defaults.
|
||||
if (empty($values['created'])) {
|
||||
$values['created'] = REQUEST_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -149,6 +160,14 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function postDelete(EntityStorageControllerInterface $storage_controller, array $nodes) {
|
||||
parent::postDelete($storage_controller, $nodes);
|
||||
\Drupal::service('node.grant_storage')->deleteNodeRecords(array_keys($nodes));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -230,7 +230,7 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete() {
|
||||
$this->database->delete('node_access')->execute();
|
||||
$this->database->truncate('node_access')->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -256,4 +256,13 @@ class NodeGrantDatabaseStorage implements NodeGrantDatabaseStorageInterface {
|
|||
return $this->database->query('SELECT COUNT(*) FROM {node_access}')->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteNodeRecords(array $nids) {
|
||||
$this->database->delete('node_access')
|
||||
->condition('nid', $nids, 'IN')
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,4 +121,13 @@ interface NodeGrantDatabaseStorageInterface {
|
|||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Remove the access records belonging to certain nodes.
|
||||
*
|
||||
* @param array $nids
|
||||
* A list of node IDs. The grant records belonging to these nodes will be
|
||||
* deleted.
|
||||
*/
|
||||
public function deleteNodeRecords(array $nids);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\node\NodeStorageController.
|
||||
*/
|
||||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\Core\Entity\FieldableDatabaseStorageController;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* Controller class for nodes.
|
||||
*
|
||||
* This extends the Drupal\Core\Entity\DatabaseStorageController class, adding
|
||||
* required special handling for node entities.
|
||||
*/
|
||||
class NodeStorageController extends FieldableDatabaseStorageController {
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\DatabaseStorageController::create().
|
||||
*/
|
||||
public function create(array $values) {
|
||||
// @todo Handle this through property defaults.
|
||||
if (empty($values['created'])) {
|
||||
$values['created'] = REQUEST_TIME;
|
||||
}
|
||||
return parent::create($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\DatabaseStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
|
||||
$queried_entities = $this->mapFromStorageRecords($queried_entities, $load_revision);
|
||||
|
||||
// Create an array of nodes for each content type and pass this to the
|
||||
// object type specific callback. To preserve backward-compatibility we
|
||||
// pass on BC decorators to node-specific hooks, while we pass on the
|
||||
// regular entity objects else.
|
||||
$typed_nodes = array();
|
||||
foreach ($queried_entities as $id => $node) {
|
||||
$typed_nodes[$node->bundle()][$id] = $queried_entities[$id];
|
||||
}
|
||||
|
||||
if ($load_revision) {
|
||||
$this->loadFieldItems($queried_entities, static::FIELD_LOAD_REVISION);
|
||||
}
|
||||
else {
|
||||
$this->loadFieldItems($queried_entities, static::FIELD_LOAD_CURRENT);
|
||||
}
|
||||
|
||||
// Besides the list of nodes, pass one additional argument to
|
||||
// hook_node_load(), containing a list of node types that were loaded.
|
||||
$argument = array_keys($typed_nodes);
|
||||
$this->hookLoadArguments = array($argument);
|
||||
|
||||
// Call hook_entity_load().
|
||||
foreach (\Drupal::moduleHandler()->getImplementations('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 (\Drupal::moduleHandler()->getImplementations($this->entityType . '_load') as $module) {
|
||||
call_user_func_array($module . '_' . $this->entityType . '_load', $args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\DatabaseStorageController::postDelete().
|
||||
*/
|
||||
protected function postDelete($nodes) {
|
||||
// Delete values from other tables also referencing this node.
|
||||
$ids = array_keys($nodes);
|
||||
|
||||
db_delete('node_access')
|
||||
->condition('nid', $ids, 'IN')
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\node\Tests\NodeLoadHooksTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\node\Tests;
|
||||
|
||||
/**
|
||||
* Tests for the hooks invoked during node_load().
|
||||
*/
|
||||
class NodeLoadHooksTest extends NodeTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node_test');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node load hooks',
|
||||
'description' => 'Test the hooks invoked when a node is being loaded.',
|
||||
'group' => 'Node',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that hook_node_load() is invoked correctly.
|
||||
*/
|
||||
function testHookNodeLoad() {
|
||||
// Create some sample articles and pages.
|
||||
$node1 = $this->drupalCreateNode(array('type' => 'article', 'status' => NODE_PUBLISHED));
|
||||
$node2 = $this->drupalCreateNode(array('type' => 'article', 'status' => NODE_PUBLISHED));
|
||||
$node3 = $this->drupalCreateNode(array('type' => 'article', 'status' => NODE_NOT_PUBLISHED));
|
||||
$node4 = $this->drupalCreateNode(array('type' => 'page', 'status' => NODE_NOT_PUBLISHED));
|
||||
|
||||
// Check that when a set of nodes that only contains articles is loaded,
|
||||
// the properties added to the node by node_test_load_node() correctly
|
||||
// reflect the expected values.
|
||||
$nodes = entity_load_multiple_by_properties('node', array('status' => NODE_PUBLISHED));
|
||||
$loaded_node = end($nodes);
|
||||
$this->assertEqual($loaded_node->node_test_loaded_nids, array($node1->id(), $node2->id()), 'hook_node_load() received the correct list of node IDs the first time it was called.');
|
||||
$this->assertEqual($loaded_node->node_test_loaded_types, array('article'), 'hook_node_load() received the correct list of node types the first time it was called.');
|
||||
|
||||
// Now, as part of the same page request, load a set of nodes that contain
|
||||
// both articles and pages, and make sure the parameters passed to
|
||||
// node_test_node_load() are correctly updated.
|
||||
$nodes = entity_load_multiple_by_properties('node', array('status' => NODE_NOT_PUBLISHED));
|
||||
$loaded_node = end($nodes);
|
||||
$this->assertEqual($loaded_node->node_test_loaded_nids, array($node3->id(), $node4->id()), 'hook_node_load() received the correct list of node IDs the second time it was called.');
|
||||
$this->assertEqual($loaded_node->node_test_loaded_types, array('article', 'page'), 'hook_node_load() received the correct list of node types the second time it was called.');
|
||||
}
|
||||
}
|
|
@ -502,20 +502,23 @@ function hook_node_create(\Drupal\Core\Entity\EntityInterface $node) {
|
|||
*
|
||||
* @param $nodes
|
||||
* An array of the nodes being loaded, keyed by nid.
|
||||
* @param $types
|
||||
* An array containing the node types present in $nodes. Allows for an early
|
||||
* return for modules that only support certain node types.
|
||||
*
|
||||
* For a detailed usage example, see nodeapi_example.module.
|
||||
*
|
||||
* @ingroup node_api_hooks
|
||||
*/
|
||||
function hook_node_load($nodes, $types) {
|
||||
function hook_node_load($nodes) {
|
||||
// Decide whether any of $types are relevant to our purposes.
|
||||
$types_we_want_to_process = \Drupal::config('my_types')->get('types');
|
||||
if (count(array_intersect($types_we_want_to_process, $types))) {
|
||||
$nids = array();
|
||||
foreach ($nodes as $node) {
|
||||
if (in_array($node->bundle(), $types_we_want_to_process)) {
|
||||
$nids = $node->id();
|
||||
}
|
||||
}
|
||||
if ($nids) {
|
||||
// Gather our extra data for each of these nodes.
|
||||
$result = db_query('SELECT nid, foo FROM {mytable} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)));
|
||||
$result = db_query('SELECT nid, foo FROM {mytable} WHERE nid IN(:nids)', array(':nids' => $nids));
|
||||
// Add our extra data to the node objects.
|
||||
foreach ($result as $record) {
|
||||
$nodes[$record->nid]->foo = $record->foo;
|
||||
|
|
|
@ -110,7 +110,7 @@ function node_access_test_form_node_form_alter(&$form, $form_state) {
|
|||
/**
|
||||
* Implements hook_node_load().
|
||||
*/
|
||||
function node_access_test_node_load($nodes, $types) {
|
||||
function node_access_test_node_load($nodes) {
|
||||
$result = db_query('SELECT nid, private FROM {node_access_test} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)));
|
||||
foreach ($result as $record) {
|
||||
$nodes[$record->nid]->private = $record->private;
|
||||
|
|
|
@ -12,22 +12,6 @@ use Drupal\Core\Entity\EntityInterface;
|
|||
use Drupal\entity\Entity\EntityDisplay;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_node_load().
|
||||
*/
|
||||
function node_test_node_load($nodes, $types) {
|
||||
// Add properties to each loaded node which record the parameters that were
|
||||
// passed in to this function, so the tests can check that (a) this hook was
|
||||
// called, and (b) the parameters were what we expected them to be.
|
||||
$nids = array_keys($nodes);
|
||||
ksort($nids);
|
||||
sort($types);
|
||||
foreach ($nodes as $node) {
|
||||
$node->node_test_loaded_nids = $nids;
|
||||
$node->node_test_loaded_types = $types;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_view().
|
||||
*/
|
||||
|
|
|
@ -98,6 +98,19 @@ class ShortcutSet extends ConfigEntityBase implements ShortcutSetInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
|
||||
parent::postLoad($storage_controller, $entities);
|
||||
foreach ($entities as $id => $entity) {
|
||||
$links = menu_load_links('shortcut-' . $id);
|
||||
foreach ($links as $menu_link) {
|
||||
$entity->links[$menu_link->uuid()] = $menu_link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -15,20 +15,6 @@ use Drupal\shortcut\ShortcutSetInterface;
|
|||
*/
|
||||
class ShortcutSetStorageController extends ConfigStorageController implements ShortcutSetStorageControllerInterface {
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\config\ConfigStorageController::attachLoad().
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
|
||||
parent::attachLoad($queried_entities, $revision_id);
|
||||
|
||||
foreach ($queried_entities as $id => $entity) {
|
||||
$links = menu_load_links('shortcut-' . $id);
|
||||
foreach ($links as $menu_link) {
|
||||
$entity->links[$menu_link->uuid()] = $menu_link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Core\Entity\ContentEntityBase;
|
|||
use Drupal\Core\Entity\Annotation\EntityType;
|
||||
use Drupal\Core\Annotation\Translation;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +21,7 @@ use Drupal\Core\Language\Language;
|
|||
* id = "entity_test",
|
||||
* label = @Translation("Test entity"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "list" = "Drupal\entity_test\EntityTestListController",
|
||||
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessController",
|
||||
|
@ -95,6 +96,16 @@ class EntityTest extends ContentEntityBase {
|
|||
unset($this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) {
|
||||
parent::preCreate($storage_controller, $values);
|
||||
if (empty($values['type'])) {
|
||||
$values['type'] = $storage_controller->entityType();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\entity\Entity::label().
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@ use Drupal\Core\Language\Language;
|
|||
* id = "entity_test_cache",
|
||||
* label = @Translation("Test entity with field cache"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessController",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\entity_test\EntityTestFormController"
|
||||
|
|
|
@ -17,7 +17,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_default_access",
|
||||
* label = @Translation("Test entity with default access"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController"
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController"
|
||||
* },
|
||||
* base_table = "entity_test",
|
||||
* entity_keys = {
|
||||
|
|
|
@ -17,7 +17,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_label",
|
||||
* label = @Translation("Entity Test label"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder"
|
||||
* },
|
||||
* base_table = "entity_test",
|
||||
|
|
|
@ -17,7 +17,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_label_callback",
|
||||
* label = @Translation("Entity test label callback"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController"
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController"
|
||||
* },
|
||||
* field_cache = FALSE,
|
||||
* base_table = "entity_test",
|
||||
|
|
|
@ -19,7 +19,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_mul",
|
||||
* label = @Translation("Test entity - data table"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessController",
|
||||
* "form" = {
|
||||
|
|
|
@ -19,7 +19,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_mulrev",
|
||||
* label = @Translation("Test entity - revisions and data table"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessController",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\entity_test\EntityTestFormController"
|
||||
|
|
|
@ -17,7 +17,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_no_label",
|
||||
* label = @Translation("Entity Test without label"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController"
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController"
|
||||
* },
|
||||
* field_cache = FALSE,
|
||||
* base_table = "entity_test",
|
||||
|
|
|
@ -19,7 +19,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* id = "entity_test_rev",
|
||||
* label = @Translation("Test entity - revisions"),
|
||||
* controllers = {
|
||||
* "storage" = "Drupal\entity_test\EntityTestStorageController",
|
||||
* "storage" = "Drupal\Core\Entity\FieldableDatabaseStorageController",
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessController",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\entity_test\EntityTestFormController"
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\entity_test\EntityTestStorageController.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_test;
|
||||
|
||||
use Drupal\Core\Entity\FieldableDatabaseStorageController;
|
||||
|
||||
/**
|
||||
* Defines the controller class for the test entity.
|
||||
*
|
||||
* This extends the Drupal\Core\Entity\DatabaseStorageController class, adding
|
||||
* required special handling for test entities.
|
||||
*/
|
||||
class EntityTestStorageController extends FieldableDatabaseStorageController {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function create(array $values) {
|
||||
if (empty($values['type'])) {
|
||||
$values['type'] = $this->entityType;
|
||||
}
|
||||
return parent::create($values);
|
||||
}
|
||||
|
||||
}
|
|
@ -108,6 +108,16 @@ class Role extends ConfigEntityBase implements RoleInterface {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
|
||||
parent::postLoad($storage_controller, $entities);
|
||||
// Sort the queried roles by their weight.
|
||||
// See \Drupal\Core\Config\Entity\ConfigEntityBase::sort().
|
||||
uasort($entities, 'static::sort');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -24,15 +24,4 @@ class RoleStorageController extends ConfigStorageController implements RoleStora
|
|||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
|
||||
// Sort the queried roles by their weight.
|
||||
// See \Drupal\Core\Config\Entity\ConfigEntityBase::sort().
|
||||
uasort($queried_entities, array($this->entityInfo['class'], 'sort'));
|
||||
|
||||
parent::attachLoad($queried_entities, $revision_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -79,9 +79,9 @@ class UserStorageController extends FieldableDatabaseStorageController implement
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\DatabaseStorageController::attachLoad().
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function attachLoad(&$queried_users, $load_revision = FALSE) {
|
||||
function postLoad(array &$queried_users) {
|
||||
foreach ($queried_users as $key => $record) {
|
||||
$queried_users[$key]->roles = array();
|
||||
if ($record->uid) {
|
||||
|
@ -95,9 +95,9 @@ class UserStorageController extends FieldableDatabaseStorageController implement
|
|||
// Add any additional roles from the database.
|
||||
$this->addRoles($queried_users);
|
||||
|
||||
// Call the default attachLoad() method. This will add fields and call
|
||||
// Call the default postLoad() method. This will add fields and call
|
||||
// hook_user_load().
|
||||
parent::attachLoad($queried_users, $load_revision);
|
||||
parent::postLoad($queried_users);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1755,7 +1755,7 @@ function user_form_process_password_confirm($element) {
|
|||
* \Drupal\node\NodeViewBuilder::buildContent(). Update code that
|
||||
* depends on these properties.
|
||||
*/
|
||||
function user_node_load($nodes, $types) {
|
||||
function user_node_load($nodes) {
|
||||
// Build an array of all uids for node authors, keyed by nid.
|
||||
$uids = array();
|
||||
foreach ($nodes as $nid => $node) {
|
||||
|
|
|
@ -286,6 +286,16 @@ class View extends ConfigEntityBase implements ViewStorageInterface {
|
|||
views_invalidate_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
|
||||
parent::postLoad($storage_controller, $entities);
|
||||
foreach ($entities as $entity) {
|
||||
$entity->mergeDefaultDisplaysOptions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -30,16 +30,4 @@ class ViewStorageController extends ConfigStorageController {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
|
||||
foreach ($queried_entities as $entity) {
|
||||
$entity->mergeDefaultDisplaysOptions();
|
||||
}
|
||||
|
||||
parent::attachLoad($queried_entities, $revision_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1140,7 +1140,7 @@ class ViewUI implements ViewStorageInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array $entities) {
|
||||
public static function postLoad(EntityStorageControllerInterface $storage_controller, array &$entities) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue