|  | 
| 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