Issues (13)

src/EActiveController.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * Date: 2017-12-07
5
 * Time: 03:18
6
 */
7
8
namespace MP\ExtendedApi;
9
10
use MP\Services\ImplementServices;
11
use Yii;
12
use yii\data\DataProviderInterface;
13
use yii\db\ActiveRecordInterface;
14
use yii\helpers\ArrayHelper;
15
use yii\rest\ActiveController;
16
use yii\web\ForbiddenHttpException;
17
use yii\web\NotFoundHttpException;
18
19
/**
20
 * Class    EActiveController
21
 * @package MP\ExtendedApi
22
 * @author  Yarmaliuk Mikhail
23
 * @version 1.0
24
 */
25
class EActiveController extends ActiveController
26
{
27
    use ImplementServices;
28
29
    const FILTER_ERROR_CODE = 405;
30
31
    /**
32
     * Search model class
33
     *
34
     * @var ActiveRecordInterface|string
35
     */
36
    public string $searchClass;
37
38
    /**
39
     * Return error if empty filtered result
40
     *
41
     * @var bool
42
     */
43
    public bool $errorFilter = false;
44
45
    /**
46
     * List external actions
47
     *
48
     * 'delete-all' => true,
49
     *
50
     * @var array
51
     */
52
    public array $externalActions = [];
53
54
    /**
55
     * Check action access
56
     *
57
     * 'index'  => 'rule',
58
     * 'update' => 'permission',
59
     *  and etc...
60
     *
61
     * @var array
62
     */
63
    public array $checkAccessRules = [];
64
65
    /**
66
     * @var array
67
     */
68
    public array $actionsParams = [];
69
70
    /**
71
     * @inheritdoc
72
     */
73
    public function actions(): array
74
    {
75
        $actions = ArrayHelper::merge(parent::actions(), [
76
            'index'  => [
77
                'class' => EIndexAction::class,
78
            ],
79
            'create' => [
80
                'class' => ECreateAction::class,
81
            ],
82
            'view'   => [
83
                'class' => EViewAction::class,
84
            ],
85
            'update' => [
86
                'class' => EUpdateAction::class,
87
            ],
88
            'delete' => [
89
                'class' => EDeleteAction::class,
90
            ],
91
        ]);
92
93
        $actions = ArrayHelper::merge($actions, $this->actionsParams);
94
95
        if (!empty($this->searchClass)) {
96
            $actions['index']['dataFilter'] = [
97
                'class'       => EActiveDataFilter::class,
98
                'searchModel' => $this->searchClass,
99
            ];
100
        }
101
102
        foreach ($this->externalActions as $externalAction => $value) {
103
            if ($value) {
104
                switch ($externalAction) {
105
                    case 'delete-all':
106
                        $actions[$externalAction]          = $actions['index'];
107
                        $actions[$externalAction]['class'] = EDeleteAllAction::class;
108
                    break;
109
110
                    case 'update-all':
111
                        $actions[$externalAction]          = $actions['index'];
112
                        $actions[$externalAction]['class'] = EUpdateAllAction::class;
113
                    break;
114
                }
115
            }
116
        }
117
118
        return $actions;
119
    }
120
121
    /**
122
     * @inheritdoc
123
     *
124
     * @param EIndexAction $action
125
     * @param mixed        $result
126
     *
127
     * @throws NotFoundHttpException
128
     */
129
    public function afterAction($action, $result)
130
    {
131
        if ($action->id === 'index' && $result instanceof DataProviderInterface) {
132
            if ($this->errorFilter && !empty($action->dataFilter->filter) && empty($result->getModels())) {
133
                $this->filterError();
134
            }
135
        }
136
137
        return parent::afterAction($action, $result);
138
    }
139
140
    /**
141
     * Throw error empty filtered result
142
     *
143
     * @throws NotFoundHttpException
144
     */
145
    public function filterError(): void
146
    {
147
        throw new NotFoundHttpException(Yii::t('app', 'Nothing found'), self::FILTER_ERROR_CODE);
148
    }
149
150
    /**
151
     * @inheritdoc
152
     */
153
    public function checkAccess($action, $model = null, $params = [])
154
    {
155
        if ($this->checkAccessRules[$action] ?? null) {
156
            $allow = Yii::$app->user->can($this->checkAccessRules[$action], ['model' => $model, 'params' => $params]);
0 ignored issues
show
The method can() 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

156
            /** @scrutinizer ignore-call */ 
157
            $allow = Yii::$app->user->can($this->checkAccessRules[$action], ['model' => $model, 'params' => $params]);

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...
157
158
            if (!$allow) {
159
                $this->forbidden();
160
            }
161
        }
162
    }
163
164
    /**
165
     * Throw forbidden error
166
     *
167
     * @throws ForbiddenHttpException
168
     */
169
    protected function forbidden(): void
170
    {
171
        throw new ForbiddenHttpException(Yii::t('app', 'You are not allowed to perform this action.'));
172
    }
173
}
174