Completed
Pull Request — 8.x-3.x (#443)
by Sebastian
02:43 queued 32s
created

PluggableSchemaBuilder::getInstance()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 8
nop 3
dl 0
loc 28
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql\Plugin\GraphQL;
4
5
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
6
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
7
8
class PluggableSchemaBuilder implements PluggableSchemaBuilderInterface {
9
  use DependencySerializationTrait {
10
    __sleep as sleepDependencies;
11
  }
12
13
  /**
14
   * The type system plugin manager aggregator service.
15
   *
16
   * @var \Drupal\graphql\Plugin\GraphQL\TypeSystemPluginManagerAggregator
17
   */
18
  protected $pluginManagers;
19
20
  /**
21
   * Static cache of type system plugin instances.
22
   *
23
   * @var \Drupal\graphql\Plugin\GraphQL\TypeSystemPluginInterface
24
   */
25
  protected $instances = [];
26
27
  /**
28
   * Static cache of plugin definitions.
29
   *
30
   * @var array
31
   */
32
  protected $definitions;
33
34
  /**
35
   * PluggableSchemaBuilderInterface constructor.
36
   *
37
   * @param \Drupal\graphql\Plugin\GraphQL\TypeSystemPluginManagerAggregator $pluginManagers
38
   *   Type system plugin manager aggregator service.
39
   */
40
  public function __construct(TypeSystemPluginManagerAggregator $pluginManagers) {
41
    $this->pluginManagers = $pluginManagers;
42
  }
43
44
  /**
45
   * {@inheritdoc}
46
   */
47
  public function getInstance($pluginType, $pluginId, array $pluginConfiguration = []) {
48
    asort($pluginConfiguration);
49
    $configCid = md5(json_encode($pluginConfiguration));
50
51
    if (!isset($this->instances[$pluginType][$pluginId][$configCid])) {
52
      $manager = $this->pluginManagers->getPluginManager($pluginType);
53
      if (empty($manager)) {
54
        throw new \LogicException(sprintf('Could not find %s plugin manager for plugin %s.', $pluginType, $pluginId));
55
      }
56
57
      // We do not allow plugin configuration for now.
58
      $instance = $manager->createInstance($pluginId, $pluginConfiguration);
59
      if (empty($instance)) {
60
        throw new \LogicException(sprintf('Could not instantiate plugin %s of type %s.', $pluginId, $pluginType));
61
      }
62
63
      if (!$instance instanceof TypeSystemPluginInterface) {
64
        throw new \LogicException(sprintf('Plugin %s of type %s does not implement \Drupal\graphql\Plugin\GraphQL\TypeSystemPluginInterface.', $pluginId, $pluginType));
65
      }
66
67
      // Initialize the static cache array if necessary.
68
      $this->instances[$pluginType] = isset($this->instances[$pluginType]) ? $this->instances[$pluginType] : [];
69
      $this->instances[$pluginType][$pluginId] = isset($this->instances[$pluginType][$pluginId]) ? $this->instances[$pluginType][$pluginId] : [];
70
      $this->instances[$pluginType][$pluginId][$configCid] = $instance;
71
    }
72
73
    return $this->instances[$pluginType][$pluginId][$configCid];
74
  }
75
76
  /**
77
   * {@inheritdoc}
78
   */
79
  public function find(callable $selector, array $types, $invert = FALSE) {
80
    $instances = [];
81
82
    /** @var \Drupal\graphql\Plugin\GraphQL\TypeSystemPluginManagerInterface $manager */
83
    foreach ($this->pluginManagers as $type => $manager) {
84
      if (!in_array($type, $types)) {
85
        continue;
86
      }
87
88
      foreach ($manager->getDefinitions() as $id => $definition) {
89
        $name = $definition['name'];
90
        if (empty($name)) {
91
          throw new InvalidPluginDefinitionException('Invalid GraphQL plugin definition. No name defined.');
92
        }
93
94
        if (!array_key_exists($name, $instances)) {
95
          if ((($invert && !$selector($definition)) || $selector($definition))) {
96
            $instances[$name] = $this->getInstance($type, $id);
97
          }
98
        }
99
      }
100
    }
101
102
    return $instances;
103
  }
104
105
  /**
106
   * {@inheritdoc}
107
   */
108
  public function findByName($name, array $types) {
109
    $result = $this->find(function($definition) use ($name) {
110
      return $definition['name'] === $name;
111
    }, $types);
112
113
    if (empty($result)) {
114
      throw new InvalidPluginDefinitionException(sprintf('GraphQL plugin with name %s could not be found.', $name));
115
    }
116
117
    return array_pop($result);
118
  }
119
120
  /**
121
   * {@inheritdoc}
122
   */
123
  public function findByDataType($dataType, array $types = [
124
    GRAPHQL_UNION_TYPE_PLUGIN,
125
    GRAPHQL_TYPE_PLUGIN,
126
    GRAPHQL_INTERFACE_PLUGIN,
127
    GRAPHQL_SCALAR_PLUGIN,
128
  ]) {
129
    $chain = explode(':', $dataType);
130
131
    while ($chain) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $chain of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
132
      $dataType = implode(':', $chain);
133
134
      $types = $this->find(function($definition) use ($dataType) {
135
        return isset($definition['data_type']) && $definition['data_type'] == $dataType;
136
      }, $types);
137
138
      if (!empty($types)) {
139
        return array_pop($types);
140
      }
141
142
      array_pop($chain);
143
    }
144
145
    return NULL;
146
  }
147
148
  /**
149
   * {@inheritdoc}
150
   */
151
  public function __sleep() {
152
    // Don't write the plugin instances into the cache.
153
    return array_diff($this->sleepDependencies(), ['instances']);
154
  }
155
}
156