|
1 |
| -<?php declare(strict_types=1); |
| 1 | +<?php declare (strict_types=1); |
2 | 2 |
|
3 | 3 | namespace OpenCloud\Common\Api;
|
4 | 4 |
|
|
11 | 11 | use OpenCloud\Common\Transport\RequestSerializer;
|
12 | 12 | use Psr\Http\Message\ResponseInterface;
|
13 | 13 |
|
14 |
| -/** |
15 |
| - * {@inheritDoc} |
16 |
| - */ |
17 |
| -abstract class Operator implements OperatorInterface |
| 14 | +trait OperatorTrait |
18 | 15 | {
|
19 | 16 | /** @var ClientInterface */
|
20 | 17 | protected $client;
|
@@ -55,18 +52,58 @@ public function __debugInfo()
|
55 | 52 | }
|
56 | 53 |
|
57 | 54 | /**
|
58 |
| - * Retrieves a populated Operation according to the definition and values provided. A |
59 |
| - * HTTP client is also injected into the object to allow it to communicate with the remote API. |
| 55 | + * Magic method which intercepts async calls, finds the sequential version, and wraps it in a |
| 56 | + * {@see Promise} object. In order for this to happen, the called methods need to be in the |
| 57 | + * following format: `createAsync`, where `create` is the sequential method being wrapped. |
| 58 | + * |
| 59 | + * @param $methodName The name of the method being invoked. |
| 60 | + * @param $args The arguments to be passed to the sequential method. |
60 | 61 | *
|
61 |
| - * @param array $definition The data that dictates how the operation works |
| 62 | + * @throws \RuntimeException If method does not exist |
62 | 63 | *
|
63 |
| - * @return Operation |
| 64 | + * @return Promise |
| 65 | + */ |
| 66 | + public function __call($methodName, $args) |
| 67 | + { |
| 68 | + $e = function ($name) { |
| 69 | + return new \RuntimeException(sprintf('%s::%s is not defined', get_class($this), $name)); |
| 70 | + }; |
| 71 | + |
| 72 | + if (substr($methodName, -5) === 'Async') { |
| 73 | + $realMethod = substr($methodName, 0, -5); |
| 74 | + if (!method_exists($this, $realMethod)) { |
| 75 | + throw $e($realMethod); |
| 76 | + } |
| 77 | + |
| 78 | + $promise = new Promise( |
| 79 | + function () use (&$promise, $realMethod, $args) { |
| 80 | + $value = call_user_func_array([$this, $realMethod], $args); |
| 81 | + $promise->resolve($value); |
| 82 | + } |
| 83 | + ); |
| 84 | + |
| 85 | + return $promise; |
| 86 | + } |
| 87 | + |
| 88 | + throw $e($methodName); |
| 89 | + } |
| 90 | + |
| 91 | + /** |
| 92 | + * {@inheritdoc} |
64 | 93 | */
|
65 | 94 | public function getOperation(array $definition): Operation
|
66 | 95 | {
|
67 | 96 | return new Operation($definition);
|
68 | 97 | }
|
69 | 98 |
|
| 99 | + /** |
| 100 | + * @param Operation $operation |
| 101 | + * @param array $userValues |
| 102 | + * @param bool $async |
| 103 | + * |
| 104 | + * @return mixed |
| 105 | + * @throws \Exception |
| 106 | + */ |
70 | 107 | protected function sendRequest(Operation $operation, array $userValues = [], bool $async = false)
|
71 | 108 | {
|
72 | 109 | $operation->validate($userValues);
|
@@ -100,76 +137,16 @@ public function executeAsync(array $definition, array $userValues = []): Promise
|
100 | 137 | public function model(string $class, $data = null): ResourceInterface
|
101 | 138 | {
|
102 | 139 | $model = new $class($this->client, $this->api);
|
103 |
| - |
104 | 140 | // @codeCoverageIgnoreStart
|
105 | 141 | if (!$model instanceof ResourceInterface) {
|
106 | 142 | throw new \RuntimeException(sprintf('%s does not implement %s', $class, ResourceInterface::class));
|
107 | 143 | }
|
108 | 144 | // @codeCoverageIgnoreEnd
|
109 |
| - |
110 | 145 | if ($data instanceof ResponseInterface) {
|
111 | 146 | $model->populateFromResponse($data);
|
112 | 147 | } elseif (is_array($data)) {
|
113 | 148 | $model->populateFromArray($data);
|
114 | 149 | }
|
115 |
| - |
116 | 150 | return $model;
|
117 | 151 | }
|
118 |
| - |
119 |
| - /** |
120 |
| - * Will create a new instance of this class with the current HTTP client and API injected in. This |
121 |
| - * is useful when enumerating over a collection since multiple copies of the same resource class |
122 |
| - * are needed. |
123 |
| - * |
124 |
| - * @return static |
125 |
| - */ |
126 |
| - public function newInstance(): self |
127 |
| - { |
128 |
| - return new static($this->client, $this->api); |
129 |
| - } |
130 |
| - |
131 |
| - /** |
132 |
| - * @return \GuzzleHttp\Psr7\Uri:null |
133 |
| - */ |
134 |
| - protected function getHttpBaseUrl() |
135 |
| - { |
136 |
| - return $this->client->getConfig('base_uri'); |
137 |
| - } |
138 |
| - |
139 |
| - /** |
140 |
| - * Magic method which intercepts async calls, finds the sequential version, and wraps it in a |
141 |
| - * {@see Promise} object. In order for this to happen, the called methods need to be in the |
142 |
| - * following format: `createAsync`, where `create` is the sequential method being wrapped. |
143 |
| - * |
144 |
| - * @param $methodName The name of the method being invoked. |
145 |
| - * @param $args The arguments to be passed to the sequential method. |
146 |
| - * |
147 |
| - * @throws \RuntimeException If method does not exist |
148 |
| - * |
149 |
| - * @return Promise |
150 |
| - */ |
151 |
| - public function __call($methodName, $args) |
152 |
| - { |
153 |
| - $e = function ($name) { |
154 |
| - return new \RuntimeException(sprintf('%s::%s is not defined', get_class($this), $name)); |
155 |
| - }; |
156 |
| - |
157 |
| - if (substr($methodName, -5) === 'Async') { |
158 |
| - $realMethod = substr($methodName, 0, -5); |
159 |
| - if (!method_exists($this, $realMethod)) { |
160 |
| - throw $e($realMethod); |
161 |
| - } |
162 |
| - |
163 |
| - $promise = new Promise( |
164 |
| - function () use (&$promise, $realMethod, $args) { |
165 |
| - $value = call_user_func_array([$this, $realMethod], $args); |
166 |
| - $promise->resolve($value); |
167 |
| - } |
168 |
| - ); |
169 |
| - |
170 |
| - return $promise; |
171 |
| - } |
172 |
| - |
173 |
| - throw $e($methodName); |
174 |
| - } |
175 | 152 | }
|
0 commit comments