Test Setup Failed
Push — master ( 29d7f6...b0c19c )
by Php Easy Api
03:16
created

Client::checkHttpMethod()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 0
dl 0
loc 16
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Resta\Client;
4
5
use Resta\Support\Utils;
6
use Resta\Contracts\HandleContracts;
7
use Resta\Support\ReflectionProcess;
8
use ReflectionException as ReflectionExceptionAlias;
9
10
class Client extends ClientAbstract implements HandleContracts
11
{
12
    /**
13
     * @var array
14
     */
15
    protected $capsule = [];
16
17
    /**
18
     * @var array
19
     */
20
    protected $except = [];
21
22
    /**
23
     * @var string
24
     */
25
    protected $method;
26
27
    /**
28
     * @var ReflectionProcess
29
     */
30
    protected $reflection;
31
32
    /**
33
     * @var null|object
34
     */
35
    protected $requestHttp;
36
37
    /**
38
     * @var null|array
39
     */
40
    protected $clientData;
41
42
    /**
43
     * Request constructor.
44
     *
45
     * @param null|array $clientData
46
     *
47
     * @throws ReflectionExceptionAlias
48
     */
49
    public function __construct($clientData=null)
50
    {
51
        //reflection process
52
        $this->reflection = app()['reflection']($this);
53
54
        //get http method via request http manager class
55
        $this->requestHttp = app()->resolve(ClientHttpManager::class);
56
57
        //get request client data
58
        $this->clientData = ($clientData===null) ? $this->requestHttp->resolve() : $clientData;
59
60
        //handle request
61
        $this->handle();
62
    }
63
64
    /**
65
     * auto validate
66
     *
67
     * @param $validate
68
     */
69
    private function autoValidate($validate)
70
    {
71
        //we get the values ​​to auto-validate.
72
        foreach ($this->{$validate} as $object=>$datas){
73
74
            // the auto-validate value must necessarily represent a class.
75
            // otherwise auto-validate is not used.
76
            if(Utils::isNamespaceExists($object)){
77
                $getObjectInstance = app()->resolve($object);
78
79
                // we get the index values,
80
                // which are called methods of the auto-validate value that represents the class.
81
                foreach ($datas as $dataKey=>$data){
82
83
                    // if the methods of the auto-validate class resolved by the container resolve method apply,
84
                    // the process of auto-validate automatic implementation will be completed.
85
                    if(is_numeric($dataKey) && method_exists($getObjectInstance,$data)){
86
                        if(isset($this->origin[$data])){
87
                            if(!is_array($this->origin[$data])){
88
                                $this->origin[$data] = array($this->origin[$data]);
89
                            }
90
                            foreach ($this->origin[$data] as $originData){
91
                                $getObjectInstance->{$data}($originData);
92
                            }
93
                        }
94
                    }
95
                }
96
            }
97
        }
98
    }
99
100
    /**
101
     * capsule inputs
102
     *
103
     * @return void|mixed
104
     */
105
    private function capsule()
106
    {
107
        // expected method is executed.
108
        // this method is a must for http method values to be found in this property.
109
        if($this->checkProperties('capsule')){
110
111
            $caret = $this->capsuleCaret();
112
113
            foreach($this->inputs as $input=>$value){
114
115
                if(isset($caret[$input]) || (
116
                        $this->checkProperties('capsule') && !in_array($input,$this->capsule)
117
                    )){
118
                    exception('capsuleRequestException')
119
                        ->overflow('The '.$input.' value cannot be sent.');
120
                }
121
            }
122
        }
123
    }
124
125
    /**
126
     * get capsule caret for request
127
     *
128
     * @return array
129
     */
130
    private function capsuleCaret()
131
    {
132
        $caret = [];
133
134
        foreach($this->inputs as $input=>$item){
135
            if(in_array('@'.$input,$this->capsule)){
136
                $caret[$input] = $item;
137
            }
138
        }
139
140
        foreach ($this->capsule as $item) {
141
            if(preg_match('#@.*#is',$item)){
142
                $this->capsule = array_diff($this->capsule,[$item]);
143
            }
144
        }
145
146
        return $caret;
147
    }
148
149
    /**
150
     * check http method
151
     *
152
     * @return void|mixed
153
     */
154
    private function checkHttpMethod()
155
    {
156
        //get http method
157
        $method = $this->requestHttp->getMethod();
0 ignored issues
show
Bug introduced by
The method getMethod() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

157
        /** @scrutinizer ignore-call */ 
158
        $method = $this->requestHttp->getMethod();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
158
159
        // Determines which HTTP method
160
        // the request object will be exposed to.
161
        if($this->checkProperties('http')){
162
163
            // if the current http method does not exist
164
            // in the http object, the exception will be thrown.
165
            if(!in_array($method,$this->http)){
0 ignored issues
show
Bug Best Practice introduced by
The property http does not exist on Resta\Client\Client. Did you maybe forget to declare it?
Loading history...
166
167
                //exception batMethodCall
168
                exception()->badMethodCall(
169
                    'Invalid http method process for '.class_basename($this).'.That is accepted http methods ['.implode(",",$this->http).'] ');
170
            }
171
        }
172
    }
173
174
    /**
175
     * check properties
176
     *
177
     * @param $properties
178
     * @return bool
179
     */
180
    private function checkProperties($properties)
181
    {
182
        // from the properties of the object properties to
183
        // the existing variables, control the array and at least one element.
184
        return (property_exists($this,$properties)
185
            && is_array($this->{$properties}) && count($this->{$properties})) ? true : false;
186
    }
187
188
    /**
189
     * register container for request
190
     *
191
     * @return mixed|void
192
     */
193
    private function containerRegister()
194
    {
195
        // we are saving the expected values ​​for the request in container.
196
        // this record can be returned in exception information.
197
        app()->register('requestExpected',$this->expected);
0 ignored issues
show
Bug Best Practice introduced by
The property expected does not exist on Resta\Client\Client. Did you maybe forget to declare it?
Loading history...
198
    }
199
200
    /**
201
     * get request except
202
     *
203
     * @param $except
204
     * @return $this
205
     */
206
    public function except($except)
207
    {
208
        // the except parameter is a callable value.
209
        if(is_callable($except)){
210
            $call = call_user_func_array($except,[$this]);
211
            $except = $call;
212
        }
213
214
        // except with the except exceptions property
215
        // and then assigning them to the inputs property.
216
        $this->except = array_merge($this->except,$except);
217
        $this->inputs = array_diff_key($this->inputs,array_flip($this->except));
218
219
        return $this;
220
    }
221
222
    /**
223
     * expected inputs
224
     *
225
     * @return void|mixed
226
     */
227
    private function expectedInputs()
228
    {
229
        // expected method is executed.
230
        // this method is a must for http method values to be found in this property.
231
        if($this->checkProperties('expected')){
232
233
            // if the expected values are not found in the inputs array,
234
            // the exception will be thrown.
235
            foreach ($this->expected as $expected){
0 ignored issues
show
Bug Best Practice introduced by
The property expected does not exist on Resta\Client\Client. Did you maybe forget to declare it?
Loading history...
236
237
                $expectedValues = [];
238
239
                // mandatory expected data for each key can be separated by | operator.
240
                // this is evaluated as "or".
241
                foreach($expectedData = explode("|",$expected) as $inputs){
242
                    if(!isset($this->inputs[$inputs])){
243
                        $expectedValues[] = $inputs;
244
                    }
245
                }
246
247
                // if the expectedData and expectedValues ​​
248
                // array are numerically equal to the expected key, the exception is thrown.
249
                if(count($expectedData)===count($expectedValues)){
250
                    exception($expected)
251
                        ->unexpectedValue('You absolutely have to send the value '.implode(" or ",$expectedValues).' for request object');
252
                }
253
            }
254
        }
255
    }
256
257
    /**
258
     * generator manager
259
     *
260
     * @throws ReflectionExceptionAlias
261
     */
262
    private function generatorManager()
263
    {
264
        // check the presence of the generator object
265
        // and operate the generator over this object.
266
        if($this->checkProperties('auto_generators')){
267
            $generators = $this->getAutoGenerators();
268
        }
269
270
        // check the presence of the generator object
271
        // and operate the generator over this object.
272
        if($this->checkProperties('generators')){
273
            $generators = array_merge(isset($generators) ? $generators: [],$this->getGenerators());
274
        }
275
276
        if(isset($generators)){
277
            $this->generatorMethod($generators);
278
        }
279
    }
280
281
    /**
282
     * generator method
283
     *
284
     * @param $generators
285
     *
286
     * @throws ReflectionExceptionAlias
287
     */
288
    private function generatorMethod($generators)
289
    {
290
        //generator array object
291
        foreach ($generators as $generator){
292
293
            //generator method name
294
            $generatorMethodName = $generator.'Generator';
295
296
            // if the generator method is present,
297
            // the fake value is assigned.
298
            if(method_exists($this,$generatorMethodName)){
299
300
                //fake registration
301
                if(!isset($this->inputs[$generator])){
302
                    $this->{$generator} = $this->{$generatorMethodName}();
303
                    $this->inputs[$generator] = $this->{$generatorMethodName}();
304
                }
305
                else {
306
307
                    if($this->checkProperties('auto_generators_dont_overwrite')
308
                        && in_array($generator,$this->getAutoGeneratorsDontOverwrite())){
309
                        $this->{$generator} = $this->{$generatorMethodName}();
310
                        $this->inputs[$generator] = $this->{$generatorMethodName}();
311
                    }
312
313
                    if($this->checkProperties('generators_dont_overwrite')
314
                        && in_array($generator,$this->getGeneratorsDontOverwrite())){
315
                        $this->{$generator} = $this->{$generatorMethodName}();
316
                        $this->inputs[$generator] = $this->{$generatorMethodName}();
317
                    }
318
319
                }
320
321
                $this->registerRequestInputs($generator);
322
            }
323
        }
324
    }
325
326
    /**
327
     * request handle
328
     *
329
     * @return mixed|void
330
     *
331
     * @throws ReflectionExceptionAlias
332
     */
333
    public function handle()
334
    {
335
        //set container for request
336
        $this->containerRegister();
337
338
        //we record the values ​​
339
        //that coming with the post.
340
        $this->initClient();
341
342
        // we update the input values ​​after
343
        // we receive and check the saved objects.
344
        $this->setClientObjects();
345
346
        // we add our user-side properties for the request object,
347
        // and on this we will set all the request object properties
348
        // that may be useful for the application.
349
        $this->requestProperties();
350
    }
351
352
    /**
353
     * get init client
354
     *
355
     * @return void
356
     */
357
    private function initClient()
358
    {
359
        // we use the http method to write
360
        // the values to the inputs and origin properties.
361
        foreach($this->clientData as $key=>$value){
362
363
            //inputs and origin properties
364
            $this->inputs[$key] = $value;
365
            $this->origin[$key] = $value;
366
        }
367
    }
368
369
    /**
370
     * request properties
371
     *
372
     * @throws ReflectionExceptionAlias
373
     */
374
    private function requestProperties()
375
    {
376
        // if a fake method is defined and it is not in
377
        // the context of any key method when access is granted,
378
        // it can be filled with fake method.
379
        $this->generatorManager();
380
381
        // contrary to capsule method,
382
        // expected values must be in the key being sent.
383
        $this->expectedInputs();
384
385
        // get capsule as mandatory values
386
        $this->capsule();
387
388
        // this method determines
389
        // how the request object will be requested,
390
        $this->checkHttpMethod();
391
392
        // it passes all keys that are sent through
393
        // a validation method on the user side.
394
        $this->validation();
395
    }
396
397
    /**
398
     * set client objects
399
     *
400
     * @throws ReflectionExceptionAlias
401
     */
402
    private function setClientObjects()
403
    {
404
        $clientObjects = $this->getClientObjects();
405
406
        // we update the input values ​​after
407
        // we receive and check the saved objects.
408
        foreach ($clientObjects as $key=>$value){
409
410
            if(isset($clientObjects['origin'][$key])){
411
412
                $this->{$key} = $clientObjects['origin'][$key];
413
                $this->inputs[$key] = $this->{$key};
414
415
                // the request update to be performed using
416
                // the method name to be used with the http method.
417
                $this->registerRequestInputs($key);
418
            }
419
        }
420
    }
421
422
    /**
423
     * register request inputs
424
     *
425
     * @param $key
426
     *
427
     * @throws ReflectionExceptionAlias
428
     */
429
    private function registerRequestInputs($key)
430
    {
431
        // the method name to be used with
432
        // the http method.
433
        $requestMethod = $this->requestHttp->getMethod().''.ucfirst($key);
434
435
        // the request update to be performed using
436
        // the method name to be used with the http method.
437
        $this->setRequestInputs($requestMethod,$key);
438
439
        // the request update to be performed using
440
        // the method name to be used without the http method.
441
        $this->setRequestInputs($key,$key);
442
    }
443
444
    /**
445
     * set request inputs
446
     *
447
     * @param $method
448
     * @param $key
449
     *
450
     * @throws ReflectionExceptionAlias
451
     */
452
    private function setRequestInputs($method,$key)
453
    {
454
        if(method_exists($this,$method) && $this->reflection->reflectionMethodParams($method)->isProtected){
455
456
            //check annotations for method
457
            $annotation = app()->resolve(RequestAnnotationManager::class,['request'=>$this]);
0 ignored issues
show
Bug introduced by
The type Resta\Client\RequestAnnotationManager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
458
            $annotation->annotation($method,$key);
459
460
            if(isset($this->inputs[$key]) && is_array($this->inputs[$key])){
461
462
                $inputKeys = $this->inputs[$key];
463
464
                $this->inputs[$key] = [];
465
                foreach ($inputKeys as $input){
466
467
                    $this->{$key}           = $input;
468
                    $keyMethod              = $this->{$method}();
469
                    $this->inputs[$key][]   = $keyMethod;
470
                }
471
            }
472
            else{
473
                if(isset($this->inputs[$key])){
474
                    $keyMethod = $this->{$method}();
475
                    $this->inputs[$key] = $keyMethod;
476
                }
477
478
            }
479
        }
480
    }
481
482
    /**
483
     * validation for request
484
     *
485
     * @return void
486
     */
487
    private function validation()
488
    {
489
        // the auto object validate property is the property
490
        // where all of your request values ​​are automatically validated.
491
        if(property_exists($this,'autoObjectValidate')
492
            && is_array($this->autoObjectValidate) && count($this->autoObjectValidate)){
493
            $this->autoValidate('autoObjectValidate');
494
        }
495
    }
496
}