Commit 7961e03a authored by alexpott's avatar alexpott

Issue #1909418 by tim.plunkett, damiankloip, larowlan, dawehner, kim.pepper:...

Issue #1909418 by tim.plunkett, damiankloip, larowlan, dawehner, kim.pepper: Allow Entity Controllers to have their dependencies injected.
parent 4ec9347a
......@@ -150,7 +150,7 @@ services:
- { name: persist }
plugin.manager.entity:
class: Drupal\Core\Entity\EntityManager
arguments: ['@container.namespaces']
arguments: ['@container.namespaces', '@service_container']
plugin.manager.archiver:
class: Drupal\Core\Archiver\ArchiverManager
arguments: ['@container.namespaces']
......
......@@ -2770,7 +2770,7 @@ function _menu_navigation_links_rebuild($menu) {
else {
// The Menu link module is not available at install time, so we need to
// hardcode the default storage controller.
$menu_link_controller = new MenuLinkStorageController('menu_link');
$menu_link_controller = new MenuLinkStorageController('menu_link', Drupal::service('database'), Drupal::service('router.route_provider'));
}
// Add normal and suggested items as links.
......
......@@ -9,9 +9,13 @@
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityControllerInterface;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Config\StorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the storage controller class for configuration entities.
......@@ -28,7 +32,7 @@
* after the config_prefix in a config name forms the entity ID. Additional or
* custom suffixes are not possible.
*/
class ConfigStorageController implements EntityStorageControllerInterface {
class ConfigStorageController implements EntityStorageControllerInterface, EntityControllerInterface {
/**
* Entity type for this controller instance.
......@@ -77,13 +81,34 @@ class ConfigStorageController implements EntityStorageControllerInterface {
protected $statusKey = 'status';
/**
* Implements Drupal\Core\Entity\EntityStorageControllerInterface::__construct().
* The config factory service.
*
* Sets basic variables.
* @var \Drupal\Core\Config\ConfigFactory
*/
public function __construct($entityType) {
$this->entityType = $entityType;
$this->entityInfo = entity_get_info($entityType);
protected $configFactory;
/**
* The config storage service.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $configStorage;
/**
* Constructs a ConfigStorageController object.
*
* @param string $entity_type
* The entity type for which the instance is created.
* @param array $entity_info
* An array of entity info for the entity type.
* @param \Drupal\Core\Config\ConfigFactory $config_factory
* The config factory service.
* @param \Drupal\Core\Config\StorageInterface $config_storage
* The config storage service.
*/
public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage) {
$this->entityType = $entity_type;
$this->entityInfo = $entity_info;
$this->hookLoadArguments = array();
$this->idKey = $this->entityInfo['entity_keys']['id'];
......@@ -93,6 +118,21 @@ public function __construct($entityType) {
else {
$this->statusKey = FALSE;
}
$this->configFactory = $config_factory;
$this->configStorage = $config_storage;
}
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static(
$entity_type,
$entity_info,
$container->get('config.factory'),
$container->get('config.storage')
);
}
/**
......@@ -231,10 +271,10 @@ protected function buildQuery($ids, $revision_id = FALSE) {
// Load all of the configuration entities.
if ($ids === NULL) {
$names = drupal_container()->get('config.storage')->listAll($prefix);
$names = $this->configStorage->listAll($prefix);
$result = array();
foreach ($names as $name) {
$config = config($name);
$config = $this->configFactory->get($name);
$result[$config->get($this->idKey)] = new $config_class($config->get(), $this->entityType);
}
return $result;
......@@ -243,7 +283,7 @@ protected function buildQuery($ids, $revision_id = FALSE) {
$result = array();
foreach ($ids as $id) {
// Add the prefix to the ID to serve as the configuration object name.
$config = config($prefix . $id);
$config = $this->configFactory->get($prefix . $id);
if (!$config->isNew()) {
$result[$id] = new $config_class($config->get(), $this->entityType);
}
......@@ -331,13 +371,13 @@ public function delete(array $entities) {
}
foreach ($entities as $id => $entity) {
$config = config($this->getConfigPrefix() . $entity->id());
$config = $this->configFactory->get($this->getConfigPrefix() . $entity->id());
$config->delete();
// Remove the entity from the manifest file. Entity IDs can contain a dot
// so we can not use Config::clear() to remove the entity from the
// manifest.
$manifest = config('manifest.' . $this->entityInfo['config_prefix']);
$manifest = $this->configFactory->get('manifest.' . $this->entityInfo['config_prefix']);
$manifest_data = $manifest->get();
unset($manifest_data[$entity->id()]);
$manifest->setData($manifest_data);
......@@ -370,7 +410,7 @@ public function save(EntityInterface $entity) {
if ($entity->getOriginalID() !== NULL) {
$id = $entity->getOriginalID();
}
$config = config($prefix . $id);
$config = $this->configFactory->get($prefix . $id);
$is_new = $config->isNew();
if (!$is_new && !isset($entity->original)) {
......@@ -384,7 +424,7 @@ public function save(EntityInterface $entity) {
// - Storage controller needs to access the original object.
// - The object needs to be renamed/copied in ConfigFactory and reloaded.
// - All instances of the object need to be renamed.
drupal_container()->get('config.factory')->rename($prefix . $id, $prefix . $entity->id());
$this->configFactory->rename($prefix . $id, $prefix . $entity->id());
}
$this->preSave($entity);
......@@ -413,7 +453,7 @@ public function save(EntityInterface $entity) {
}
$update_manifest = FALSE;
$config = config('manifest.' . $this->entityInfo['config_prefix']);
$config = $this->configFactory->get('manifest.' . $this->entityInfo['config_prefix']);
$manifest = $config->get();
// If the save operation resulted in a rename remove the old entity id from
// the manifest file.
......
......@@ -133,6 +133,21 @@ public function __construct($environment, $debug, ClassLoader $class_loader, $al
$this->allowDumping = $allow_dumping;
}
/**
* {@inheritdoc}
*/
public function serialize() {
return serialize(array($this->environment, $this->debug, $this->classLoader, $this->allowDumping));
}
/**
* {@inheritdoc}
*/
public function unserialize($data) {
list($environment, $debug, $class_loader, $allow_dumping) = unserialize($data);
$this->__construct($environment, $debug, $class_loader, $allow_dumping);
}
/**
* Overrides Kernel::init().
*/
......
......@@ -13,7 +13,9 @@
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Component\Uuid\Uuid;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Database\Connection;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a base entity controller class.
......@@ -23,7 +25,7 @@
* This class can be used as-is by most simple entity types. Entity types
* requiring special handling can extend the class.
*/
class DatabaseStorageController implements EntityStorageControllerInterface {
class DatabaseStorageController implements EntityStorageControllerInterface, EntityControllerInterface {
/**
* Static cache of entities.
......@@ -114,16 +116,38 @@ class DatabaseStorageController implements EntityStorageControllerInterface {
*/
protected $cache;
/**
* Active database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static(
$entity_type,
$entity_info,
$container->get('database')
);
}
/**
* Constructs a DatabaseStorageController object.
*
* @param string $entityType
* @param string $entity_type
* The entity type for which the instance is created.
*/
public function __construct($entityType) {
$this->entityType = $entityType;
$this->entityInfo = entity_get_info($entityType);
* @param array $entity_info
* An array of entity info for the entity type.
* @param \Drupal\Core\Database\Connection $database
* The database connection to be used.
*/
public function __construct($entity_type, array $entity_info, Connection $database) {
$this->database = $database;
$this->entityType = $entity_type;
$this->entityInfo = $entity_info;
$this->entityCache = array();
$this->hookLoadArguments = array();
......@@ -280,7 +304,7 @@ public function deleteRevision($revision_id) {
throw new EntityStorageException('Default revision can not be deleted');
}
db_delete($this->revisionTable)
$this->database->delete($this->revisionTable)
->condition($this->revisionKey, $revision->getRevisionId())
->execute();
$this->invokeHook('revision_delete', $revision);
......@@ -334,7 +358,7 @@ protected function buildPropertyQuery(QueryInterface $entity_query, array $value
* A SelectQuery object for loading the entity.
*/
protected function buildQuery($ids, $revision_id = FALSE) {
$query = db_select($this->entityInfo['base_table'], 'base');
$query = $this->database->select($this->entityInfo['base_table'], 'base');
$query->addTag($this->entityType . '_load_multiple');
......@@ -476,7 +500,7 @@ public function delete(array $entities) {
// If no IDs or invalid IDs were passed, do nothing.
return;
}
$transaction = db_transaction();
$transaction = $this->database->startTransaction();
try {
$this->preDelete($entities);
......@@ -485,12 +509,12 @@ public function delete(array $entities) {
}
$ids = array_keys($entities);
db_delete($this->entityInfo['base_table'])
$this->database->delete($this->entityInfo['base_table'])
->condition($this->idKey, $ids, 'IN')
->execute();
if ($this->revisionKey) {
db_delete($this->revisionTable)
$this->database->delete($this->revisionTable)
->condition($this->idKey, $ids, 'IN')
->execute();
}
......@@ -516,7 +540,7 @@ public function delete(array $entities) {
* Implements \Drupal\Core\Entity\EntityStorageControllerInterface::save().
*/
public function save(EntityInterface $entity) {
$transaction = db_transaction();
$transaction = $this->database->startTransaction();
try {
// Load the stored entity, if any.
if (!$entity->isNew() && !isset($entity->original)) {
......@@ -594,7 +618,7 @@ protected function saveRevision(EntityInterface $entity) {
if ($entity->isNewRevision()) {
drupal_write_record($this->revisionTable, $record);
if ($entity->isDefaultRevision()) {
db_update($this->entityInfo['base_table'])
$this->database->update($this->entityInfo['base_table'])
->fields(array($this->revisionKey => $record[$this->revisionKey]))
->condition($this->idKey, $entity->id())
->execute();
......
......@@ -15,6 +15,7 @@
use Drupal\Core\Entity\DatabaseStorageController;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Database\Connection;
/**
* Implements Field API specific enhancements to the DatabaseStorageController class.
......@@ -52,8 +53,8 @@ class DatabaseStorageControllerNG extends DatabaseStorageController {
/**
* Overrides DatabaseStorageController::__construct().
*/
public function __construct($entityType) {
parent::__construct($entityType);
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'];
......@@ -223,7 +224,7 @@ protected function mapFromStorageRecords(array $records, $load_revision = FALSE)
*/
protected function attachPropertyData(array &$entities, $load_revision = FALSE) {
if ($this->dataTable) {
$query = db_select($this->dataTable, 'data', array('fetch' => PDO::FETCH_ASSOC))
$query = $this->database->select($this->dataTable, 'data', array('fetch' => PDO::FETCH_ASSOC))
->fields('data')
->condition($this->idKey, array_keys($entities))
->orderBy('data.' . $this->idKey);
......@@ -271,7 +272,7 @@ protected function attachPropertyData(array &$entities, $load_revision = FALSE)
* Added mapping from entities to storage records before saving.
*/
public function save(EntityInterface $entity) {
$transaction = db_transaction();
$transaction = $this->database->startTransaction();
try {
// Ensure we are dealing with the actual entity.
$entity = $entity->getNGEntity();
......@@ -364,7 +365,7 @@ protected function saveRevision(EntityInterface $entity) {
if ($entity->isNewRevision()) {
drupal_write_record($this->revisionTable, $record);
if ($entity->isDefaultRevision()) {
db_update($this->entityInfo['base_table'])
$this->database->update($this->entityInfo['base_table'])
->fields(array($this->revisionKey => $record->{$this->revisionKey}))
->condition($this->idKey, $record->{$this->idKey})
->execute();
......@@ -387,11 +388,11 @@ protected function saveRevision(EntityInterface $entity) {
*/
protected function savePropertyData(EntityInterface $entity) {
// Delete and insert to handle removed values.
db_delete($this->dataTable)
$this->database->delete($this->dataTable)
->condition($this->idKey, $entity->id())
->execute();
$query = db_insert($this->dataTable);
$query = $this->database->insert($this->dataTable);
foreach ($entity->getTranslationLanguages() as $langcode => $language) {
$record = $this->mapToDataStorageRecord($entity, $langcode);
......@@ -498,7 +499,7 @@ public function delete(array $entities) {
return;
}
$transaction = db_transaction();
$transaction = $this->database->startTransaction();
try {
// Ensure we are dealing with the actual entities.
foreach ($entities as $id => $entity) {
......@@ -511,18 +512,18 @@ public function delete(array $entities) {
}
$ids = array_keys($entities);
db_delete($this->entityInfo['base_table'])
$this->database->delete($this->entityInfo['base_table'])
->condition($this->idKey, $ids)
->execute();
if ($this->revisionKey) {
db_delete($this->revisionTable)
$this->database->delete($this->revisionTable)
->condition($this->idKey, $ids)
->execute();
}
if ($this->dataTable) {
db_delete($this->dataTable)
$this->database->delete($this->dataTable)
->condition($this->idKey, $ids)
->execute();
}
......
<?php
/**
* @file
* Contains \Drupal\Core\Entity\EntityControllerInterface.
*/
namespace Drupal\Core\Entity;
use Drupal\Core\Entity\EntityStorageControllerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a common interface for entity controllers.
*
* This interface can be implemented by entity controllers that require
* dependency injection. These are not controllers in the routing sense of the
* word, but instead are handlers that perform a specific function for an entity
* type.
*/
interface EntityControllerInterface {
/**
* Instantiates a new instance of this entity controller.
*
* This is a factory method that returns a new instance of this object. The
* factory should pass any needed dependencies into the constructor of this
* object, but not the container itself. Every call to this method must return
* a new instance of this object; that is, it may not implement a singleton.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The service container this object should use.
* @param string $entity_type
* The entity type which the controller handles.
* @param array $entity_info
* An array of entity info for the entity type.
*
* @return static
* A new instance of the entity controller.
*/
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info);
}
......@@ -15,6 +15,7 @@
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
use Drupal\Core\Plugin\Discovery\InfoHookDecorator;
use Drupal\Core\Cache\CacheBackendInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Manages entity type plugin definitions.
......@@ -32,6 +33,13 @@
*/
class EntityManager extends PluginManagerBase {
/**
* The injection container that should be passed into the controller factory.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* Contains instantiated controllers keyed by controller type and entity type.
*
......@@ -45,8 +53,10 @@ class EntityManager extends PluginManagerBase {
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations,
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The service container this object should use.
*/
public function __construct(\Traversable $namespaces) {
public function __construct(\Traversable $namespaces, ContainerInterface $container) {
// Allow the plugin definition to be altered by hook_entity_info_alter().
$annotation_namespaces = array(
'Drupal\Core\Entity\Annotation' => DRUPAL_ROOT . '/core/lib',
......@@ -57,6 +67,7 @@ public function __construct(\Traversable $namespaces) {
$this->discovery = new CacheDecorator($this->discovery, 'entity_info:' . language(Language::TYPE_INTERFACE)->langcode, 'cache', CacheBackendInterface::CACHE_PERMANENT, array('entity_info' => TRUE));
$this->factory = new DefaultFactory($this->discovery);
$this->container = $container;
}
/**
......@@ -126,7 +137,12 @@ public function getControllerClass($entity_type, $controller_type, $nested = NUL
public function getStorageController($entity_type) {
if (!isset($this->controllers['storage'][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'storage');
$this->controllers['storage'][$entity_type] = new $class($entity_type);
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) {
$this->controllers['storage'][$entity_type] = $class::createInstance($this->container, $entity_type, $this->getDefinition($entity_type));
}
else {
$this->controllers['storage'][$entity_type] = new $class($entity_type);
}
}
return $this->controllers['storage'][$entity_type];
}
......@@ -143,7 +159,12 @@ public function getStorageController($entity_type) {
public function getListController($entity_type) {
if (!isset($this->controllers['listing'][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'list');
$this->controllers['listing'][$entity_type] = new $class($entity_type, $this->getStorageController($entity_type));
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) {
$this->controllers['listing'][$entity_type] = $class::createInstance($this->container, $entity_type, $this->getDefinition($entity_type));
}
else {
$this->controllers['listing'][$entity_type] = new $class($entity_type, $this->getStorageController($entity_type));
}
}
return $this->controllers['listing'][$entity_type];
}
......@@ -162,7 +183,12 @@ public function getListController($entity_type) {
public function getFormController($entity_type, $operation) {
if (!isset($this->controllers['form'][$operation][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'form', $operation);
$this->controllers['form'][$operation][$entity_type] = new $class($operation);
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) {
$this->controllers['form'][$operation][$entity_type] = $class::createInstance($this->container, $entity_type, $this->getDefinition($entity_type));
}
else {
$this->controllers['form'][$operation][$entity_type] = new $class($operation);
}
}
return $this->controllers['form'][$operation][$entity_type];
}
......@@ -179,7 +205,12 @@ public function getFormController($entity_type, $operation) {
public function getRenderController($entity_type) {
if (!isset($this->controllers['render'][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'render');
$this->controllers['render'][$entity_type] = new $class($entity_type);
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) {
$this->controllers['render'][$entity_type] = $class::createInstance($this->container, $entity_type, $this->getDefinition($entity_type));
}
else {
$this->controllers['render'][$entity_type] = new $class($entity_type);
}
}
return $this->controllers['render'][$entity_type];
}
......@@ -196,7 +227,12 @@ public function getRenderController($entity_type) {
public function getAccessController($entity_type) {
if (!isset($this->controllers['access'][$entity_type])) {
$class = $this->getControllerClass($entity_type, 'access');
$this->controllers['access'][$entity_type] = new $class($entity_type);
if (in_array('Drupal\Core\Entity\EntityControllerInterface', class_implements($class))) {
$this->controllers['access'][$entity_type] = $class::createInstance($this->container, $entity_type, $this->getDefinition($entity_type));
}
else {
$this->controllers['access'][$entity_type] = new $class($entity_type);
}
}
return $this->controllers['access'][$entity_type];
}
......
......@@ -9,11 +9,45 @@
use Drupal\Core\Entity\EntityFormController;
use Drupal\Core\Language\Language;
use Drupal\Core\Entity\EntityControllerInterface;
use Drupal\Core\Path\AliasManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form controller for the node edit forms.
*/
class MenuLinkFormController extends EntityFormController {
class MenuLinkFormController extends EntityFormController implements EntityControllerInterface {
/**
* The path alias manager.
*
* @var \Drupal\Core\Path\AliasManagerInterface
*/
protected $pathAliasManager;
/**
* Constructs a new MenuLinkFormController object.
*
* @param string $operation
* The name of the current operation.
* @param \Drupal\Core\Path\AliasManagerInterface $path_alias_manager
* The path alias manager.
*/
public function __construct($operation, AliasManagerInterface $path_alias_manager) {
parent::__construct($operation);
$this->pathAliasManager = $path_alias_manager;
}
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info, $operation = NULL) {
return new static(
$operation,
$container->get('path.alias_manager.cached')
);
}
/**
* Overrides EntityFormController::form().
......@@ -149,7 +183,7 @@ protected function actions(array $form, array &$form_state) {
public function validate(array $form, array &$form_state) {
$menu_link = $this->buildEntity($form, $form_state);
$normal_path = drupal_container()->get('path.alias_manager.cached')->getSystemPath($menu_link->link_path);
$normal_path = $this->pathAliasManager->getSystemPath($menu_link->link_path);
if ($menu_link->link_path != $normal_path) {
drupal_set_message(t('The menu system stores system paths only, but will use the URL alias for display. %link_path has been stored as %normal_path', array('%link_path' => $menu_link->link_path, '%normal_path' => $normal_path)));
$menu_link->link_path = $normal_path;
......
......@@ -10,6 +10,9 @@
use Drupal\Core\Entity\DatabaseStorageController;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Database\Connection;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Cmf\Component\Routing\RouteProviderInterface;
use Symfony\Component\HttpFoundation\Request;
/**
......@@ -34,17 +37,47 @@ class MenuLinkStorageController extends DatabaseStorageController {
*/
protected static $routerItemFields = array();
/**
* The route provider service.
*
* @var \Symfony\Cmf\Component\Routing\RouteProviderInterface
*/
protected $routeProvider;
/**
* Overrides DatabaseStorageController::__construct().
*
* @param string $entity_type
* The entity type for which the instance is created.
* @param array $entity_info
* An array of entity info for the entity type.
* @param \Drupal\Core\Database\Connection $database
* The database connection to be used.
* @param \Symfony\Cmf\Component\Routing\RouteProviderInterface $route_provider
* The route provider service.
*/
public function __construct($entityType) {
parent::__construct($entityType);
public function __construct($entity_type, array $entity_info, Connection $database, RouteProviderInterface $route_provider) {
parent::__construct($entity_type, $entity_info, $database);
$this->routeProvider = $route_provider;
if (empty(static::$routerItemFields)) {
static::$routerItemFields = array_diff(drupal_schema_fields_sql('menu_router'), array('weight'));
}
}
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) {
return new static(
$entity_type,
$entity_info,
$container->get('database'),
$container->get('router.route_provider')
);
}
/**
* Overrides DatabaseStorageController::buildQuery().
*/
......@@ -80,7 +113,7 @@ protected function attachLoad(&$menu_links, $load_revision = FALSE) {
// Now mass-load any routes needed and associate them.
if ($routes) {
$route_objects = drupal_container()->get('router.route_provider')->getRoutesByNames($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])) {
......@@ -101,7 +134,7 @@ public function save(EntityInterface $entity) {
// would be confusing in that situation.
$return = SAVED_UPDATED;
$transaction = db_transaction();
$transaction = $this->database->startTransaction();
try {
// Load the stored entity, if any.
if (!$entity->isNew() && !isset($entity->original)) {
......@@ -109,7 +142,7 @@ public function save(EntityInterface $entity) {
}
if ($entity->isNew()) {
$entity->mlid = db_insert($this->entityInfo['base_table'])->fields(array('menu_name' => 'tools'))->execute();
$entity->mlid = $this->database->insert($this->entityInfo