Completed
Pull Request — 8.x-3.x (#399)
by Philipp
02:23
created

CreateEntity::resolve()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 37
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 19
nc 4
nop 3
dl 0
loc 37
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql_core\Plugin\GraphQL\Mutations\Entity;
4
5
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
6
use Drupal\Core\Entity\EntityTypeManagerInterface;
7
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
8
use Drupal\Core\StringTranslation\StringTranslationTrait;
9
use Drupal\graphql_core\Plugin\GraphQL\Mutations\Entity\EntityMutationInputTrait;
10
use Drupal\graphql_core\GraphQL\EntityCrudOutputWrapper;
11
use Drupal\graphql\Plugin\GraphQL\Mutations\MutationPluginBase;
12
use Symfony\Component\DependencyInjection\ContainerInterface;
13
use Youshido\GraphQL\Execution\ResolveInfo;
14
15
/**
16
 * Create an entity.
17
 *
18
 * @GraphQLMutation(
19
 *   id = "create_entity",
20
 *   type = "EntityCrudOutput",
21
 *   secure = true,
22
 *   nullable = false,
23
 *   schema_cache_tags = {"entity_types", "entity_bundles"},
24
 *   deriver = "Drupal\graphql_core\Plugin\Deriver\Mutations\CreateEntityDeriver"
25
 * )
26
 */
27
class CreateEntity extends MutationPluginBase implements ContainerFactoryPluginInterface {
28
  use DependencySerializationTrait;
29
  use StringTranslationTrait;
30
  use EntityMutationInputTrait;
31
32
  /**
33
   * The entity type manager.
34
   *
35
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
36
   */
37
  protected $entityTypeManager;
38
39
  /**
40
   * {@inheritdoc}
41
   */
42
  public function __construct(array $configuration, $pluginId, $pluginDefinition, EntityTypeManagerInterface $entityTypeManager) {
43
    $this->entityTypeManager = $entityTypeManager;
44
    parent::__construct($configuration, $pluginId, $pluginDefinition);
45
  }
46
47
  /**
48
   * {@inheritdoc}
49
   */
50
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
51
    return new static(
52
      $configuration,
53
      $pluginId,
54
      $pluginDefinition,
55
      $container->get('entity_type.manager')
56
    );
57
  }
58
59
  /**
60
   * {@inheritdoc}
61
   */
62
  public function resolve($value, array $args, ResolveInfo $info) {
63
    $entityTypeId = $this->pluginDefinition['entity_type'];
64
    $bundleName = $this->pluginDefinition['entity_bundle'];
65
    $bundleKey = $this->entityTypeManager->getDefinition($entityTypeId)->getKey('bundle');
66
    $storage = $this->entityTypeManager->getStorage($entityTypeId);
67
68
    // The raw input needs to be converted to use the proper field and property
69
    // keys because we usually convert them to camel case when adding them to
70
    // the schema.
71
    $inputArgs = $args['input'];
72
    /** @var \Youshido\GraphQL\Type\Object\AbstractObjectType $type */
73
    $type = $this->config->getArgument('input')->getType();
0 ignored issues
show
Bug introduced by
The method getArgument does only exist in Youshido\GraphQL\Config\Field\FieldConfig, but not in Youshido\GraphQL\Config\...Object\ObjectTypeConfig.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
74
    /** @var \Drupal\graphql_core\Plugin\GraphQL\InputTypes\Mutations\EntityInput $inputType */
75
    $inputType = $type->getNamedType();
76
    $input = $this->extractEntityInput($inputArgs, $inputType);
77
78
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
79
    $entity = $storage->create($input + [
80
      $bundleKey => $bundleName,
81
    ]);
82
83
    if (!$entity->access('create')) {
84
      return new EntityCrudOutputWrapper(NULL, NULL, [
85
        $this->t('You do not have the necessary permissions to create entities of this type.'),
86
      ]);
87
    }
88
89
    if (($violations = $entity->validate()) && $violations->count()) {
90
      return new EntityCrudOutputWrapper(NULL, $violations);
91
    }
92
93
    if (($status = $entity->save()) && $status === SAVED_NEW) {
94
      return new EntityCrudOutputWrapper($entity);
95
    }
96
97
    return NULL;
98
  }
99
100
}
101