Completed
Push — 8.x-3.x ( e67c0e...2e01b0 )
by Philipp
02:27
created

PluggableSchemaBuilder::getDefinitions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 0
dl 0
loc 20
rs 9.4285
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
    foreach ($this->getDefinitions() as $index => $definition) {
82
      $name = $definition['definition']['name'];
83
      if (empty($name)) {
84
        throw new InvalidPluginDefinitionException('Invalid GraphQL plugin definition. No name defined.');
85
      }
86
87
      if (!array_key_exists($name, $instances) && in_array($definition['definition']['pluginType'], $types)) {
88
        if ((($invert && !$selector($definition['definition'])) || $selector($definition['definition']))) {
89
          $instances[$name] = $this->getInstance($definition['type'], $definition['id']);
90
        }
91
      }
92
    }
93
94
    return $instances;
95
  }
96
97
  /**
98
   * {@inheritdoc}
99
   */
100
  public function findByName($name, array $types) {
101
    $result = $this->find(function($definition) use ($name) {
102
      return $definition['name'] === $name;
103
    }, $types);
104
105
    if (empty($result)) {
106
      throw new InvalidPluginDefinitionException(sprintf('GraphQL plugin with name %s could not be found.', $name));
107
    }
108
109
    return array_pop($result);
110
  }
111
112
  /**
113
   * {@inheritdoc}
114
   */
115
  public function findByDataType($dataType, array $types = [
116
    GRAPHQL_UNION_TYPE_PLUGIN,
117
    GRAPHQL_TYPE_PLUGIN,
118
    GRAPHQL_INTERFACE_PLUGIN,
119
    GRAPHQL_SCALAR_PLUGIN,
120
  ]) {
121
    $chain = explode(':', $dataType);
122
123
    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...
124
      $dataType = implode(':', $chain);
125
126
      $types = $this->find(function($definition) use ($dataType) {
127
        return isset($definition['data_type']) && $definition['data_type'] == $dataType;
128
      }, $types);
129
130
      if (!empty($types)) {
131
        return array_pop($types);
132
      }
133
134
      array_pop($chain);
135
    }
136
137
    return NULL;
138
  }
139
140
  /**
141
   * Collects and aggregates all plugin definitions.
142
   *
143
   *
144
   * @return array
145
   *   The plugin definitions array.
146
   */
147
  protected function getDefinitions() {
148
    $this->definitions = [];
149
150
    /** @var \Drupal\graphql\Plugin\GraphQL\TypeSystemPluginManagerInterface $manager */
151
    foreach ($this->pluginManagers as $manager) {
152
      foreach ($manager->getDefinitions() as $pluginId => $definition) {
153
        $this->definitions[] = [
154
          'id' => $pluginId,
155
          'type' => $definition['pluginType'],
156
          'weight' => $definition['weight'],
157
          'definition' => $definition,
158
        ];
159
      }
160
    }
161
162
    uasort($this->definitions, '\Drupal\Component\Utility\SortArray::sortByWeightElement');
163
    $this->definitions = array_reverse($this->definitions);
164
165
    return $this->definitions;
166
  }
167
168
  /**
169
   * {@inheritdoc}
170
   */
171
  public function __sleep() {
172
    // Don't write the plugin instances into the cache.
173
    return array_diff($this->sleepDependencies(), ['instances']);
174
  }
175
}
176