diff --git a/core/core.services.yml b/core/core.services.yml index 9a36139..56142b9 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -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'] diff --git a/core/includes/menu.inc b/core/includes/menu.inc index fb11da2..2fa83db 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -2769,7 +2769,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. diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php index 095114a..1ce4456 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php @@ -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. diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 8651134..56cf9b6 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\Serializer\SerializerInterface; /** * The DrupalKernel class is the core of Drupal itself. @@ -134,6 +135,21 @@ public function __construct($environment, $debug, ClassLoader $class_loader, $al } /** + * {@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(). */ public function init() { diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php index 6bb91e1..aa77bc2 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php @@ -12,7 +12,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. @@ -22,7 +24,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. @@ -113,16 +115,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(); @@ -279,7 +303,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); @@ -333,7 +357,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'); @@ -475,7 +499,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); @@ -484,12 +508,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(); } @@ -515,7 +539,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)) { @@ -593,7 +617,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(); diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php index 9b7020a..0cecd94 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php @@ -14,6 +14,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. @@ -51,8 +52,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']; @@ -222,7 +223,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); @@ -270,7 +271,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(); @@ -363,7 +364,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(); @@ -386,11 +387,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); @@ -497,7 +498,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) { @@ -510,18 +511,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(); } diff --git a/core/lib/Drupal/Core/Entity/EntityControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityControllerInterface.php new file mode 100644 index 0000000..79232c1 --- /dev/null +++ b/core/lib/Drupal/Core/Entity/EntityControllerInterface.php @@ -0,0 +1,43 @@ + DRUPAL_ROOT . '/core/lib', @@ -56,6 +66,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; } /** @@ -125,7 +136,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]; } @@ -142,7 +158,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]; } @@ -161,7 +182,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]; } @@ -178,7 +204,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]; } @@ -195,7 +226,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]; } diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php index 79bd8de..032d621 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkFormController.php @@ -8,11 +8,45 @@ namespace Drupal\menu_link; use Drupal\Core\Entity\EntityFormController; +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(). @@ -148,7 +182,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; diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php index dd4ffcc..5e91187 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php @@ -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; /** * Controller class for menu links. @@ -34,10 +37,28 @@ 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')); @@ -45,6 +66,18 @@ public function __construct($entityType) { } /** + * {@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(). */ protected function buildQuery($ids, $revision_id = FALSE) { @@ -79,7 +112,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])) { @@ -100,7 +133,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)) { @@ -108,7 +141,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['base_table'])->fields(array('menu_name' => 'tools'))->execute(); $entity->enforceIsNew(); } @@ -364,7 +397,7 @@ protected function updateParentalStatus(EntityInterface $entity, $exclude = FALS } $parent_has_children = ((bool) $query->execute()) ? 1 : 0; - db_update('menu_links') + $this->database->update('menu_links') ->fields(array('has_children' => $parent_has_children)) ->condition('mlid', $entity->plid) ->execute(); @@ -495,7 +528,7 @@ protected function setParents(EntityInterface $entity, EntityInterface $parent) public function findChildrenRelativeDepth(EntityInterface $entity) { // @todo Since all we need is a specific field from the base table, does it // make sense to convert to EFQ? - $query = db_select('menu_links'); + $query = $this->database->select('menu_links'); $query->addField('menu_links', 'depth'); $query->condition('menu_name', $entity->menu_name); $query->orderBy('depth', 'DESC'); @@ -523,7 +556,7 @@ public function findChildrenRelativeDepth(EntityInterface $entity) { * A menu link entity. */ protected function moveChildren(EntityInterface $entity) { - $query = db_update($this->entityInfo['base_table']); + $query = $this->database->update($this->entityInfo['base_table']); $query->fields(array('menu_name' => $entity->menu_name)); diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php index 2b90e18..61915d6 100644 --- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php @@ -113,4 +113,21 @@ function testCompileDIC() { $modules = $container->getParameter('container.modules'); $this->assertEqual($modules['bundle_test'], drupal_get_filename('module', 'bundle_test')); } + + /** + * Tests kernel serialization/unserialization. + */ + public function testSerialization() { + $classloader = drupal_classloader(); + // @todo: write a memory based storage backend for testing. + $module_enabled = array( + 'system' => 'system', + 'user' => 'user', + ); + $kernel = new DrupalKernel('testing', FALSE, $classloader); + + $string = serialize($kernel); + $unserialized_kernel = unserialize($string); + $this->assertTrue($unserialized_kernel instanceof DrupalKernel); + } } diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 3d8e981..e282226 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -10,6 +10,10 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityMalformedException; use Drupal\Core\Entity\DatabaseStorageController; +use Drupal\Core\Password\PasswordInterface; +use Drupal\Core\Database\Connection; +use Drupal\user\UserDataInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Controller class for users. @@ -20,6 +24,54 @@ class UserStorageController extends DatabaseStorageController { /** + * Provides the password hashing service object. + * + * @var \Drupal\Core\Password\PasswordInterface + */ + protected $password; + + /** + * Provides the user data service object. + * + * @var \Drupal\user\UserDataInterface + */ + protected $userData; + + /** + * Constructs a new UserStorageController object. + * + * @param string $entityType + * 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 \Drupal\Core\Password\PasswordInterface $password + * The password hashing service. + * @param \Drupal\user\UserDataInterface $user_data + * The user data service. + */ + public function __construct($entity_type, $entity_info, Connection $database, PasswordInterface $password, UserDataInterface $user_data) { + parent::__construct($entity_type, $entity_info, $database); + + $this->password = $password; + $this->userData = $user_data; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) { + return new static( + $entity_type, + $entity_info, + $container->get('database'), + $container->get('password'), + $container->get('user.data') + ); + } + + /** * Overrides Drupal\Core\Entity\DatabaseStorageController::attachLoad(). */ function attachLoad(&$queried_users, $load_revision = FALSE) { @@ -62,7 +114,7 @@ public function create(array $values) { */ public function save(EntityInterface $entity) { if (empty($entity->uid)) { - $entity->uid = db_next_id(db_query('SELECT MAX(uid) FROM {users}')->fetchField()); + $entity->uid = $this->database->nextId(db_query('SELECT MAX(uid) FROM {users}')->fetchField()); $entity->enforceIsNew(); } parent::save($entity); @@ -75,7 +127,7 @@ protected function preSave(EntityInterface $entity) { // Update the user password if it has changed. if ($entity->isNew() || (!empty($entity->pass) && $entity->pass != $entity->original->pass)) { // Allow alternate password hashing schemes. - $entity->pass = drupal_container()->get('password')->hash(trim($entity->pass)); + $entity->pass = $this->password->hash(trim($entity->pass)); // Abort if the hashing failed and returned FALSE. if (!$entity->pass) { throw new EntityMalformedException('The entity does not have a password.'); @@ -98,7 +150,7 @@ protected function preSave(EntityInterface $entity) { // Store account cancellation information. foreach (array('user_cancel_method', 'user_cancel_notify') as $key) { if (isset($entity->{$key})) { - drupal_container()->get('user.data')->set('user', $entity->id(), substr($key, 5), $entity->{$key}); + $this->userData->set('user', $entity->id(), substr($key, 5), $entity->{$key}); } } } @@ -123,11 +175,11 @@ protected function postSave(EntityInterface $entity, $update) { // Reload user roles if provided. if ($entity->roles != $entity->original->roles) { - db_delete('users_roles') + $this->database->delete('users_roles') ->condition('uid', $entity->uid) ->execute(); - $query = db_insert('users_roles')->fields(array('uid', 'rid')); + $query = $this->database->insert('users_roles')->fields(array('uid', 'rid')); foreach (array_keys($entity->roles) as $rid) { if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { $query->values(array( @@ -154,7 +206,7 @@ protected function postSave(EntityInterface $entity, $update) { else { // Save user roles. if (count($entity->roles) > 1) { - $query = db_insert('users_roles')->fields(array('uid', 'rid')); + $query = $this->database->insert('users_roles')->fields(array('uid', 'rid')); foreach (array_keys($entity->roles) as $rid) { if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { $query->values(array( @@ -172,9 +224,9 @@ protected function postSave(EntityInterface $entity, $update) { * Overrides Drupal\Core\Entity\DatabaseStorageController::postDelete(). */ protected function postDelete($entities) { - db_delete('users_roles') + $this->database->delete('users_roles') ->condition('uid', array_keys($entities), 'IN') ->execute(); - drupal_container()->get('user.data')->delete(NULL, array_keys($entities)); + $this->userData->delete(NULL, array_keys($entities)); } } diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php index 40f0086..56bc02a 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewAddFormController.php @@ -7,14 +7,47 @@ namespace Drupal\views_ui; +use Drupal\Core\Entity\EntityControllerInterface; use Drupal\views\Plugin\views\wizard\WizardPluginBase; use Drupal\views\Plugin\views\wizard\WizardException; -use Drupal\views\Views; +use Drupal\views\Plugin\ViewsPluginManager; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Form controller for the Views edit form. */ -class ViewAddFormController extends ViewFormControllerBase { +class ViewAddFormController extends ViewFormControllerBase implements EntityControllerInterface { + + /** + * The wizard plugin manager. + * + * @var \Drupal\views\Plugin\ViewsPluginManager + */ + protected $wizardManager; + + /** + * Constructs a new ViewEditFormController object. + * + * @param string $operation + * The name of the current operation. + * @param \Drupal\views\Plugin\ViewsPluginManager $wizard_manager + * The wizard plugin manager. + */ + public function __construct($operation, ViewsPluginManager $wizard_manager) { + parent::__construct($operation); + + $this->wizardManager = $wizard_manager; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info, $operation = NULL) { + return new static( + $operation, + $container->get('plugin.manager.views.wizard') + ); + } /** * {@inheritdoc} @@ -97,7 +130,7 @@ public function form(array $form, array &$form_state) { // Create the "Show" dropdown, which allows the base table of the view to be // selected. - $wizard_plugins = Views::pluginManager('wizard')->getDefinitions(); + $wizard_plugins = $this->wizardManager->getDefinitions(); $options = array(); foreach ($wizard_plugins as $key => $wizard) { $options[$key] = $wizard['title']; @@ -116,7 +149,7 @@ public function form(array $form, array &$form_state) { // Build the rest of the form based on the currently selected wizard plugin. $wizard_key = $show_form['wizard_key']['#default_value']; - $wizard_instance = Views::pluginManager('wizard')->createInstance($wizard_key); + $wizard_instance = $this->wizardManager->createInstance($wizard_key); $form = $wizard_instance->build_form($form, $form_state); return $form; @@ -144,7 +177,7 @@ protected function actions(array $form, array &$form_state) { */ public function validate(array $form, array &$form_state) { $wizard_type = $form_state['values']['show']['wizard_key']; - $wizard_instance = Views::pluginManager('wizard')->createInstance($wizard_type); + $wizard_instance = $this->wizardManager->createInstance($wizard_type); $form_state['wizard'] = $wizard_instance->getDefinition(); $form_state['wizard_instance'] = $wizard_instance; $errors = $form_state['wizard_instance']->validateView($form, $form_state); diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php index 9f3e0b6..b35ee01 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewEditFormController.php @@ -12,11 +12,57 @@ use Drupal\Core\Ajax\ReplaceCommand; use Drupal\Component\Utility\NestedArray; use Drupal\views\ViewExecutable; +use Drupal\Core\Entity\EntityControllerInterface; +use Drupal\user\TempStoreFactory; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Form controller for the Views edit form. */ -class ViewEditFormController extends ViewFormControllerBase { +class ViewEditFormController extends ViewFormControllerBase implements EntityControllerInterface { + + /** + * The views temp store. + * + * @var \Drupal\user\TempStore + */ + protected $tempStore; + + /** + * The request object. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; + + /** + * Constructs a new ViewEditFormController object. + * + * @param string $operation + * The name of the current operation. + * @param \Drupal\user\TempStoreFactory $temp_store_factory + * The factory for the temp store object. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + */ + public function __construct($operation, TempStoreFactory $temp_store_factory, Request $request) { + parent::__construct($operation); + + $this->tempStore = $temp_store_factory->get('views'); + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info, $operation = NULL) { + return new static( + $operation, + $container->get('user.tempstore'), + $container->get('request') + ); + } /** * Overrides Drupal\Core\Entity\EntityFormController::form(). @@ -222,10 +268,9 @@ public function submit(array $form, array &$form_state) { } $view->set('display', $displays); - // Direct the user to the right url, if the path of the display has changed. - $query = drupal_container()->get('request')->query; // @todo: Revisit this when http://drupal.org/node/1668866 is in. - $destination = $query->get('destination'); + $destination = $this->request->query->get('destination'); + if (!empty($destination)) { // Find out the first display which has a changed path and redirect to this url. $old_view = views_get_view($view->id()); @@ -252,7 +297,7 @@ public function submit(array $form, array &$form_state) { drupal_set_message(t('The view %name has been saved.', array('%name' => $view->label()))); // Remove this view from cache so we can edit it properly. - drupal_container()->get('user.tempstore')->get('views')->delete($view->id()); + $this->tempStore->delete($view->id()); } /** @@ -266,7 +311,7 @@ public function submit(array $form, array &$form_state) { public function cancel(array $form, array &$form_state) { // Remove this view from cache so edits will be lost. $view = $this->entity; - drupal_container()->get('user.tempstore')->get('views')->delete($view->id()); + $this->tempStore->delete($view->id()); $form_state['redirect'] = 'admin/structure/views'; } @@ -707,7 +752,7 @@ public function renderDisplayTop(ViewUI $view) { * should not yet redirect to the destination. */ public function submitDelayDestination($form, &$form_state) { - $query = \Drupal::request()->query; + $query = $this->request->query; // @todo: Revisit this when http://drupal.org/node/1668866 is in. $destination = $query->get('destination'); if (isset($destination) && $form_state['redirect'] !== FALSE) { diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php index 3a8adf6..b18c471 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewPreviewFormController.php @@ -7,10 +7,45 @@ namespace Drupal\views_ui; +use Drupal\Core\Entity\EntityControllerInterface; +use Drupal\user\TempStoreFactory; +use Symfony\Component\DependencyInjection\ContainerInterface; + /** * Form controller for the Views preview form. */ -class ViewPreviewFormController extends ViewFormControllerBase { +class ViewPreviewFormController extends ViewFormControllerBase implements EntityControllerInterface { + + /** + * The views temp store. + * + * @var \Drupal\user\TempStore + */ + protected $tempStore; + + /** + * Constructs a new ViewPreviewFormController object. + * + * @param string $operation + * The name of the current operation. + * @param \Drupal\user\TempStoreFactory $temp_store_factory + * The factory for the temp store object. + */ + public function __construct($operation, TempStoreFactory $temp_store_factory) { + parent::__construct($operation); + + $this->tempStore = $temp_store_factory->get('views'); + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info, $operation = NULL) { + return new static( + $operation, + $container->get('user.tempstore') + ); + } /** * Overrides Drupal\Core\Entity\EntityFormController::form(). @@ -99,7 +134,7 @@ public function submitPreview($form, &$form_state) { // Rebuild the form with a pristine $view object. $view = $this->entity; // Attempt to load the view from temp store, otherwise create a new one. - if (!$new_view = drupal_container()->get('user.tempstore')->get('views')->get($view->id())) { + if (!$new_view = $this->tempStore->get($view->id())) { $new_view = new ViewUI($view); } $form_state['build_info']['args'][0] = $new_view;