Issues (150)

src/Blocks/EntitiesTrait.php (3 issues)

assigning incompatible types to properties.

Bug Documentation Minor
1
<?php
2
3
namespace SoliDry\Blocks;
4
5
use Illuminate\Container\Container;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Http\Request;
8
use Illuminate\Http\Response;
9
use Illuminate\Database\Eloquent\SoftDeletes;
10
use Illuminate\Support\Facades\DB;
11
use SoliDry\Exceptions\ErrorHandler;
12
use SoliDry\Extension\ApiController;
13
use SoliDry\Extension\BaseFormRequest;
14
use SoliDry\Extension\BaseModel;
15
use SoliDry\Extension\JSONApiInterface;
16
use SoliDry\Helpers\Classes;
17
use SoliDry\Helpers\ConfigHelper as conf;
18
use SoliDry\Helpers\ConfigOptions;
19
use SoliDry\Helpers\Json;
20
use SoliDry\Types\DefaultInterface;
21
use SoliDry\Types\DirsInterface;
22
use SoliDry\Types\ModelsInterface;
23
use SoliDry\Types\PhpInterface;
24
use SoliDry\Types\ApiInterface;
25
26
/**
27
 * Class EntitiesTrait
28
 *
29
 * @package SoliDry\Blocks
30
 * @property ApiController entity
31
 * @property BaseFormRequest $formRequest
32
 * @property ApiController props
33
 * @property BaseModel model
34
 * @property ApiController modelEntity
35
 * @property ConfigOptions configOptions
36
 * @property Json json
37
 * @property \SoliDry\Containers\Response response
38
 */
39
trait EntitiesTrait
40
{
41
    use ErrorHandler;
42
43
    /**
44
     * Gets form request entity fully qualified path
45
     *
46
     * @param string $version
47
     * @param string $object
48
     * @return string
49
     */
50
    public function getFormRequestEntity(string $version, string $object): string
51
    {
52
        return DirsInterface::MODULES_DIR . PhpInterface::BACKSLASH . strtoupper($version) .
53
            PhpInterface::BACKSLASH . DirsInterface::HTTP_DIR .
54
            PhpInterface::BACKSLASH .
55
            DirsInterface::FORM_REQUEST_DIR . PhpInterface::BACKSLASH .
56
            $object .
57
            DefaultInterface::FORM_REQUEST_POSTFIX;
58
    }
59
60
    /**
61
     *  Sets all props/entities needed to process request
62
     *
63
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
64
     * @throws \ReflectionException
65
     */
66
    protected function setEntities(): void
67
    {
68
        $this->entity = Classes::cutEntity(Classes::getObjectName($this), DefaultInterface::CONTROLLER_POSTFIX);
0 ignored issues
show
Documentation Bug introduced by
It seems like SoliDry\Helpers\Classes:...ce::CONTROLLER_POSTFIX) of type string is incompatible with the declared type SoliDry\Extension\ApiController of property $entity.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
69
        $formRequestEntity = $this->getFormRequestEntity(conf::getModuleName(), $this->entity);
70
71
        $this->formRequest = new $formRequestEntity();
72
        $this->props = get_object_vars($this->formRequest);
0 ignored issues
show
Documentation Bug introduced by
It seems like get_object_vars($this->formRequest) of type array is incompatible with the declared type SoliDry\Extension\ApiController of property $props.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
73
74
        $this->modelEntity = Classes::getModelEntity($this->entity);
0 ignored issues
show
Documentation Bug introduced by
It seems like SoliDry\Helpers\Classes:...elEntity($this->entity) of type string is incompatible with the declared type SoliDry\Extension\ApiController of property $modelEntity.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
75
        $this->model = new $this->modelEntity();
76
77
        $container = Container::getInstance();
78
        $this->response = $container->make(\SoliDry\Containers\Response::class);
79
        $this->response->setFormRequest($this->formRequest);
80
        $this->response->setEntity($this->entity);
81
    }
82
83
    /**
84
     * Save bulk transactionally, if there are some errors - rollback
85
     *
86
     * @param Request $request
87
     * @return Response
88
     * @throws \InvalidArgumentException
89
     * @throws \LogicException
90
     */
91
    protected function saveBulk(Request $request): Response
92
    {
93
        $meta = [];
94
        $collection = new Collection();
95
96
        $json = Json::decode($request->getContent());
97
        $jsonApiAttributes = Json::getBulkAttributes($json);
98
99
        try {
100
            DB::beginTransaction();
101
            foreach ($jsonApiAttributes as $jsonObject) {
102
103
                $this->model = new $this->modelEntity();
104
105
                // FSM initial state check
106
                if ($this->configOptions->isStateMachine() === true) {
107
                    $this->checkFsmCreate($jsonObject);
108
                }
109
110
                // spell check
111
                if ($this->configOptions->isSpellCheck() === true) {
112
                    $meta[] = $this->spellCheck($jsonObject);
113
                }
114
115
                // fill in model
116
                foreach ($this->props as $k => $v) {
117
                    // request fields should match FormRequest fields
118
                    if (isset($jsonObject[$k])) {
119
                        $this->model->$k = $jsonObject[$k];
120
                    }
121
                }
122
123
                // set bit mask
124
                if ($this->configOptions->isBitMask() === true) {
125
                    $this->setMaskCreate($jsonObject);
126
                }
127
128
                $collection->push($this->model);
129
                $this->model->save();
130
131
                // jwt
132
                if ($this->configOptions->getIsJwtAction() === true) {
133
                    $this->createJwtUser(); // !!! model is overridden
134
                }
135
136
                // set bit mask from model -> response
137
                if ($this->configOptions->isBitMask() === true) {
138
                    $this->model = $this->setFlagsCreate();
139
                }
140
            }
141
142
            DB::commit();
143
        } catch (\PDOException $e) {
144
            DB::rollBack();
145
146
            return $this->getErrorResponse($request, $e);
147
        }
148
149
        return $this->response->get($collection, $meta);
150
    }
151
152
    /**
153
     * Mutates/Updates a bulk by applying it to transaction/rollback procedure
154
     *
155
     * @param Request $request
156
     * @return Response
157
     * @throws \InvalidArgumentException
158
     * @throws \SoliDry\Exceptions\AttributesException
159
     * @throws \LogicException
160
     */
161
    protected function mutateBulk(Request $request): Response
162
    {
163
        $meta = [];
164
        $collection = new Collection();
165
166
        $json = Json::decode($request->getContent());
167
        $jsonApiAttributes = Json::getBulkAttributes($json);
168
169
        try {
170
            DB::beginTransaction();
171
            foreach ($jsonApiAttributes as $jsonObject) {
172
173
                $model = $this->getEntity($jsonObject[JSONApiInterface::CONTENT_ID]);
174
175
                // FSM transition check
176
                if ($this->configOptions->isStateMachine() === true) {
177
                    $this->checkFsmUpdate($jsonObject, $model);
178
                }
179
180
                // spell check
181
                if ($this->configOptions->isSpellCheck() === true) {
182
                    $meta[] = $this->spellCheck($jsonObject);
183
                }
184
185
                $this->processUpdate($model, $jsonObject);
186
                $collection->push($model);
187
                $model->save();
188
189
                // set bit mask
190
                if ($this->configOptions->isBitMask() === true) {
191
                    $this->setFlagsUpdate($model);
192
                }
193
194
            }
195
            DB::commit();
196
        } catch (\PDOException $e) {
197
            DB::rollBack();
198
199
            return $this->getErrorResponse($request, $e);
200
        }
201
202
        return $this->response->get($collection, $meta);
203
    }
204
205
    /**
206
     * Deletes bulk by applying it to transaction/rollback procedure
207
     *
208
     * @param Request $request
209
     * @return Response
210
     * @throws \LogicException
211
     */
212
    public function removeBulk(Request $request): Response
213
    {
214
        $json = Json::decode($request->getContent());
215
        $jsonApiAttributes = Json::getBulkAttributes($json);
216
217
        try {
218
            DB::beginTransaction();
219
220
            foreach ($jsonApiAttributes as $jsonObject) {
221
                $model = $this->getEntity($jsonObject[JSONApiInterface::CONTENT_ID]);
222
223
                if ($model === null) {
224
                    DB::rollBack();
225
226
                    return $this->response->getModelNotFoundError($this->modelEntity, $jsonObject[JSONApiInterface::CONTENT_ID]);
227
                }
228
229
                $model->delete();
230
            }
231
232
            DB::commit();
233
        } catch (\PDOException $e) {
234
            DB::rollBack();
235
236
            return $this->getErrorResponse($request, $e);
237
        }
238
239
        return $this->response->removeBulk();
240
    }
241
242
    /**
243
     * Gets the relations of entity or null
244
     * @param string $objectName
245
     *
246
     * @return mixed
247
     */
248
    private function getRelationType(string $objectName)
249
    {
250
        if (empty($this->generator->types[$objectName][ApiInterface::RAML_PROPS]
251
            [ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]) === false
252
        ) {
253
            return trim(
254
                $this->generator->types[$objectName][ApiInterface::RAML_PROPS]
255
                [ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]
256
            );
257
        }
258
259
        return null;
260
    }
261
262
    /**
263
     * Sets use stmt for Soft Delete op on model Entity
264
     *
265
     * @throws \ReflectionException
266
     */
267
    private function setUseSoftDelete(): void
268
    {
269
        if ($this->isSoftDelete()) {
270
            $this->setUse(Classes::getObjectName(SoftDeletes::class), true, true);
271
        }
272
    }
273
274
    /**
275
     * Sets property for Soft Delete op on model Entity
276
     */
277
    private function setPropSoftDelete(): void
278
    {
279
        if ($this->isSoftDelete()) {
280
            $this->createPropertyArray(ModelsInterface::PROPERTY_DATES, PhpInterface::PHP_MODIFIER_PROTECTED, [ModelsInterface::COLUMN_DEL_AT]);
281
        }
282
    }
283
}