Failed Conditions
Branch experimental/sf (68db07)
by Kentaro
42:17 queued 33:39
created

ProductController::index()   C

Complexity

Conditions 9
Paths 20

Size

Total Lines 119

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 46
CRAP Score 9.3546

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
nc 20
nop 3
dl 0
loc 119
rs 6.4444
c 1
b 0
f 0
ccs 46
cts 55
cp 0.8364
crap 9.3546

How to fix   Long Method   

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
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Controller\Admin\Product;
15
16
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
17
use Eccube\Common\Constant;
18
use Eccube\Controller\AbstractController;
19
use Eccube\Entity\BaseInfo;
20
use Eccube\Entity\Master\CsvType;
21
use Eccube\Entity\ProductTag;
22
use Eccube\Event\EccubeEvents;
23
use Eccube\Event\EventArgs;
24
use Eccube\Form\Type\Admin\ProductType;
25
use Eccube\Form\Type\Admin\SearchProductType;
26
use Eccube\Repository\CategoryRepository;
27
use Eccube\Repository\Master\PageMaxRepository;
28
use Eccube\Repository\Master\ProductStatusRepository;
29
use Eccube\Repository\ProductClassRepository;
30
use Eccube\Repository\ProductImageRepository;
31
use Eccube\Repository\ProductRepository;
32
use Eccube\Repository\TagRepository;
33
use Eccube\Repository\TaxRuleRepository;
34
use Eccube\Service\CsvExportService;
35
use Knp\Component\Pager\Paginator;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
39
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
40
use Eccube\Util\FormUtil;
41
use Symfony\Component\Filesystem\Filesystem;
42
use Symfony\Component\HttpFoundation\File\File;
43
use Symfony\Component\HttpFoundation\JsonResponse;
44
use Symfony\Component\HttpFoundation\Request;
45
use Symfony\Component\HttpFoundation\StreamedResponse;
46
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
47
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
48
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
49
use Eccube\Entity\Product;
50
use Eccube\Entity\ProductClass;
51
use Eccube\Entity\Master\ProductStatus;
52
use Eccube\Entity\ProductStock;
53
use Eccube\Entity\ProductImage;
54
use Eccube\Entity\ProductCategory;
55
use Eccube\Entity\ExportCsvRow;
56
use Symfony\Component\HttpFoundation\RedirectResponse;
57
58
class ProductController extends AbstractController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
59
{
60
    /**
61
     * @var CsvExportService
62
     */
63
    protected $csvExportService;
64
65
    /**
66
     * @var ProductClassRepository
67
     */
68
    protected $productClassRepository;
69
70
    /**
71
     * @var ProductImageRepository
72
     */
73
    protected $productImageRepository;
74
75
    /**
76
     * @var TaxRuleRepository
77
     */
78
    protected $taxRuleRepository;
79
80
    /**
81
     * @var CategoryRepository
82
     */
83
    protected $categoryRepository;
84
85
    /**
86
     * @var ProductRepository
87
     */
88
    protected $productRepository;
89
90
    /**
91
     * @var BaseInfo
92
     */
93
    protected $BaseInfo;
94
95
    /**
96
     * @var PageMaxRepository
97
     */
98
    protected $pageMaxRepository;
99
100
    /**
101
     * @var ProductStatusRepository
102
     */
103
    protected $productStatusRepository;
104
105
    /**
106
     * @var TagRepository
107
     */
108
    protected $tagRepository;
109
110
    /**
111
     * ProductController constructor.
112
     *
113
     * @param CsvExportService $csvExportService
0 ignored issues
show
introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
114
     * @param ProductClassRepository $productClassRepository
0 ignored issues
show
introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
115
     * @param ProductImageRepository $productImageRepository
0 ignored issues
show
introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
116
     * @param TaxRuleRepository $taxRuleRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
117
     * @param CategoryRepository $categoryRepository
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
118
     * @param ProductRepository $productRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
119
     * @param BaseInfo $BaseInfo
0 ignored issues
show
introduced by
Expected 16 spaces after parameter type; 1 found
Loading history...
120
     * @param PageMaxRepository $pageMaxRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
121
     * @param ProductStatusRepository $productStatusRepository
122
     * @param TagRepository $tagRepository
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
123
     */
124 26
    public function __construct(
125
        CsvExportService $csvExportService,
126
        ProductClassRepository $productClassRepository,
127
        ProductImageRepository $productImageRepository,
128
        TaxRuleRepository $taxRuleRepository,
129
        CategoryRepository $categoryRepository,
130
        ProductRepository $productRepository,
131
        BaseInfo $BaseInfo,
132
        PageMaxRepository $pageMaxRepository,
133
        ProductStatusRepository $productStatusRepository,
134
        TagRepository $tagRepository
135
    ) {
136 26
        $this->csvExportService = $csvExportService;
137 26
        $this->productClassRepository = $productClassRepository;
138 26
        $this->productImageRepository = $productImageRepository;
139 26
        $this->taxRuleRepository = $taxRuleRepository;
140 26
        $this->categoryRepository = $categoryRepository;
141 26
        $this->productRepository = $productRepository;
142 26
        $this->BaseInfo = $BaseInfo;
143 26
        $this->pageMaxRepository = $pageMaxRepository;
144 26
        $this->productStatusRepository = $productStatusRepository;
145 26
        $this->tagRepository = $tagRepository;
146
    }
147
148
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$page_no" missing
Loading history...
introduced by
Doc comment for parameter "$paginator" missing
Loading history...
149
     * @Route("/%eccube_admin_route%/product", name="admin_product")
150
     * @Route("/%eccube_admin_route%/product/page/{page_no}", requirements={"page_no" = "\d+"}, name="admin_product_page")
151
     * @Template("@admin/Product/index.twig")
152
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
153 4
    public function index(Request $request, $page_no = null, Paginator $paginator)
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
154
    {
155 4
        $builder = $this->formFactory
156 4
            ->createBuilder(SearchProductType::class);
157
158 4
        $event = new EventArgs(
159
            [
160 4
                'builder' => $builder,
161
            ],
162 4
            $request
163
        );
164 4
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_INITIALIZE, $event);
165
166 4
        $searchForm = $builder->getForm();
167
168
        /**
169
         * ページの表示件数は, 以下の順に優先される.
170
         * - リクエストパラメータ
171
         * - セッション
172
         * - デフォルト値
173
         * また, セッションに保存する際は mtb_page_maxと照合し, 一致した場合のみ保存する.
174
         **/
175 4
        $page_count = $this->session->get('eccube.admin.order.search.page_count',
176 4
            $this->eccubeConfig->get('eccube_default_page_count'));
177
178 4
        $page_count_param = (int) $request->get('page_count');
179 4
        $pageMaxis = $this->pageMaxRepository->findAll();
180
181 4
        if ($page_count_param) {
182
            foreach ($pageMaxis as $pageMax) {
183
                if ($page_count_param == $pageMax->getName()) {
184
                    $page_count = $pageMax->getName();
185
                    $this->session->set('eccube.admin.order.search.page_count', $page_count);
186
                    break;
187
                }
188
            }
189
        }
190
191 4
        if ('POST' === $request->getMethod()) {
192 2
            $searchForm->handleRequest($request);
193
194 2
            if ($searchForm->isValid()) {
195
                /**
196
                 * 検索が実行された場合は, セッションに検索条件を保存する.
197
                 * ページ番号は最初のページ番号に初期化する.
198
                 */
199 2
                $page_no = 1;
200 2
                $searchData = $searchForm->getData();
201
202
                // 検索条件, ページ番号をセッションに保持.
203 2
                $this->session->set('eccube.admin.product.search', FormUtil::getViewData($searchForm));
204 2
                $this->session->set('eccube.admin.product.search.page_no', $page_no);
205
            } else {
206
                // 検索エラーの際は, 詳細検索枠を開いてエラー表示する.
207
                return [
208 2
                    'searchForm' => $searchForm->createView(),
209
                    'pagination' => [],
210
                    'pageMaxis' => $pageMaxis,
211
                    'page_no' => $page_no,
212
                    'page_count' => $page_count,
213
                    'has_errors' => true,
214
                ];
215
            }
216
        } else {
217 2
            if (null !== $page_no || $request->get('resume')) {
218
                /*
219
                 * ページ送りの場合または、他画面から戻ってきた場合は, セッションから検索条件を復旧する.
220
                 */
221 1
                if ($page_no) {
222
                    // ページ送りで遷移した場合.
223 1
                    $this->session->set('eccube.admin.product.search.page_no', (int) $page_no);
224
                } else {
225
                    // 他画面から遷移した場合.
226
                    $page_no = $this->session->get('eccube.admin.product.search.page_no', 1);
227
                }
228 1
                $viewData = $this->session->get('eccube.admin.product.search', []);
229 1
                $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
230
            } else {
231
                /**
232
                 * 初期表示の場合.
233
                 */
234 1
                $page_no = 1;
235
                // submit default value
236 1
                $viewData = FormUtil::getViewData($searchForm);
237 1
                $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
238
239
                // セッション中の検索条件, ページ番号を初期化.
240 1
                $this->session->set('eccube.admin.product.search', $searchData);
241 1
                $this->session->set('eccube.admin.product.search.page_no', $page_no);
242
            }
243
        }
244
245 4
        $qb = $this->productRepository->getQueryBuilderBySearchDataForAdmin($searchData);
246
247 4
        $event = new EventArgs(
248
            [
249 4
                'qb' => $qb,
250 4
                'searchData' => $searchData,
251
            ],
252 4
            $request
253
        );
254
255 4
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH, $event);
256
257 4
        $pagination = $paginator->paginate(
258 4
            $qb,
259 4
            $page_no,
260 4
            $page_count
261
        );
262
263
        return [
264 4
            'searchForm' => $searchForm->createView(),
265 4
            'pagination' => $pagination,
266 4
            'pageMaxis' => $pageMaxis,
267 4
            'page_no' => $page_no,
268 4
            'page_count' => $page_count,
269
            'has_errors' => false,
270
        ];
271
    }
272
273
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$Product" missing
Loading history...
274
     * @Method("GET")
275
     * @Route("/%eccube_admin_route%/product/classes/{id}/load", name="admin_product_classes_load", requirements={"id" = "\d+"})
276
     * @Template("@admin/Product/product_class_popup.twig")
277
     * @ParamConverter("Product")
278
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
279 1
    public function loadProductClasses(Request $request, Product $Product)
280
    {
281 1
        if (!$request->isXmlHttpRequest()) {
282
            throw new BadRequestHttpException();
283
        }
284
285 1
        $data = [];
286
        /** @var $Product ProductRepository */
287 1
        if (!$Product) {
288
            throw new NotFoundHttpException();
289
        }
290
291 1
        if ($Product->hasProductClass()) {
0 ignored issues
show
Documentation Bug introduced by
The method hasProductClass does not exist on object<Eccube\Repository\ProductRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
292 1
            $class = $Product->getProductClasses();
0 ignored issues
show
Documentation Bug introduced by
The method getProductClasses does not exist on object<Eccube\Repository\ProductRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
293 1
            foreach ($class as $item) {
294 1
                if ($item['visible']) {
295 1
                    $data[] = $item;
296
                }
297
            }
298
        }
299
300
        return [
301 1
            'data' => $data,
302
        ];
303
    }
304
305
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
306
     * @Method("POST")
307
     * @Route("/%eccube_admin_route%/product/product/image/add", name="admin_product_image_add")
308
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
309
    public function addImage(Request $request)
310
    {
311
        if (!$request->isXmlHttpRequest()) {
312
            throw new BadRequestHttpException('リクエストが不正です');
313
        }
314
315
        $images = $request->files->get('admin_product');
316
317
        $files = [];
318
        if (count($images) > 0) {
319
            foreach ($images as $img) {
320
                foreach ($img as $image) {
321
                    //ファイルフォーマット検証
322
                    $mimeType = $image->getMimeType();
323
                    if (0 !== strpos($mimeType, 'image')) {
324
                        throw new UnsupportedMediaTypeHttpException('ファイル形式が不正です');
325
                    }
326
327
                    $extension = $image->getClientOriginalExtension();
328
                    $filename = date('mdHis').uniqid('_').'.'.$extension;
329
                    $image->move($this->eccubeConfig['eccube_temp_image_dir'], $filename);
330
                    $files[] = $filename;
331
                }
332
            }
333
        }
334
335
        $event = new EventArgs(
336
            [
337
                'images' => $images,
338
                'files' => $files,
339
            ],
340
            $request
341
        );
342
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_ADD_IMAGE_COMPLETE, $event);
343
        $files = $event->getArgument('files');
344
345
        return $this->json(['files' => $files], 200);
346
    }
347
348
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
349
     * @Route("/%eccube_admin_route%/product/product/new", name="admin_product_product_new")
350
     * @Route("/%eccube_admin_route%/product/product/{id}/edit", requirements={"id" = "\d+"}, name="admin_product_product_edit")
351
     * @Template("@admin/Product/product.twig")
352
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
353 18
    public function edit(Request $request, $id = null)
354
    {
355 18
        $has_class = false;
356 18
        if (is_null($id)) {
357 5
            $Product = new Product();
358 5
            $ProductClass = new ProductClass();
359 5
            $ProductStatus = $this->productStatusRepository->find(ProductStatus::DISPLAY_HIDE);
360
            $Product
361 5
                ->addProductClass($ProductClass)
362 5
                ->setStatus($ProductStatus);
363
            $ProductClass
364 5
                ->setVisible(true)
365 5
                ->setStockUnlimited(true)
366 5
                ->setProduct($Product);
367 5
            $ProductStock = new ProductStock();
368 5
            $ProductClass->setProductStock($ProductStock);
369 5
            $ProductStock->setProductClass($ProductClass);
370
        } else {
371 13
            $Product = $this->productRepository->find($id);
372 13
            if (!$Product) {
373
                throw new NotFoundHttpException();
374
            }
375
            // 規格無しの商品の場合は、デフォルト規格を表示用に取得する
376 13
            $has_class = $Product->hasProductClass();
377 13
            if (!$has_class) {
378 11
                $ProductClasses = $Product->getProductClasses();
379 11
                foreach ($ProductClasses as $pc) {
380 11
                    if (!is_null($pc->getClassCategory1())) {
381
                        continue;
382
                    }
383 11
                    if ($pc->isVisible()) {
384 11
                        $ProductClass = $pc;
385 11
                        break;
386
                    }
387
                }
388 11
                if ($this->BaseInfo->isOptionProductTaxRule() && $ProductClass->getTaxRule()) {
389 6
                    $ProductClass->setTaxRate($ProductClass->getTaxRule()->getTaxRate());
0 ignored issues
show
Bug introduced by
The variable $ProductClass does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
390
                }
391 11
                $ProductStock = $ProductClasses[0]->getProductStock();
392
            }
393
        }
394
395 18
        $builder = $this->formFactory
396 18
            ->createBuilder(ProductType::class, $Product);
397
398
        // 規格あり商品の場合、規格関連情報をFormから除外
399 18
        if ($has_class) {
400 2
            $builder->remove('class');
401
        }
402
403 18
        $event = new EventArgs(
404
            [
405 18
                'builder' => $builder,
406 18
                'Product' => $Product,
407
            ],
408 18
            $request
409
        );
410 18
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_INITIALIZE, $event);
411
412 18
        $form = $builder->getForm();
413
414 18
        if (!$has_class) {
415 16
            $ProductClass->setStockUnlimited($ProductClass->isStockUnlimited());
416 16
            $form['class']->setData($ProductClass);
417
        }
418
419
        // ファイルの登録
420 18
        $images = [];
421 18
        $ProductImages = $Product->getProductImage();
422 18
        foreach ($ProductImages as $ProductImage) {
423 13
            $images[] = $ProductImage->getFileName();
424
        }
425 18
        $form['images']->setData($images);
426
427 18
        $categories = [];
428 18
        $ProductCategories = $Product->getProductCategories();
429 18
        foreach ($ProductCategories as $ProductCategory) {
430
            /* @var $ProductCategory \Eccube\Entity\ProductCategory */
431 13
            $categories[] = $ProductCategory->getCategory();
432
        }
433 18
        $form['Category']->setData($categories);
434
435 18
        $Tags = [];
436 18
        $ProductTags = $Product->getProductTag();
437 18
        foreach ($ProductTags as $ProductTag) {
438 1
            $Tags[] = $ProductTag->getTag();
439
        }
440 18
        $form['Tag']->setData($Tags);
441
442 18
        if ('POST' === $request->getMethod()) {
443 13
            $form->handleRequest($request);
444 13
            if ($form->isValid()) {
445 13
                log_info('商品登録開始', [$id]);
446 13
                $Product = $form->getData();
447
448 13
                if (!$has_class) {
449 13
                    $ProductClass = $form['class']->getData();
450
451
                    // 個別消費税
452 13
                    if ($this->BaseInfo->isOptionProductTaxRule()) {
453 12
                        if ($ProductClass->getTaxRate() !== null) {
454 8
                            if ($ProductClass->getTaxRule()) {
455 4
                                $ProductClass->getTaxRule()->setTaxRate($ProductClass->getTaxRate());
456
                            } else {
457 4
                                $taxrule = $this->taxRuleRepository->newTaxRule();
458 4
                                $taxrule->setTaxRate($ProductClass->getTaxRate());
459 4
                                $taxrule->setApplyDate(new \DateTime());
460 4
                                $taxrule->setProduct($Product);
461 4
                                $taxrule->setProductClass($ProductClass);
462 4
                                $ProductClass->setTaxRule($taxrule);
463
                            }
464
465 8
                            $ProductClass->getTaxRule()->setTaxRate($ProductClass->getTaxRate());
466
                        } else {
467 4
                            if ($ProductClass->getTaxRule()) {
468 2
                                $this->taxRuleRepository->delete($ProductClass->getTaxRule());
469 2
                                $ProductClass->setTaxRule(null);
470
                            }
471
                        }
472
                    }
473 13
                    $this->entityManager->persist($ProductClass);
474
475
                    // 在庫情報を作成
476 13
                    if (!$ProductClass->isStockUnlimited()) {
477
                        $ProductStock->setStock($ProductClass->getStock());
0 ignored issues
show
Bug introduced by
The variable $ProductStock does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
478
                    } else {
479
                        // 在庫無制限時はnullを設定
480 13
                        $ProductStock->setStock(null);
481
                    }
482 13
                    $this->entityManager->persist($ProductStock);
483
                }
484
485
                // カテゴリの登録
486
                // 一度クリア
487
                /* @var $Product \Eccube\Entity\Product */
488 13
                foreach ($Product->getProductCategories() as $ProductCategory) {
489 10
                    $Product->removeProductCategory($ProductCategory);
490 10
                    $this->entityManager->remove($ProductCategory);
491
                }
492 13
                $this->entityManager->persist($Product);
493 13
                $this->entityManager->flush();
494
495 13
                $count = 1;
496 13
                $Categories = $form->get('Category')->getData();
497 13
                $categoriesIdList = [];
498 13
                foreach ($Categories as $Category) {
499 View Code Duplication
                    foreach ($Category->getPath() as $ParentCategory) {
500
                        if (!isset($categoriesIdList[$ParentCategory->getId()])) {
501
                            $ProductCategory = $this->createProductCategory($Product, $ParentCategory, $count);
502
                            $this->entityManager->persist($ProductCategory);
503
                            $count++;
504
                            /* @var $Product \Eccube\Entity\Product */
505
                            $Product->addProductCategory($ProductCategory);
506
                            $categoriesIdList[$ParentCategory->getId()] = true;
507
                        }
508
                    }
509
                    if (!isset($categoriesIdList[$Category->getId()])) {
510
                        $ProductCategory = $this->createProductCategory($Product, $Category, $count);
511
                        $this->entityManager->persist($ProductCategory);
512
                        $count++;
513
                        /* @var $Product \Eccube\Entity\Product */
514
                        $Product->addProductCategory($ProductCategory);
515
                        $categoriesIdList[$ParentCategory->getId()] = true;
0 ignored issues
show
Bug introduced by
The variable $ParentCategory seems to be defined by a foreach iteration on line 499. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
516
                    }
517
                }
518
519
                // 画像の登録
520 13
                $add_images = $form->get('add_images')->getData();
521 13
                foreach ($add_images as $add_image) {
522
                    $ProductImage = new \Eccube\Entity\ProductImage();
523
                    $ProductImage
524
                        ->setFileName($add_image)
525
                        ->setProduct($Product)
526
                        ->setSortNo(1);
527
                    $Product->addProductImage($ProductImage);
528
                    $this->entityManager->persist($ProductImage);
529
530
                    // 移動
531
                    $file = new File($this->eccubeConfig['eccube_temp_image_dir'].'/'.$add_image);
532
                    $file->move($this->eccubeConfig['eccube_save_image_dir']);
533
                }
534
535
                // 画像の削除
536 13
                $delete_images = $form->get('delete_images')->getData();
537 13
                foreach ($delete_images as $delete_image) {
538
                    $ProductImage = $this->productImageRepository
539
                        ->findOneBy(['file_name' => $delete_image]);
540
541
                    // 追加してすぐに削除した画像は、Entityに追加されない
542
                    if ($ProductImage instanceof ProductImage) {
543
                        $Product->removeProductImage($ProductImage);
544
                        $this->entityManager->remove($ProductImage);
545
                    }
546
                    $this->entityManager->persist($Product);
547
548
                    // 削除
549
                    $fs = new Filesystem();
550
                    $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$delete_image);
551
                }
552 13
                $this->entityManager->persist($Product);
553 13
                $this->entityManager->flush();
554
555 13
                $sortNos = $request->get('sort_no_images');
556 13
                if ($sortNos) {
557
                    foreach ($sortNos as $sortNo) {
558
                        list($filename, $sortNo_val) = explode('//', $sortNo);
559
                        $ProductImage = $this->productImageRepository
560
                            ->findOneBy([
561
                                'file_name' => $filename,
562
                                'Product' => $Product,
563
                            ]);
564
                        $ProductImage->setSortNo($sortNo_val);
565
                        $this->entityManager->persist($ProductImage);
0 ignored issues
show
Bug introduced by
It seems like $ProductImage defined by $this->productImageRepos...'Product' => $Product)) on line 559 can also be of type null; however, Doctrine\Common\Persiste...bjectManager::persist() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
566
                    }
567
                }
568 13
                $this->entityManager->flush();
569
570
                // 商品タグの登録
571
                // 商品タグを一度クリア
572 13
                $ProductTags = $Product->getProductTag();
573 13
                foreach ($ProductTags as $ProductTag) {
574 1
                    $Product->removeProductTag($ProductTag);
575 1
                    $this->entityManager->remove($ProductTag);
576
                }
577
578
                // 商品タグの登録
579 13
                $Tags = $form->get('Tag')->getData();
580 13
                foreach ($Tags as $Tag) {
581 13
                    $ProductTag = new ProductTag();
582
                    $ProductTag
583 13
                        ->setProduct($Product)
584 13
                        ->setTag($Tag);
585 13
                    $Product->addProductTag($ProductTag);
586 13
                    $this->entityManager->persist($ProductTag);
587
                }
588
589 13
                $Product->setUpdateDate(new \DateTime());
590 13
                $this->entityManager->flush();
591
592 13
                log_info('商品登録完了', [$id]);
593
594 13
                $event = new EventArgs(
595
                    [
596 13
                        'form' => $form,
597 13
                        'Product' => $Product,
598
                    ],
599 13
                    $request
600
                );
601 13
                $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_COMPLETE, $event);
602
603 13
                $this->addSuccess('admin.register.complete', 'admin');
604
605 13
                if ($returnLink = $form->get('return_link')->getData()) {
606 1
                    return $this->redirect($returnLink);
607
                }
608
609 13
                return $this->redirectToRoute('admin_product_product_edit', ['id' => $Product->getId()]);
610
            }
611
        }
612
613
        // 検索結果の保持
614 5
        $builder = $this->formFactory
615 5
            ->createBuilder(SearchProductType::class);
616
617 5
        $event = new EventArgs(
618
            [
619 5
                'builder' => $builder,
620 5
                'Product' => $Product,
621
            ],
622 5
            $request
623
        );
624 5
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_SEARCH, $event);
625
626 5
        $searchForm = $builder->getForm();
627
628 5
        if ('POST' === $request->getMethod()) {
629
            $searchForm->handleRequest($request);
630
        }
631
632
        // Get Tags
633 5
        $TagsList = $this->tagRepository->getList();
634
635
        // ツリー表示のため、ルートからのカテゴリを取得
636 5
        $TopCategories = $this->categoryRepository->getList(null);
637 5
        $ChoicedCategoryIds = array_map(function ($Category) {
638 3
            return $Category->getId();
639 5
        }, $form->get('Category')->getData());
640
641
        return [
642 5
            'Product' => $Product,
643 5
            'Tags' => $Tags,
644 5
            'TagsList' => $TagsList,
645 5
            'form' => $form->createView(),
646 5
            'searchForm' => $searchForm->createView(),
647 5
            'has_class' => $has_class,
648 5
            'id' => $id,
649 5
            'TopCategories' => $TopCategories,
650 5
            'ChoicedCategoryIds' => $ChoicedCategoryIds,
651
        ];
652
    }
653
654
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
655
     * @Method("DELETE")
656
     * @Route("/%eccube_admin_route%/product/product/{id}/delete", requirements={"id" = "\d+"}, name="admin_product_product_delete")
657
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
658 1
    public function delete(Request $request, $id = null)
659
    {
660 1
        $this->isTokenValid();
661 1
        $session = $request->getSession();
662 1
        $page_no = intval($session->get('eccube.admin.product.search.page_no'));
663 1
        $page_no = $page_no ? $page_no : Constant::ENABLED;
664 1
        $message = null;
665 1
        $success = false;
666
667 1
        if (!is_null($id)) {
668
            /* @var $Product \Eccube\Entity\Product */
669 1
            $Product = $this->productRepository->find($id);
670 1 View Code Duplication
            if (!$Product) {
671
                if ($request->isXmlHttpRequest()) {
672
                    $message = trans('admin.delete.warning');
673
674
                    return new JsonResponse(['success' => $success, 'message' => $message]);
675
                } else {
676
                    $this->deleteMessage();
677
                    $rUrl = $this->generateUrl('admin_product_page', ['page_no' => $page_no]).'?resume='.Constant::ENABLED;
678
679
                    return $this->redirect($rUrl);
680
                }
681
            }
682
683 1
            if ($Product instanceof Product) {
684 1
                log_info('商品削除開始', [$id]);
685
686 1
                $deleteImages = $Product->getProductImage();
687 1
                $ProductClasses = $Product->getProductClasses();
688
689
                try {
690 1
                    $this->productRepository->delete($Product);
691 1
                    $this->entityManager->flush();
692
693 1
                    $event = new EventArgs(
694
                        [
695 1
                            'Product' => $Product,
696 1
                            'ProductClass' => $ProductClasses,
697 1
                            'deleteImages' => $deleteImages,
698
                        ],
699 1
                        $request
700
                    );
701 1
                    $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_DELETE_COMPLETE, $event);
702 1
                    $deleteImages = $event->getArgument('deleteImages');
703
704
                    // 画像ファイルの削除(commit後に削除させる)
705 1
                    foreach ($deleteImages as $deleteImage) {
706
                        try {
707 1
                            $fs = new Filesystem();
708 1
                            $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$deleteImage);
709 1
                        } catch (\Exception $e) {
710
                            // エラーが発生しても無視する
711
                        }
712
                    }
713
714 1
                    log_info('商品削除完了', [$id]);
715
716 1
                    $success = true;
717 1
                    $message = trans('admin.delete.complete');
718
                } catch (ForeignKeyConstraintViolationException $e) {
719
                    log_info('商品削除エラー', [$id]);
720 1
                    $message = trans('admin.delete.failed.foreign_key', ['%name%' => $Product->getName()]);
721
                }
722
            } else {
723
                log_info('商品削除エラー', [$id]);
724 1
                $message = trans('admin.delete.failed');
725
            }
726
        } else {
727
            log_info('商品削除エラー', [$id]);
728
            $message = trans('admin.delete.failed');
729
        }
730
731 1 View Code Duplication
        if ($request->isXmlHttpRequest()) {
732
            return new JsonResponse(['success' => $success, 'message' => $message]);
733
        } else {
734 1
            if ($success) {
735 1
                $this->addSuccess($message, 'admin');
736
            } else {
737
                $this->addError($message, 'admin');
738
            }
739
740 1
            $rUrl = $this->generateUrl('admin_product_page', ['page_no' => $page_no]).'?resume='.Constant::ENABLED;
741
742 1
            return $this->redirect($rUrl);
743
        }
744
    }
745
746
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
747
     * @Method("POST")
748
     * @Route("/%eccube_admin_route%/product/product/{id}/copy", requirements={"id" = "\d+"}, name="admin_product_product_copy")
749
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
750 1
    public function copy(Request $request, $id = null)
751
    {
752 1
        $this->isTokenValid();
753
754 1
        if (!is_null($id)) {
755 1
            $Product = $this->productRepository->find($id);
756 1
            if ($Product instanceof Product) {
757 1
                $CopyProduct = clone $Product;
758 1
                $CopyProduct->copy();
759 1
                $ProductStatus = $this->productStatusRepository->find(ProductStatus::DISPLAY_HIDE);
760 1
                $CopyProduct->setStatus($ProductStatus);
761
762 1
                $CopyProductCategories = $CopyProduct->getProductCategories();
763 1
                foreach ($CopyProductCategories as $Category) {
764 1
                    $this->entityManager->persist($Category);
765
                }
766
767
                // 規格あり商品の場合は, デフォルトの商品規格を取得し登録する.
768 1
                if ($CopyProduct->hasProductClass()) {
769 1
                    $dummyClass = $this->productClassRepository->findOneBy([
770 1
                        'visible' => false,
771
                        'ClassCategory1' => null,
772
                        'ClassCategory2' => null,
773 1
                        'Product' => $Product,
774
                    ]);
775 1
                    $dummyClass = clone $dummyClass;
776 1
                    $dummyClass->setProduct($CopyProduct);
777 1
                    $CopyProduct->addProductClass($dummyClass);
778
                }
779
780 1
                $CopyProductClasses = $CopyProduct->getProductClasses();
781 1
                foreach ($CopyProductClasses as $Class) {
782 1
                    $Stock = $Class->getProductStock();
783 1
                    $CopyStock = clone $Stock;
784 1
                    $CopyStock->setProductClass($Class);
785 1
                    $this->entityManager->persist($CopyStock);
786
787 1
                    $TaxRule = $Class->getTaxRule();
788 1
                    if ($TaxRule) {
789
                        $CopyTaxRule = clone $TaxRule;
790
                        $CopyTaxRule->setProductClass($Class);
791
                        $CopyTaxRule->setProduct($CopyProduct);
792
                        $this->entityManager->persist($CopyTaxRule);
793
                    }
794 1
                    $this->entityManager->persist($Class);
795
                }
796 1
                $Images = $CopyProduct->getProductImage();
797 1
                foreach ($Images as $Image) {
798
                    // 画像ファイルを新規作成
799 1
                    $extension = pathinfo($Image->getFileName(), PATHINFO_EXTENSION);
800 1
                    $filename = date('mdHis').uniqid('_').'.'.$extension;
801
                    try {
802 1
                        $fs = new Filesystem();
803 1
                        $fs->copy($this->eccubeConfig['eccube_save_image_dir'].'/'.$Image->getFileName(), $this->eccubeConfig['eccube_save_image_dir'].'/'.$filename);
804 1
                    } catch (\Exception $e) {
805
                        // エラーが発生しても無視する
806
                    }
807 1
                    $Image->setFileName($filename);
808
809 1
                    $this->entityManager->persist($Image);
810
                }
811 1
                $Tags = $CopyProduct->getProductTag();
812 1
                foreach ($Tags as $Tag) {
813
                    $this->entityManager->persist($Tag);
814
                }
815
816 1
                $this->entityManager->persist($CopyProduct);
817
818 1
                $this->entityManager->flush();
819
820 1
                $event = new EventArgs(
821
                    [
822 1
                        'Product' => $Product,
823 1
                        'CopyProduct' => $CopyProduct,
824 1
                        'CopyProductCategories' => $CopyProductCategories,
825 1
                        'CopyProductClasses' => $CopyProductClasses,
826 1
                        'images' => $Images,
827 1
                        'Tags' => $Tags,
828
                    ],
829 1
                    $request
830
                );
831 1
                $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_COPY_COMPLETE, $event);
832
833 1
                $this->addSuccess('admin.product.copy.complete', 'admin');
834
835 1
                return $this->redirectToRoute('admin_product_product_edit', ['id' => $CopyProduct->getId()]);
836
            } else {
837
                $this->addError('admin.product.copy.failed', 'admin');
838
            }
839
        } else {
840
            $msg = trans('admin.product.copy.failed');
841
            $this->addError($msg, 'admin');
842
        }
843
844
        return $this->redirectToRoute('admin_product');
845
    }
846
847
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
848
     * @Route("/%eccube_admin_route%/product/product/{id}/display", requirements={"id" = "\d+"}, name="admin_product_product_display")
849
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
850
    public function display(Request $request, $id = null)
851
    {
852
        $event = new EventArgs(
853
            [],
854
            $request
855
        );
856
        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_DISPLAY_COMPLETE, $event);
857
858
        if (!is_null($id)) {
859
            return $this->redirectToRoute('product_detail', ['id' => $id, 'admin' => '1']);
860
        }
861
862
        return $this->redirectToRoute('admin_product');
863
    }
864
865
    /**
866
     * 商品CSVの出力.
867
     *
868
     * @Route("/%eccube_admin_route%/export", name="admin_product_export")
869
     *
870
     * @param Request $request
871
     *
872
     * @return StreamedResponse
873
     */
874
    public function export(Request $request)
875
    {
876
        // タイムアウトを無効にする.
877
        set_time_limit(0);
878
879
        // sql loggerを無効にする.
880
        $em = $this->entityManager;
881
        $em->getConfiguration()->setSQLLogger(null);
882
883
        $response = new StreamedResponse();
884
        $response->setCallback(function () use ($request) {
885
            // CSV種別を元に初期化.
886
            $this->csvExportService->initCsvType(CsvType::CSV_TYPE_PRODUCT);
887
888
            // ヘッダ行の出力.
889
            $this->csvExportService->exportHeader();
890
891
            // 商品データ検索用のクエリビルダを取得.
892
            $qb = $this->csvExportService
893
                ->getProductQueryBuilder($request);
894
895
            // Get stock status
896
            $isOutOfStock = 0;
897
            $session = $request->getSession();
898
            if ($session->has('eccube.admin.product.search')) {
899
                $searchData = $session->get('eccube.admin.product.search', []);
900
                if (isset($searchData['stock_status']) && $searchData['stock_status'] === 0) {
901
                    $isOutOfStock = 1;
902
                }
903
            }
904
905
            // joinする場合はiterateが使えないため, select句をdistinctする.
906
            // http://qiita.com/suin/items/2b1e98105fa3ef89beb7
907
            // distinctのmysqlとpgsqlの挙動をあわせる.
908
            // http://uedatakeshi.blogspot.jp/2010/04/distinct-oeder-by-postgresmysql.html
909
            $qb->resetDQLPart('select')
910
                ->resetDQLPart('orderBy')
911
                ->orderBy('p.update_date', 'DESC');
912
913
            if ($isOutOfStock) {
914
                $qb->select('p, pc')
915
                    ->distinct();
916
            } else {
917
                $qb->select('p')
918
                    ->distinct();
919
            }
920
            // データ行の出力.
921
            $this->csvExportService->setExportQueryBuilder($qb);
922
923 View Code Duplication
            $this->csvExportService->exportData(function ($entity, CsvExportService $csvService) use ($request) {
924
                $Csvs = $csvService->getCsvs();
925
926
                /** @var $Product \Eccube\Entity\Product */
927
                $Product = $entity;
928
929
                /** @var $ProductClassess \Eccube\Entity\ProductClass[] */
930
                $ProductClassess = $Product->getProductClasses();
931
932
                foreach ($ProductClassess as $ProductClass) {
933
                    $ExportCsvRow = new ExportCsvRow();
934
935
                    // CSV出力項目と合致するデータを取得.
936
                    foreach ($Csvs as $Csv) {
937
                        // 商品データを検索.
938
                        $ExportCsvRow->setData($csvService->getData($Csv, $Product));
939
                        if ($ExportCsvRow->isDataNull()) {
940
                            // 商品規格情報を検索.
941
                            $ExportCsvRow->setData($csvService->getData($Csv, $ProductClass));
942
                        }
943
944
                        $event = new EventArgs(
945
                            [
946
                                'csvService' => $csvService,
947
                                'Csv' => $Csv,
948
                                'ProductClass' => $ProductClass,
949
                                'ExportCsvRow' => $ExportCsvRow,
950
                            ],
951
                            $request
952
                        );
953
                        $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_CSV_EXPORT, $event);
954
955
                        $ExportCsvRow->pushData();
956
                    }
957
958
                    // $row[] = number_format(memory_get_usage(true));
959
                    // 出力.
960
                    $csvService->fputcsv($ExportCsvRow->getRow());
961
                }
962
            });
963
        });
964
965
        $now = new \DateTime();
966
        $filename = 'product_'.$now->format('YmdHis').'.csv';
967
        $response->headers->set('Content-Type', 'application/octet-stream');
968
        $response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
969
        $response->send();
970
971
        log_info('商品CSV出力ファイル名', [$filename]);
972
973
        return $response;
974
    }
975
976
    /**
977
     * ProductCategory作成
978
     *
979
     * @param \Eccube\Entity\Product $Product
980
     * @param \Eccube\Entity\Category $Category
981
     *
982
     * @return \Eccube\Entity\ProductCategory
983
     */
984 View Code Duplication
    private function createProductCategory($Product, $Category, $count)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
985
    {
986
        $ProductCategory = new ProductCategory();
987
        $ProductCategory->setProduct($Product);
988
        $ProductCategory->setProductId($Product->getId());
989
        $ProductCategory->setCategory($Category);
990
        $ProductCategory->setCategoryId($Category->getId());
991
        $ProductCategory->setSortNo($count);
992
993
        return $ProductCategory;
994
    }
995
996
    /**
997
     * Bulk public action
998
     *
999
     * @Method("POST")
1000
     * @Route("/%eccube_admin_route%/product/bulk/product-status/{id}", requirements={"id" = "\d+"}, name="admin_product_bulk_product_status")
1001
     *
1002
     * @param Request $request
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
1003
     * @param ProductStatus $ProductStatus
1004
     *
1005
     * @return RedirectResponse
1006
     */
1007 1
    public function bulkProductStatus(Request $request, ProductStatus $ProductStatus)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
1008
    {
1009 1
        $this->isTokenValid();
1010
1011
        /** @var Product[] $Products */
1012 1
        $Products = $this->productRepository->findBy(['id' => $request->get('ids')]);
1013 1
        $count = 0;
1014 1
        foreach ($Products as $Product) {
1015
            try {
1016 1
                $Product->setStatus($ProductStatus);
1017 1
                $this->productRepository->save($Product);
1018 1
                $count++;
1019
            } catch (\Exception $e) {
1020 1
                $this->addError($e->getMessage(), 'admin');
1021
            }
1022
        }
1023
        try {
1024 1 View Code Duplication
            if ($count) {
1025 1
                $this->entityManager->flush();
1026 1
                $msg = $this->translator->trans('admin.product.index.bulk_product_status_success_count', [
1027 1
                    '%count%' => $count,
1028 1
                    '%status%' => $ProductStatus->getName(),
1029
                ]);
1030 1
                $this->addSuccess($msg, 'admin');
1031
            }
1032
        } catch (\Exception $e) {
1033
            $this->addError($e->getMessage(), 'admin');
1034
        }
1035
1036 1
        return $this->redirectToRoute('admin_product', ['resume' => Constant::ENABLED]);
1037
    }
1038
}
1039