1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Drupal\graphql\GraphQL\Batching; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Base class for field buffering services. |
7
|
|
|
*/ |
8
|
|
View Code Duplication |
abstract class BufferBase { |
|
|
|
|
9
|
|
|
|
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* The the array of buffers. |
13
|
|
|
* |
14
|
|
|
* @var \SplObjectStorage[] |
15
|
|
|
*/ |
16
|
|
|
protected $buffers = []; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* The array of result sets. |
20
|
|
|
* |
21
|
|
|
* @var \SplObjectStorage[] |
22
|
|
|
*/ |
23
|
|
|
protected $results = []; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @param object $item |
27
|
|
|
* The item to get the buffer id for. |
28
|
|
|
* @return string |
29
|
|
|
* The buffer id. |
30
|
|
|
*/ |
31
|
|
|
protected function getBufferId($item) { |
|
|
|
|
32
|
|
|
return ""; |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Helper function to create a resolver for a singular buffer. |
37
|
|
|
* |
38
|
|
|
* @param object $item |
39
|
|
|
* The item to add to the buffer. |
40
|
|
|
* |
41
|
|
|
* @return \Closure |
42
|
|
|
* The callback to invoke to load the result for this buffer item. |
43
|
|
|
*/ |
44
|
|
|
protected function createBufferResolver($item) { |
45
|
|
|
$bufferId = $this->getBufferId($item); |
46
|
|
|
if (!isset($this->buffers[$bufferId])) { |
47
|
|
|
$this->buffers[$bufferId] = new \SplObjectStorage(); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
if (!isset($this->results[$bufferId])) { |
51
|
|
|
$this->results[$bufferId] = new \SplObjectStorage(); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
// Add the created item to the buffer. |
55
|
|
|
$this->buffers[$bufferId]->attach($item, $item); |
56
|
|
|
|
57
|
|
|
// Return a callback that can be used to resolve the buffer item. |
58
|
|
|
return $this->createResolver($item, $this->buffers[$bufferId], $this->results[$bufferId]); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Creates a callback to invoke to load the result for this buffer item. |
63
|
|
|
* |
64
|
|
|
* @param object $item |
65
|
|
|
* The item to add to create the resolver for. |
66
|
|
|
* @param \SplObjectStorage $buffer |
67
|
|
|
* The buffer. |
68
|
|
|
* @param \SplObjectStorage $result |
69
|
|
|
* The result set. |
70
|
|
|
* |
71
|
|
|
* @return \Closure |
72
|
|
|
* The callback to invoke to load the result for this buffer item. |
73
|
|
|
*/ |
74
|
|
|
protected function createResolver($item, \SplObjectStorage $buffer, \SplObjectStorage $result) { |
75
|
|
|
// Return the closure that will resolve and return the result for the item. |
76
|
|
|
return function () use ($item, $buffer, $result) { |
77
|
|
|
return $this->resolveItem($item, $buffer, $result); |
78
|
|
|
}; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Returns the result of the given item after processing the buffer if needed. |
83
|
|
|
* |
84
|
|
|
* @param object $item |
85
|
|
|
* The buffer item to retrieve the result for. |
86
|
|
|
* @param \SplObjectStorage $buffer |
87
|
|
|
* The buffer. |
88
|
|
|
* @param \SplObjectStorage $result |
89
|
|
|
* The result set. |
90
|
|
|
* |
91
|
|
|
* @return mixed |
92
|
|
|
* The result of resolving the given buffer item. |
93
|
|
|
*/ |
94
|
|
|
protected function resolveItem($item, \SplObjectStorage $buffer, \SplObjectStorage $result) { |
95
|
|
|
if ($buffer->contains($item)) { |
96
|
|
|
$results = $this->resolveBuffer($buffer); |
97
|
|
|
|
98
|
|
|
// Remove the resolved items from the buffer and add them to the results. |
99
|
|
|
$buffer->removeAll($results); |
100
|
|
|
$result->addAll($results); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
if ($result->contains($item)) { |
104
|
|
|
return $result[$item]; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
throw new \LogicException('Failed to resolve item.'); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Resolves the given buffer wholly. |
112
|
|
|
* |
113
|
|
|
* @param \SplObjectStorage $buffer |
114
|
|
|
* The buffer to be resolved wholly. |
115
|
|
|
* |
116
|
|
|
* @return \SplObjectStorage |
117
|
|
|
* The resolved results for the given buffer, keyed by the corresponding |
118
|
|
|
* buffer items. |
119
|
|
|
*/ |
120
|
|
|
protected function resolveBuffer(\SplObjectStorage $buffer) { |
121
|
|
|
// Convert the buffer to an array that we can later use to map the results |
122
|
|
|
// to the correct batch items. |
123
|
|
|
$buffer = iterator_to_array($buffer, FALSE); |
124
|
|
|
|
125
|
|
|
// Assign the loaded items to their corresponding batch items. |
126
|
|
|
$output = new \SplObjectStorage(); |
127
|
|
|
foreach ($this->resolveBufferArray($buffer) as $key => $item) { |
128
|
|
|
$output->attach($buffer[$key], $item); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
return $output; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Resolve the buffer as an array. |
136
|
|
|
* |
137
|
|
|
* Simplifies sub-class implementations by concealing the object storage |
138
|
|
|
* details of the buffer object. |
139
|
|
|
* |
140
|
|
|
* @param array $buffer |
141
|
|
|
* The buffer as an array. |
142
|
|
|
* |
143
|
|
|
* @return array |
144
|
|
|
* The resolved results, keyed by their corresponding buffer item array key. |
145
|
|
|
*/ |
146
|
|
|
protected function resolveBufferArray(array $buffer) { |
|
|
|
|
147
|
|
|
throw new \LogicException('Method not implemented.'); |
148
|
|
|
} |
149
|
|
|
} |
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.