Completed
Pull Request — 8.x-3.x (#409)
by Sebastian
02:31
created

CreateEntityBase::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 4
dl 0
loc 4
rs 10
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\Plugin\GraphQL\InputTypes\InputTypePluginBase;
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
abstract class CreateEntityBase extends MutationPluginBase implements ContainerFactoryPluginInterface {
16
  use DependencySerializationTrait;
17
  use StringTranslationTrait;
18
19
  /**
20
   * The entity type manager.
21
   *
22
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
23
   */
24
  protected $entityTypeManager;
25
26
  /**
27
   * {@inheritdoc}
28
   */
29
  public function __construct(array $configuration, $pluginId, $pluginDefinition, EntityTypeManagerInterface $entityTypeManager) {
30
    $this->entityTypeManager = $entityTypeManager;
31
    parent::__construct($configuration, $pluginId, $pluginDefinition);
32
  }
33
34
  /**
35
   * {@inheritdoc}
36
   */
37
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
38
    return new static(
39
      $configuration,
40
      $pluginId,
41
      $pluginDefinition,
42
      $container->get('entity_type.manager')
43
    );
44
  }
45
46
  /**
47
   * {@inheritdoc}
48
   */
49
  public function resolve($value, array $args, ResolveInfo $info) {
50
    $entityTypeId = $this->pluginDefinition['entity_type'];
51
    $bundleName = $this->pluginDefinition['entity_bundle'];
52
    $bundleKey = $this->entityTypeManager->getDefinition($entityTypeId)->getKey('bundle');
53
    $storage = $this->entityTypeManager->getStorage($entityTypeId);
54
55
    // The raw input needs to be converted to use the proper field and property
56
    // keys because we usually convert them to camel case when adding them to
57
    // the schema.
58
    $inputArgs = $args['input'];
59
    /** @var \Youshido\GraphQL\Type\Object\AbstractObjectType $type */
60
    $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...
61
    /** @var \Drupal\graphql\Plugin\GraphQL\InputTypes\InputTypePluginBase $inputType */
62
    $inputType = $type->getNamedType();
63
    $input = $this->extractEntityInput($inputArgs, $inputType);
64
65
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
66
    $entity = $storage->create($input + [
67
      $bundleKey => $bundleName,
68
    ]);
69
70
    if (!$entity->access('create')) {
71
      return new EntityCrudOutputWrapper(NULL, NULL, [
72
        $this->t('You do not have the necessary permissions to create entities of this type.'),
73
      ]);
74
    }
75
76
    if (($violations = $entity->validate()) && $violations->count()) {
77
      return new EntityCrudOutputWrapper(NULL, $violations);
78
    }
79
80
    if (($status = $entity->save()) && $status === SAVED_NEW) {
81
      return new EntityCrudOutputWrapper($entity);
82
    }
83
84
    return NULL;
85
  }
86
87
  /**
88
   * Extract entity values from the resolver args.
89
   *
90
   * Loops over all input values and assigns them to their original field names.
91
   *
92
   * @param array $inputArgs
93
   *   The entity values provided through the resolver args.
94
   * @param \Drupal\graphql\Plugin\GraphQL\InputTypes\InputTypePluginBase $inputType
95
   *   The input type.
96
   *
97
   * @return array
98
   *   The extracted entity values with their proper, internal field names.
99
   */
100
  abstract protected function extractEntityInput(array $inputArgs, InputTypePluginBase $inputType);
101
102
}
103