Completed
Push — 4.0 ( b48f64...137622 )
by chihiro
20:21 queued 10s
created

CsvImportController   F

Complexity

Total Complexity 219

Size/Duplication

Total Lines 1366
Duplicated Lines 21.82 %

Coupling/Cohesion

Components 1
Dependencies 35

Test Coverage

Coverage 68.69%

Importance

Changes 0
Metric Value
dl 298
loc 1366
ccs 430
cts 626
cp 0.6869
rs 0.8
c 0
b 0
f 0
wmc 219
lcom 1
cbo 35

16 Methods

Rating   Name   Duplication   Size   Complexity  
F csvCategory() 30 153 31
A csvTemplate() 0 14 3
A renderWithError() 0 16 3
B createProductImage() 0 39 8
A __construct() 21 21 1
F csvProduct() 115 396 87
B createProductCategory() 17 56 10
B createProductTag() 8 39 8
F createProductClass() 30 139 33
F updateProductClass() 67 147 29
A addErrors() 0 4 1
A getErrors() 0 4 1
A hasErrors() 0 4 1
B getProductCsvHeader() 0 120 1
A getCategoryCsvHeader() 0 25 1
A makeProductCategory() 10 10 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like CsvImportController 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 CsvImportController, and based on these observations, apply Extract Interface, too.

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\Admin\AbstractCsvImportController;
19
use Eccube\Entity\BaseInfo;
20
use Eccube\Entity\Category;
21
use Eccube\Entity\Product;
22
use Eccube\Entity\ProductCategory;
23
use Eccube\Entity\ProductClass;
24
use Eccube\Entity\ProductImage;
25
use Eccube\Entity\ProductStock;
26
use Eccube\Entity\ProductTag;
27
use Eccube\Form\Type\Admin\CsvImportType;
28
use Eccube\Repository\BaseInfoRepository;
29
use Eccube\Repository\CategoryRepository;
30
use Eccube\Repository\ClassCategoryRepository;
31
use Eccube\Repository\DeliveryDurationRepository;
32
use Eccube\Repository\Master\ProductStatusRepository;
33
use Eccube\Repository\Master\SaleTypeRepository;
34
use Eccube\Repository\ProductRepository;
35
use Eccube\Repository\TagRepository;
36
use Eccube\Service\CsvImportService;
37
use Eccube\Util\CacheUtil;
38
use Eccube\Util\StringUtil;
39
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
40
use Symfony\Component\Filesystem\Filesystem;
41
use Symfony\Component\Form\FormInterface;
42
use Symfony\Component\HttpFoundation\Request;
43
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
44
use Symfony\Component\Routing\Annotation\Route;
45
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
46
use Symfony\Component\Validator\Validator\ValidatorInterface;
47
48
class CsvImportController extends AbstractCsvImportController
49
{
50
    /**
51
     * @var DeliveryDurationRepository
52
     */
53
    protected $deliveryDurationRepository;
54
55
    /**
56
     * @var SaleTypeRepository
57
     */
58
    protected $saleTypeRepository;
59
60
    /**
61
     * @var TagRepository
62
     */
63
    protected $tagRepository;
64
65
    /**
66
     * @var CategoryRepository
67
     */
68
    protected $categoryRepository;
69
70
    /**
71
     * @var ClassCategoryRepository
72
     */
73
    protected $classCategoryRepository;
74
75
    /**
76
     * @var ProductStatusRepository
77
     */
78
    protected $productStatusRepository;
79
80
    /**
81
     * @var ProductRepository
82
     */
83
    protected $productRepository;
84
85
    /**
86
     * @var BaseInfo
87
     */
88
    protected $BaseInfo;
89
90
    /**
91
     * @var ValidatorInterface
92
     */
93
    protected $validator;
94
95
    private $errors = [];
96
97
    /**
98
     * CsvImportController constructor.
99
     *
100
     * @param DeliveryDurationRepository $deliveryDurationRepository
101 16
     * @param SaleTypeRepository $saleTypeRepository
102
     * @param TagRepository $tagRepository
103 16
     * @param CategoryRepository $categoryRepository
104 16
     * @param ClassCategoryRepository $classCategoryRepository
105 16
     * @param ProductStatusRepository $productStatusRepository
106 16
     * @param ProductRepository $productRepository
107 16
     * @param BaseInfoRepository $baseInfoRepository
108 16
     * @param ValidatorInterface $validator
109 16
     *
110 16
     * @throws \Doctrine\ORM\NoResultException
111
     * @throws \Doctrine\ORM\NonUniqueResultException
112
     */
113 View Code Duplication
    public function __construct(
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...
114
        DeliveryDurationRepository $deliveryDurationRepository,
115
        SaleTypeRepository $saleTypeRepository,
116
        TagRepository $tagRepository,
117
        CategoryRepository $categoryRepository,
118
        ClassCategoryRepository $classCategoryRepository,
119 10
        ProductStatusRepository $productStatusRepository,
120
        ProductRepository $productRepository,
121 10
        BaseInfoRepository $baseInfoRepository,
122 10
        ValidatorInterface $validator
123 10
    ) {
124 10
        $this->deliveryDurationRepository = $deliveryDurationRepository;
125 10
        $this->saleTypeRepository = $saleTypeRepository;
126 10
        $this->tagRepository = $tagRepository;
127 10
        $this->categoryRepository = $categoryRepository;
128 10
        $this->classCategoryRepository = $classCategoryRepository;
129 10
        $this->productStatusRepository = $productStatusRepository;
130 10
        $this->productRepository = $productRepository;
131
        $this->BaseInfo = $baseInfoRepository->get();
132
        $this->validator = $validator;
133
    }
134
135 10
    /**
136 10
     * 商品登録CSVアップロード
137 10
     *
138 10
     * @Route("/%eccube_admin_route%/product/product_csv_upload", name="admin_product_csv_import")
139 10
     * @Template("@admin/Product/csv_product.twig")
140 10
     */
141
    public function csvProduct(Request $request, CacheUtil $cacheUtil)
142 10
    {
143
        $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm();
144 10
        $headers = $this->getProductCsvHeader();
145
        if ('POST' === $request->getMethod()) {
146
            $form->handleRequest($request);
147
            if ($form->isValid()) {
148
                $formFile = $form['import_file']->getData();
149
                if (!empty($formFile)) {
150 10
                    log_info('商品CSV登録開始');
151
                    $data = $this->getImportData($formFile);
152 10 View Code Duplication
                    if ($data === false) {
153
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
154
155
                        return $this->renderWithError($form, $headers, false);
156
                    }
157
                    $getId = function ($item) {
158 10
                        return $item['id'];
159 10
                    };
160
                    $requireHeader = array_keys(array_map($getId, array_filter($headers, function ($value) {
161 10
                        return $value['required'];
162 10
                    })));
163
164 10
                    $columnHeaders = $data->getColumnHeaders();
165 10
166 10 View Code Duplication
                    if (count(array_diff($requireHeader, $columnHeaders)) > 0) {
167
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
168
169
                        return $this->renderWithError($form, $headers, false);
170
                    }
171
172
                    $size = count($data);
173 10
174 7 View Code Duplication
                    if ($size < 1) {
175 7
                        $this->addErrors(trans('admin.common.csv_invalid_no_data'));
176
177 4
                        return $this->renderWithError($form, $headers, false);
178 3
                    }
179 3
180 1
                    $headerSize = count($columnHeaders);
181 1
                    $headerByKey = array_flip(array_map($getId, $headers));
182
                    $deleteImages = [];
183 3
184
                    $this->entityManager->getConfiguration()->setSQLLogger(null);
185
                    $this->entityManager->getConnection()->beginTransaction();
186 1
                    // CSVファイルの登録処理
187 1
                    foreach ($data as $row) {
188
                        $line = $data->key() + 1;
189 1
                        if ($headerSize != count($row)) {
190
                            $message = trans('admin.common.csv_invalid_format_line', ['%line%' => $line]);
191
                            $this->addErrors($message);
192
193 8
                            return $this->renderWithError($form, $headers);
194 1
                        }
195 1
196
                        if (!isset($row[$headerByKey['id']]) || StringUtil::isBlank($row[$headerByKey['id']])) {
197 7
                            $Product = new Product();
198 6
                            $this->entityManager->persist($Product);
199 6
                        } else {
200 1
                            if (preg_match('/^\d+$/', $row[$headerByKey['id']])) {
201 1
                                $Product = $this->productRepository->find($row[$headerByKey['id']]);
202
                                if (!$Product) {
203 6
                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['id']]);
204
                                    $this->addErrors($message);
205
206 1
                                    return $this->renderWithError($form, $headers);
207 1
                                }
208
                            } else {
209
                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['id']]);
210
                                $this->addErrors($message);
211 8
212
                                return $this->renderWithError($form, $headers);
213
                            }
214
215
                            if (isset($row[$headerByKey['product_del_flg']])) {
216
                                if (StringUtil::isNotBlank($row[$headerByKey['product_del_flg']]) && $row[$headerByKey['product_del_flg']] == (string) Constant::ENABLED) {
217 8
                                    // 商品を物理削除
218
                                    $deleteImages[] = $Product->getProductImage();
219
220 8
                                    try {
221 3
                                        $this->productRepository->delete($Product);
222
                                        $this->entityManager->flush();
223 5
224
                                        continue;
225
                                    } catch (ForeignKeyConstraintViolationException $e) {
226 8
                                        $message = trans('admin.common.csv_invalid_foreign_key', ['%line%' => $line, '%name%' => $Product->getName()]);
227 4
                                        $this->addErrors($message);
228
229 5
                                        return $this->renderWithError($form, $headers);
230
                                    }
231
                                }
232 8
                            }
233 4
                        }
234
235 4
                        if (StringUtil::isBlank($row[$headerByKey['status']])) {
236
                            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['status']]);
237
                            $this->addErrors($message);
238 8
                        } else {
239 3
                            if (preg_match('/^\d+$/', $row[$headerByKey['status']])) {
240
                                $ProductStatus = $this->productStatusRepository->find($row[$headerByKey['status']]);
241 5
                                if (!$ProductStatus) {
242
                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['status']]);
243
                                    $this->addErrors($message);
244 8
                                } else {
245 3
                                    $Product->setStatus($ProductStatus);
246
                                }
247 5
                            } else {
248
                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['status']]);
249
                                $this->addErrors($message);
250
                            }
251 8
                        }
252
253 8
                        if (StringUtil::isBlank($row[$headerByKey['name']])) {
254
                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['name']]);
255
                            $this->addErrors($message);
256 8
257
                            return $this->renderWithError($form, $headers);
258
                        } else {
259 8
                            $Product->setName(StringUtil::trimAll($row[$headerByKey['name']]));
260
                        }
261
262 View Code Duplication
                        if (isset($row[$headerByKey['note']]) && StringUtil::isNotBlank($row[$headerByKey['note']])) {
263 8
                            $Product->setNote(StringUtil::trimAll($row[$headerByKey['note']]));
264 8
                        } else {
265
                            $Product->setNote(null);
266 7
                        }
267 7
268 View Code Duplication
                        if (isset($row[$headerByKey['description_list']]) && StringUtil::isNotBlank($row[$headerByKey['description_list']])) {
269
                            $Product->setDescriptionList(StringUtil::trimAll($row[$headerByKey['description_list']]));
270
                        } else {
271
                            $Product->setDescriptionList(null);
272
                        }
273
274 View Code Duplication
                        if (isset($row[$headerByKey['description_detail']]) && StringUtil::isNotBlank($row[$headerByKey['description_detail']])) {
275
                            $Product->setDescriptionDetail(StringUtil::trimAll($row[$headerByKey['description_detail']]));
276
                        } else {
277
                            $Product->setDescriptionDetail(null);
278
                        }
279 7
280 2 View Code Duplication
                        if (isset($row[$headerByKey['search_word']]) && StringUtil::isNotBlank($row[$headerByKey['search_word']])) {
281
                            $Product->setSearchWord(StringUtil::trimAll($row[$headerByKey['search_word']]));
282
                        } else {
283
                            $Product->setSearchWord(null);
284
                        }
285
286 View Code Duplication
                        if (isset($row[$headerByKey['free_area']]) && StringUtil::isNotBlank($row[$headerByKey['free_area']])) {
287
                            $Product->setFreeArea(StringUtil::trimAll($row[$headerByKey['free_area']]));
288
                        } else {
289
                            $Product->setFreeArea(null);
290 2
                        }
291 2
292
                        // 商品画像登録
293
                        $this->createProductImage($row, $Product, $data, $headerByKey);
294 2
295
                        $this->entityManager->flush();
296
297 2
                        // 商品カテゴリ登録
298 2
                        $this->createProductCategory($row, $Product, $data, $headerByKey);
299 2
300 2
                        //タグ登録
301
                        $this->createProductTag($row, $Product, $data, $headerByKey);
302
303
                        // 商品規格が存在しなければ新規登録
304 2
                        /** @var ProductClass[] $ProductClasses */
305
                        $ProductClasses = $Product->getProductClasses();
306
                        if ($ProductClasses->count() < 1) {
0 ignored issues
show
Bug introduced by
The method count cannot be called on $ProductClasses (of type array<integer,object<Eccube\Entity\ProductClass>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
307
                            // 規格分類1(ID)がセットされていると規格なし商品、規格あり商品を作成
308
                            $ProductClassOrg = $this->createProductClass($row, $Product, $data, $headerByKey);
309 View Code Duplication
                            if ($this->BaseInfo->isOptionProductDeliveryFee()) {
310
                                if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isBlank($row[$headerByKey['delivery_fee']])) {
311 2
                                    $deliveryFee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
312 2
                                    $errors = $this->validator->validate($deliveryFee, new GreaterThanOrEqual(['value' => 0]));
313 2
                                    if ($errors->count() === 0) {
314 2
                                        $ProductClassOrg->setDeliveryFee($deliveryFee);
315
                                    } else {
316
                                        $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
317
                                        $this->addErrors($message);
318 2
                                    }
319 2
                                }
320
                            }
321
322
                            if (isset($row[$headerByKey['class_category1']]) && StringUtil::isNotBlank($row[$headerByKey['class_category1']])) {
323
                                if (isset($row[$headerByKey['class_category2']]) && $row[$headerByKey['class_category1']] == $row[$headerByKey['class_category2']]) {
324 2
                                    $message = trans('admin.common.csv_invalid_not_same', [
325
                                        '%line%' => $line,
326
                                        '%name1%' => $headerByKey['class_category1'],
327
                                        '%name2%' => $headerByKey['class_category2'],
328
                                    ]);
329
                                    $this->addErrors($message);
330
                                } else {
331
                                    // 商品規格あり
332 2
                                    // 規格分類あり商品を作成
333 2
                                    $ProductClass = clone $ProductClassOrg;
334
                                    $ProductStock = clone $ProductClassOrg->getProductStock();
335 2
336 2
                                    // 規格分類1、規格分類2がnullであるデータを非表示
337
                                    $ProductClassOrg->setVisible(false);
338
339 5
                                    // 規格分類1、2をそれぞれセットし作成
340
                                    $ClassCategory1 = null;
341 7
                                    if (preg_match('/^\d+$/', $row[$headerByKey['class_category1']])) {
342
                                        $ClassCategory1 = $this->classCategoryRepository->find($row[$headerByKey['class_category1']]);
343
                                        if (!$ClassCategory1) {
344
                                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
345
                                            $this->addErrors($message);
346 2
                                        } else {
347 2
                                            $ProductClass->setClassCategory1($ClassCategory1);
348 2
                                        }
349
                                    } else {
350 2
                                        $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
351 2
                                        $this->addErrors($message);
352 2
                                    }
353
354
                                    if (isset($row[$headerByKey['class_category2']]) && StringUtil::isNotBlank($row[$headerByKey['class_category2']])) {
355 2
                                        if (preg_match('/^\d+$/', $row[$headerByKey['class_category2']])) {
356 2
                                            $ClassCategory2 = $this->classCategoryRepository->find($row[$headerByKey['class_category2']]);
357 View Code Duplication
                                            if (!$ClassCategory2) {
358 1
                                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
359
                                                $this->addErrors($message);
360 1
                                            } else {
361
                                                if ($ClassCategory1 &&
362
                                                    ($ClassCategory1->getClassName()->getId() == $ClassCategory2->getClassName()->getId())
363
                                                ) {
364
                                                    $message = trans('admin.common.csv_invalid_not_same', ['%line%' => $line, '%name1%' => $headerByKey['class_category1'], '%name2%' => $headerByKey['class_category2']]);
365
                                                    $this->addErrors($message);
366
                                                } else {
367
                                                    $ProductClass->setClassCategory2($ClassCategory2);
368
                                                }
369
                                            }
370
                                        } else {
371
                                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
372 1
                                            $this->addErrors($message);
373 2
                                        }
374
                                    }
375
                                    $ProductClass->setProductStock($ProductStock);
376
                                    $ProductStock->setProductClass($ProductClass);
377
378 2
                                    $this->entityManager->persist($ProductClass);
379 1
                                    $this->entityManager->persist($ProductStock);
380 1
                                }
381 1
                            } else {
382
                                if (isset($row[$headerByKey['class_category2']]) && StringUtil::isNotBlank($row[$headerByKey['class_category2']])) {
383
                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
384 1
                                    $this->addErrors($message);
385
                                }
386
                            }
387 1
                        } else {
388 1
                            // 商品規格の更新
389
                            $flag = false;
390
                            $classCategoryId1 = StringUtil::isBlank($row[$headerByKey['class_category1']]) ? null : $row[$headerByKey['class_category1']];
391
                            $classCategoryId2 = StringUtil::isBlank($row[$headerByKey['class_category2']]) ? null : $row[$headerByKey['class_category2']];
392
393
                            foreach ($ProductClasses as $pc) {
394
                                $classCategory1 = is_null($pc->getClassCategory1()) ? null : $pc->getClassCategory1()->getId();
395
                                $classCategory2 = is_null($pc->getClassCategory2()) ? null : $pc->getClassCategory2()->getId();
396
397
                                // 登録されている商品規格を更新
398 1
                                if ($classCategory1 == $classCategoryId1 &&
399 1
                                    $classCategory2 == $classCategoryId2
400 1
                                ) {
401 1
                                    $this->updateProductClass($row, $Product, $pc, $data, $headerByKey);
402
403 1 View Code Duplication
                                    if ($this->BaseInfo->isOptionProductDeliveryFee()) {
404
                                        $headerByKey['delivery_fee'] = trans('csvimport.label.delivery_fee');
405
                                        if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
406
                                            $deliveryFee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
407
                                            $errors = $this->validator->validate($deliveryFee, new GreaterThanOrEqual(['value' => 0]));
408
                                            if ($errors->count() === 0) {
409
                                                $pc->setDeliveryFee($deliveryFee);
410 1
                                            } else {
411 1
                                                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
412 1
                                                $this->addErrors($message);
413
                                            }
414
                                        }
415
                                    }
416 1
                                    $flag = true;
417 1
                                    break;
418 1
                                }
419
                            }
420
421
                            // 商品規格を登録
422 1
                            if (!$flag) {
423 1
                                $pc = $ProductClasses[0];
424
                                if ($pc->getClassCategory1() == null &&
425
                                    $pc->getClassCategory2() == null
426
                                ) {
427
                                    // 規格分類1、規格分類2がnullであるデータを非表示
428
                                    $pc->setVisible(false);
429
                                }
430 1
431
                                if (isset($row[$headerByKey['class_category1']]) && isset($row[$headerByKey['class_category2']])
432
                                    && $row[$headerByKey['class_category1']] == $row[$headerByKey['class_category2']]) {
433
                                    $message = trans('admin.common.csv_invalid_not_same', [
434
                                        '%line%' => $line,
435 1
                                        '%name1%' => $headerByKey['class_category1'],
436
                                        '%name2%' => $headerByKey['class_category2'],
437
                                    ]);
438
                                    $this->addErrors($message);
439
                                } else {
440
                                    // 必ず規格分類1がセットされている
441
                                    // 規格分類1、2をそれぞれセットし作成
442
                                    $ClassCategory1 = null;
443
                                    if (preg_match('/^\d+$/', $classCategoryId1)) {
444 1
                                        $ClassCategory1 = $this->classCategoryRepository->find($classCategoryId1);
445
                                        if (!$ClassCategory1) {
446 1
                                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
447
                                            $this->addErrors($message);
448
                                        }
449
                                    } else {
450
                                        $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
451
                                        $this->addErrors($message);
452
                                    }
453
454
                                    $ClassCategory2 = null;
455
                                    if (isset($row[$headerByKey['class_category2']]) && StringUtil::isNotBlank($row[$headerByKey['class_category2']])) {
456
                                        if ($pc->getClassCategory1() != null && $pc->getClassCategory2() == null) {
457 1
                                            $message = trans('admin.common.csv_invalid_can_not', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
458
                                            $this->addErrors($message);
459
                                        } else {
460
                                            if (preg_match('/^\d+$/', $classCategoryId2)) {
461 8
                                                $ClassCategory2 = $this->classCategoryRepository->find($classCategoryId2);
462 3 View Code Duplication
                                                if (!$ClassCategory2) {
463
                                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
464 5
                                                    $this->addErrors($message);
465
                                                } else {
466 5
                                                    if ($ClassCategory1 &&
467 5
                                                        ($ClassCategory1->getClassName()->getId() == $ClassCategory2->getClassName()->getId())
468 5
                                                    ) {
469 5
                                                        $message = trans('admin.common.csv_invalid_not_same', [
470 5
                                                            '%line%' => $line,
471
                                                            '%name1%' => $headerByKey['class_category1'],
472
                                                            '%name2%' => $headerByKey['class_category2'],
473
                                                        ]);
474
                                                        $this->addErrors($message);
475 5
                                                    }
476
                                                }
477
                                            } else {
478
                                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
479
                                                $this->addErrors($message);
480
                                            }
481
                                        }
482
                                    } else {
483
                                        if ($pc->getClassCategory1() != null && $pc->getClassCategory2() != null) {
484 6
                                            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
485
                                            $this->addErrors($message);
486 6
                                        }
487
                                    }
488 6
                                    $ProductClass = $this->createProductClass($row, $Product, $data, $headerByKey, $ClassCategory1, $ClassCategory2);
0 ignored issues
show
Bug introduced by
It seems like $ClassCategory1 defined by $this->classCategoryRepo...find($classCategoryId1) on line 444 can also be of type object; however, Eccube\Controller\Admin\...r::createProductClass() does only seem to accept null, 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...
Bug introduced by
It seems like $ClassCategory2 defined by $this->classCategoryRepo...find($classCategoryId2) on line 461 can also be of type object; however, Eccube\Controller\Admin\...r::createProductClass() does only seem to accept null, 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...
489 6
490 6 View Code Duplication
                                    if ($this->BaseInfo->isOptionProductDeliveryFee()) {
491 6
                                        if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
492 6
                                            $deliveryFee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
493 6
                                            $errors = $this->validator->validate($deliveryFee, new GreaterThanOrEqual(['value' => 0]));
494 6
                                            if ($errors->count() === 0) {
495 6
                                                $ProductClass->setDeliveryFee($deliveryFee);
496 6
                                            } else {
497
                                                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
498
                                                $this->addErrors($message);
499
                                            }
500
                                        }
501
                                    }
502
                                    $Product->addProductClass($ProductClass);
503
                                }
504
                            }
505 6
                        }
506
                        if ($this->hasErrors()) {
507 6
                            return $this->renderWithError($form, $headers);
508 6
                        }
509 1
                        $this->entityManager->persist($Product);
510
                    }
511 1
                    $this->entityManager->flush();
512
                    $this->entityManager->getConnection()->commit();
513
514 5
                    // 画像ファイルの削除(commit後に削除させる)
515 5 View Code Duplication
                    foreach ($deleteImages as $images) {
516
                        foreach ($images as $image) {
517
                            try {
518
                                $fs = new Filesystem();
519
                                $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$image);
520 5
                            } catch (\Exception $e) {
521 5
                                // エラーが発生しても無視する
522
                            }
523 5
                        }
524
                    }
525 5
526 5
                    log_info('商品CSV登録完了');
527 1
                    $message = 'admin.common.csv_upload_complete';
528
                    $this->session->getFlashBag()->add('eccube.admin.success', $message);
529
530
                    $cacheUtil->clearDoctrineCache();
531
                }
532 1
            }
533 1
        }
534
535
        return $this->renderWithError($form, $headers);
536
    }
537
538 1
    /**
539
     * カテゴリ登録CSVアップロード
540
     *
541
     * @Route("/%eccube_admin_route%/product/category_csv_upload", name="admin_product_category_csv_import")
542
     * @Template("@admin/Product/csv_category.twig")
543
     */
544
    public function csvCategory(Request $request, CacheUtil $cacheUtil)
545 5
    {
546 1
        $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm();
547
548
        $headers = $this->getCategoryCsvHeader();
549
        if ('POST' === $request->getMethod()) {
550
            $form->handleRequest($request);
551
            if ($form->isValid()) {
552
                $formFile = $form['import_file']->getData();
553
                if (!empty($formFile)) {
554
                    log_info('カテゴリCSV登録開始');
555
                    $data = $this->getImportData($formFile);
556 View Code Duplication
                    if ($data === false) {
557
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
558
559
                        return $this->renderWithError($form, $headers, false);
560
                    }
561
562
                    $getId = function ($item) {
563
                        return $item['id'];
564
                    };
565 5
                    $requireHeader = array_keys(array_map($getId, array_filter($headers, function ($value) {
566 1
                        return $value['required'];
567
                    })));
568 1
569
                    $headerByKey = array_flip(array_map($getId, $headers));
570 4
571
                    $columnHeaders = $data->getColumnHeaders();
572 View Code Duplication
                    if (count(array_diff($requireHeader, $columnHeaders)) > 0) {
573 4
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
574 4
575 1
                        return $this->renderWithError($form, $headers, false);
576
                    }
577
578
                    $size = count($data);
579 View Code Duplication
                    if ($size < 1) {
580
                        $this->addErrors(trans('admin.common.csv_invalid_no_data'));
581
582 1
                        return $this->renderWithError($form, $headers, false);
583 1
                    }
584
                    $this->entityManager->getConfiguration()->setSQLLogger(null);
585
                    $this->entityManager->getConnection()->beginTransaction();
586
                    // CSVファイルの登録処理
587
                    foreach ($data as $row) {
588
                        /** @var $Category Category */
589 4
                        $Category = new Category();
590
                        if (isset($row[$headerByKey['id']]) && strlen($row[$headerByKey['id']]) > 0) {
591 View Code Duplication
                            if (!preg_match('/^\d+$/', $row[$headerByKey['id']])) {
592 4
                                $this->addErrors(($data->key() + 1).'行目のカテゴリIDが存在しません。');
593
594
                                return $this->renderWithError($form, $headers);
595
                            }
596
                            $Category = $this->categoryRepository->find($row[$headerByKey['id']]);
597
                            if (!$Category) {
598
                                $this->addErrors(($data->key() + 1).'行目のカテゴリIDが存在しません。');
599
600 4
                                return $this->renderWithError($form, $headers);
601 4
                            }
602 1
                            if ($row[$headerByKey['id']] == $row[$headerByKey['parent_category_id']]) {
603
                                $this->addErrors(($data->key() + 1).'行目のカテゴリIDと親カテゴリIDが同じです。');
604
605
                                return $this->renderWithError($form, $headers);
606 4
                            }
607
                        }
608 4
609
                        if (isset($row[$headerByKey['category_del_flg']]) && StringUtil::isNotBlank($row[$headerByKey['category_del_flg']])) {
610
                            if (StringUtil::trimAll($row[$headerByKey['category_del_flg']]) == 1) {
611
                                if ($Category->getId()) {
612
                                    log_info('カテゴリ削除開始', [$Category->getId()]);
613
                                    try {
614 4
                                        $this->categoryRepository->delete($Category);
615
                                        log_info('カテゴリ削除完了', [$Category->getId()]);
616
                                    } catch (ForeignKeyConstraintViolationException $e) {
617 4
                                        log_info('カテゴリ削除エラー', [$Category->getId(), $e]);
618 4
                                        $message = trans('admin.common.delete_error_foreign_key', ['%name%' => $Category->getName()]);
619
                                        $this->addError($message, 'admin');
620
621 4
                                        return $this->renderWithError($form, $headers);
622 4
                                    }
623 4
                                }
624 4
625
                                continue;
626
                            }
627
                        }
628
629 4
                        if (!isset($row[$headerByKey['category_name']]) || StringUtil::isBlank($row[$headerByKey['category_name']])) {
630
                            $this->addErrors(($data->key() + 1).'行目のカテゴリ名が設定されていません。');
631
632
                            return $this->renderWithError($form, $headers);
633
                        } else {
634
                            $Category->setName(StringUtil::trimAll($row[$headerByKey['category_name']]));
635
                        }
636
637
                        $ParentCategory = null;
638
                        if (isset($row[$headerByKey['parent_category_id']]) && StringUtil::isNotBlank($row[$headerByKey['parent_category_id']])) {
639 View Code Duplication
                            if (!preg_match('/^\d+$/', $row[$headerByKey['parent_category_id']])) {
640
                                $this->addErrors(($data->key() + 1).'行目の親カテゴリIDが存在しません。');
641
642
                                return $this->renderWithError($form, $headers);
643
                            }
644
645
                            /** @var $ParentCategory Category */
646
                            $ParentCategory = $this->categoryRepository->find($row[$headerByKey['parent_category_id']]);
647
                            if (!$ParentCategory) {
648
                                $this->addErrors(($data->key() + 1).'行目の親カテゴリIDが存在しません。');
649
650
                                return $this->renderWithError($form, $headers);
651
                            }
652
                        }
653
                        $Category->setParent($ParentCategory);
654
655
                        // Level
656
                        if (isset($row['階層']) && StringUtil::isNotBlank($row['階層'])) {
657 View Code Duplication
                            if ($ParentCategory == null && $row['階層'] != 1) {
658
                                $this->addErrors(($data->key() + 1).'行目の親カテゴリIDが存在しません。');
659
660
                                return $this->renderWithError($form, $headers);
661
                            }
662
                            $level = StringUtil::trimAll($row['階層']);
663 16
                        } else {
664
                            $level = 1;
665 16
                            if ($ParentCategory) {
666 7
                                $level = $ParentCategory->getHierarchy() + 1;
667 6
                            }
668
                        }
669
670
                        $Category->setHierarchy($level);
671 16
672
                        if ($this->eccubeConfig['eccube_category_nest_level'] < $Category->getHierarchy()) {
673
                            $this->addErrors(($data->key() + 1).'行目のカテゴリが最大レベルを超えているため設定できません。');
674 16
675 16
                            return $this->renderWithError($form, $headers);
676 16
                        }
677
678
                        if ($this->hasErrors()) {
679
                            return $this->renderWithError($form, $headers);
680
                        }
681
                        $this->entityManager->persist($Category);
682
                        $this->categoryRepository->save($Category);
683
                    }
684
685
                    $this->entityManager->getConnection()->commit();
686
                    log_info('カテゴリCSV登録完了');
687 8
                    $message = 'admin.common.csv_upload_complete';
688
                    $this->session->getFlashBag()->add('eccube.admin.success', $message);
689 8
690
                    $cacheUtil->clearDoctrineCache();
691 4
                }
692 4
            }
693 2
        }
694 2
695
        return $this->renderWithError($form, $headers);
696
    }
697
698 4
    /**
699
     * アップロード用CSV雛形ファイルダウンロード
700 4
     *
701
     * @Route("/%eccube_admin_route%/product/csv_template/{type}", requirements={"type" = "\w+"}, name="admin_product_csv_template")
702 4
     */
703 4
    public function csvTemplate(Request $request, $type)
704 4
    {
705
        if ($type == 'product') {
706
            $headers = $this->getProductCsvHeader();
707 4
            $filename = 'product.csv';
708
        } elseif ($type == 'category') {
709
            $headers = $this->getCategoryCsvHeader();
710
            $filename = 'category.csv';
711
        } else {
712 4
            throw new NotFoundHttpException();
713 4
        }
714 4
715 4
        return $this->sendTemplateResponse($request, array_keys($headers), $filename);
716 4
    }
717
718 4
    /**
719 4
     * 登録、更新時のエラー画面表示
720 4
     *
721
     * @param FormInterface $form
722
     * @param array $headers
723
     * @param bool $rollback
724
     *
725
     * @return array
726
     *
727
     * @throws \Doctrine\DBAL\ConnectionException
728
     */
729
    protected function renderWithError($form, $headers, $rollback = true)
730
    {
731
        if ($this->hasErrors()) {
732
            if ($rollback) {
733
                $this->entityManager->getConnection()->rollback();
734
            }
735 8
        }
736
737
        $this->removeUploadedFile();
738 8
739 8
        return [
740 2
            'form' => $form->createView(),
741 2
            'headers' => $headers,
742 2
            'errors' => $this->errors,
743
        ];
744
    }
745 8
746
    /**
747 4
     * 商品画像の削除、登録
748 4
     *
749 4
     * @param $row
750 4
     * @param Product $Product
751 4
     * @param CsvImportService $data
752 4
     */
753 4
    protected function createProductImage($row, Product $Product, $data, $headerByKey)
754 4
    {
755
        if (isset($row[$headerByKey['product_image']]) && StringUtil::isNotBlank($row[$headerByKey['product_image']])) {
756
            // 画像の削除
757
            $ProductImages = $Product->getProductImage();
758
            foreach ($ProductImages as $ProductImage) {
759
                $Product->removeProductImage($ProductImage);
760
                $this->entityManager->remove($ProductImage);
761
            }
762 4
763 4
            // 画像の登録
764 4
            $images = explode(',', $row[$headerByKey['product_image']]);
765 4
766 4
            $sortNo = 1;
767
768 4
            $pattern = "/\\$|^.*.\.\\\.*|\/$|^.*.\.\/\.*/";
769 4
            foreach ($images as $image) {
770
                $fileName = StringUtil::trimAll($image);
771
772 4
                // 商品画像名のフォーマットチェック
773
                if (strlen($fileName) > 0 && preg_match($pattern, $fileName)) {
774
                    $message = trans('admin.common.csv_invalid_image', ['%line%' => $data->key() + 1, '%name%' => $headerByKey['product_image']]);
775
                    $this->addErrors($message);
776
                } else {
777
                    // 空文字は登録対象外
778
                    if (!empty($fileName)) {
779
                        $ProductImage = new ProductImage();
780
                        $ProductImage->setFileName($fileName);
781 4
                        $ProductImage->setProduct($Product);
782
                        $ProductImage->setSortNo($sortNo);
783
784
                        $Product->addProductImage($ProductImage);
785
                        $sortNo++;
786 4
                        $this->entityManager->persist($ProductImage);
787
                    }
788
                }
789
            }
790
        }
791
    }
792
793
    /**
794 4
     * 商品カテゴリの削除、登録
795
     *
796
     * @param $row
797
     * @param Product $Product
798
     * @param CsvImportService $data
799
     * @param $headerByKey
800
     */
801
    protected function createProductCategory($row, Product $Product, $data, $headerByKey)
802
    {
803
        // カテゴリの削除
804
        $ProductCategories = $Product->getProductCategories();
805
        foreach ($ProductCategories as $ProductCategory) {
806
            $Product->removeProductCategory($ProductCategory);
807 8
            $this->entityManager->remove($ProductCategory);
808
            $this->entityManager->flush();
809
        }
810 8
811 8
        if (isset($row[$headerByKey['product_category']]) && StringUtil::isNotBlank($row[$headerByKey['product_category']])) {
812 1
            // カテゴリの登録
813 1
            $categories = explode(',', $row[$headerByKey['product_category']]);
814
            $sortNo = 1;
815
            $categoriesIdList = [];
816 8
            foreach ($categories as $category) {
817
                $line = $data->key() + 1;
818 4
                if (preg_match('/^\d+$/', $category)) {
819 4
                    $Category = $this->categoryRepository->find($category);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $Category is correct as $this->categoryRepository->find($category) (which targets Doctrine\ORM\EntityRepository::find()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
820 4
                    if (!$Category) {
821 4
                        $message = trans('admin.common.csv_invalid_not_found_target', [
822 4
                            '%line%' => $line,
823
                            '%name%' => $headerByKey['product_category'],
824 4
                            '%target_name%' => $category,
825 4
                        ]);
826
                        $this->addErrors($message);
827 4
                    } else {
828 4 View Code Duplication
                        foreach ($Category->getPath() as $ParentCategory) {
829
                            if (!isset($categoriesIdList[$ParentCategory->getId()])) {
830 4
                                $ProductCategory = $this->makeProductCategory($Product, $ParentCategory, $sortNo);
831
                                $this->entityManager->persist($ProductCategory);
832 4
                                $sortNo++;
833
834
                                $Product->addProductCategory($ProductCategory);
835 4
                                $categoriesIdList[$ParentCategory->getId()] = true;
836
                            }
837
                        }
838
                        if (!isset($categoriesIdList[$Category->getId()])) {
839
                            $ProductCategory = $this->makeProductCategory($Product, $Category, $sortNo);
840
                            $sortNo++;
841 4
                            $this->entityManager->persist($ProductCategory);
842
                            $Product->addProductCategory($ProductCategory);
843
                            $categoriesIdList[$Category->getId()] = true;
844
                        }
845
                    }
846 View Code Duplication
                } else {
847
                    $message = trans('admin.common.csv_invalid_not_found_target', [
848
                        '%line%' => $line,
849
                        '%name%' => $headerByKey['product_category'],
850
                        '%target_name%' => $category,
851
                    ]);
852
                    $this->addErrors($message);
853
                }
854
            }
855
        }
856
    }
857
858
    /**
859 8
     * タグの登録
860
     *
861
     * @param array $row
862 8
     * @param Product $Product
863 8
     * @param CsvImportService $data
864 8
     */
865
    protected function createProductTag($row, Product $Product, $data, $headerByKey)
866 8
    {
867 8
        // タグの削除
868 8
        $ProductTags = $Product->getProductTag();
869 8
        foreach ($ProductTags as $ProductTag) {
870 8
            $Product->removeProductTag($ProductTag);
871
            $this->entityManager->remove($ProductTag);
872
        }
873
874 8
        if (isset($row[$headerByKey['product_tag']]) && StringUtil::isNotBlank($row[$headerByKey['product_tag']])) {
875
            // タグの登録
876
            $tags = explode(',', $row[$headerByKey['product_tag']]);
877
            foreach ($tags as $tag_id) {
878 8
                $Tag = null;
879
                if (preg_match('/^\d+$/', $tag_id)) {
880
                    $Tag = $this->tagRepository->find($tag_id);
881
882
                    if ($Tag) {
883
                        $ProductTags = new ProductTag();
884
                        $ProductTags
885 8
                            ->setProduct($Product)
886 8
                            ->setTag($Tag);
887
888 8
                        $Product->addProductTag($ProductTags);
889 3
890 3
                        $this->entityManager->persist($ProductTags);
891 3
                    }
892
                }
893 View Code Duplication
                if (!$Tag) {
894
                    $message = trans('admin.common.csv_invalid_not_found_target', [
895 3
                        '%line%' => $data->key() + 1,
896
                        '%name%' => $headerByKey['product_tag'],
897
                        '%target_name%' => $tag_id,
898
                    ]);
899
                    $this->addErrors($message);
900
                }
901
            }
902
        }
903 8
    }
904 3
905
    /**
906 5
     * 商品規格分類1、商品規格分類2がnullとなる商品規格情報を作成
907
     *
908
     * @param $row
909 8
     * @param Product $Product
910
     * @param CsvImportService $data
911
     * @param $headerByKey
912
     * @param null $ClassCategory1
913 8
     * @param null $ClassCategory2
914 4
     *
915
     * @return ProductClass
916 4
     */
917 4
    protected function createProductClass($row, Product $Product, $data, $headerByKey, $ClassCategory1 = null, $ClassCategory2 = null)
918 4
    {
919 4
        // 規格分類1、規格分類2がnullとなる商品を作成
920
        $ProductClass = new ProductClass();
921
        $ProductClass->setProduct($Product);
922 4
        $ProductClass->setVisible(true);
923
924
        $line = $data->key() + 1;
925
        if (isset($row[$headerByKey['sale_type']]) && StringUtil::isNotBlank($row[$headerByKey['sale_type']])) {
926 4
            if (preg_match('/^\d+$/', $row[$headerByKey['sale_type']])) {
927
                $SaleType = $this->saleTypeRepository->find($row[$headerByKey['sale_type']]);
928 4
                if (!$SaleType) {
929 4
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
930 4
                    $this->addErrors($message);
931
                } else {
932
                    $ProductClass->setSaleType($SaleType);
933
                }
934
            } else {
935
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
936
                $this->addErrors($message);
937 8
            }
938
        } else {
939
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
940
            $this->addErrors($message);
941
        }
942
943
        $ProductClass->setClassCategory1($ClassCategory1);
944
        $ProductClass->setClassCategory2($ClassCategory2);
945
946
        if (isset($row[$headerByKey['delivery_date']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_date']])) {
947 8
            if (preg_match('/^\d+$/', $row[$headerByKey['delivery_date']])) {
948 3
                $DeliveryDuration = $this->deliveryDurationRepository->find($row[$headerByKey['delivery_date']]);
949 3
                if (!$DeliveryDuration) {
950 3
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
951
                    $this->addErrors($message);
952
                } else {
953
                    $ProductClass->setDeliveryDuration($DeliveryDuration);
954
                }
955
            } else {
956
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
957 8
                $this->addErrors($message);
958 8
            }
959 8
        }
960 8
961 View Code Duplication
        if (isset($row[$headerByKey['product_code']]) && StringUtil::isNotBlank($row[$headerByKey['product_code']])) {
962
            $ProductClass->setCode(StringUtil::trimAll($row[$headerByKey['product_code']]));
963 8
        } else {
964
            $ProductClass->setCode(null);
965
        }
966
967 View Code Duplication
        if (!isset($row[$headerByKey['stock_unlimited']])
968
            || StringUtil::isBlank($row[$headerByKey['stock_unlimited']])
969
            || $row[$headerByKey['stock_unlimited']] == (string) Constant::DISABLED
970 8
        ) {
971 3
            $ProductClass->setStockUnlimited(false);
972 3
            // 在庫数が設定されていなければエラー
973 3
            if (isset($row[$headerByKey['stock']]) && StringUtil::isNotBlank($row[$headerByKey['stock']])) {
974
                $stock = str_replace(',', '', $row[$headerByKey['stock']]);
975
                if (preg_match('/^\d+$/', $stock) && $stock >= 0) {
976
                    $ProductClass->setStock($stock);
977
                } else {
978
                    $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
979
                    $this->addErrors($message);
980 8
                }
981 8
            } else {
982 8
                $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
983 8
                $this->addErrors($message);
984
            }
985 8
        } elseif ($row[$headerByKey['stock_unlimited']] == (string) Constant::ENABLED) {
986 4
            $ProductClass->setStockUnlimited(true);
987
            $ProductClass->setStock(null);
988
        } else {
989 4
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock_unlimited']]);
990
            $this->addErrors($message);
991
        }
992 8
993 8
        if (isset($row[$headerByKey['sale_limit']]) && StringUtil::isNotBlank($row[$headerByKey['sale_limit']])) {
994
            $saleLimit = str_replace(',', '', $row[$headerByKey['sale_limit']]);
995 8
            if (preg_match('/^\d+$/', $saleLimit) && $saleLimit >= 0) {
996
                $ProductClass->setSaleLimit($saleLimit);
997
            } else {
998
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['sale_limit']]);
999
                $this->addErrors($message);
1000
            }
1001
        }
1002
1003
        if (isset($row[$headerByKey['price01']]) && StringUtil::isNotBlank($row[$headerByKey['price01']])) {
1004
            $price01 = str_replace(',', '', $row[$headerByKey['price01']]);
1005
            $errors = $this->validator->validate($price01, new GreaterThanOrEqual(['value' => 0]));
1006
            if ($errors->count() === 0) {
1007
                $ProductClass->setPrice01($price01);
1008 1
            } else {
1009
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price01']]);
1010 1
                $this->addErrors($message);
1011
            }
1012 1
        }
1013 1
1014
        if (isset($row[$headerByKey['price02']]) && StringUtil::isNotBlank($row[$headerByKey['price02']])) {
1015
            $price02 = str_replace(',', '', $row[$headerByKey['price02']]);
1016
            $errors = $this->validator->validate($price02, new GreaterThanOrEqual(['value' => 0]));
1017 1
            if ($errors->count() === 0) {
1018 1
                $ProductClass->setPrice02($price02);
1019 1
            } else {
1020
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1021
                $this->addErrors($message);
1022
            }
1023 1
        } else {
1024
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1025
            $this->addErrors($message);
1026
        }
1027
1028
        if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
1029
            $delivery_fee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
1030
            $errors = $this->validator->validate($delivery_fee, new GreaterThanOrEqual(['value' => 0]));
1031
            if ($errors->count() === 0) {
1032 1
                $ProductClass->setDeliveryFee($delivery_fee);
1033 1
            } else {
1034 1
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
1035 1
                $this->addErrors($message);
1036
            }
1037
        }
1038
1039 1
        $Product->addProductClass($ProductClass);
1040
        $ProductStock = new ProductStock();
1041
        $ProductClass->setProductStock($ProductStock);
1042
        $ProductStock->setProductClass($ProductClass);
1043
1044
        if (!$ProductClass->isStockUnlimited()) {
1045
            $ProductStock->setStock($ProductClass->getStock());
1046
        } else {
1047 1
            // 在庫無制限時はnullを設定
1048 1
            $ProductStock->setStock(null);
1049 1
        }
1050 1
1051
        $this->entityManager->persist($ProductClass);
1052
        $this->entityManager->persist($ProductStock);
1053
1054 1
        return $ProductClass;
1055
    }
1056
1057
    /**
1058
     * 商品規格情報を更新
1059
     *
1060
     * @param $row
1061
     * @param Product $Product
1062 1
     * @param ProductClass $ProductClass
1063
     * @param CsvImportService $data
1064
     *
1065
     * @return ProductClass
1066
     */
1067
    protected function updateProductClass($row, Product $Product, ProductClass $ProductClass, $data, $headerByKey)
1068
    {
1069
        $ProductClass->setProduct($Product);
1070
1071
        $line = $data->key() + 1;
1072
        if ($row[$headerByKey['sale_type']] == '') {
1073
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1074
            $this->addErrors($message);
1075
        } else {
1076
            if (preg_match('/^\d+$/', $row[$headerByKey['sale_type']])) {
1077 1
                $SaleType = $this->saleTypeRepository->find($row[$headerByKey['sale_type']]);
1078 1
                if (!$SaleType) {
1079
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1080
                    $this->addErrors($message);
1081
                } else {
1082
                    $ProductClass->setSaleType($SaleType);
1083 1
                }
1084
            } else {
1085
                $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1086
                $this->addErrors($message);
1087 1
            }
1088 1
        }
1089
1090 1
        // 規格分類1、2をそれぞれセットし作成
1091 View Code Duplication
        if ($row[$headerByKey['class_category1']] != '') {
1092
            if (preg_match('/^\d+$/', $row[$headerByKey['class_category1']])) {
1093
                $ClassCategory = $this->classCategoryRepository->find($row[$headerByKey['class_category1']]);
1094 1
                if (!$ClassCategory) {
1095 1
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
1096 1
                    $this->addErrors($message);
1097
                } else {
1098
                    $ProductClass->setClassCategory1($ClassCategory);
1099 1
                }
1100
            } else {
1101
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
1102 1
                $this->addErrors($message);
1103 1
            }
1104 1
        }
1105
1106 View Code Duplication
        if ($row[$headerByKey['class_category2']] != '') {
1107
            if (preg_match('/^\d+$/', $row[$headerByKey['class_category2']])) {
1108
                $ClassCategory = $this->classCategoryRepository->find($row[$headerByKey['class_category2']]);
1109
                if (!$ClassCategory) {
1110
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
1111 1
                    $this->addErrors($message);
1112 1
                } else {
1113 1
                    $ProductClass->setClassCategory2($ClassCategory);
1114 1
                }
1115
            } else {
1116
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
1117
                $this->addErrors($message);
1118
            }
1119
        }
1120
1121 1 View Code Duplication
        if ($row[$headerByKey['delivery_date']] != '') {
1122 1
            if (preg_match('/^\d+$/', $row[$headerByKey['delivery_date']])) {
1123 1
                $DeliveryDuration = $this->deliveryDurationRepository->find($row[$headerByKey['delivery_date']]);
1124 1
                if (!$DeliveryDuration) {
1125
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
1126
                    $this->addErrors($message);
1127
                } else {
1128
                    $ProductClass->setDeliveryDuration($DeliveryDuration);
1129
                }
1130
            } else {
1131 1
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
1132
                $this->addErrors($message);
1133
            }
1134
        }
1135 1
1136 1
        if (StringUtil::isNotBlank($row[$headerByKey['product_code']])) {
1137 1
            $ProductClass->setCode(StringUtil::trimAll($row[$headerByKey['product_code']]));
1138
        } else {
1139
            $ProductClass->setCode(null);
1140
        }
1141
1142 View Code Duplication
        if (!isset($row[$headerByKey['stock_unlimited']])
1143
            || StringUtil::isBlank($row[$headerByKey['stock_unlimited']])
1144 1
            || $row[$headerByKey['stock_unlimited']] == (string) Constant::DISABLED
1145
        ) {
1146 1
            $ProductClass->setStockUnlimited(false);
1147 1
            // 在庫数が設定されていなければエラー
1148
            if ($row[$headerByKey['stock']] == '') {
1149
                $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
1150 1
                $this->addErrors($message);
1151
            } else {
1152
                $stock = str_replace(',', '', $row[$headerByKey['stock']]);
1153 1
                if (preg_match('/^\d+$/', $stock) && $stock >= 0) {
1154
                    $ProductClass->setStock($row[$headerByKey['stock']]);
1155
                } else {
1156
                    $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
1157
                    $this->addErrors($message);
1158
                }
1159 7
            }
1160
        } elseif ($row[$headerByKey['stock_unlimited']] == (string) Constant::ENABLED) {
1161 7
            $ProductClass->setStockUnlimited(true);
1162 7
            $ProductClass->setStock(null);
1163
        } else {
1164
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock_unlimited']]);
1165
            $this->addErrors($message);
1166
        }
1167
1168 16
        if ($row[$headerByKey['sale_limit']] != '') {
1169
            $saleLimit = str_replace(',', '', $row[$headerByKey['sale_limit']]);
1170 16
            if (preg_match('/^\d+$/', $saleLimit) && $saleLimit >= 0) {
1171
                $ProductClass->setSaleLimit($saleLimit);
1172
            } else {
1173
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['sale_limit']]);
1174
                $this->addErrors($message);
1175
            }
1176 16
        }
1177
1178 16
        if ($row[$headerByKey['price01']] != '') {
1179
            $price01 = str_replace(',', '', $row[$headerByKey['price01']]);
1180
            $errors = $this->validator->validate($price01, new GreaterThanOrEqual(['value' => 0]));
1181
            if ($errors->count() === 0) {
1182
                $ProductClass->setPrice01($price01);
1183
            } else {
1184
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price01']]);
1185
                $this->addErrors($message);
1186 10
            }
1187
        }
1188
1189 10
        if ($row[$headerByKey['price02']] == '') {
1190
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1191
            $this->addErrors($message);
1192
        } else {
1193
            $price02 = str_replace(',', '', $row[$headerByKey['price02']]);
1194 10
            $errors = $this->validator->validate($price02, new GreaterThanOrEqual(['value' => 0]));
1195
            if ($errors->count() === 0) {
1196
                $ProductClass->setPrice02($price02);
1197
            } else {
1198
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1199 10
                $this->addErrors($message);
1200
            }
1201
        }
1202
1203
        $ProductStock = $ProductClass->getProductStock();
1204 10
1205
        if (!$ProductClass->isStockUnlimited()) {
1206
            $ProductStock->setStock($ProductClass->getStock());
1207
        } else {
1208
            // 在庫無制限時はnullを設定
1209 10
            $ProductStock->setStock(null);
1210
        }
1211
1212
        return $ProductClass;
1213
    }
1214 10
1215
    /**
1216
     * 登録、更新時のエラー画面表示
1217
     */
1218
    protected function addErrors($message)
1219 10
    {
1220
        $this->errors[] = $message;
1221
    }
1222
1223
    /**
1224 10
     * @return array
1225
     */
1226
    protected function getErrors()
1227
    {
1228
        return $this->errors;
1229 10
    }
1230
1231
    /**
1232
     * @return boolean
1233
     */
1234 10
    protected function hasErrors()
1235
    {
1236
        return count($this->getErrors()) > 0;
1237
    }
1238
1239 10
    /**
1240
     * 商品登録CSVヘッダー定義
1241
     *
1242
     * @return array
1243
     */
1244 10
    private function getProductCsvHeader()
1245
    {
1246
        return [
1247
            trans('admin.product.product_csv.product_id_col') => [
1248
                'id' => 'id',
1249 10
                'description' => 'admin.product.product_csv.product_id_description',
1250
                'required' => false,
1251
            ],
1252
            trans('admin.product.product_csv.display_status_col') => [
1253
                'id' => 'status',
1254 10
                'description' => 'admin.product.product_csv.display_status_description',
1255
                'required' => true,
1256
            ],
1257
            trans('admin.product.product_csv.product_name_col') => [
1258
                'id' => 'name',
1259 10
                'description' => 'admin.product.product_csv.product_name_description',
1260
                'required' => true,
1261
            ],
1262
            trans('admin.product.product_csv.shop_memo_col') => [
1263
                'id' => 'note',
1264 10
                'description' => 'admin.product.product_csv.shop_memo_description',
1265
                'required' => false,
1266
            ],
1267
            trans('admin.product.product_csv.description_list_col') => [
1268
                'id' => 'description_list',
1269 10
                'description' => 'admin.product.product_csv.description_list_description',
1270
                'required' => false,
1271
            ],
1272
            trans('admin.product.product_csv.description_detail_col') => [
1273
                'id' => 'description_detail',
1274 10
                'description' => 'admin.product.product_csv.description_detail_description',
1275
                'required' => false,
1276
            ],
1277
            trans('admin.product.product_csv.keyword_col') => [
1278
                'id' => 'search_word',
1279 10
                'description' => 'admin.product.product_csv.keyword_description',
1280
                'required' => false,
1281
            ],
1282
            trans('admin.product.product_csv.free_area_col') => [
1283
                'id' => 'free_area',
1284 10
                'description' => 'admin.product.product_csv.free_area_description',
1285
                'required' => false,
1286
            ],
1287
            trans('admin.product.product_csv.delete_flag_col') => [
1288
                'id' => 'product_del_flg',
1289 10
                'description' => 'admin.product.product_csv.delete_flag_description',
1290
                'required' => false,
1291
            ],
1292
            trans('admin.product.product_csv.product_image_col') => [
1293
                'id' => 'product_image',
1294 10
                'description' => 'admin.product.product_csv.product_image_description',
1295
                'required' => false,
1296
            ],
1297
            trans('admin.product.product_csv.category_col') => [
1298
                'id' => 'product_category',
1299 10
                'description' => 'admin.product.product_csv.category_description',
1300
                'required' => false,
1301
            ],
1302
            trans('admin.product.product_csv.tag_col') => [
1303
                'id' => 'product_tag',
1304
                'description' => 'admin.product.product_csv.tag_description',
1305
                'required' => false,
1306
            ],
1307
            trans('admin.product.product_csv.sale_type_col') => [
1308
                'id' => 'sale_type',
1309
                'description' => 'admin.product.product_csv.sale_type_description',
1310 6
                'required' => true,
1311
            ],
1312
            trans('admin.product.product_csv.class_category1_col') => [
1313 6
                'id' => 'class_category1',
1314
                'description' => 'admin.product.product_csv.class_category1_description',
1315
                'required' => false,
1316
            ],
1317
            trans('admin.product.product_csv.class_category2_col') => [
1318 6
                'id' => 'class_category2',
1319
                'description' => 'admin.product.product_csv.class_category2_description',
1320
                'required' => false,
1321
            ],
1322
            trans('admin.product.product_csv.delivery_duration_col') => [
1323 6
                'id' => 'delivery_date',
1324
                'description' => 'admin.product.product_csv.delivery_duration_description',
1325
                'required' => false,
1326
            ],
1327
            trans('admin.product.product_csv.product_code_col') => [
1328 6
                'id' => 'product_code',
1329
                'description' => 'admin.product.product_csv.product_code_description',
1330
                'required' => false,
1331
            ],
1332
            trans('admin.product.product_csv.stock_col') => [
1333
                'id' => 'stock',
1334
                'description' => 'admin.product.product_csv.stock_description',
1335
                'required' => false,
1336
            ],
1337
            trans('admin.product.product_csv.stock_unlimited_col') => [
1338
                'id' => 'stock_unlimited',
1339
                'description' => 'admin.product.product_csv.stock_unlimited_description',
1340
                'required' => false,
1341
            ],
1342
            trans('admin.product.product_csv.sale_limit_col') => [
1343
                'id' => 'sale_limit',
1344
                'description' => 'admin.product.product_csv.sale_limit_description',
1345 4
                'required' => false,
1346
            ],
1347 4
            trans('admin.product.product_csv.normal_price_col') => [
1348 4
                'id' => 'price01',
1349 4
                'description' => 'admin.product.product_csv.normal_price_description',
1350 4
                'required' => false,
1351 4
            ],
1352 4
            trans('admin.product.product_csv.sale_price_col') => [
1353
                'id' => 'price02',
1354 4
                'description' => 'admin.product.product_csv.sale_price_description',
1355
                'required' => true,
1356
            ],
1357
            trans('admin.product.product_csv.delivery_fee_col') => [
1358
                'id' => 'delivery_fee',
1359
                'description' => 'admin.product.product_csv.delivery_fee_description',
1360
                'required' => false,
1361
            ],
1362
        ];
1363
    }
1364
1365
    /**
1366
     * カテゴリCSVヘッダー定義
1367
     */
1368
    private function getCategoryCsvHeader()
1369
    {
1370
        return [
1371
            trans('admin.product.category_csv.category_id_col') => [
1372
                'id' => 'id',
1373
                'description' => 'admin.product.category_csv.category_id_description',
1374
                'required' => false,
1375
            ],
1376
            trans('admin.product.category_csv.category_name_col') => [
1377
                'id' => 'category_name',
1378
                'description' => 'admin.product.category_csv.category_name_description',
1379
                'required' => true,
1380
            ],
1381
            trans('admin.product.category_csv.parent_category_id_col') => [
1382
                'id' => 'parent_category_id',
1383
                'description' => 'admin.product.category_csv.parent_category_id_description',
1384
                'required' => false,
1385
            ],
1386
            trans('admin.product.category_csv.delete_flag_col') => [
1387
                'id' => 'category_del_flg',
1388
                'description' => 'admin.product.category_csv.delete_flag_description',
1389
                'required' => false,
1390
            ],
1391
        ];
1392
    }
1393
1394
    /**
1395
     * ProductCategory作成
1396
     *
1397
     * @param \Eccube\Entity\Product $Product
1398
     * @param \Eccube\Entity\Category $Category
1399
     * @param int $sortNo
1400
     *
1401
     * @return ProductCategory
1402
     */
1403 View Code Duplication
    private function makeProductCategory($Product, $Category, $sortNo)
0 ignored issues
show
Unused Code introduced by
The parameter $sortNo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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...
1404
    {
1405
        $ProductCategory = new ProductCategory();
1406
        $ProductCategory->setProduct($Product);
1407
        $ProductCategory->setProductId($Product->getId());
1408
        $ProductCategory->setCategory($Category);
1409
        $ProductCategory->setCategoryId($Category->getId());
1410
1411
        return $ProductCategory;
1412
    }
1413
}
1414