bundleInfo = $bundle_info; $this->resourceTypeRepository = $resource_type_repository; $this->fieldManager = $field_manager; $this->entityTypeRepository = $entity_type_repository; $this->enhancerManager = $enhancer_manager; $this->config = $config; $this->request = $request; $this->typedConfigManager = $typed_config_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.bundle.info'), $container->get('jsonapi.resource_type.repository'), $container->get('entity_field.manager'), $container->get('entity_type.repository'), $container->get('plugin.manager.resource_field_enhancer'), $container->get('config.factory')->get('jsonapi_extras.settings'), $container->get('request_stack')->getCurrentRequest(), $container->get('config.typed') ); } /** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); // Disable caching on this form. $form_state->setCached(FALSE); $entity_type_id = $this->request->get('entity_type_id'); $bundle = $this->request->get('bundle'); /** @var \Drupal\jsonapi_extras\Entity\JsonapiResourceConfig $entity */ $entity = $this->getEntity(); $resource_id = $entity->get('id'); // If we are editing an entity we don't want the Entity Type and Bundle // picker, that info is locked. if (!$entity_type_id || !$bundle) { if (!$resource_id) { // We can't build the form without an entity type and bundle. throw new \InvalidArgumentException('Unable to load entity type or bundle for the overrides form.'); } list($entity_type_id, $bundle) = explode('--', $resource_id); $form['#title'] = $this->t('Edit %label resource config', ['%label' => $resource_id]); } if ($entity_type_id && $resource_type = $this->resourceTypeRepository->get($entity_type_id, $bundle)) { // Get the JSON API resource type. $resource_config_id = sprintf('%s--%s', $entity_type_id, $bundle); $existing_entity = $this->entityTypeManager ->getStorage('jsonapi_resource_config')->load($resource_config_id); if ($existing_entity && $entity->isNew()) { drupal_set_message($this->t('This override already exists, please edit it instead.')); return $form; } $form['bundle_wrapper']['fields_wrapper'] = $this->buildOverridesForm($resource_type, $entity); $form['id'] = [ '#type' => 'hidden', '#value' => sprintf('%s--%s', $entity_type_id, $bundle), ]; } return $form; } /** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { if (!method_exists($this->typedConfigManager, 'createFromNameAndData')) { // Versions of Drupal before 8.4 have poor support for constraints. In // those scenarios we don't validate the form submission. return; } $typed_config = $this->typedConfigManager ->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()); } } /** * {@inheritdoc} */ public function save(array $form, FormStateInterface $form_state) { $resource_config = $this->entity; $status = $resource_config->save(); switch ($status) { case SAVED_NEW: drupal_set_message($this->t('Created the %label JSON API Resource overwrites.', [ '%label' => $resource_config->label(), ])); break; default: drupal_set_message($this->t('Saved the %label JSON API Resource overwrites.', [ '%label' => $resource_config->label(), ])); } $form_state->setRedirectUrl($resource_config->urlInfo('collection')); } /** * Builds the part of the form that contains the overrides. * * @param \Drupal\jsonapi\ResourceType\ResourceType $resource_type * The resource type being overridden. * @param \Drupal\jsonapi_extras\Entity\JsonapiResourceConfig $entity * The configuration entity backing this form. * * @return array * The partial form. */ protected function buildOverridesForm(ResourceType $resource_type, JsonapiResourceConfig $entity) { $entity_type_id = $resource_type->getEntityTypeId(); $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); $bundle = $resource_type->getBundle(); if ($entity_type instanceof ContentEntityTypeInterface) { $field_names = array_map(function (FieldDefinitionInterface $field_definition) { return $field_definition->getName(); }, $this->fieldManager->getFieldDefinitions($entity_type_id, $bundle)); } else { $field_names = array_keys($entity_type->getPropertiesToExport()); array_unshift($field_names, $entity_type->getKey('id')); } $overrides_form['overrides']['entity'] = [ '#type' => 'details', '#title' => $this->t('Entity'), '#description' => $this->t('Override configuration for the resource entity.'), '#open' => !$entity->get('resourceType') || !$entity->get('path'), ]; $overrides_form['overrides']['entity']['disabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Disabled'), '#description' => $this->t('Check this if you want to disable this resource. Disabling a resource can have unexpected results when following relationships belonging to that resource.'), '#default_value' => $entity->get('disabled'), ]; $resource_type_name = $entity->get('resourceType'); if (!$resource_type_name) { $resource_type_name = sprintf('%s--%s', $entity_type_id, $bundle); } $overrides_form['overrides']['entity']['resourceType'] = [ '#type' => 'textfield', '#title' => $this->t('Resource Type'), '#description' => $this->t('Overrides the type of the resource. Example: Change "node--article" to "articles".'), '#default_value' => $resource_type_name, '#states' => [ 'visible' => [ ':input[name="disabled"]' => ['checked' => FALSE], ], ], ]; $path = $entity->get('path'); if (!$path) { $path = sprintf('%s/%s', $entity_type_id, $bundle); } $prefix = $this->config->get('path_prefix'); $overrides_form['overrides']['entity']['path'] = [ '#type' => 'textfield', '#title' => $this->t('Resource Path'), '#field_prefix' => sprintf('/%s/', $prefix), '#description' => $this->t('Overrides the path of the resource. Example: Use "articles" to change "/@prefix/node/article" to "/@prefix/articles".', [ '@prefix' => $prefix, ]), '#default_value' => $path, '#required' => TRUE, '#states' => [ 'visible' => [ ':input[name="disabled"]' => ['checked' => FALSE], ], ], ]; $overrides_form['overrides']['fields'] = [ '#type' => 'details', '#title' => $this->t('Fields'), '#open' => TRUE, ]; $markup = ''; $markup .= '