Products::read()   B
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 36
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
c 1
b 0
f 0
dl 0
loc 36
rs 8.8977
cc 6
nc 4
nop 1
1
<?php
2
3
namespace WagnerMontanini\GoomerApi\Api;
4
5
use WagnerMontanini\GoomerApi\Support\Pager;
6
use WagnerMontanini\GoomerApi\Models\Product;
7
use WagnerMontanini\GoomerApi\Models\Restaurant;
8
use WagnerMontanini\GoomerApi\Models\ProductCategory;
9
10
/**
11
 * Class Products
12
 * @package WagnerMontanini\GoomerApi
13
 */
14
class Products extends GoomerApi
15
{
16
    /**
17
     * Products constructor.
18
     * @throws \Exception
19
     */
20
    public function __construct()
21
    {
22
        parent::__construct();
23
    }
24
25
    /**
26
     * list all products
27
     * @param array $data
28
     * @throws \Exception
29
     */
30
    public function index(array $data): void
31
    {   
32
        $where = "";
33
        $params = "";
34
        $values = $this->headers;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->headers can also be of type boolean. However, the property $headers is declared as type array|false. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
35
        
36
        if (empty($data["restaurant_id"]) || !$restaurant_id = filter_var($data["restaurant_id"], FILTER_VALIDATE_INT) ) {
37
            $this->call(
38
                400,
39
                "invalid_data",
40
                "É preciso informar o ID do restaurante para verificar os produtos"
41
            )->back();
42
            return;
43
        }
44
        $category_id = explode('&',$_SERVER['REQUEST_URI']);
45
        
46
        if (!empty($category_id) && count($category_id) == 2) {
47
            $category = explode('=',$category_id[1]);
48
            if($category[0] == 'category_id'){
49
                $category_id = filter_var($category[1], FILTER_VALIDATE_INT);
50
                $where  = " AND category_id=:category_id";
51
                $params = "&category_id={$category_id}";
52
            }
53
        }
54
55
        //get products
56
        $products = (new Product())->find("restaurant_id=:restaurant_id{$where}","restaurant_id={$restaurant_id}{$params}");
57
        
58
        if (!$products->count()) {
59
            $this->call(
60
                404,
61
                "not_found",
62
                "Nada encontrado para sua busca."
63
            )->back(["results" => 0]);
64
            return;
65
        }
66
67
        $page = (!empty($values["page"]) ? $values["page"] : 1);
68
        $pager = new Pager(url("/restaurants/{restaurant_id}/products"));
69
        $pager->pager($products->count(), 10, $page);
70
71
        $response["results"] = $products->count();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Loading history...
72
        $response["page"] = $pager->page();
73
        $response["pages"] = $pager->pages();
74
75
        foreach ($products->limit($pager->limit())->offset($pager->offset())->order("name ASC")->fetch(true) as $product) {
76
            $response["products"][] = $product->restaurant()->category()->data();
77
        }
78
79
        $this->back($response);
80
        return;
81
    }
82
83
    /**
84
     * @param array $data
85
     * @throws \Exception
86
     */
87
    public function create(array $data): void
88
    {
89
        $request = $this->requestLimit("productsCreate", 5, 60);
90
        if (!$request) {
91
            return;
92
        }
93
94
        if (empty($data["restaurant_id"]) || !$restaurant_id = filter_var($data["restaurant_id"], FILTER_VALIDATE_INT) ) {
95
            $this->call(
96
                400,
97
                "invalid_data",
98
                "É preciso informar o ID do restaurante para criar os produtos"
99
            )->back();
100
            return;
101
        }
102
        
103
        $restaurant = (new Restaurant())->findById($restaurant_id);
104
105
        if (!$restaurant) {
106
            $this->call(
107
                404,
108
                "not_found",
109
                "Você tentou cadastrar um produto em um restaurante que não existe"
110
            )->back();
111
            return;
112
        }
113
114
        if ( empty($data["category_id"]) || !$category_id = filter_var($data["category_id"], FILTER_VALIDATE_INT) || empty($data["name"]) || empty($data["price"]) ) {
0 ignored issues
show
Comprehensibility introduced by
Consider adding parentheses for clarity. Current Interpretation: $category_id = (filter_v... empty($data['price'])), Probably Intended Meaning: ($category_id = filter_v...| empty($data['price'])
Loading history...
115
            $this->call(
116
                400,
117
                "empty_data",
118
                "Para criar informe o ID da categoria do produto, o nome do produto e o preço do produto"
119
            )->back();
120
            return ;
121
        }
122
123
        $category = (new ProductCategory())->findById($category_id);
0 ignored issues
show
Bug introduced by
$category_id of type true is incompatible with the type integer expected by parameter $id of CoffeeCode\DataLayer\DataLayer::findById(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

123
        $category = (new ProductCategory())->findById(/** @scrutinizer ignore-type */ $category_id);
Loading history...
124
125
        if (!$category) {
126
            $this->call(
127
                404,
128
                "not_found",
129
                "Você tentou cadastrar um produto em uma categoria que não existe"
130
            )->back();
131
            return;
132
        }
133
134
        $product = new Product();
135
        $product->restaurant_id = $restaurant_id;
0 ignored issues
show
Bug Best Practice introduced by
The property restaurant_id does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
136
        $product->category_id = $category_id;
0 ignored issues
show
Bug Best Practice introduced by
The property category_id does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
137
        $product->name = filter_var($data["name"], FILTER_SANITIZE_STRIPPED);
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
138
        $product->price = filter_var($data["price"], FILTER_SANITIZE_STRIPPED);
0 ignored issues
show
Bug Best Practice introduced by
The property price does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
139
        $product->image = (!empty($data["image"])) ? filter_var($data["image"], FILTER_SANITIZE_STRIPPED) : null;
0 ignored issues
show
Bug Best Practice introduced by
The property image does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
140
        $product->description = (!empty($data["description"])) ? filter_var($data["description"], FILTER_SANITIZE_STRIPPED) : null;
0 ignored issues
show
Bug Best Practice introduced by
The property description does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
141
        $product->old_price = (!empty($data["old_price"])) ? filter_var($data["old_price"], FILTER_SANITIZE_STRIPPED) : 0.00;
0 ignored issues
show
Bug Best Practice introduced by
The property old_price does not exist on WagnerMontanini\GoomerApi\Models\Product. Since you implemented __set, consider adding a @property annotation.
Loading history...
142
        $product->save();
143
144
        if($product->fail()){
145
            $this->call(
146
                400,
147
                "empty_data",
148
                $product->fail()->getMessage()
149
            )->back();
150
            return;
151
        }
152
153
        $this->back(["product" => $product->restaurant()->category()->data()]);
154
        return;
155
    }
156
157
    /**
158
     * @param array $data
159
     */
160
    public function read(array $data): void
161
    {
162
        if (empty($data["restaurant_id"]) || !$restaurant_id = filter_var($data["restaurant_id"], FILTER_VALIDATE_INT) ) {
163
            $this->call(
164
                400,
165
                "invalid_data",
166
                "É preciso informar o ID do restaurante para verificar o produto"
167
            )->back();
168
            return;
169
        }
170
171
        
172
        if (empty($data["product_id"]) || !$product_id = filter_var($data["product_id"], FILTER_VALIDATE_INT) ) {
173
            $this->call(
174
                400,
175
                "invalid_data",
176
                "É preciso informar o ID do produto que deseja consultar"
177
            )->back();
178
            return;
179
        }
180
181
        $product = (new Product())->find("restaurant_id = :restaurant_id AND id = :id",
182
                                "restaurant_id={$restaurant_id}&id=$product_id")->fetch();
183
184
        if (!$product) {
185
            $this->call(
186
                404,
187
                "not_found",
188
                "Você tentou acessar um produto que não existe neste restaurante"
189
            )->back();
190
            return;
191
        }
192
193
        $response["product"] = $product->restaurant()->category()->data();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Loading history...
194
        
195
        $this->back($response);
196
    }
197
198
    /**
199
     * @param array $data
200
     */
201
    public function update(array $data): void
202
    {
203
        if ( empty($data["restaurant_id"]) || !$restaurant_id = filter_var($data["restaurant_id"], FILTER_VALIDATE_INT)) {
204
            $this->call(
205
                400,
206
                "invalid_data",
207
                "É preciso informar o ID do restaurante para atualizar o produto"
208
            )->back();
209
            return;
210
        }
211
212
        if (empty($data["product_id"]) || !$product_id = filter_var($data["product_id"], FILTER_VALIDATE_INT) ) {
213
            $this->call(
214
                400,
215
                "invalid_data",
216
                "É preciso informar o ID do produto que deseja atualizar"
217
            )->back();
218
            return;
219
        }
220
221
        $product = (new Product())->find("restaurant_id = :restaurant_id AND id = :id",
222
                                "restaurant_id={$restaurant_id}&id=$product_id")->fetch();
223
224
        if (!$product) {
225
            $this->call(
226
                404,
227
                "not_found",
228
                "Você tentou atualizar um produto de um restaurante que não existe"
229
            )->back();
230
            return;
231
        }
232
        
233
        $product->name = (!empty($data["name"])) ? filter_var($data["name"], FILTER_SANITIZE_STRIPPED) : $product->name;
234
        $product->price = (!empty($data["price"])) ? filter_var($data["price"], FILTER_SANITIZE_STRIPPED) : $product->price;
235
        $product->image = (!empty($data["image"])) ? filter_var($data["image"], FILTER_SANITIZE_STRIPPED) : $product->image;
236
        $product->description = (!empty($data["description"])) ? filter_var($data["description"], FILTER_SANITIZE_STRIPPED) : $product->description;
237
        $product->old_price = (!empty($data["old_price"])) ? filter_var($data["old_price"], FILTER_SANITIZE_STRIPPED) : $product->old_price;
238
        $product->save();
239
240
        if($product->fail()){
241
            $this->call(
242
                400,
243
                "empty_data",
244
                $product->fail()->getMessage()
245
            )->back();
246
            return;
247
        }
248
249
        $this->back(["product" => $product->restaurant()->category()->data()]);
250
        return;
251
    }
252
253
    /**
254
     * @param array $data
255
     */
256
    public function delete(array $data): void
257
    {
258
        if (empty($data["restaurant_id"]) || !$restaurant_id = filter_var($data["restaurant_id"], FILTER_VALIDATE_INT)) {
259
            $this->call(
260
                400,
261
                "invalid_data",
262
                "É preciso informar o ID do restaurante para deletar o produto"
263
            )->back();
264
            return;
265
        }
266
267
        if (empty($data["product_id"]) || !$product_id = filter_var($data["product_id"], FILTER_VALIDATE_INT) ) {
268
            $this->call(
269
                400,
270
                "invalid_data",
271
                "É preciso informar o ID do produto que deseja deletar"
272
            )->back();
273
            return;
274
        }
275
276
        $product = (new Product())->find("restaurant_id = :restaurant_id AND id = :id",
277
                                "restaurant_id={$restaurant_id}&id=$product_id")->fetch();
278
279
        if (!$product) {
280
            $this->call(
281
                404,
282
                "not_found",
283
                "Você tentou excluir um produto de um restaurante que não existe"
284
            )->back();
285
            return;
286
        }
287
288
        $product->destroy();
289
        $this->call(
290
            200,
291
            "success",
292
            "O produto foi excluído com sucesso",
293
            "accepted"
294
        )->back();
295
    }
296
}