diff --git a/jsonapi_extras.info.yml b/jsonapi_extras.info.yml index 622f2bbf38b83dcf9e47428b033f6c75e7efc8a0..deeb2d8f652d5ac6ef555455d419148d9d7d9da3 100644 --- a/jsonapi_extras.info.yml +++ b/jsonapi_extras.info.yml @@ -4,4 +4,4 @@ description: Builds on top of JSON API to deliver extra functionality. core: 8.x package: Web services dependencies: - - jsonapi:jsonapi + - jsonapi:jsonapi (>=8.x-1.10) diff --git a/src/EventSubscriber/JsonApiExtrasRouteAlterSubscriber.php b/src/EventSubscriber/JsonApiExtrasRouteAlterSubscriber.php index af53cec7fad75bb03e53e9afbc3152d221f60419..92cea84d8055df5c1595e21faa2b384df6a08fa0 100644 --- a/src/EventSubscriber/JsonApiExtrasRouteAlterSubscriber.php +++ b/src/EventSubscriber/JsonApiExtrasRouteAlterSubscriber.php @@ -58,8 +58,7 @@ class JsonApiExtrasRouteAlterSubscriber implements EventSubscriberInterface { $collection->get('jsonapi.resource_list') ->setPath($path); - /** @var \Drupal\jsonapi_extras\ResourceType\ConfigurableResourceType $resource_type */ - foreach ($this->resourceTypeRepository->all() as $resource_type) { + foreach ($this->getEnabledResourceTypes() as $resource_type) { // Overwrite routes. $paths = $this->getPathsForResourceType($resource_type, $prefix); foreach ($paths as $route_name => $path) { @@ -111,4 +110,17 @@ class JsonApiExtrasRouteAlterSubscriber implements EventSubscriberInterface { return $paths; } + /** + * Get all the enabled resources. + * + * @return \Drupal\jsonapi_extras\ResourceType\ConfigurableResourceType[] + * The enabled resource types. + */ + protected function getEnabledResourceTypes() { + $all = $this->resourceTypeRepository->all(); + return array_filter($all, function (ConfigurableResourceType $resource_type) { + return !$resource_type->isInternal(); + }); + } + } diff --git a/src/JsonapiResourceConfigListBuilder.php b/src/JsonapiResourceConfigListBuilder.php index 5d22f41237a453c14348dc6f79037ea6b7840a0a..48476de379a0863b38e16ffe9ab68dd58a9a3397 100644 --- a/src/JsonapiResourceConfigListBuilder.php +++ b/src/JsonapiResourceConfigListBuilder.php @@ -140,7 +140,7 @@ class JsonapiResourceConfigListBuilder extends ConfigEntityListBuilder { } $prefix = $this->config->get('path_prefix'); - foreach ($this->resourceTypeRepository->getResourceTypes(TRUE) as $resource_type) { + foreach ($this->resourceTypeRepository->all() as $resource_type) { /** @var \Drupal\jsonapi_extras\ResourceType\ConfigurableResourceType $resource_type */ $entity_type_id = $resource_type->getEntityTypeId(); $bundle = $resource_type->getBundle(); diff --git a/src/ResourceType/ConfigurableResourceTypeRepository.php b/src/ResourceType/ConfigurableResourceTypeRepository.php index f07c4eadd3dad19bccefa212cda237076f63a310..96c05d18105b202ae0482b6a9c2739172fd77f4b 100644 --- a/src/ResourceType/ConfigurableResourceTypeRepository.php +++ b/src/ResourceType/ConfigurableResourceTypeRepository.php @@ -5,10 +5,8 @@ namespace Drupal\jsonapi_extras\ResourceType; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityRepositoryInterface; -use Drupal\jsonapi\ResourceType\ResourceType; use Drupal\jsonapi\ResourceType\ResourceTypeRepository; use Drupal\jsonapi_extras\Plugin\ResourceFieldEnhancerManager; -use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; @@ -76,46 +74,10 @@ class ConfigurableResourceTypeRepository extends ResourceTypeRepository { */ public function all() { if (!$this->all) { - $this->all = $this->getResourceTypes(FALSE); - } - return $this->all; - } - - /** - * {@inheritdoc} - */ - public function get($entity_type_id, $bundle) { - if (empty($entity_type_id)) { - throw new PreconditionFailedHttpException('Server error. The current route is malformed.'); - } - - foreach ($this->getResourceTypes(FALSE) as $resource) { - if ($resource->getEntityTypeId() == $entity_type_id && $resource->getBundle() == $bundle) { - return $resource; - } - } - - return NULL; - } - - /** - * Returns an array of resource types. - * - * @param bool $include_disabled - * TRUE to included disabled resource types. - * - * @return array - * An array of resource types. - * - * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException - */ - public function getResourceTypes($include_disabled = TRUE) { - if (!isset($this->resourceTypes)) { - $this->resourceTypes = []; foreach ($this->getEntityTypeBundleTuples() as $tuple) { list($entity_type_id, $bundle) = $tuple; $resource_config_id = sprintf('%s--%s', $entity_type_id, $bundle); - $this->resourceTypes[] = new ConfigurableResourceType( + $this->all[] = new ConfigurableResourceType( $entity_type_id, $bundle, $this->entityTypeManager->getDefinition($entity_type_id)->getClass(), @@ -124,22 +86,12 @@ class ConfigurableResourceTypeRepository extends ResourceTypeRepository { $this->configFactory ); } - foreach ($this->resourceTypes as $resource_type) { + foreach ($this->all as $resource_type) { $relatable_resource_types = $this->calculateRelatableResourceTypes($resource_type); $resource_type->setRelatableResourceTypes($relatable_resource_types); } } - - if (!isset($this->enabledResourceTypes) && !$include_disabled) { - $this->enabledResourceTypes = $this->filterOutDisabledResourceTypes( - $this->resourceTypes, - $this->getResourceConfigs() - ); - } - - return ($include_disabled) ? - $this->resourceTypes : - $this->enabledResourceTypes; + return $this->all; } /** @@ -180,29 +132,6 @@ class ConfigurableResourceTypeRepository extends ResourceTypeRepository { return $resource_configs; } - /** - * Takes a list of resource types and removes the disabled from it. - * - * @param \Drupal\jsonapi\ResourceType\ResourceType[] $resource_types - * The list of resource types including disabled ones. - * @param \Drupal\Core\Entity\EntityInterface[] $resource_configs - * The configuration entities that accompany the resource types. - * - * @return \Drupal\jsonapi\ResourceType\ResourceType[] - * The list of enabled resource types. - */ - protected function filterOutDisabledResourceTypes($resource_types, $resource_configs) { - return array_filter($resource_types, function (ResourceType $resource_type) use ($resource_configs) { - $resource_config_id = sprintf( - '%s--%s', - $resource_type->getEntityTypeId(), - $resource_type->getBundle() - ); - $resource_config = isset($resource_configs[$resource_config_id]) ? $resource_configs[$resource_config_id] : new NullJsonapiResourceConfig([], ''); - return !$resource_config->get('disabled'); - }); - } - /** * Entity type ID and bundle iterator. * diff --git a/tests/src/Functional/JsonExtrasApiFunctionalTest.php b/tests/src/Functional/JsonExtrasApiFunctionalTest.php index 1a97821f22814839f3955e2222249bb6b9e0bf04..a0ee8390d0529df48ee7acd2dd6b9dbb2dfaadec 100644 --- a/tests/src/Functional/JsonExtrasApiFunctionalTest.php +++ b/tests/src/Functional/JsonExtrasApiFunctionalTest.php @@ -5,6 +5,8 @@ namespace Drupal\Tests\jsonapi_extras\Functional; use Drupal\Component\Serialization\Json; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Url; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; use Drupal\jsonapi_extras\Entity\JsonapiResourceConfig; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; @@ -46,6 +48,26 @@ class JsonExtrasApiFunctionalTest extends JsonApiFunctionalTestBase { FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ); + FieldStorageConfig::create([ + 'field_name' => 'field_timestamp', + 'entity_type' => 'node', + 'type' => 'timestamp', + 'settings' => [], + 'cardinality' => 1, + ])->save(); + + $field_config = FieldConfig::create([ + 'field_name' => 'field_timestamp', + 'label' => 'Timestamp', + 'entity_type' => 'node', + 'bundle' => 'article', + 'required' => FALSE, + 'settings' => [], + 'description' => '', + ]); + $field_config->save(); + + $config = \Drupal::configFactory()->getEditable('jsonapi_extras.settings'); $config->set('path_prefix', 'api'); $config->set('include_count', TRUE); @@ -53,6 +75,8 @@ class JsonExtrasApiFunctionalTest extends JsonApiFunctionalTestBase { $this->grantPermissions(Role::load(Role::ANONYMOUS_ID), ['access jsonapi resource list']); static::overrideResources(); $this->resetAll(); + $role = $this->user->get('roles')[0]->entity; + $this->grantPermissions($role, ['administer nodes', 'administer site configuration']); } /** @@ -161,9 +185,9 @@ class JsonExtrasApiFunctionalTest extends JsonApiFunctionalTestBase { $this->tags[1]->vocabs->set(0, 'tags'); $this->tags[1]->save(); $output = Json::decode($this->drupalGet('/api/taxonomy_term/tags/' . $this->tags[0]->uuid() . '/vocabs')); - $this->assertEmpty($output['data']); + $this->assertTrue(empty($output['data'])); $output = Json::decode($this->drupalGet('/api/taxonomy_term/tags/' . $this->tags[0]->uuid() . '/relationships/vocabs')); - $this->assertEmpty($output['data']); + $this->assertTrue(empty($output['data'])); // 15. Test included resource. $output = Json::decode($this->drupalGet( @@ -209,11 +233,9 @@ class JsonExtrasApiFunctionalTest extends JsonApiFunctionalTestBase { 'attributes' => [ 'langcode' => 'en', 'title' => 'My custom title', - 'isPublished' => '1', - 'isPromoted' => '1', 'default_langcode' => '1', 'body' => 'Custom value', - 'updatedAt' => '2017-12-23T08:45:17+0100', + 'timestamp' => '2017-12-23T08:45:17+0100', ], 'relationships' => [ 'contentType' => [ @@ -244,9 +266,9 @@ class JsonExtrasApiFunctionalTest extends JsonApiFunctionalTestBase { $this->assertArrayHasKey('internalId', $created_response['data']['attributes']); $this->assertCount(2, $created_response['data']['relationships']['tags']['data']); $this->assertSame($created_response['data']['links']['self'], $response->getHeader('Location')[0]); - $date = new \DateTime($body['data']['attributes']['updatedAt']); + $date = new \DateTime($body['data']['attributes']['timestamp']); $created_node = Node::load($created_response['data']['attributes']['internalId']); - $this->assertSame((int) $date->format('U'), (int) $created_node->getChangedTime()); + $this->assertSame((int) $date->format('U'), (int) $created_node->get('field_timestamp')->value); // 2. Successful relationships PATCH. $uuid = $created_response['data']['id']; @@ -409,6 +431,15 @@ class JsonExtrasApiFunctionalTest extends JsonApiFunctionalTestBase { 'enhancer' => ['id' => 'uuid_link'], 'disabled' => FALSE, ], + 'field_timestamp' => [ + 'fieldName' => 'field_timestamp', + 'publicName' => 'timestamp', + 'enhancer' => [ + 'id' => 'date_time', + 'settings' => ['dateTimeFormat' => 'Y-m-d\TH:i:sO'], + ], + 'disabled' => FALSE, + ], 'comment' => [ 'fieldName' => 'comment', 'publicName' => 'comment',