Completed
Push — 8.x-3.x ( 846059...f266e0 )
by Sebastian
02:34 queued 16s
created

FieldPluginBase::getDefinition()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 12

Duplication

Lines 18
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 18
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql\Plugin\GraphQL\Fields;
4
5
use Drupal\Component\Plugin\PluginBase;
6
use Drupal\graphql\GraphQL\Cache\CacheableValue;
7
use Drupal\graphql\GraphQL\Field\Field;
8
use Drupal\graphql\GraphQL\SecureFieldInterface;
9
use Drupal\graphql\Plugin\GraphQL\PluggableSchemaBuilderInterface;
10
use Drupal\graphql\Plugin\GraphQL\Traits\ArgumentAwarePluginTrait;
11
use Drupal\graphql\Plugin\GraphQL\Traits\CacheablePluginTrait;
12
use Drupal\graphql\Plugin\GraphQL\Traits\NamedPluginTrait;
13
use Drupal\graphql\Plugin\GraphQL\TypeSystemPluginInterface;
14
use Youshido\GraphQL\Execution\DeferredResolver;
15
use Youshido\GraphQL\Execution\ResolveInfo;
16
use Youshido\GraphQL\Type\ListType\ListType;
17
18
/**
19
 * Base class for field plugins.
20
 */
21
abstract class FieldPluginBase extends PluginBase implements TypeSystemPluginInterface, SecureFieldInterface {
22
  use CacheablePluginTrait;
23
  use NamedPluginTrait;
24
  use ArgumentAwarePluginTrait;
25
26
  /**
27
   * The field instance.
28
   *
29
   * @var \Drupal\graphql\GraphQL\Field\Field
30
   */
31
  protected $definition;
32
33
  /**
34
   * {@inheritdoc}
35
   */
36 View Code Duplication
  public function getDefinition(PluggableSchemaBuilderInterface $schemaBuilder) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
37
    if (!isset($this->definition)) {
38
      $definition = $this->getPluginDefinition();
39
40
      $config = [
41
        'name' => $this->buildName(),
42
        'description' => $this->buildDescription(),
43
        'type' => $this->buildType($schemaBuilder),
44
        'args' => $this->buildArguments($schemaBuilder),
45
        'isDeprecated' => !empty($definition['deprecated']),
46
        'deprecationReason' => !empty($definition['deprecated']) ? !empty($definition['deprecated']) : '',
47
      ];
48
49
      $this->definition = new Field($this, $schemaBuilder, $config);
50
    }
51
52
    return $this->definition;
53
  }
54
55
  /**
56
   * {@inheritdoc}
57
   */
58
  public function isSecure() {
59
    return isset($this->getPluginDefinition()['secure']) && $this->getPluginDefinition()['secure'];
60
  }
61
62
  /**
63
   * {@inheritdoc}
64
   */
65
  public function resolve($value, array $args, ResolveInfo $info) {
66
    return $this->resolveDeferred([$this, 'resolveValues'], $value, $args, $info);
67
  }
68
69
  /**
70
   * {@inheritdoc}
71
   */
72
  public function resolveDeferred(callable $callback, $value, array $args, ResolveInfo $info) {
73
    $result = $callback($value, $args, $info);
74
    if (is_callable($result)) {
75
      return new DeferredResolver(function () use ($result, $args, $info, $value) {
76
        return $this->resolveDeferred($result, $value, $args, $info);
77
      });
78
    }
79
80
    return $this->cacheable(iterator_to_array($result), $value, $args, $info);
81
  }
82
83
  /**
84
   * Wrap the result in a CacheableValue.
85
   *
86
   * @param array $result
87
   *   The field result.
88
   * @param mixed $value
89
   *   The parent value.
90
   * @param array $args
91
   *   The field arguments.
92
   * @param \Youshido\GraphQL\Execution\ResolveInfo $info
93
   *   The resolve info object.
94
   *
95
   * @return \Drupal\graphql\GraphQL\Cache\CacheableValue
96
   *   The cacheable value.
97
   */
98
  protected function cacheable(array $result, $value, array $args, ResolveInfo $info) {
99
    $dependencies = $this->getCacheDependencies($result, $value, $args, $info);
100
    // The field resolver may yield cache value wrappers. Unwrap them.
101
    $result = array_map(function ($item) {
102
      return $item instanceof CacheableValue ? $item->getValue() : $item;
103
    }, $result);
104
105
    if ($info->getReturnType()->getNullableType() instanceof ListType) {
106
      return new CacheableValue($result, $dependencies);
107
    }
108
109
    $result = !empty($result) ? reset($result) : NULL;
110
    return new CacheableValue($result, $dependencies);
111
  }
112
113
  /**
114
   * Retrieve the list of cache dependencies for a given value and arguments.
115
   *
116
   * @param array $result
117
   *   The result of the field.
118
   * @param mixed $parent
119
   *   The parent value.
120
   * @param array $args
121
   *   The arguments passed to the field.
122
   * @param \Youshido\GraphQL\Execution\ResolveInfo $info
123
   *   The resolve info object.
124
   *
125
   * @return array
126
   *   A list of cacheable dependencies.
127
   */
128
  protected function getCacheDependencies(array $result, $parent, array $args, ResolveInfo $info) {
129
    // Default implementation just returns the value itself.
130
    return $result;
131
  }
132
133
  /**
134
   * Retrieve the list of field values.
135
   *
136
   * Always returns a list of field values. Even for single value fields.
137
   * Single/multi field handling is responsibility of the base class.
138
   *
139
   * @param mixed $value
140
   *   The current object value.
141
   * @param array $args
142
   *   Field arguments.
143
   * @param \Youshido\GraphQL\Execution\ResolveInfo $info
144
   *   The resolve info object.
145
   *
146
   * @return \Generator
147
   *   The value generator.
148
   */
149
  protected function resolveValues($value, array $args, ResolveInfo $info) {
150
    // Allow overriding this class without having to declare this method.
151
    yield NULL;
152
  }
153
154
}
155