CreateEntityBase::create()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
c 0
b 0
f 0
dl 0
loc 7
rs 10
cc 1
nc 1
nop 4
1
<?php
2
3
namespace Drupal\graphql_core\Plugin\GraphQL\Mutations\Entity;
4
5
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\DependencyIn...dencySerializationTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Drupal\Core\Entity\ContentEntityInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Entity\ContentEntityInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Drupal\Core\Entity\EntityInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Entity\EntityInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Drupal\Core\Entity\EntityTypeManagerInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Entity\EntityTypeManagerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Plugin\ContainerFactoryPluginInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Drupal\Core\Render\RenderContext;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Render\RenderContext was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Drupal\Core\Render\RendererInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Render\RendererInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Drupal\Core\StringTranslation\StringTranslationTrait;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\StringTransl...\StringTranslationTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Drupal\graphql\GraphQL\Execution\ResolveContext;
14
use Drupal\graphql_core\GraphQL\EntityCrudOutputWrapper;
15
use Drupal\graphql\Plugin\GraphQL\Mutations\MutationPluginBase;
16
use Symfony\Component\DependencyInjection\ContainerInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Depend...tion\ContainerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use GraphQL\Type\Definition\ResolveInfo;
18
19
abstract class CreateEntityBase extends MutationPluginBase implements ContainerFactoryPluginInterface {
20
  use DependencySerializationTrait;
21
  use StringTranslationTrait;
22
23
  /**
24
   * The entity type manager.
25
   *
26
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
27
   */
28
  protected $entityTypeManager;
29
30
  /**
31
   * The renderer service.
32
   *
33
   * @var \Drupal\Core\Render\RendererInterface
34
   */
35
  protected $renderer;
36
37
  /**
38
   * {@inheritdoc}
39
   */
40
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
41
    return new static(
42
      $configuration,
43
      $pluginId,
44
      $pluginDefinition,
45
      $container->get('entity_type.manager'),
46
      $container->get('renderer')
47
    );
48
  }
49
50
  /**
51
   * CreateEntityBase constructor.
52
   *
53
   * @param array $configuration
54
   *   The plugin configuration array.
55
   * @param string $pluginId
56
   *   The plugin id.
57
   * @param mixed $pluginDefinition
58
   *   The plugin definition array.
59
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
60
   *   The entity type manager service.
61
   * @param \Drupal\Core\Render\RendererInterface $renderer
62
   *   The renderer service.
63
   */
64
  public function __construct(array $configuration, $pluginId, $pluginDefinition, EntityTypeManagerInterface $entityTypeManager, RendererInterface $renderer) {
65
    parent::__construct($configuration, $pluginId, $pluginDefinition);
66
    $this->entityTypeManager = $entityTypeManager;
67
    $this->renderer = $renderer;
68
  }
69
70
  /**
71
   * {@inheritdoc}
72
   */
73
  public function resolve($value, array $args, ResolveContext $context, ResolveInfo $info) {
74
    // There are cases where the Drupal entity API calls emit the cache metadata
75
    // in the current render context. In such cases
76
    // EarlyRenderingControllerWrapperSubscriber throws the leaked cache
77
    // metadata exception. To avoid this, wrap the execution in its own render
78
    // context.
79
    return $this->renderer->executeInRenderContext(new RenderContext(), function () use ($value, $args, $context, $info) {
80
      $entityTypeId = $this->pluginDefinition['entity_type'];
81
82
      // The raw input needs to be converted to use the proper field and property
83
      // keys because we usually convert them to camel case when adding them to
84
      // the schema.
85
      $input = $this->extractEntityInput($value, $args, $context, $info);
86
87
      $entityDefinition = $this->entityTypeManager->getDefinition($entityTypeId);
88
      if ($entityDefinition->hasKey('bundle')) {
89
        $bundleName = $this->pluginDefinition['entity_bundle'];
90
        $bundleKey = $entityDefinition->getKey('bundle');
91
92
        // Add the entity's bundle with the correct key.
93
        $input[$bundleKey] = $bundleName;
94
      }
95
96
      $storage = $this->entityTypeManager->getStorage($entityTypeId);
97
      $entity = $storage->create($input);
98
      return $this->resolveOutput($entity, $args, $info);
99
    });
100
  }
101
102
  /**
103
   * Extract entity values from the resolver args.
104
   *
105
   * Loops over all input values and assigns them to their original field names.
106
   *
107
   * @param $value
108
   *   The parent value.
109
   * @param array $args
110
   *   The entity values provided through the resolver args.
111
   * @param \Drupal\graphql\GraphQL\Execution\ResolveContext $context
112
   *   The resolve context.
113
   * @param \GraphQL\Type\Definition\ResolveInfo $info
114
   *   The resolve info object.
115
   *
116
   * @return array
117
   *   The extracted entity values with their proper, internal field names.
118
   */
119
  abstract protected function extractEntityInput($value, array $args, ResolveContext $context, ResolveInfo $info);
120
121
  /**
122
   * Formats the output of the mutation.
123
   *
124
   * The default implementation wraps the created entity in another object to
125
   * transport possible error messages and constraint violations after applying
126
   * some access checks and input validation.
127
   *
128
   * @param \Drupal\Core\Entity\EntityInterface $entity
129
   *   The created entity.
130
   * @param array $args
131
   *   The arguments array.
132
   * @param \GraphQL\Type\Definition\ResolveInfo $info
133
   *   The resolve info object.
134
   *
135
   * @return mixed
136
   *   The output for the created entity.
137
   */
138
  protected function resolveOutput(EntityInterface $entity, array $args, ResolveInfo $info) {
139
    if (!$entity->access('create')) {
140
      return new EntityCrudOutputWrapper(NULL, NULL, [
141
        $this->t('You do not have the necessary permissions to create entities of this type.'),
142
      ]);
143
    }
144
145
    if ($entity instanceof ContentEntityInterface) {
146
      if (($violations = $entity->validate()) && $violations->count()) {
147
        return new EntityCrudOutputWrapper(NULL, $violations);
148
      }
149
    }
150
151
    if (($status = $entity->save()) && $status === SAVED_NEW) {
0 ignored issues
show
Bug introduced by
The constant Drupal\graphql_core\Plug...ations\Entity\SAVED_NEW was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
152
      return new EntityCrudOutputWrapper($entity);
153
    }
154
155
    return NULL;
156
  }
157
158
}
159