Passed
Push — master ( 21d927...ee3ef8 )
by Php Easy Api
03:01
created

Request::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Resta\Request;
4
5
use Resta\Support\Utils;
6
use Store\Services\RequestClient;
0 ignored issues
show
Bug introduced by
The type Store\Services\RequestClient 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...
7
use Resta\Contracts\HandleContracts;
8
use Resta\Support\ReflectionProcess;
9
10
class Request extends RequestClient implements HandleContracts
11
{
12
    /**
13
     * @var array $origin
14
     */
15
    protected $origin = [];
16
17
    /**
18
     * @var array $inputs
19
     */
20
    protected $inputs = [];
21
22
    /**
23
     * @var array $except
24
     */
25
    protected $except = [];
26
27
    /**
28
     * @var $capsule
0 ignored issues
show
Documentation Bug introduced by
The doc comment $capsule at position 0 could not be parsed: Unknown type name '$capsule' at position 0 in $capsule.
Loading history...
29
     */
30
    protected $capsule;
31
32
    /**
33
     * @var $method
0 ignored issues
show
Documentation Bug introduced by
The doc comment $method at position 0 could not be parsed: Unknown type name '$method' at position 0 in $method.
Loading history...
34
     */
35
    protected $method;
36
37
    /**
38
     * @var $reflection ReflectionProcess
0 ignored issues
show
Documentation Bug introduced by
The doc comment $reflection at position 0 could not be parsed: Unknown type name '$reflection' at position 0 in $reflection.
Loading history...
39
     */
40
    protected $reflection;
41
42
    /**
43
     * @var $data
0 ignored issues
show
Documentation Bug introduced by
The doc comment $data at position 0 could not be parsed: Unknown type name '$data' at position 0 in $data.
Loading history...
44
     */
45
    protected $requestHttp;
46
47
    /**
48
     * Request constructor.
49
     */
50
    public function __construct()
51
    {
52
        //reflection process
53
        $this->reflection = app()['reflection']($this);
54
55
        //get http method via request http manager class
56
        $this->requestHttp = app()->resolve(RequestHttpManager::class);
57
58
        // if we leave the request process to the application side,
59
        // then in this case we refer to the requestClient object in
60
        // the services section of the store directory.
61
        (property_exists($this,'app') && $this->app) ? parent::handle() : $this->handle();
62
    }
63
64
    /**
65
     * auto validate
66
     *
67
     * @return mixed
68
     */
69
    private function autoValidate($validate)
70
    {
71
        foreach ($this->{$validate} as $object=>$datas){
72
            if(Utils::isNamespaceExists($object)){
73
                $getObjectInstance = app()->resolve($object);
74
                foreach ($datas as $dataKey=>$data){
75
                    if(is_numeric($dataKey) && method_exists($getObjectInstance,$data)){
76
                        if(isset($this->origin[$data])){
77
                            if(!is_array($this->origin[$data])){
78
                                $this->origin[$data] = array($this->origin[$data]);
79
                            }
80
                            foreach ($this->origin[$data] as $originData){
81
                                $getObjectInstance->{$data}($originData);
82
                            }
83
                        }
84
                    }
85
                }
86
            }
87
        }
88
    }
89
90
    /**
91
     * check http method
92
     *
93
     * @return void|mixed
94
     */
95
    private function checkHttpMethod()
96
    {
97
        //get http method
98
        $method = $this->requestHttp->getMethod();
99
100
        // Determines which HTTP method
101
        // the request object will be exposed to.
102
        if($this->checkProperties('http')){
103
104
            // if the current http method does not exist
105
            // in the http object, the exception will be thrown.
106
            if(!in_array($method,$this->http)){
107
108
                //exception batMethodCall
109
                exception()->badMethodCall(
110
                    'Invalid http method process for '.class_basename($this).'.That is accepted http methods ['.implode(",",$this->http).'] ');
111
            }
112
        }
113
    }
114
115
    /**
116
     * check properties
117
     *
118
     * @param $properties
119
     * @return bool
120
     */
121
    private function checkProperties($properties)
122
    {
123
        // from the properties of the object properties to
124
        // the existing variables, control the array and at least one element.
125
        return (property_exists($this,$properties)
126
            && is_array($this->{$properties}) && count($this->{$properties})) ? true : false;
127
    }
128
129
    /**
130
     * register container for request
131
     *
132
     * @return mixed|void
133
     */
134
    private function containerRegister()
135
    {
136
        // we are saving the expected values ​​for the request in container.
137
        // this record can be returned in exception information.
138
        app()->register('requestExpected',$this->expected);
139
    }
140
141
    /**
142
     * get request except
143
     *
144
     * @param $except
145
     * @return $this
146
     */
147
    public function except($except)
148
    {
149
        // the except parameter is a callable value.
150
        if(is_callable($except)){
151
            $call = call_user_func_array($except,[$this]);
152
            $except = $call;
153
        }
154
155
        // except with the except exceptions property
156
        // and then assigning them to the inputs property.
157
        $this->except = array_merge($this->except,$except);
158
        $this->inputs = array_diff_key($this->inputs,array_flip($this->except));
159
160
        return $this;
161
    }
162
163
    /**
164
     * expected inputs
165
     *
166
     * @return void|mixed
167
     */
168
    private function expectedInputs()
169
    {
170
        // expected method is executed.
171
        // this method is a must for http method values to be found in this property.
172
        if($this->checkProperties('expected')){
173
174
            // if the expected values are not found in the inputs array,
175
            // the exception will be thrown.
176
            foreach ($this->expected as $expected){
177
                if(!isset($this->inputs[$expected])){
178
                    exception()->unexpectedValue('You absolutely have to send the value '.$expected.' for request object');
179
                }
180
            }
181
        }
182
    }
183
184
    /**
185
     * generator manager
186
     *
187
     * @return void|mixed
188
     */
189
    private function generatorManager()
190
    {
191
        // check the presence of the generator object
192
        // and operate the generator over this object.
193
        if($this->checkProperties('auto_generators')){
194
            $generators = $this->auto_generators;
195
        }
196
197
        // check the presence of the generator object
198
        // and operate the generator over this object.
199
        if($this->checkProperties('generators')){
200
            $generators = array_merge(isset($generators) ? $generators: [],$this->generators);
201
        }
202
203
        if(isset($generators)){
204
            $this->generatorMethod($generators);
205
        }
206
    }
207
208
    /**
209
     * generator method
210
     *
211
     * @param $generators
212
     */
213
    private function generatorMethod($generators)
214
    {
215
        //generator array object
216
        foreach ($generators as $generator){
217
218
            //generator method name
219
            $generatorMethodName = $generator.'Generator';
220
221
            // if the generator method is present,
222
            // the fake value is assigned.
223
            if(method_exists($this,$generatorMethodName)){
224
225
                //fake registration
226
                if(!isset($this->inputs[$generator])){
227
                    $this->{$generator} = $this->{$generatorMethodName}();
228
                    $this->inputs[$generator] = $this->{$generatorMethodName}();
229
                }
230
                else {
231
232
                    if($this->checkProperties('auto_generators_dont_overwrite')
233
                        && in_array($generator,$this->auto_generators_dont_overwrite)){
234
                        $this->{$generator} = $this->{$generatorMethodName}();
235
                        $this->inputs[$generator] = $this->{$generatorMethodName}();
236
                    }
237
238
                    if($this->checkProperties('generators_dont_overwrite')
239
                        && in_array($generator,$this->generators_dont_overwrite)){
240
                        $this->{$generator} = $this->{$generatorMethodName}();
241
                        $this->inputs[$generator] = $this->{$generatorMethodName}();
242
                    }
243
244
                }
245
246
                $this->registerRequestInputs($generator);
247
            }
248
        }
249
    }
250
251
    /**
252
     * get inputs
253
     *
254
     * @return array
255
     */
256
    protected function get()
257
    {
258
        return $this->inputs;
259
    }
260
261
    /**
262
     * get client objects
263
     *
264
     * @return array
265
     */
266
    private function getClientObjects()
267
    {
268
        return array_diff_key($this->getObjects(),['inputs'=>[]]);
269
    }
270
271
    /**
272
     * get object vars
273
     *
274
     * @return array
275
     */
276
    private function getObjects()
277
    {
278
        return get_object_vars($this);
279
    }
280
281
    /**
282
     * request handle
283
     *
284
     * @return void
285
     */
286
    public function handle()
287
    {
288
        //set container for request
289
        $this->containerRegister();
290
291
        //we record the values ​​
292
        //that coming with the post.
293
        $this->initClient();
294
295
        // we update the input values ​​after
296
        // we receive and check the saved objects.
297
        $this->setClientObjects();
298
299
        // we add our user-side properties for the request object,
300
        // and on this we will set all the request object properties
301
        // that may be useful for the application.
302
        $this->requestProperties();
303
    }
304
305
    /**
306
     * get init client
307
     *
308
     * @return void
309
     */
310
    private function initClient()
311
    {
312
        // we use the http method to write
313
        // the values to the inputs and origin properties.
314
        foreach($this->requestHttp->resolve() as $key=>$value){
315
316
            //inputs and origin properties
317
            $this->inputs[$key] = $value;
318
            $this->origin[$key] = $value;
319
        }
320
    }
321
322
    /**
323
     * request properties
324
     *
325
     * @return void|mixed
326
     */
327
    private function requestProperties()
328
    {
329
        // if a fake method is defined and it is not in
330
        // the context of any key method when access is granted,
331
        // it can be filled with fake method.
332
        $this->generatorManager();
333
334
        // contrary to capsule method,
335
        // expected values must be in the key being sent.
336
        $this->expectedInputs();
337
338
        // this method determines
339
        // how the request object will be requested,
340
        $this->checkHttpMethod();
341
342
        // it passes all keys that are sent through
343
        // a validation method on the user side.
344
        $this->validation();
345
    }
346
347
    /**
348
     * set client objects
349
     *
350
     * @return mixed
351
     */
352
    private function setClientObjects()
353
    {
354
        $clientObjects = $this->getClientObjects();
355
356
        // we update the input values ​​after
357
        // we receive and check the saved objects.
358
        foreach ($clientObjects as $key=>$value){
359
360
            if(isset($clientObjects['origin'][$key])){
361
362
                $this->{$key} = $clientObjects['origin'][$key];
363
                $this->inputs[$key] = $this->{$key};
364
365
                // the request update to be performed using
366
                // the method name to be used with the http method.
367
                $this->registerRequestInputs($key);
368
            }
369
        }
370
    }
371
372
    /**
373
     * register request inputs
374
     *
375
     * @param $key
376
     */
377
    private function registerRequestInputs($key)
378
    {
379
        // the method name to be used with
380
        // the http method.
381
        $requestMethod = $this->requestHttp->getMethod().''.ucfirst($key);
382
383
        // the request update to be performed using
384
        // the method name to be used with the http method.
385
        $this->setRequestInputs($requestMethod,$key);
386
387
        // the request update to be performed using
388
        // the method name to be used without the http method.
389
        $this->setRequestInputs($key,$key);
390
    }
391
392
    /**
393
     * set request inputs
394
     *
395
     * @param $method
396
     * @param $key
397
     */
398
    private function setRequestInputs($method,$key)
399
    {
400
        if(method_exists($this,$method) && $this->reflection->reflectionMethodParams($method)->isProtected){
401
402
            //check annotations for method
403
            $annotation = app()->resolve(RequestAnnotationManager::class,['request'=>$this]);
404
            $annotation->annotation($method,$key);
405
406
            if(isset($this->inputs[$key]) && is_array($this->inputs[$key])){
407
408
                $inputKeys = $this->inputs[$key];
409
410
                $this->inputs[$key] = [];
411
                foreach ($inputKeys as $input){
412
413
                    $this->{$key}           = $input;
414
                    $keyMethod              = $this->{$method}();
415
                    $this->inputs[$key][]   = $keyMethod;
416
                }
417
            }
418
            else{
419
                if(isset($this->inputs[$key])){
420
                    $keyMethod = $this->{$method}();
421
                    $this->inputs[$key] = $keyMethod;
422
                }
423
424
            }
425
        }
426
    }
427
428
    /**
429
     * validation
430
     *
431
     * @return void
432
     */
433
    private function validation()
434
    {
435
        if(property_exists($this,'autoObjectValidate') && is_array($this->autoObjectValidate) && count($this->autoObjectValidate)){
436
            $this->autoValidate('autoObjectValidate');
437
        }
438
        // we need to find the rule method
439
        // because we can not validate it.
440
        if(method_exists($this,'rule')){
441
            $this->rule();
442
        }
443
444
        // if we only want to make a rule of
445
        // the specified request object, we will use
446
        // the rule method with the prefix of the request object.
447
        $validName=strtolower(str_replace('Request','',class_basename($this))).'Rule';
448
449
        //if the specified method exists;
450
        if(method_exists($this,$validName)){
451
            $this->{$validName}();
452
        }
453
    }
454
}