RequestFilter::beforeAction()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 21
c 0
b 0
f 0
ccs 0
cts 20
cp 0
rs 8.9617
cc 6
nc 5
nop 1
crap 42
1
<?php
2
3
namespace indigerd\scenarios\filters;
4
5
use Yii;
6
use yii\base\Action;
7
use yii\base\ActionFilter;
8
use yii\base\InvalidConfigException;
9
use yii\web\Request;
10
use yii\web\Response;
11
use indigerd\scenarios\Scenario;
12
use indigerd\scenarios\exception\RequestValidateException;
13
use indigerd\scenarios\validation\factory\ValidatorCollectionFactory;
14
use indigerd\scenarios\validation\factory\ValidatorFactory;
15
16
class RequestFilter extends ActionFilter
17
{
18
    public $filters = [];
19
20
    /**
21
     * @var Request the current request. If not set, the `request` application component will be used.
22
     */
23
    public $request;
24
25
    /**
26
     * @var Response the response to be sent. If not set, the `response` application component will be used.
27
     */
28
    public $response;
29
30
    public $validatorFactory;
31
32
    public $validatorCollectionFactory;
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function init()
38
    {
39
        if ($this->request === null) {
40
            $this->request = Yii::$app->getRequest();
41
        }
42
        if ($this->response === null) {
43
            $this->response = Yii::$app->getResponse();
44
        }
45
        if ($this->validatorFactory === null) {
46
            $this->validatorFactory = ValidatorFactory::class;
47
        }
48
        if ($this->validatorCollectionFactory === null) {
49
            $this->validatorCollectionFactory = ValidatorCollectionFactory::class;
50
        }
51
        foreach ($this->filters as $action => $filter) {
52
            if ($filter instanceof Scenario) {
53
                continue;
54
            }
55
            $scenario = '';
56
            $rules    = [];
57
            if (\is_string($filter)) {
58
                $scenario = $filter;
59
            }
60
            if (\is_array($filter)) {
61
                if (!isset($filter['class'])) {
62
                    throw new InvalidConfigException('Invalid request filters configuration');
63
                }
64
                $scenario = $filter['class'];
65
                $rules = isset($filter['rules']) ? $filter['rules'] : [];
66
            }
67
            if (!\is_a($scenario, Scenario::class, true)) {
68
                throw new InvalidConfigException('Invalid request filters configuration');
69
            }
70
71
            $this->filters[$action] = new $scenario(
72
                new $this->validatorFactory,
73
                new $this->validatorCollectionFactory,
74
                $rules
75
            );
76
        }
77
    }
78
79
    /**
80
     * @inheritdoc
81
     */
82
    public function beforeAction(Action $action)
83
    {
84
        if ($this->request->getIsHead() or $this->request->getIsOptions()) {
85
            return true;
86
        }
87
        if (isset($this->filters[$action->id])) {
88
            try {
89
                /** @var Scenario $scenario */
90
                $scenario = $this->filters[$action->id];
91
                $scenario->validateRequest(
92
                    $this->request,
93
                    ($this->request->getIsGet() ? 'query' : 'body')
94
                );
95
            } catch (RequestValidateException $e) {
96
                $this->response->data = $e->getErrorCollection();
97
                $this->response->setStatusCode(422, 'Request validation failed');
98
                return false;
99
            }
100
        }
101
        return true;
102
    }
103
}
104