summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordereine2017-09-07 07:28:41 +0200
committerMateu Aguiló Bosch2017-09-07 07:28:41 +0200
commit79128a7ab815a8fc47b8ca735dde8960839556b6 (patch)
tree82207be1af5f2a964a402de38180b7f77b1d693b
parenta9fedf0b826e088a569c93875773c1713c8ee3d9 (diff)
fix(Performance): Improve the performance of loading resource configs (#2907093 by dagmar, dawehner)
-rw-r--r--src/Entity/JsonapiResourceConfig.php1
-rw-r--r--src/Form/JsonapiResourceConfigForm.php53
-rw-r--r--src/Plugin/Validation/Constraint/DuplicateFieldConstraint.php17
-rw-r--r--src/Plugin/Validation/Constraint/DuplicateFieldConstraintValidator.php83
-rw-r--r--src/ResourceType/ConfigurableResourceTypeRepository.php31
5 files changed, 134 insertions, 51 deletions
diff --git a/src/Entity/JsonapiResourceConfig.php b/src/Entity/JsonapiResourceConfig.php
index 35fea3d..54b829e 100644
--- a/src/Entity/JsonapiResourceConfig.php
+++ b/src/Entity/JsonapiResourceConfig.php
@@ -24,6 +24,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
* },
* config_prefix = "jsonapi_resource_config",
* admin_permission = "administer site configuration",
+ * static_cache = TRUE,
* entity_keys = {
* "id" = "id",
* "label" = "label",
diff --git a/src/Form/JsonapiResourceConfigForm.php b/src/Form/JsonapiResourceConfigForm.php
index 9372d4e..591026b 100644
--- a/src/Form/JsonapiResourceConfigForm.php
+++ b/src/Form/JsonapiResourceConfigForm.php
@@ -165,50 +165,15 @@ class JsonapiResourceConfigForm extends EntityForm {
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
- $form_values = $form_state->getValues();
- $resourceFields = $form_values['resourceFields'];
- $overrides = [];
-
- // Get the field values
- foreach ($resourceFields as $field => $data) {
- // Only get the overridden fields.
- if ($data['fieldName'] != $data['publicName']) {
- // Store the publicName for comparison.
- $overrides[$field] = $data['publicName'];
- }
- }
-
- // Compare the overrides and find any duplicate values.
- $deduped_overrides = array_unique($overrides);
- $dupes = array_diff_assoc($overrides, $deduped_overrides);
- // Set an error if there are duplicates.
- if ($dupes) {
- foreach ($dupes as $field => $value) {
- $form_state->setErrorbyName('resourceFields][' . $field . '][publicName', $this->t('The override must be unique.'));
- }
- }
- // Now compare the overrides with the default names to validate no dupes exist.
- foreach ($overrides as $field => $override) {
- if (array_key_exists($override, $resourceFields)) {
- $form_state->setErrorByName('resourceFields][' . $field . '][publicName', $this->t('The override must be unique.'));
- }
- }
-
- // Validate URL and resource type
- $resource_types = $this->entityTypeManager
- ->getStorage('jsonapi_resource_config')
- ->loadByProperties(['disabled' => FALSE]);
- foreach ($resource_types as $id => $resource_type) {
- if ($this->entity->id() == $id) {
- continue;
- }
-
- if ($resource_type->get('resourceType') == $form_values['resourceType']) {
- $form_state->setErrorByName('resourceType', $this->t('There is already resource (:name) with this override.', [':name' => $resource_type->id()]));
- }
- if ($resource_type->get('path') == $form_values['path']) {
- $form_state->setErrorByName('path', $this->t('There is already resource (:name) with this path.', [':name' => $resource_type->id()]));
- }
+ /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
+ $typed_config_manager = \Drupal::service('config.typed');
+ $typed_config = $typed_config_manager->createFromNameAndData($this->entity->id(), $this->entity->toArray());
+ $constraints = $typed_config->validate();
+
+ /** @var \Symfony\Component\Validator\ConstraintViolation $violation */
+ foreach ($constraints as $violation) {
+ $form_path = str_replace('.', '][', $violation->getPropertyPath());
+ $form_state->setErrorByName($form_path, $violation->getMessage());
}
}
diff --git a/src/Plugin/Validation/Constraint/DuplicateFieldConstraint.php b/src/Plugin/Validation/Constraint/DuplicateFieldConstraint.php
new file mode 100644
index 0000000..cb1cd9b
--- /dev/null
+++ b/src/Plugin/Validation/Constraint/DuplicateFieldConstraint.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Drupal\jsonapi_extras\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Constraint(
+ * id = "jsonapi_extras__duplicate_field",
+ * label = @Translation("Duplicate field", context = "Validation")
+ * )
+ */
+class DuplicateFieldConstraint extends Constraint {
+
+ public $message = 'The override must be unique.';
+
+}
diff --git a/src/Plugin/Validation/Constraint/DuplicateFieldConstraintValidator.php b/src/Plugin/Validation/Constraint/DuplicateFieldConstraintValidator.php
new file mode 100644
index 0000000..45f5c96
--- /dev/null
+++ b/src/Plugin/Validation/Constraint/DuplicateFieldConstraintValidator.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\jsonapi_extras\Plugin\Validation\Constraint;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ */
+class DuplicateFieldConstraintValidator extends ConstraintValidator {
+
+ /**
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+ */
+ protected $entityTypeManager;
+
+ /**
+ * DuplicateFieldConstraintValidator constructor.
+ */
+ public function __construct(EntityTypeManagerInterface $entityTypeManager = NULL) {
+ $this->entityTypeManager = $entityTypeManager ?: \Drupal::entityTypeManager();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate($entity_data, Constraint $constraint) {
+ $resourceFields = $entity_data['resourceFields'];
+ $overrides = [];
+
+ // Get the field values
+ foreach ($resourceFields as $field => $data) {
+ // Only get the overridden fields.
+ if ($data['fieldName'] != $data['publicName']) {
+ // Store the publicName for comparison.
+ $overrides[$field] = $data['publicName'];
+ }
+ }
+
+ // Compare the overrides and find any duplicate values.
+ $deduped_overrides = array_unique($overrides);
+ $dupes = array_diff_assoc($overrides, $deduped_overrides);
+ // Set an error if there are duplicates.
+ if ($dupes) {
+ foreach ($dupes as $field => $value) {
+ $this->context->buildViolation($constraint->message)
+ ->atPath("resourceFields.$field.publicName")
+ ->addViolation();
+ }
+ }
+ // Now compare the overrides with the default names to validate no dupes exist.
+ foreach ($overrides as $field => $override) {
+ if (array_key_exists($override, $resourceFields)) {
+ $this->context->buildViolation($constraint->message)
+ ->atPath("resourceFields.$field.publicName")
+ ->addViolation();
+ }
+ }
+
+ // Validate URL and resource type
+ $resource_types = $this->entityTypeManager
+ ->getStorage('jsonapi_resource_config')
+ ->loadByProperties(['disabled' => FALSE]);
+ foreach ($resource_types as $id => $resource_type) {
+ if ($entity_data['id'] == $id) {
+ continue;
+ }
+
+ if ($resource_type->get('resourceType') == $entity_data['resourceType']) {
+ $this->context->buildViolation('There is already resource (@name) with this resource type.', ['@name' => $resource_type->id()])
+ ->atPath('resourceType')
+ ->addViolation();
+ }
+ if ($resource_type->get('path') == $entity_data['path']) {
+ $this->context->buildViolation('There is already resource (@name) with this path.', ['@name' => $resource_type->id()])
+ ->atPath('resourceType')
+ ->addViolation();
+ }
+ }
+ }
+
+}
diff --git a/src/ResourceType/ConfigurableResourceTypeRepository.php b/src/ResourceType/ConfigurableResourceTypeRepository.php
index a014942..d8ac047 100644
--- a/src/ResourceType/ConfigurableResourceTypeRepository.php
+++ b/src/ResourceType/ConfigurableResourceTypeRepository.php
@@ -35,6 +35,11 @@ class ConfigurableResourceTypeRepository extends ResourceTypeRepository {
protected $configFactory;
/**
+ * @var \Drupal\jsonapi_extras\ResourceType\ConfigurableResourceType[]
+ */
+ protected $resourceTypes;
+
+ /**
* {@inheritdoc}
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_manager, EntityRepositoryInterface $entity_repository, ResourceFieldEnhancerManager $enhancer_manager, ConfigFactoryInterface $config_factory) {
@@ -81,18 +86,29 @@ class ConfigurableResourceTypeRepository extends ResourceTypeRepository {
* An array of resource types.
*/
public function getResourceTypes($include_disabled = TRUE) {
+ if (isset($this->resourceTypes)) {
+ return $this->resourceTypes;
+ }
+
$entity_type_ids = array_keys($this->entityTypeManager->getDefinitions());
$resource_types = [];
+
+ $resource_config_ids = [];
foreach ($entity_type_ids as $entity_type_id) {
$bundles = array_keys($this->bundleManager->getBundleInfo($entity_type_id));
- $current_types = array_map(function ($bundle) use ($entity_type_id, $include_disabled) {
+ $resource_config_ids = array_merge($resource_config_ids, array_map(function ($bundle) use ($entity_type_id) {
+ $resource_config_ids[] = sprintf('%s--%s', $entity_type_id, $bundle);
+ }, $bundles));
+ }
+
+ $resource_configs = $this->entityTypeManager->getStorage('jsonapi_resource_config')->loadMultiple($resource_config_ids);
+
+ foreach ($entity_type_ids as $entity_type_id) {
+ $bundles = array_keys($this->bundleManager->getBundleInfo($entity_type_id));
+ $current_types = array_map(function ($bundle) use ($entity_type_id, $include_disabled, $resource_configs) {
$resource_config_id = sprintf('%s--%s', $entity_type_id, $bundle);
- $resource_config = $this->entityRepository->loadEntityByConfigTarget(
- 'jsonapi_resource_config',
- $resource_config_id
- );
- $resource_config = $resource_config ?: new NullJsonapiResourceConfig([], '');
+ $resource_config = isset($resource_configs[$resource_config_id]) ? $resource_configs[$resource_config_id] : new NullJsonapiResourceConfig([], '');
if (!$include_disabled && $resource_config->get('disabled')) {
return NULL;
}
@@ -108,7 +124,8 @@ class ConfigurableResourceTypeRepository extends ResourceTypeRepository {
$resource_types = array_merge($resource_types, $current_types);
}
- return array_filter($resource_types);
+ $this->resourceTypes = array_filter($resource_types);
+ return $this->resourceTypes;
}
}