ProductController   B
last analyzed

Complexity

Total Complexity 47

Size/Duplication

Total Lines 402
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 213
c 2
b 0
f 1
dl 0
loc 402
rs 8.64
wmc 47

17 Methods

Rating   Name   Duplication   Size   Complexity  
A refactorAllImages() 0 4 1
A create() 0 3 1
A getExport() 0 3 1
C index() 0 160 13
A store() 0 4 1
A getRank() 0 41 4
A editSeo() 0 3 1
A changeAmount() 0 4 1
A destroy() 0 7 2
A update() 0 29 6
A changeRank() 0 4 1
A changeActive() 0 4 1
A storeCopy() 0 27 6
A edit() 0 10 1
A editPrice() 0 3 1
A postExport() 0 47 5
A copy() 0 10 1

How to fix   Complexity   

Complex Class

Complex classes like ProductController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProductController, and based on these observations, apply Extract Interface, too.

1
<?php namespace App\Http\Controllers\Backend;
2
3
/**
4
 * ProductController
5
 *
6
 * This is the controller of the products of the shop
7
 * @author Matthijs Neijenhuijs <[email protected]>
8
 * @version 0.1
9
 */
10
11
use App\Http\Controllers\Controller;
12
use Hideyo\Ecommerce\Framework\Services\Product\ProductFacade as ProductService;
13
use Hideyo\Ecommerce\Framework\Services\Product\ProductCombinationFacade as ProductCombinationService;
14
use Hideyo\Ecommerce\Framework\Services\ProductCategory\ProductCategoryFacade as ProductCategoryService;
15
use Hideyo\Ecommerce\Framework\Services\TaxRate\TaxRateFacade as TaxRateService;
16
use Hideyo\Ecommerce\Framework\Services\Brand\BrandFacade as BrandService;
17
use Illuminate\Http\Request;
18
use Excel;
0 ignored issues
show
Bug introduced by
The type Excel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
20
class ProductController extends Controller
21
{
22
    public function index(Request $request)
23
    {
24
        if ($request->wantsJson()) {
25
26
            $product = ProductService::getModel()->select(
27
                ['product.*', 
28
                'brand.title as brandtitle', 
29
                'product_category.title as categorytitle']
30
            )->with(array('productCategory', 'brand', 'subcategories', 'attributes',  'productImages','taxRate'))
31
32
            ->leftJoin('product_category as product_category', 'product_category.id', '=', 'product.product_category_id')
33
34
            ->leftJoin('brand as brand', 'brand.id', '=', 'product.brand_id')
35
36
            ->where('product.shop_id', '=', auth('hideyobackend')->user()->selected_shop_id);
0 ignored issues
show
Bug introduced by
Accessing selected_shop_id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
37
            
38
            $datatables = \DataTables::of($product)
39
            ->filterColumn('reference_code', function ($query, $keyword) {
40
                $query->whereRaw("product.reference_code like ?", ["%{$keyword}%"]);
41
            })
42
            ->filterColumn('active', function ($query, $keyword) {
43
                $query->whereRaw("product.active like ?", ["%{$keyword}%"]);
44
                ;
45
            })
46
47
            ->addColumn('rank', function ($product) {
48
                return '<input type="text" class="change-rank" value="'.$product->rank.'" style="width:50px;" data-url="/admin/product/change-rank/'.$product->id.'">';
49
              
50
            })
51
52
            ->filterColumn('title', function ($query, $keyword) {
53
54
                $query->where(
55
                    function ($query) use ($keyword) {
56
                        $query->whereRaw("product.title like ?", ["%{$keyword}%"]);
57
                        $query->orWhereRaw("product.reference_code like ?", ["%{$keyword}%"]);
58
                             $query->orWhereRaw("brand.title like ?", ["%{$keyword}%"]);
59
                        ;
60
                    }
61
                );
62
            })
63
64
            ->filterColumn('categorytitle', function ($query, $keyword) {
65
                $query->whereRaw("product_category.title like ?", ["%{$keyword}%"]);
66
            })
67
68
            ->addColumn('active', function ($product) {
69
                if ($product->active) {
70
                    return '<a href="#" class="change-active" data-url="'.url()->route('product.change-active', array('productId' => $product->id)).'"><span class="glyphicon glyphicon-ok icon-green"></span></a>';
71
                }
72
                
73
                return '<a href="#" class="change-active" data-url="'.url()->route('product.change-active', array('productId' => $product->id)).'"><span class="glyphicon glyphicon-remove icon-red"></span></a>';
74
            })
75
76
            ->addColumn('title', function ($product) {
77
                if ($product->brand) {
78
                    return $product->brand->title.' | '.$product->title;
79
                }
80
                
81
                return $product->title;
82
            })
83
84
85
            ->addColumn('amount', function ($product) {
86
                if ($product->attributes->count()) {
87
                    return '<a href="/admin/product/'.$product->id.'/product-combination">combinations</a>';
88
                }
89
                
90
                return '<input type="text" class="change-amount" value="'.$product->amount.'" style="width:50px;" data-url="'.url()->route('product.change-amount', array('productId' => $product->id)).'">';
91
            })
92
93
            ->addColumn('image', function ($product) {
94
                if ($product->productImages->count()) {
95
                    return '<img src="/files/product/100x100/'.$product->id.'/'.$product->productImages->first()->file.'"  />';
96
                }
97
            })
98
            ->addColumn('price', function ($product) {
99
100
                $result = "";
101
                if ($product->price) {
102
103
                    $taxRate = 0;
104
                    $priceInc = 0;
105
                    $taxValue = 0;
106
107
                    if (isset($product->taxRate->rate)) {
108
                        $taxRate = $product->taxRate->rate;
109
                        $priceInc = (($product->taxRate->rate / 100) * $product->price) + $product->price;
110
                        $taxValue = $priceInc - $product->price;
111
                    }
112
113
                    $discountPriceInc = false;
114
                    $discountPriceEx = false;
115
                    $discountTaxRate = 0;
116
                    if ($product->discount_value) {
117
                        if ($product->discount_type == 'amount') {
118
                            $discountPriceInc = $priceInc - $product->discount_value;
119
                            $discountPriceEx = $discountPriceInc / 1.21;
120
                        } elseif ($product->discount_type == 'percent') {
121
                            $tax = ($product->discount_value / 100) * $priceInc;
122
                            $discountPriceInc = $priceInc - $tax;
123
                            $discountPriceEx = $discountPriceInc / 1.21;
124
                        }
125
                        $discountTaxRate = $discountPriceInc - $discountPriceEx;
126
                        $discountPriceInc = $discountPriceInc;
127
                        $discountPriceEx = $discountPriceEx;
128
                    }
129
130
131
                    $output = array(
132
                        'orginal_price_ex_tax'  => $product->price,
133
                        'orginal_price_ex_tax_number_format'  => number_format($product->price, 2, '.', ''),
134
                        'orginal_price_inc_tax' => $priceInc,
135
                        'orginal_price_inc_tax_number_format' => number_format($priceInc, 2, '.', ''),
136
                        'tax_rate' => $taxRate,
137
                        'tax_value' => $taxValue,
138
                        'currency' => 'EU',
139
                        'discount_price_inc' => $discountPriceInc,
140
                        'discount_price_inc_number_format' => number_format($discountPriceInc, 2, '.', ''),
0 ignored issues
show
Bug introduced by
It seems like $discountPriceInc can also be of type false; however, parameter $number of number_format() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

140
                        'discount_price_inc_number_format' => number_format(/** @scrutinizer ignore-type */ $discountPriceInc, 2, '.', ''),
Loading history...
141
                        'discount_price_ex' => $discountPriceEx,
142
                        'discount_price_ex_number_format' => number_format($discountPriceEx, 2, '.', ''),
143
                        'discount_tax_value' => $discountTaxRate,
144
                        'discount_value' => $product->discount_value,
145
                        'amount' => $product->amount
146
                        );
147
148
                    $result =  '&euro; '.$output['orginal_price_ex_tax_number_format'].' / &euro; '.$output['orginal_price_inc_tax_number_format'];
149
150
151
                    if ($product->discount_value) {
152
                        $result .= '<br/> discount: yes';
153
                    }
154
                }
155
156
                return $result;
157
            })
158
159
160
            ->addColumn('categorytitle', function ($product) {
161
                if ($product->subcategories()->count()) {
162
                    $subcategories = $product->subcategories()->pluck('title')->toArray();
163
                    return $product->categorytitle.', <small> '.implode(', ', $subcategories).'</small>';
164
                }
165
                
166
                return $product->categorytitle;
167
            })
168
169
            ->addColumn('action', function ($product) {
170
                $deleteLink = \Form::deleteajax(url()->route('product.destroy', $product->id), 'Delete', '', array('class'=>'btn btn-default btn-sm btn-danger'), $product->title);
171
                $copy = '<a href="'.url()->route('product.copy', $product->id).'" class="btn btn-default btn-sm btn-info"><i class="entypo-pencil"></i>Copy</a>';
172
173
                $links = '<a href="'.url()->route('product.edit', $product->id).'" class="btn btn-default btn-sm btn-success"><i class="entypo-pencil"></i>Edit</a>  '.$copy.' '.$deleteLink;
174
175
                return $links;
176
            });
177
178
            return $datatables->rawColumns(['action', 'active', 'amount', 'categorytitle', 'image'])->make(true);
179
        }
180
        
181
        return view('backend.product.index')->with('product', ProductService::selectAll());
182
    }
183
184
    public function getRank(Request $request)
185
    {
186
        if ($request->wantsJson()) {
187
188
            $product = ProductService::getModel()->select(
189
                ['product.*', 
190
                'brand.title as brandtitle', 
191
                'product_category.title as categorytitle']
192
            )->with(array('productCategory', 'brand', 'subcategories', 'attributes',  'productImages','taxRate'))
193
            ->leftJoin('product_category as product_category', 'product_category.id', '=', 'product.product_category_id')
194
            ->leftJoin('brand as brand', 'brand.id', '=', 'product.brand_id')
195
            ->where('product.shop_id', '=', auth('hideyobackend')->user()->selected_shop_id);
0 ignored issues
show
Bug introduced by
Accessing selected_shop_id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
196
            
197
            $datatables = \DataTables::of($product)
198
            ->addColumn('rank', function ($product) {
199
                return '<input type="text" class="change-rank" value="'.$product->rank.'" style="width:50px;" data-url="'.url()->route('product.change-rank', array('productId' => $product->id)).'">';
200
            })
201
            ->filterColumn('categorytitle', function ($query, $keyword) {
202
                $query->whereRaw("product_category.title like ?", ["%{$keyword}%"]);
203
            })
204
            ->addColumn('title', function ($product) {
205
                if ($product->brand) {
206
                    return $product->brand->title.' | '.$product->title;
207
                }
208
                
209
                return $product->title;      
210
            })
211
            ->addColumn('categorytitle', function ($product) {
212
                if ($product->subcategories()->count()) {
213
                    $subcategories = $product->subcategories()->pluck('title')->toArray();
214
                    return $product->categorytitle.', <small> '.implode(', ', $subcategories).'</small>';
215
                }
216
                
217
                return $product->categorytitle;
218
            });
219
220
            return $datatables->rawColumns(['rank', 'action'])->make(true);
221
222
        }
223
        
224
        return view('backend.product.rank')->with('product', ProductService::selectAll());
225
    }
226
227
    public function refactorAllImages()
228
    {
229
        $this->productImage->refactorAllImagesByShopId(auth('hideyobackend')->user()->selected_shop_id);
0 ignored issues
show
Bug introduced by
Accessing selected_shop_id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
Bug Best Practice introduced by
The property productImage does not exist on App\Http\Controllers\Backend\ProductController. Did you maybe forget to declare it?
Loading history...
230
        return redirect()->route('product.index');
231
    }
232
233
    public function create()
234
    {
235
        return view('backend.product.create')->with(array('brands' => BrandService::selectAll()->pluck('title', 'id')->toArray(), 'taxRates' => TaxRateService::selectAll()->pluck('title', 'id'), 'productCategories' => ProductCategoryService::selectAllProductPullDown()->pluck('title', 'id')));
236
    }
237
238
    public function store(Request $request)
239
    {
240
        $result  = ProductService::create($request->all());
241
        return ProductService::notificationRedirect('product.index', $result, 'The product was inserted.');
242
    }
243
244
    public function changeActive($productId)
245
    {
246
        $result = ProductService::changeActive($productId);
247
        return response()->json($result);
248
    }
249
250
    public function changeAmount($productId, $amount)
251
    {
252
        $result = ProductService::changeAmount($productId, $amount);
253
        return response()->json($result);
254
    }
255
256
257
    public function changeRank($productId, $rank = 0)
258
    {
259
        $result = ProductService::changeRank($productId, $rank);
260
        return response()->json($result);
261
    }
262
263
    public function edit($productId)
264
    {
265
        $product = ProductService::find($productId);
266
267
        return view('backend.product.edit')->with(
268
            array(
269
            'product' => $product,
270
            'brands' => BrandService::selectAll()->pluck('title', 'id')->toArray(),
271
            'productCategories' => ProductCategoryService::selectAllProductPullDown()->pluck('title', 'id'),
272
            'taxRates' => TaxRateService::selectAll()->pluck('title', 'id')
273
            )
274
        );
275
    }
276
277
    public function getExport()
278
    {
279
        return view('backend.product.export')->with(array());
280
    }
281
282
    public function postExport()
283
    {
284
285
        $result  =  ProductService::selectAllExport();
286
        Excel::create('export', function ($excel) use ($result) {
287
288
            $excel->sheet('Products', function ($sheet) use ($result) {
289
                $newArray = array();
290
                foreach ($result as $row) {
291
                    $category = "";
292
                    if ($row->productCategory) {
293
                        $category = $row->productCategory->title;
294
                    }
295
296
                    $priceDetails = $row->getPriceDetails();
297
298
299
                    $newArray[$row->id] = array(
300
                    'title' => $row->title,
301
                    'category' => $category,
302
                    'amount' => $row->amount,
303
                    'reference_code' => $row->reference_code,
304
                    'orginal_price_ex_tax_number_format' => $priceDetails['orginal_price_ex_tax_number_format'],
305
                    'orginal_price_inc_tax_number_format' => $priceDetails['orginal_price_inc_tax_number_format'],
306
                    'tax_rate' => $priceDetails['tax_rate'],
307
                    'currency' => $priceDetails['currency']
308
309
                    );
310
311
312
                    $images = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $images is dead and can be removed.
Loading history...
313
                    if ($row->productImages->count()) {
314
                        $i = 0;
315
                        foreach ($row->productImages as $image) {
316
                            $i++;
317
                            $newArray[$row->id]['image_'.$i] =  url('/').'/files/product/800x800/'.$row->id.'/'.$image->file;
318
                        }
319
                    }
320
                }
321
322
                $sheet->fromArray($newArray);
323
            });
324
        })->download('xls');
325
326
327
        flash('The product export is completed.');
328
        return redirect()->route('product.index');
329
    }
330
331
    public function copy($productId)
332
    {
333
        $product = ProductService::find($productId);
334
335
        return view('backend.product.copy')->with(
336
            array(
337
                'brands' => BrandService::selectAll()->pluck('title', 'id')->toArray(),
338
            'product' => $product,
339
            'productCategories' => ProductCategoryService::selectAll()->pluck('title', 'id'),
340
            'taxRates' => TaxRateService::selectAll()->pluck('title', 'id')
341
            )
342
        );
343
    }
344
345
    public function storeCopy(Request $request, $productId)
346
    {
347
        $product = ProductService::find($productId);
348
        $result  = ProductService::createCopy($request->all(), $productId);
349
350
        if (isset($result->id)) {
351
            if ($product->attributes) {
352
                foreach ($product->attributes as $attribute) {
353
                    $inputAttribute = $attribute->toArray();
354
355
                    foreach ($attribute->combinations as $row2) {
356
                        $inputAttribute['selected_attribute_ids'][] = $row2->attribute->id;
357
                    }
358
359
                    $this->productCombination->create($inputAttribute, $result->id);
0 ignored issues
show
Bug Best Practice introduced by
The property productCombination does not exist on App\Http\Controllers\Backend\ProductController. Did you maybe forget to declare it?
Loading history...
360
                }
361
            }
362
363
            flash('The product copy is inserted.');
364
            return redirect()->route('product.index');
365
        }
366
367
        foreach ($result->errors()->all() as $error) {
368
            flash($error);
369
        }
370
        
371
        return redirect()->back()->withInput();
372
    }
373
374
    public function editSeo($id)
375
    {
376
        return view('backend.product.edit_seo')->with(array('product' => ProductService::find($id)));
377
    }
378
379
    public function editPrice($id)
380
    {
381
        return view('backend.product.edit_price')->with(array('product' => ProductService::find($id), 'taxRates' => TaxRateService::selectAll()->pluck('title', 'id')));
382
    }
383
384
    public function update(Request $request, $productId)
385
    {
386
        $input = $request->all();
387
        $result  = ProductService::updateById($input, $productId);
388
389
        $redirect = redirect()->route('product.index');
390
391
        if (isset($result->id)) {
392
            if ($request->get('seo')) {
393
                flash('Product seo was updated.');
394
                $redirect = redirect()->route('product.edit_seo', $productId);
395
            } elseif ($request->get('price')) {
396
                flash('Product price was updated.');
397
                $redirect = redirect()->route('product.edit_price', $productId);
398
            } elseif ($request->get('product-combination')) {
399
                flash('Product combination leading attribute group was updated.');
400
                $redirect = redirect()->route('product-combination.index', $productId);
401
            } else {
402
                flash('Product was updated.');
403
            }
404
405
            return $redirect;
406
        }
407
408
        foreach ($result->errors()->all() as $error) {
409
            flash($error);
410
        }
411
412
        return redirect()->back()->withInput()->withErrors($result->errors()->all());
413
    }
414
415
    public function destroy($id)
416
    {
417
        $result  = ProductService::destroy($id);
418
419
        if ($result) {
420
            flash('The product was deleted.');
421
            return redirect()->route('product.index');
422
        }
423
    }
424
}
425