Passed
Push — hypernext ( 670104...c80301 )
by Nico
14:24
created

AbstractProcessor::getParamsObject()   D

Complexity

Conditions 18
Paths 11

Size

Total Lines 43
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 29
c 1
b 0
f 0
nc 11
nop 0
dl 0
loc 43
rs 4.8666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
/**
3
 * @author Nicolas CARPi <[email protected]>
4
 * @copyright 2012 Nicolas CARPi
5
 * @see https://www.elabftw.net Official website
6
 * @license AGPL-3.0
7
 * @package elabftw
8
 */
9
10
namespace Elabftw\Elabftw;
11
12
use Elabftw\Exceptions\IllegalActionException;
13
use Elabftw\Interfaces\CrudInterface;
14
use Elabftw\Interfaces\ProcessorInterface;
15
use Elabftw\Models\AbstractEntity;
16
use Elabftw\Models\ApiKeys;
17
use Elabftw\Models\Comments;
18
use Elabftw\Models\Config;
19
use Elabftw\Models\Experiments;
20
use Elabftw\Models\FavTags;
21
use Elabftw\Models\Items;
22
use Elabftw\Models\ItemsTypes;
23
use Elabftw\Models\Links;
24
use Elabftw\Models\PrivacyPolicy;
25
use Elabftw\Models\Status;
26
use Elabftw\Models\Steps;
27
use Elabftw\Models\Tags;
28
use Elabftw\Models\TeamGroups;
29
use Elabftw\Models\Templates;
30
use Elabftw\Models\Todolist;
31
use Elabftw\Models\UnfinishedSteps;
32
use Elabftw\Models\Uploads;
33
use Elabftw\Models\Users;
34
use Elabftw\Services\Check;
35
use Elabftw\Services\Email;
36
use function property_exists;
37
use Symfony\Component\HttpFoundation\Request;
38
39
/**
40
 * Mother class to process a request
41
 */
42
abstract class AbstractProcessor implements ProcessorInterface
43
{
44
    public AbstractEntity $Entity;
45
46
    public string $content = '';
47
48
    public string $target = '';
49
50
    protected string $action;
51
52
    protected ?int $id = null;
53
54
    protected CrudInterface | Users $Model;
55
56
    protected array $extra = array();
57
58
    public function __construct(private Users $Users, Request $request)
59
    {
60
        $this->process($request);
61
    }
62
63
    public function getModel(): CrudInterface | Users
64
    {
65
        return $this->Model;
66
    }
67
68
    public function getAction(): string
69
    {
70
        return $this->action;
71
    }
72
73
    public function getTarget(): string
74
    {
75
        return $this->target;
76
    }
77
78
    // @phpstan-ignore-next-line
79
    public function getParams()
80
    {
81
        if ($this->action === 'create' || $this->action === 'read' || $this->action === 'update') {
82
            return $this->getParamsObject();
83
        }
84
    }
85
86
    protected function processJson(string $json): void
87
    {
88
        $decoded = json_decode($json);
89
        $this->action = $decoded->action ?? '';
90
        $this->setTarget($decoded->target ?? '');
91
92
        if (property_exists($decoded, 'entity') && $decoded->entity !== null) {
93
            $id = (int) $decoded->entity->id;
94
            if ($id === 0) {
95
                $id = null;
96
            }
97
            $this->Entity = $this->getEntity($decoded->entity->type, $id);
98
        }
99
        $this->id = $this->setId((int) ($decoded->id ?? 0));
100
        $this->Model = $this->buildModel($decoded->model ?? '');
101
        $this->content = $decoded->content ?? '';
102
        if (property_exists($decoded, 'extraParams')) {
103
            $this->extra = (array) $decoded->extraParams;
104
        }
105
    }
106
107
    abstract protected function process(Request $request): void;
108
109
    protected function setTarget(string $target): void
110
    {
111
        $this->target = Check::target($target);
112
    }
113
114
    protected function getEntity(string $type, ?int $itemId = null): AbstractEntity
115
    {
116
        if ($type === 'experiment') {
117
            return new Experiments($this->Users, $itemId);
118
        } elseif ($type === 'template') {
119
            return new Templates($this->Users, $itemId);
120
        } elseif ($type === 'itemtype') {
121
            return new ItemsTypes($this->Users, $itemId);
122
        }
123
        return new Items($this->Users, $itemId);
124
    }
125
126
    protected function buildModel(string $model): CrudInterface | Users
127
    {
128
        switch ($model) {
129
            case 'apikey':
130
                return new ApiKeys($this->Users, $this->id);
131
            case 'status':
132
                return new Status($this->Users->team, $this->id);
133
            case 'comment':
134
                return new Comments($this->Entity, new Email(Config::getConfig(), $this->Users), $this->id);
135
            case 'link':
136
                return new Links($this->Entity, $this->id);
137
            case 'favtag':
138
                return new FavTags($this->Users, $this->id);
139
            case 'step':
140
                return new Steps($this->Entity, $this->id);
141
            case 'unfinishedsteps':
142
                return new UnfinishedSteps($this->Entity);
143
            case 'upload':
144
                return new Uploads($this->Entity, $this->id);
145
            case 'privacypolicy':
146
                return new PrivacyPolicy(Config::getConfig());
147
            case 'teamgroup':
148
                return new TeamGroups($this->Users, $this->id);
149
            case 'tag':
150
                return new Tags($this->Entity, $this->id);
151
            case 'experiment':
152
            case 'item':
153
            case 'template':
154
            case 'itemtype':
155
                return $this->Entity;
156
            case 'todolist':
157
                return new Todolist((int) $this->Users->userData['userid'], $this->id);
158
            case 'user':
159
                return $this->Users;
160
            default:
161
                throw new IllegalActionException('Bad model');
162
        }
163
    }
164
165
    protected function setId(?int $id): ?int
166
    {
167
        if (!isset($id) || $id === 0) {
168
            return null;
169
        }
170
        $id = Check::id((int) $id);
171
        if ($id === false) {
172
            throw new IllegalActionException('Bad id');
173
        }
174
        return $id;
175
    }
176
177
    // @phpstan-ignore-next-line
178
    private function getParamsObject()
179
    {
180
        if ($this->Model instanceof Comments ||
181
            $this->Model instanceof Todolist ||
182
            $this->Model instanceof Links ||
183
            $this->Model instanceof FavTags ||
184
            $this->Model instanceof Users ||
185
            $this->Model instanceof PrivacyPolicy) {
186
            return new ContentParams($this->content, $this->target);
187
        }
188
        if ($this->Model instanceof Experiments || $this->Model instanceof Items || $this->Model instanceof Templates) {
189
            return new EntityParams($this->content, $this->target, $this->extra);
190
        }
191
        if ($this->Model instanceof ItemsTypes) {
192
            return new ItemTypeParams($this->content, $this->target, $this->extra);
193
        }
194
        if ($this->Model instanceof UnfinishedSteps) {
195
            return new UnfinishedStepsParams($this->extra);
196
        }
197
        if ($this->Model instanceof Steps) {
198
            return new StepParams($this->content, $this->target);
199
        }
200
        if ($this->Model instanceof Status) {
201
            return new StatusParams(
202
                $this->content,
203
                $this->extra['color'],
204
                (bool) $this->extra['isTimestampable'],
205
                (bool) $this->extra['isDefault']
206
            );
207
        }
208
        if ($this->Model instanceof ApiKeys) {
209
            // TODO only giv extra as third param and the get function will extract the correct stuff from it?
210
            // will help with homogeneisation of Params class
211
            return new CreateApikey($this->content, $this->target, (int) $this->extra['canwrite']);
212
        }
213
        if ($this->Model instanceof Tags) {
214
            return new TagParams($this->content, $this->target);
215
        }
216
        if ($this->Model instanceof Uploads) {
217
            return new UploadParams($this->content, $this->target);
218
        }
219
        if ($this->Model instanceof TeamGroups) {
220
            return new TeamGroupParams($this->content, $this->target, $this->extra);
221
        }
222
    }
223
}
224