From 503103058f6a426f6682b92ec3482b91f0092d72 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Thu, 8 Aug 2013 01:57:58 +0200 Subject: [PATCH] Issue #2011122 by hussainweb, kgoel, chrisjlee: Replace drupal_container() with injected services in the rest module. --- .../lib/Drupal/rest/Plugin/ResourceBase.php | 44 +++++++++++++- .../Plugin/Type/ResourcePluginManager.php | 32 +++++----- .../rest/Plugin/views/display/RestExport.php | 58 +++++++++++++++++-- .../rest/lib/Drupal/rest/Tests/CreateTest.php | 2 +- .../lib/Drupal/rest/Tests/RESTTestBase.php | 2 +- .../rest/lib/Drupal/rest/Tests/UpdateTest.php | 2 +- .../rest/Tests/Views/StyleSerializerTest.php | 2 +- core/modules/rest/rest.module | 14 ++--- core/modules/rest/rest.services.yml | 9 ++- 9 files changed, 128 insertions(+), 37 deletions(-) diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php b/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php index e851352253c..b829c7c02b4 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/ResourceBase.php @@ -8,13 +8,51 @@ namespace Drupal\rest\Plugin; use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; /** * Common base class for resource plugins. */ -abstract class ResourceBase extends PluginBase implements ResourceInterface { +abstract class ResourceBase extends PluginBase implements ContainerFactoryPluginInterface, ResourceInterface { + + /** + * The available serialization formats. + * + * @var array + */ + protected $serializerFormats = array(); + + /** + * Constructs a Drupal\rest\Plugin\ResourceBase object. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param array $plugin_definition + * The plugin implementation definition. + * @param array $serializer_formats + * The available serialization formats. + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, array $serializer_formats) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->serializerFormats = $serializer_formats; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->getParameter('serializer.formats') + ); + } /** * Implements ResourceInterface::permissions(). @@ -68,8 +106,7 @@ abstract class ResourceBase extends PluginBase implements ResourceInterface { case 'HEAD': // Restrict GET and HEAD requests to the media type specified in the // HTTP Accept headers. - $formats = drupal_container()->getParameter('serializer.formats'); - foreach ($formats as $format_name) { + foreach ($this->serializerFormats as $format_name) { // Expose one route per available format. //$format_route = new Route($route->getPattern(), $route->getDefaults(), $route->getRequirements()); $format_route = clone $route; @@ -124,4 +161,5 @@ abstract class ResourceBase extends PluginBase implements ResourceInterface { } return $available; } + } diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/Type/ResourcePluginManager.php b/core/modules/rest/lib/Drupal/rest/Plugin/Type/ResourcePluginManager.php index 602063458ca..0ad6b0fab9c 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/Type/ResourcePluginManager.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/Type/ResourcePluginManager.php @@ -7,33 +7,35 @@ namespace Drupal\rest\Plugin\Type; -use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator; -use Drupal\Component\Plugin\Factory\ReflectionFactory; -use Drupal\Component\Plugin\PluginManagerBase; -use Drupal\Core\Plugin\Discovery\AlterDecorator; -use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Language\LanguageManager; +use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\Plugin\Discovery\CacheDecorator; /** * Manages discovery and instantiation of resource plugins. */ -class ResourcePluginManager extends PluginManagerBase { +class ResourcePluginManager extends DefaultPluginManager { /** - * Overrides Drupal\Component\Plugin\PluginManagerBase::__construct(). + * Constructs a new \Drupal\rest\Plugin\Type\ResourcePluginManager object. * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations, + * keyed by the corresponding namespace to look for plugin implementations. + * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend + * Cache backend instance to use. + * @param \Drupal\Core\Language\LanguageManager $language_manager + * The language manager. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler to invoke the alter hook with. */ - public function __construct(\Traversable $namespaces) { - // Create resource plugin derivatives from declaratively defined resources. - $this->discovery = new AnnotatedClassDiscovery('Plugin/rest/resource', $namespaces); - $this->discovery = new DerivativeDiscoveryDecorator($this->discovery); - $this->discovery = new AlterDecorator($this->discovery, 'rest_resource'); - $this->discovery = new CacheDecorator($this->discovery, 'rest'); + public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) { + parent::__construct('Plugin/rest/resource', $namespaces); - $this->factory = new ReflectionFactory($this->discovery); + $this->setCacheBackend($cache_backend, $language_manager, 'rest_plugins'); + $this->alterInfo($module_handler, 'rest_resource'); } /** diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/views/display/RestExport.php b/core/modules/rest/lib/Drupal/rest/Plugin/views/display/RestExport.php index 694a4225faa..33a7e6b6c52 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/views/display/RestExport.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/views/display/RestExport.php @@ -9,8 +9,11 @@ namespace Drupal\rest\Plugin\views\display; use Drupal\Component\Annotation\Plugin; use Drupal\Core\Annotation\Translation; +use Drupal\Core\ContentNegotiation; use Drupal\views\ViewExecutable; use Drupal\views\Plugin\views\display\PathPluginBase; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\RouteCollection; @@ -69,17 +72,60 @@ class RestExport extends PathPluginBase { */ protected $mimeType; + /** + * The content negotiation library. + * + * @var \Drupal\Core\ContentNegotiation + */ + protected $contentNegotiation; + + /** + * The request object. + * + * @var \Symfony\Component\HttpFoundation\Request + */ + protected $request; + + /** + * Constructs a Drupal\rest\Plugin\ResourceBase object. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param array $plugin_definition + * The plugin implementation definition. + * @param \Drupal\Core\ContentNegotiation $content_negotiation + * The content negotiation library. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, ContentNegotiation $content_negotiation, Request $request) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->contentNegotiation = $content_negotiation; + $this->request = $request; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('content_negotiation'), + $container->get('request') + ); + } + /** * {@inheritdoc} */ public function initDisplay(ViewExecutable $view, array &$display, array &$options = NULL) { parent::initDisplay($view, $display, $options); - $container = drupal_container(); - $negotiation = $container->get('content_negotiation'); - $request = $container->get('request'); - - $request_content_type = $negotiation->getContentType($request); + $request_content_type = $this->contentNegotiation->getContentType($this->request); // Only use the requested content type if it's not 'html'. If it is then // default to 'json' to aid debugging. // @todo Remove the need for this when we have better content negotiation. @@ -87,7 +133,7 @@ class RestExport extends PathPluginBase { $this->setContentType($request_content_type); } - $this->setMimeType($request->getMimeType($this->contentType)); + $this->setMimeType($this->request->getMimeType($this->contentType)); } /** diff --git a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php index 00ca7e58fd8..0a75cb397e3 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php @@ -33,7 +33,7 @@ class CreateTest extends RESTTestBase { * Tests several valid and invalid create requests on all entity types. */ public function testCreate() { - $serializer = drupal_container()->get('serializer'); + $serializer = $this->container->get('serializer'); $entity_types = array('entity_test', 'node'); foreach ($entity_types as $entity_type) { diff --git a/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php b/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php index 6ad900042a8..7f5417794ba 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/RESTTestBase.php @@ -209,7 +209,7 @@ abstract class RESTTestBase extends WebTestBase { $config->save(); // Rebuild routing cache, so that the REST API paths are available. - drupal_container()->get('router.builder')->rebuild(); + $this->container->get('router.builder')->rebuild(); // Reset the Simpletest permission cache, so that the new resource // permissions get picked up. drupal_static_reset('checkPermissions'); diff --git a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php index 0c17d6e1868..b417f2aa119 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php @@ -33,7 +33,7 @@ class UpdateTest extends RESTTestBase { * Tests several valid and invalid partial update requests on test entities. */ public function testPatchUpdate() { - $serializer = drupal_container()->get('serializer'); + $serializer = $this->container->get('serializer'); // @todo once EntityNG is implemented for other entity types test all other // entity types here as well. $entity_type = 'entity_test'; diff --git a/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php b/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php index 332310e4ad6..48bf9556ef2 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php @@ -109,7 +109,7 @@ class StyleSerializerTest extends PluginTestBase { $this->executeView($view); // Get the serializer service. - $serializer = drupal_container()->get('serializer'); + $serializer = $this->container->get('serializer'); $entities = array(); foreach ($view->result as $row) { diff --git a/core/modules/rest/rest.module b/core/modules/rest/rest.module index 9fe2674860c..d0e055143ac 100644 --- a/core/modules/rest/rest.module +++ b/core/modules/rest/rest.module @@ -10,14 +10,12 @@ */ function rest_permission() { $permissions = array(); - if (drupal_container()->has('plugin.manager.rest')) { - $manager = drupal_container()->get('plugin.manager.rest'); - $resources = config('rest.settings')->get('resources'); - if ($resources && $enabled = array_intersect_key($manager->getDefinitions(), $resources)) { - foreach ($enabled as $key => $resource) { - $plugin = $manager->getInstance(array('id' => $key)); - $permissions = array_merge($permissions, $plugin->permissions()); - } + $manager = Drupal::service('plugin.manager.rest'); + $resources = config('rest.settings')->get('resources'); + if ($resources && $enabled = array_intersect_key($manager->getDefinitions(), $resources)) { + foreach ($enabled as $key => $resource) { + $plugin = $manager->getInstance(array('id' => $key)); + $permissions = array_merge($permissions, $plugin->permissions()); } } return $permissions; diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml index 97817addae6..d238442e03a 100644 --- a/core/modules/rest/rest.services.yml +++ b/core/modules/rest/rest.services.yml @@ -1,7 +1,14 @@ services: plugin.manager.rest: class: Drupal\rest\Plugin\Type\ResourcePluginManager - arguments: ['@container.namespaces'] + arguments: ['@container.namespaces', '@cache.rest', '@language_manager', '@module_handler'] + cache.rest: + class: Drupal\Core\Cache\CacheBackendInterface + tags: + - { name: cache.bin } + factory_method: get + factory_service: cache_factory + arguments: [rest] rest.route_subscriber: class: Drupal\rest\EventSubscriber\RouteSubscriber tags: