diff --git a/core/modules/rest/src/CacheableResourceResponse.php b/core/modules/rest/src/CacheableResourceResponse.php index ff4180c..897022d 100644 --- a/core/modules/rest/src/CacheableResourceResponse.php +++ b/core/modules/rest/src/CacheableResourceResponse.php @@ -12,7 +12,7 @@ use Symfony\Component\HttpFoundation\Response; -class CacheableResourceResponse extends Response implements CacheableResponseInterface { +class CacheableResourceResponse extends Response implements CacheableResponseInterface, ResourceResponseInterface { use CacheableResponseTrait; use ResourceResponseTrait; diff --git a/core/modules/rest/src/Plugin/rest/resource/UserRegistrationResource.php b/core/modules/rest/src/Plugin/rest/resource/UserRegistrationResource.php index 732cdba..552e56c 100644 --- a/core/modules/rest/src/Plugin/rest/resource/UserRegistrationResource.php +++ b/core/modules/rest/src/Plugin/rest/resource/UserRegistrationResource.php @@ -7,12 +7,8 @@ namespace Drupal\rest\Plugin\rest\resource; -use Drupal\Core\Config\Config; -use Drupal\Core\Render\RenderContext; -use Drupal\Core\Render\RendererInterface; +use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\Session\AccountInterface; -use Drupal\rest\CacheableResourceResponse; -use Drupal\rest\ResourceResponse; use Drupal\rest\UncacheableResourceResponse; use Drupal\user\UserInterface; use Psr\Log\LoggerInterface; @@ -49,13 +45,6 @@ class UserRegistrationResource extends ResourceBase { protected $currentUser; /** - * The renderer. - * - * @var \Drupal\Core\Render\RendererInterface - */ - protected $renderer; - - /** * Constructs a new RestPermissions instance. * * @param array $configuration @@ -72,14 +61,11 @@ class UserRegistrationResource extends ResourceBase { * A user settings config instance. * @param \Drupal\Core\Session\AccountInterface $current_user * A user settings config instance. - * @param \Drupal\Core\Render\RendererInterface $renderer - * The renderer. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, ImmutableConfig $user_settings, AccountInterface $current_user, RendererInterface $renderer) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, ImmutableConfig $user_settings, AccountInterface $current_user) { parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); $this->userSettings = $user_settings; $this->currentUser = $current_user; - $this->renderer = $renderer; } /** @@ -93,8 +79,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->getParameter('serializer.formats'), $container->get('logger.factory')->get('rest'), $container->get('config.factory')->get('user.settings'), - $container->get('current_user'), - $container->get('renderer') + $container->get('current_user') ); } @@ -146,16 +131,16 @@ public function post(UserInterface $account = NULL) { // Make sure that the user entity is valid (email and name are valid). $this->validate($account); - + // Create the account. $account->save(); - // Send emails from a render context to add bubbleable_metadata to the - // response. + $register = $this->userSettings->get('register'); // No email verification is required. Activating the user. if ($register == 'visitors') { if (!$this->userSettings->get('verify_mail')) { // Notification will be sent if activated. $account->activate(); + // Save changes to apply active status to the account. $account->save(); } // No administrator approval required. @@ -181,7 +166,7 @@ public function routes() { $collection = new RouteCollection(); $route = $this->getBaseRoute('/entity/user/register', 'POST'); - $route->setPath('/entity/user/register'); + // Restrict the incoming HTTP Content-type header to the known // serialization formats. $route->addRequirements(array('_content_type_format' => implode('|', $this->serializerFormats))); diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php index f525985..6dcb39f 100644 --- a/core/modules/rest/src/RequestHandler.php +++ b/core/modules/rest/src/RequestHandler.php @@ -7,6 +7,7 @@ namespace Drupal\rest; +use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\Render\RenderContext; use Drupal\Core\Routing\RouteMatchInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; @@ -103,26 +104,35 @@ public function handle(RouteMatchInterface $route_match, Request $request) { } // Serialize the outgoing data for the response, if available. - if ($response instanceof CacheableResourceResponse && $data = $response->getResponseData()) { - // Serialization can invoke rendering (e.g., generating URLs), but the - // serialization API does not provide a mechanism to collect the - // bubbleable metadata associated with that (e.g., language and other - // contexts), so instead, allow those to "leak" and collect them here in - // a render context. - // @todo Add test coverage for language negotiation contexts in - // https://www.drupal.org/node/2135829. - $context = new RenderContext(); - $output = $this->container->get('renderer')->executeInRenderContext($context, function() use ($serializer, $data, $format) { - return $serializer->serialize($data, $format); - }); - $response->setContent($output); - if (!$context->isEmpty()) { - $response->addCacheableDependency($context->pop()); - } + if ($response instanceof ResourceResponseInterface && $data = $response->getResponseData()) { + // Cacheable Response. + if ($response instanceof CacheableResponseInterface) { + // Serialization can invoke rendering (e.g., generating URLs), but the + // serialization API does not provide a mechanism to collect the + // bubbleable metadata associated with that (e.g., language and other + // contexts), so instead, allow those to "leak" and collect them here in + // a render context. + // @todo Add test coverage for language negotiation contexts in + // https://www.drupal.org/node/2135829. + $context = new RenderContext(); + $output = $this->container->get('renderer')->executeInRenderContext($context, function () use ($serializer, $data, $format) { + return $serializer->serialize($data, $format); + }); + $response->setContent($output); + if (!$context->isEmpty()) { + $response->addCacheableDependency($context->pop()); + } - $response->headers->set('Content-Type', $request->getMimeType($format)); - // Add rest settings config's cache tags. - $response->addCacheableDependency($this->container->get('config.factory')->get('rest.settings')); + $response->headers->set('Content-Type', $request->getMimeType($format)); + // Add rest settings config's cache tags. + $response->addCacheableDependency($this->container->get('config.factory')->get('rest.settings')); + } + else { + // Uncacheable Response. + $output = $serializer->serialize($data, $format); + $response->setContent($output); + $response->headers->set('Content-Type', $request->getMimeType($format)); + } } return $response; } diff --git a/core/modules/rest/src/ResourceResponseInterface.php b/core/modules/rest/src/ResourceResponseInterface.php new file mode 100644 index 0000000..a889dae --- /dev/null +++ b/core/modules/rest/src/ResourceResponseInterface.php @@ -0,0 +1,23 @@ +drupalGetHeader('location')); $id = end($url_parts); - $this->assertHeader('Location', 'user/' . $id); + $this->assertHeader('Location', 'http://drupal8/user/' . $id); $this->assertTrue((bool) \Drupal::entityQuery('user') ->condition('name', 'Druplicon') diff --git a/core/modules/rest/src/UncacheableResourceResponse.php b/core/modules/rest/src/UncacheableResourceResponse.php index 74e2cc1..0c4eb9b 100644 --- a/core/modules/rest/src/UncacheableResourceResponse.php +++ b/core/modules/rest/src/UncacheableResourceResponse.php @@ -9,7 +9,7 @@ use Symfony\Component\HttpFoundation\Response; -class UncacheableResourceResponse extends Response { +class UncacheableResourceResponse extends Response implements ResourceResponseInterface { use ResourceResponseTrait; diff --git a/core/modules/rest/tests/src/Unit/UserRegistrationResourceTest.php b/core/modules/rest/tests/src/Unit/UserRegistrationResourceTest.php index 18f95f7..c3f3f2c 100644 --- a/core/modules/rest/tests/src/Unit/UserRegistrationResourceTest.php +++ b/core/modules/rest/tests/src/Unit/UserRegistrationResourceTest.php @@ -50,7 +50,8 @@ protected function setUp() { parent::setUp(); $this->logger = $this->getMock('Psr\Log\LoggerInterface'); - $this->userSettings = $this->getMockBuilder('Drupal\Core\Config\Config') + + $this->userSettings = $this->getMockBuilder('Drupal\Core\Config\ImmutableConfig') ->setMethods(['get']) ->disableOriginalConstructor() ->getMock(); @@ -59,11 +60,7 @@ protected function setUp() { ->disableOriginalConstructor() ->getMock(); - $this->renderer = $this->getMockBuilder('Drupal\Core\Render\RendererInterface') - ->disableOriginalConstructor() - ->getMock(); - - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser, $this->renderer); + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser); $this->reflection = new \ReflectionClass($this->testClass); } @@ -176,7 +173,7 @@ public function testRegistrationAdminOnlyPost() { ->method('get') ->will($this->returnValue(USER_REGISTER_ADMINISTRATORS_ONLY)); - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser, $this->renderer); + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser); $entity = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() ->getMock(); @@ -197,7 +194,7 @@ public function testRegistrationAnonymousOnlyPost() { ->method('isAnonymous') ->will($this->returnValue(FALSE)); - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser, $this->renderer); + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser); $entity = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() ->getMock(); @@ -217,7 +214,7 @@ public function testFieldAccessValidation() { ->method('isAnonymous') ->will($this->returnValue(TRUE)); - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser, $this->renderer); + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings, $this->currentUser); $entity = $this->getMockBuilder('Drupal\user\Entity\User') ->disableOriginalConstructor() ->getMock();