Completed
Push — 4.0 ( 51ae79...7b064c )
by Kiyotaka
01:07 queued 19s
created

CsvImportController::getCsvTempFiles()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 14
ccs 0
cts 0
cp 0
crap 6
rs 9.7998
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.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\ProductImageRepository;
35
use Eccube\Repository\ProductRepository;
36
use Eccube\Repository\TagRepository;
37
use Eccube\Repository\TaxRuleRepository;
38
use Eccube\Service\CsvImportService;
39
use Eccube\Util\CacheUtil;
40
use Eccube\Util\StringUtil;
41
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
42
use Symfony\Component\Filesystem\Filesystem;
43
use Symfony\Component\Finder\Finder;
44
use Symfony\Component\Form\FormInterface;
45
use Symfony\Component\HttpFoundation\File\UploadedFile;
46
use Symfony\Component\HttpFoundation\Request;
47
use Symfony\Component\HttpFoundation\StreamedResponse;
48
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
49
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
50
use Symfony\Component\Routing\Annotation\Route;
51
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
52
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
53
use Symfony\Component\Validator\Validator\ValidatorInterface;
54
55
class CsvImportController extends AbstractCsvImportController
56
{
57
    /**
58
     * @var DeliveryDurationRepository
59
     */
60
    protected $deliveryDurationRepository;
61
62
    /**
63
     * @var SaleTypeRepository
64
     */
65
    protected $saleTypeRepository;
66
67
    /**
68
     * @var TagRepository
69
     */
70
    protected $tagRepository;
71
72
    /**
73
     * @var CategoryRepository
74
     */
75
    protected $categoryRepository;
76
77
    /**
78
     * @var ClassCategoryRepository
79
     */
80
    protected $classCategoryRepository;
81
82
    /**
83
     * @var ProductImageRepository
84
     */
85
    protected $productImageRepository;
86
87
    /**
88
     * @var ProductStatusRepository
89
     */
90
    protected $productStatusRepository;
91
92
    /**
93
     * @var ProductRepository
94
     */
95
    protected $productRepository;
96
97
    /**
98
     * @var TaxRuleRepository
99
     */
100
    private $taxRuleRepository;
101 16
102
    /**
103 16
     * @var BaseInfo
104 16
     */
105 16
    protected $BaseInfo;
106 16
107 16
    /**
108 16
     * @var ValidatorInterface
109 16
     */
110 16
    protected $validator;
111
112
    private $errors = [];
113
114
    protected $isSplitCsv = false;
115
116
    protected $csvFileNo = 1;
117
118
    protected $currentLineNo = 1;
119 10
120
    /**
121 10
     * CsvImportController constructor.
122 10
     *
123 10
     * @param DeliveryDurationRepository $deliveryDurationRepository
124 10
     * @param SaleTypeRepository $saleTypeRepository
125 10
     * @param TagRepository $tagRepository
126 10
     * @param CategoryRepository $categoryRepository
127 10
     * @param ClassCategoryRepository $classCategoryRepository
128 10
     * @param ProductImageRepository $productImageRepository
129 10
     * @param ProductStatusRepository $productStatusRepository
130 10
     * @param ProductRepository $productRepository
131
     * @param TaxRuleRepository $taxRuleRepository
132
     * @param BaseInfoRepository $baseInfoRepository
133
     * @param ValidatorInterface $validator
134
     * @throws \Exception
135 10
     */
136 10 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...
137 10
        DeliveryDurationRepository $deliveryDurationRepository,
138 10
        SaleTypeRepository $saleTypeRepository,
139 10
        TagRepository $tagRepository,
140 10
        CategoryRepository $categoryRepository,
141
        ClassCategoryRepository $classCategoryRepository,
142 10
        ProductImageRepository $productImageRepository,
143
        ProductStatusRepository $productStatusRepository,
144 10
        ProductRepository $productRepository,
145
        TaxRuleRepository $taxRuleRepository,
146
        BaseInfoRepository $baseInfoRepository,
147
        ValidatorInterface $validator
148
    ) {
149
        $this->deliveryDurationRepository = $deliveryDurationRepository;
150 10
        $this->saleTypeRepository = $saleTypeRepository;
151
        $this->tagRepository = $tagRepository;
152 10
        $this->categoryRepository = $categoryRepository;
153
        $this->classCategoryRepository = $classCategoryRepository;
154
        $this->productImageRepository = $productImageRepository;
155
        $this->productStatusRepository = $productStatusRepository;
156
        $this->productRepository = $productRepository;
157
        $this->taxRuleRepository = $taxRuleRepository;
158 10
        $this->BaseInfo = $baseInfoRepository->get();
159 10
        $this->validator = $validator;
160
    }
161 10
162 10
    /**
163
     * 商品登録CSVアップロード
164 10
     *
165 10
     * @Route("/%eccube_admin_route%/product/product_csv_upload", name="admin_product_csv_import")
166 10
     * @Template("@admin/Product/csv_product.twig")
167
     *
168
     * @return array
169
     *
170
     * @throws \Doctrine\DBAL\ConnectionException
171
     * @throws \Doctrine\ORM\NoResultException
172
     */
173 10
    public function csvProduct(Request $request, CacheUtil $cacheUtil)
174 7
    {
175 7
        $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm();
176
        $headers = $this->getProductCsvHeader();
177 4
        if ('POST' === $request->getMethod()) {
178 3
            $form->handleRequest($request);
179 3
            if ($form->isValid()) {
180 1
                $this->isSplitCsv = $form['is_split_csv']->getData();
181 1
                $this->csvFileNo = $form['csv_file_no']->getData();
182
183 3
                $formFile = $form['import_file']->getData();
184
                if (!empty($formFile)) {
185
                    log_info('商品CSV登録開始');
186 1
                    $data = $this->getImportData($formFile);
187 1 View Code Duplication
                    if ($data === false) {
188
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
189 1
190
                        return $this->renderWithError($form, $headers, false);
191
                    }
192
                    $getId = function ($item) {
193 8
                        return $item['id'];
194 1
                    };
195 1
                    $requireHeader = array_keys(array_map($getId, array_filter($headers, function ($value) {
196
                        return $value['required'];
197 7
                    })));
198 6
199 6
                    $columnHeaders = $data->getColumnHeaders();
200 1
201 1 View Code Duplication
                    if (count(array_diff($requireHeader, $columnHeaders)) > 0) {
202
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
203 6
204
                        return $this->renderWithError($form, $headers, false);
205
                    }
206 1
207 1
                    $size = count($data);
208
209 View Code Duplication
                    if ($size < 1) {
210
                        $this->addErrors(trans('admin.common.csv_invalid_no_data'));
211 8
212
                        return $this->renderWithError($form, $headers, false);
213
                    }
214
215
                    $headerSize = count($columnHeaders);
216
                    $headerByKey = array_flip(array_map($getId, $headers));
217 8
                    $deleteImages = [];
218
219
                    $this->entityManager->getConfiguration()->setSQLLogger(null);
220 8
                    $this->entityManager->getConnection()->beginTransaction();
221 3
                    // CSVファイルの登録処理
222
                    foreach ($data as $row) {
223 5
                        $line = $this->convertLineNo($data->key() + 1);
224
                        $this->currentLineNo = $line;
225
                        if ($headerSize != count($row)) {
226 8
                            $message = trans('admin.common.csv_invalid_format_line', ['%line%' => $line]);
227 4
                            $this->addErrors($message);
228
229 5
                            return $this->renderWithError($form, $headers);
230
                        }
231
232 8
                        if (!isset($row[$headerByKey['id']]) || StringUtil::isBlank($row[$headerByKey['id']])) {
233 4
                            $Product = new Product();
234
                            $this->entityManager->persist($Product);
235 4
                        } else {
236
                            if (preg_match('/^\d+$/', $row[$headerByKey['id']])) {
237
                                $Product = $this->productRepository->find($row[$headerByKey['id']]);
238 8
                                if (!$Product) {
239 3
                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['id']]);
240
                                    $this->addErrors($message);
241 5
242
                                    return $this->renderWithError($form, $headers);
243
                                }
244 8
                            } else {
245 3
                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['id']]);
246
                                $this->addErrors($message);
247 5
248
                                return $this->renderWithError($form, $headers);
249
                            }
250
251 8
                            if (isset($row[$headerByKey['product_del_flg']])) {
252
                                if (StringUtil::isNotBlank($row[$headerByKey['product_del_flg']]) && $row[$headerByKey['product_del_flg']] == (string) Constant::ENABLED) {
253 8
                                    // 商品を物理削除
254
                                    $deleteImages[] = $Product->getProductImage();
255
256 8
                                    try {
257
                                        $this->productRepository->delete($Product);
258
                                        $this->entityManager->flush();
259 8
260
                                        continue;
261
                                    } catch (ForeignKeyConstraintViolationException $e) {
262
                                        $message = trans('admin.common.csv_invalid_foreign_key', ['%line%' => $line, '%name%' => $Product->getName()]);
263 8
                                        $this->addErrors($message);
264 8
265
                                        return $this->renderWithError($form, $headers);
266 7
                                    }
267 7
                                }
268
                            }
269
                        }
270
271
                        if (StringUtil::isBlank($row[$headerByKey['status']])) {
272
                            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['status']]);
273
                            $this->addErrors($message);
274
                        } else {
275
                            if (preg_match('/^\d+$/', $row[$headerByKey['status']])) {
276
                                $ProductStatus = $this->productStatusRepository->find($row[$headerByKey['status']]);
277
                                if (!$ProductStatus) {
278
                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['status']]);
279 7
                                    $this->addErrors($message);
280 2
                                } else {
281
                                    $Product->setStatus($ProductStatus);
282
                                }
283
                            } else {
284
                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['status']]);
285
                                $this->addErrors($message);
286
                            }
287
                        }
288
289
                        if (StringUtil::isBlank($row[$headerByKey['name']])) {
290 2
                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['name']]);
291 2
                            $this->addErrors($message);
292
293
                            return $this->renderWithError($form, $headers);
294 2
                        } else {
295
                            $Product->setName(StringUtil::trimAll($row[$headerByKey['name']]));
296
                        }
297 2
298 2 View Code Duplication
                        if (isset($row[$headerByKey['note']])) {
299 2
                            if (StringUtil::isNotBlank($row[$headerByKey['note']])) {
300 2
                                $Product->setNote(StringUtil::trimAll($row[$headerByKey['note']]));
301
                            } else {
302
                                $Product->setNote(null);
303
                            }
304 2
                        }
305
306 View Code Duplication
                        if (isset($row[$headerByKey['description_list']])) {
307
                            if (StringUtil::isNotBlank($row[$headerByKey['description_list']])) {
308
                                $Product->setDescriptionList(StringUtil::trimAll($row[$headerByKey['description_list']]));
309
                            } else {
310
                                $Product->setDescriptionList(null);
311 2
                            }
312 2
                        }
313 2
314 2
                        if (isset($row[$headerByKey['description_detail']])) {
315
                            if (StringUtil::isNotBlank($row[$headerByKey['description_detail']])) {
316
                                if (mb_strlen($row[$headerByKey['description_detail']]) > $this->eccubeConfig['eccube_ltext_len']) {
317
                                    $message = trans('admin.common.csv_invalid_description_detail_upper_limit', [
318 2
                                        '%line%' => $line,
319 2
                                        '%name%' => $headerByKey['description_detail'],
320
                                        '%max%' => $this->eccubeConfig['eccube_ltext_len'],
321
                                    ]);
322
                                    $this->addErrors($message);
323
324 2
                                    return $this->renderWithError($form, $headers);
325
                                } else {
326
                                    $Product->setDescriptionDetail(StringUtil::trimAll($row[$headerByKey['description_detail']]));
327
                                }
328
                            } else {
329
                                $Product->setDescriptionDetail(null);
330
                            }
331
                        }
332 2
333 2 View Code Duplication
                        if (isset($row[$headerByKey['search_word']])) {
334
                            if (StringUtil::isNotBlank($row[$headerByKey['search_word']])) {
335 2
                                $Product->setSearchWord(StringUtil::trimAll($row[$headerByKey['search_word']]));
336 2
                            } else {
337
                                $Product->setSearchWord(null);
338
                            }
339 5
                        }
340
341 7 View Code Duplication
                        if (isset($row[$headerByKey['free_area']])) {
342
                            if (StringUtil::isNotBlank($row[$headerByKey['free_area']])) {
343
                                $Product->setFreeArea(StringUtil::trimAll($row[$headerByKey['free_area']]));
344
                            } else {
345
                                $Product->setFreeArea(null);
346 2
                            }
347 2
                        }
348 2
349
                        // 商品画像登録
350 2
                        $this->createProductImage($row, $Product, $data, $headerByKey);
351 2
352 2
                        $this->entityManager->flush();
353
354
                        // 商品カテゴリ登録
355 2
                        $this->createProductCategory($row, $Product, $data, $headerByKey);
356 2
357
                        //タグ登録
358 1
                        $this->createProductTag($row, $Product, $data, $headerByKey);
359
360 1
                        // 商品規格が存在しなければ新規登録
361
                        /** @var ProductClass[] $ProductClasses */
362
                        $ProductClasses = $Product->getProductClasses();
363
                        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...
364
                            // 規格分類1(ID)がセットされていると規格なし商品、規格あり商品を作成
365
                            $ProductClassOrg = $this->createProductClass($row, $Product, $data, $headerByKey);
366 View Code Duplication
                            if ($this->BaseInfo->isOptionProductDeliveryFee()) {
367
                                if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
368
                                    $deliveryFee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
369
                                    $errors = $this->validator->validate($deliveryFee, new GreaterThanOrEqual(['value' => 0]));
370
                                    if ($errors->count() === 0) {
371
                                        $ProductClassOrg->setDeliveryFee($deliveryFee);
372 1
                                    } else {
373 2
                                        $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
374
                                        $this->addErrors($message);
375
                                    }
376
                                }
377
                            }
378 2
379 1
                            // 商品別税率機能が有効の場合に税率を更新
380 1 View Code Duplication
                            if ($this->BaseInfo->isOptionProductTaxRule()) {
381 1
                                if (isset($row[$headerByKey['tax_rate']]) && StringUtil::isNotBlank($row[$headerByKey['tax_rate']])) {
382
                                    $taxRate = $row[$headerByKey['tax_rate']];
383
                                    $errors = $this->validator->validate($taxRate, new GreaterThanOrEqual(['value' => 0]));
384 1
                                    if ($errors->count() === 0) {
385
                                        if ($ProductClassOrg->getTaxRule()) {
386
                                            // 商品別税率の設定があれば税率を更新
387 1
                                            $ProductClassOrg->getTaxRule()->setTaxRate($taxRate);
388 1
                                        } else {
389
                                            // 商品別税率の設定がなければ新規作成
390
                                            $TaxRule = $this->taxRuleRepository->newTaxRule();
391
                                            $TaxRule->setTaxRate($taxRate);
392
                                            $TaxRule->setApplyDate(new \DateTime());
393
                                            $TaxRule->setProduct($Product);
394
                                            $TaxRule->setProductClass($ProductClassOrg);
395
                                            $ProductClassOrg->setTaxRule($TaxRule);
396
                                        }
397
                                    } else {
398 1
                                        $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['tax_rate']]);
399 1
                                        $this->addErrors($message);
400 1
                                    }
401 1
                                } else {
402
                                    // 税率の入力がなければ税率の設定を削除
403 1
                                    if ($ProductClassOrg->getTaxRule()) {
404
                                        $this->taxRuleRepository->delete($ProductClassOrg->getTaxRule());
405
                                        $ProductClassOrg->setTaxRule(null);
406
                                    }
407
                                }
408
                            }
409
410 1
                            if (isset($row[$headerByKey['class_category1']]) && StringUtil::isNotBlank($row[$headerByKey['class_category1']])) {
411 1
                                if (isset($row[$headerByKey['class_category2']]) && $row[$headerByKey['class_category1']] == $row[$headerByKey['class_category2']]) {
412 1
                                    $message = trans('admin.common.csv_invalid_not_same', [
413
                                        '%line%' => $line,
414
                                        '%name1%' => $headerByKey['class_category1'],
415
                                        '%name2%' => $headerByKey['class_category2'],
416 1
                                    ]);
417 1
                                    $this->addErrors($message);
418 1
                                } else {
419
                                    // 商品規格あり
420
                                    // 規格分類あり商品を作成
421
                                    $ProductClass = clone $ProductClassOrg;
422 1
                                    $ProductStock = clone $ProductClassOrg->getProductStock();
423 1
424
                                    // 規格分類1、規格分類2がnullであるデータを非表示
425
                                    $ProductClassOrg->setVisible(false);
426
427
                                    // 規格分類1、2をそれぞれセットし作成
428
                                    $ClassCategory1 = null;
429
                                    if (preg_match('/^\d+$/', $row[$headerByKey['class_category1']])) {
430 1
                                        $ClassCategory1 = $this->classCategoryRepository->find($row[$headerByKey['class_category1']]);
431
                                        if (!$ClassCategory1) {
432
                                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
433
                                            $this->addErrors($message);
434
                                        } else {
435 1
                                            $ProductClass->setClassCategory1($ClassCategory1);
436
                                        }
437
                                    } else {
438
                                        $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
439
                                        $this->addErrors($message);
440
                                    }
441
442
                                    if (isset($row[$headerByKey['class_category2']]) && StringUtil::isNotBlank($row[$headerByKey['class_category2']])) {
443
                                        if (preg_match('/^\d+$/', $row[$headerByKey['class_category2']])) {
444 1
                                            $ClassCategory2 = $this->classCategoryRepository->find($row[$headerByKey['class_category2']]);
445 View Code Duplication
                                            if (!$ClassCategory2) {
446 1
                                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
447
                                                $this->addErrors($message);
448
                                            } else {
449
                                                if ($ClassCategory1 &&
450
                                                    ($ClassCategory1->getClassName()->getId() == $ClassCategory2->getClassName()->getId())
451
                                                ) {
452
                                                    $message = trans('admin.common.csv_invalid_not_same', ['%line%' => $line, '%name1%' => $headerByKey['class_category1'], '%name2%' => $headerByKey['class_category2']]);
453
                                                    $this->addErrors($message);
454
                                                } else {
455
                                                    $ProductClass->setClassCategory2($ClassCategory2);
456
                                                }
457 1
                                            }
458
                                        } else {
459
                                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
460
                                            $this->addErrors($message);
461 8
                                        }
462 3
                                    }
463
                                    $ProductClass->setProductStock($ProductStock);
464 5
                                    $ProductStock->setProductClass($ProductClass);
465
466 5
                                    $this->entityManager->persist($ProductClass);
467 5
                                    $this->entityManager->persist($ProductStock);
468 5
                                }
469 5
                            } else {
470 5
                                if (isset($row[$headerByKey['class_category2']]) && StringUtil::isNotBlank($row[$headerByKey['class_category2']])) {
471
                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
472
                                    $this->addErrors($message);
473
                                }
474
                            }
475 5
                        } else {
476
                            // 商品規格の更新
477
                            $flag = false;
478
                            $classCategoryId1 = StringUtil::isBlank($row[$headerByKey['class_category1']]) ? null : $row[$headerByKey['class_category1']];
479
                            $classCategoryId2 = StringUtil::isBlank($row[$headerByKey['class_category2']]) ? null : $row[$headerByKey['class_category2']];
480
481
                            foreach ($ProductClasses as $pc) {
482
                                $classCategory1 = is_null($pc->getClassCategory1()) ? null : $pc->getClassCategory1()->getId();
483
                                $classCategory2 = is_null($pc->getClassCategory2()) ? null : $pc->getClassCategory2()->getId();
484 6
485
                                // 登録されている商品規格を更新
486 6
                                if ($classCategory1 == $classCategoryId1 &&
487
                                    $classCategory2 == $classCategoryId2
488 6
                                ) {
489 6
                                    $this->updateProductClass($row, $Product, $pc, $data, $headerByKey);
490 6
491 6 View Code Duplication
                                    if ($this->BaseInfo->isOptionProductDeliveryFee()) {
492 6
                                        if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
493 6
                                            $deliveryFee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
494 6
                                            $errors = $this->validator->validate($deliveryFee, new GreaterThanOrEqual(['value' => 0]));
495 6
                                            if ($errors->count() === 0) {
496 6
                                                $pc->setDeliveryFee($deliveryFee);
497
                                            } else {
498
                                                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
499
                                                $this->addErrors($message);
500
                                            }
501
                                        }
502
                                    }
503
504
                                    // 商品別税率機能が有効の場合に税率を更新
505 6 View Code Duplication
                                    if ($this->BaseInfo->isOptionProductTaxRule()) {
506
                                        if (isset($row[$headerByKey['tax_rate']]) && StringUtil::isNotBlank($row[$headerByKey['tax_rate']])) {
507 6
                                            $taxRate = $row[$headerByKey['tax_rate']];
508 6
                                            $errors = $this->validator->validate($taxRate, new GreaterThanOrEqual(['value' => 0]));
509 1
                                            if ($errors->count() === 0) {
510
                                                if ($pc->getTaxRule()) {
511 1
                                                    // 商品別税率の設定があれば税率を更新
512
                                                    $pc->getTaxRule()->setTaxRate($taxRate);
513
                                                } else {
514 5
                                                    // 商品別税率の設定がなければ新規作成
515 5
                                                    $TaxRule = $this->taxRuleRepository->newTaxRule();
516
                                                    $TaxRule->setTaxRate($taxRate);
517
                                                    $TaxRule->setApplyDate(new \DateTime());
518
                                                    $TaxRule->setProduct($Product);
519
                                                    $TaxRule->setProductClass($pc);
520 5
                                                    $pc->setTaxRule($TaxRule);
521 5
                                                }
522
                                            } else {
523 5
                                                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['tax_rate']]);
524
                                                $this->addErrors($message);
525 5
                                            }
526 5
                                        } else {
527 1
                                            // 税率の入力がなければ税率の設定を削除
528
                                            if ($pc->getTaxRule()) {
529
                                                $this->taxRuleRepository->delete($pc->getTaxRule());
530
                                                $pc->setTaxRule(null);
531
                                            }
532 1
                                        }
533 1
                                    }
534
535
                                    $flag = true;
536
                                    break;
537
                                }
538 1
                            }
539
540
                            // 商品規格を登録
541
                            if (!$flag) {
542
                                $pc = $ProductClasses[0];
543
                                if ($pc->getClassCategory1() == null &&
544
                                    $pc->getClassCategory2() == null
545 5
                                ) {
546 1
                                    // 規格分類1、規格分類2がnullであるデータを非表示
547
                                    $pc->setVisible(false);
548
                                }
549
550
                                if (isset($row[$headerByKey['class_category1']]) && isset($row[$headerByKey['class_category2']])
551
                                    && $row[$headerByKey['class_category1']] == $row[$headerByKey['class_category2']]) {
552
                                    $message = trans('admin.common.csv_invalid_not_same', [
553
                                        '%line%' => $line,
554
                                        '%name1%' => $headerByKey['class_category1'],
555
                                        '%name2%' => $headerByKey['class_category2'],
556
                                    ]);
557
                                    $this->addErrors($message);
558
                                } else {
559
                                    // 必ず規格分類1がセットされている
560
                                    // 規格分類1、2をそれぞれセットし作成
561
                                    $ClassCategory1 = null;
562
                                    if (preg_match('/^\d+$/', $classCategoryId1)) {
563
                                        $ClassCategory1 = $this->classCategoryRepository->find($classCategoryId1);
564
                                        if (!$ClassCategory1) {
565 5
                                            $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
566 1
                                            $this->addErrors($message);
567
                                        }
568 1
                                    } else {
569
                                        $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
570 4
                                        $this->addErrors($message);
571
                                    }
572
573 4
                                    $ClassCategory2 = null;
574 4
                                    if (isset($row[$headerByKey['class_category2']]) && StringUtil::isNotBlank($row[$headerByKey['class_category2']])) {
575 1
                                        if ($pc->getClassCategory1() != null && $pc->getClassCategory2() == null) {
576
                                            $message = trans('admin.common.csv_invalid_can_not', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
577
                                            $this->addErrors($message);
578
                                        } else {
579
                                            if (preg_match('/^\d+$/', $classCategoryId2)) {
580
                                                $ClassCategory2 = $this->classCategoryRepository->find($classCategoryId2);
581 View Code Duplication
                                                if (!$ClassCategory2) {
582 1
                                                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
583 1
                                                    $this->addErrors($message);
584
                                                } else {
585
                                                    if ($ClassCategory1 &&
586
                                                        ($ClassCategory1->getClassName()->getId() == $ClassCategory2->getClassName()->getId())
587
                                                    ) {
588
                                                        $message = trans('admin.common.csv_invalid_not_same', [
589 4
                                                            '%line%' => $line,
590
                                                            '%name1%' => $headerByKey['class_category1'],
591
                                                            '%name2%' => $headerByKey['class_category2'],
592 4
                                                        ]);
593
                                                        $this->addErrors($message);
594
                                                    }
595
                                                }
596
                                            } else {
597
                                                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
598
                                                $this->addErrors($message);
599
                                            }
600 4
                                        }
601 4
                                    } else {
602 1
                                        if ($pc->getClassCategory1() != null && $pc->getClassCategory2() != null) {
603
                                            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
604
                                            $this->addErrors($message);
605
                                        }
606 4
                                    }
607
                                    $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 563 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 580 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...
608 4
609 View Code Duplication
                                    if ($this->BaseInfo->isOptionProductDeliveryFee()) {
610
                                        if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
611
                                            $deliveryFee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
612
                                            $errors = $this->validator->validate($deliveryFee, new GreaterThanOrEqual(['value' => 0]));
613
                                            if ($errors->count() === 0) {
614 4
                                                $ProductClass->setDeliveryFee($deliveryFee);
615
                                            } else {
616
                                                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
617 4
                                                $this->addErrors($message);
618 4
                                            }
619
                                        }
620
                                    }
621 4
622 4
                                    // 商品別税率機能が有効の場合に税率を更新
623 4
                                    if ($this->BaseInfo->isOptionProductTaxRule()) {
624 4
                                        if (isset($row[$headerByKey['tax_rate']]) && StringUtil::isNotBlank($row[$headerByKey['tax_rate']])) {
625
                                            $taxRate = $row[$headerByKey['tax_rate']];
626
                                            $errors = $this->validator->validate($taxRate, new GreaterThanOrEqual(['value' => 0]));
627
                                            if ($errors->count() === 0) {
628
                                                $TaxRule = $this->taxRuleRepository->newTaxRule();
629 4
                                                $TaxRule->setTaxRate($taxRate);
630
                                                $TaxRule->setApplyDate(new \DateTime());
631
                                                $TaxRule->setProduct($Product);
632
                                                $TaxRule->setProductClass($ProductClass);
633
                                                $ProductClass->setTaxRule($TaxRule);
634
                                            } else {
635
                                                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['tax_rate']]);
636
                                                $this->addErrors($message);
637
                                            }
638
                                        }
639
                                    }
640
641
                                    $Product->addProductClass($ProductClass);
642
                                }
643
                            }
644
                        }
645
                        if ($this->hasErrors()) {
646
                            return $this->renderWithError($form, $headers);
647
                        }
648
                        $this->entityManager->persist($Product);
649
                    }
650
                    $this->entityManager->flush();
651
                    $this->entityManager->getConnection()->commit();
652
653
                    // 画像ファイルの削除(commit後に削除させる)
654 View Code Duplication
                    foreach ($deleteImages as $images) {
655
                        /** @var ProductImage $image */
656
                        foreach ($images as $image) {
657
                            if ($this->productImageRepository->findOneBy(['file_name' => $image->getFileName()])) {
658
                                continue;
659
                            }
660
                            try {
661
                                $fs = new Filesystem();
662
                                $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$image);
663 16
                            } catch (\Exception $e) {
664
                                // エラーが発生しても無視する
665 16
                            }
666 7
                        }
667 6
                    }
668
669
                    log_info('商品CSV登録完了');
670
                    if (!$this->isSplitCsv) {
671 16
                        $message = 'admin.common.csv_upload_complete';
672
                        $this->session->getFlashBag()->add('eccube.admin.success', $message);
673
                    }
674 16
675 16
                    $cacheUtil->clearDoctrineCache();
676 16
                }
677
            }
678
        }
679
680
        return $this->renderWithError($form, $headers);
681
    }
682
683
    /**
684
     * カテゴリ登録CSVアップロード
685
     *
686
     * @Route("/%eccube_admin_route%/product/category_csv_upload", name="admin_product_category_csv_import")
687 8
     * @Template("@admin/Product/csv_category.twig")
688
     */
689 8
    public function csvCategory(Request $request, CacheUtil $cacheUtil)
690
    {
691 4
        $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm();
692 4
693 2
        $headers = $this->getCategoryCsvHeader();
694 2
        if ('POST' === $request->getMethod()) {
695
            $form->handleRequest($request);
696
            if ($form->isValid()) {
697
                $formFile = $form['import_file']->getData();
698 4
                if (!empty($formFile)) {
699
                    log_info('カテゴリCSV登録開始');
700 4
                    $data = $this->getImportData($formFile);
701 View Code Duplication
                    if ($data === false) {
702 4
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
703 4
704 4
                        return $this->renderWithError($form, $headers, false);
705
                    }
706
707 4
                    $getId = function ($item) {
708
                        return $item['id'];
709
                    };
710
                    $requireHeader = array_keys(array_map($getId, array_filter($headers, function ($value) {
711
                        return $value['required'];
712 4
                    })));
713 4
714 4
                    $headerByKey = array_flip(array_map($getId, $headers));
715 4
716 4
                    $columnHeaders = $data->getColumnHeaders();
717 View Code Duplication
                    if (count(array_diff($requireHeader, $columnHeaders)) > 0) {
718 4
                        $this->addErrors(trans('admin.common.csv_invalid_format'));
719 4
720 4
                        return $this->renderWithError($form, $headers, false);
721
                    }
722
723
                    $size = count($data);
724 View Code Duplication
                    if ($size < 1) {
725
                        $this->addErrors(trans('admin.common.csv_invalid_no_data'));
726
727
                        return $this->renderWithError($form, $headers, false);
728
                    }
729
                    $this->entityManager->getConfiguration()->setSQLLogger(null);
730
                    $this->entityManager->getConnection()->beginTransaction();
731
                    // CSVファイルの登録処理
732
                    foreach ($data as $row) {
733
                        /** @var $Category Category */
734
                        $Category = new Category();
735 8
                        if (isset($row[$headerByKey['id']]) && strlen($row[$headerByKey['id']]) > 0) {
736 View Code Duplication
                            if (!preg_match('/^\d+$/', $row[$headerByKey['id']])) {
737
                                $this->addErrors(($data->key() + 1).'行目のカテゴリIDが存在しません。');
738 8
739 8
                                return $this->renderWithError($form, $headers);
740 2
                            }
741 2
                            $Category = $this->categoryRepository->find($row[$headerByKey['id']]);
742 2
                            if (!$Category) {
743
                                $this->addErrors(($data->key() + 1).'行目の更新対象のカテゴリIDが存在しません。新規登録の場合は、カテゴリIDの値を空で登録してください。');
744
745 8
                                return $this->renderWithError($form, $headers);
746
                            }
747 4
                            if ($row[$headerByKey['id']] == $row[$headerByKey['parent_category_id']]) {
748 4
                                $this->addErrors(($data->key() + 1).'行目のカテゴリIDと親カテゴリIDが同じです。');
749 4
750 4
                                return $this->renderWithError($form, $headers);
751 4
                            }
752 4
                        }
753 4
754 4
                        if (isset($row[$headerByKey['category_del_flg']]) && StringUtil::isNotBlank($row[$headerByKey['category_del_flg']])) {
755
                            if (StringUtil::trimAll($row[$headerByKey['category_del_flg']]) == 1) {
756
                                if ($Category->getId()) {
757
                                    log_info('カテゴリ削除開始', [$Category->getId()]);
758
                                    try {
759
                                        $this->categoryRepository->delete($Category);
760
                                        log_info('カテゴリ削除完了', [$Category->getId()]);
761
                                    } catch (ForeignKeyConstraintViolationException $e) {
762 4
                                        log_info('カテゴリ削除エラー', [$Category->getId(), $e]);
763 4
                                        $message = trans('admin.common.delete_error_foreign_key', ['%name%' => $Category->getName()]);
764 4
                                        $this->addError($message, 'admin');
765 4
766 4
                                        return $this->renderWithError($form, $headers);
767
                                    }
768 4
                                }
769 4
770
                                continue;
771
                            }
772 4
                        }
773
774
                        if (!isset($row[$headerByKey['category_name']]) || StringUtil::isBlank($row[$headerByKey['category_name']])) {
775
                            $this->addErrors(($data->key() + 1).'行目のカテゴリ名が設定されていません。');
776
777
                            return $this->renderWithError($form, $headers);
778
                        } else {
779
                            $Category->setName(StringUtil::trimAll($row[$headerByKey['category_name']]));
780
                        }
781 4
782
                        $ParentCategory = null;
783
                        if (isset($row[$headerByKey['parent_category_id']]) && StringUtil::isNotBlank($row[$headerByKey['parent_category_id']])) {
784 View Code Duplication
                            if (!preg_match('/^\d+$/', $row[$headerByKey['parent_category_id']])) {
785
                                $this->addErrors(($data->key() + 1).'行目の親カテゴリIDが存在しません。');
786 4
787
                                return $this->renderWithError($form, $headers);
788
                            }
789
790
                            /** @var $ParentCategory Category */
791
                            $ParentCategory = $this->categoryRepository->find($row[$headerByKey['parent_category_id']]);
792
                            if (!$ParentCategory) {
793
                                $this->addErrors(($data->key() + 1).'行目の親カテゴリIDが存在しません。');
794 4
795
                                return $this->renderWithError($form, $headers);
796
                            }
797
                        }
798
                        $Category->setParent($ParentCategory);
799
800
                        // Level
801
                        if (isset($row['階層']) && StringUtil::isNotBlank($row['階層'])) {
802 View Code Duplication
                            if ($ParentCategory == null && $row['階層'] != 1) {
803
                                $this->addErrors(($data->key() + 1).'行目の親カテゴリIDが存在しません。');
804
805
                                return $this->renderWithError($form, $headers);
806
                            }
807 8
                            $level = StringUtil::trimAll($row['階層']);
808
                        } else {
809
                            $level = 1;
810 8
                            if ($ParentCategory) {
811 8
                                $level = $ParentCategory->getHierarchy() + 1;
812 1
                            }
813 1
                        }
814
815
                        $Category->setHierarchy($level);
816 8
817
                        if ($this->eccubeConfig['eccube_category_nest_level'] < $Category->getHierarchy()) {
818 4
                            $this->addErrors(($data->key() + 1).'行目のカテゴリが最大レベルを超えているため設定できません。');
819 4
820 4
                            return $this->renderWithError($form, $headers);
821 4
                        }
822 4
823
                        if ($this->hasErrors()) {
824 4
                            return $this->renderWithError($form, $headers);
825 4
                        }
826
                        $this->entityManager->persist($Category);
827 4
                        $this->categoryRepository->save($Category);
828 4
                    }
829
830 4
                    $this->entityManager->getConnection()->commit();
831
                    log_info('カテゴリCSV登録完了');
832 4
                    $message = 'admin.common.csv_upload_complete';
833
                    $this->session->getFlashBag()->add('eccube.admin.success', $message);
834
835 4
                    $cacheUtil->clearDoctrineCache();
836
                }
837
            }
838
        }
839
840
        return $this->renderWithError($form, $headers);
841 4
    }
842
843
    /**
844
     * アップロード用CSV雛形ファイルダウンロード
845
     *
846
     * @Route("/%eccube_admin_route%/product/csv_template/{type}", requirements={"type" = "\w+"}, name="admin_product_csv_template")
847
     *
848
     * @param $type
849
     *
850
     * @return StreamedResponse
851
     */
852
    public function csvTemplate(Request $request, $type)
853
    {
854
        if ($type == 'product') {
855
            $headers = $this->getProductCsvHeader();
856
            $filename = 'product.csv';
857
        } elseif ($type == 'category') {
858
            $headers = $this->getCategoryCsvHeader();
859 8
            $filename = 'category.csv';
860
        } else {
861
            throw new NotFoundHttpException();
862 8
        }
863 8
864 8
        return $this->sendTemplateResponse($request, array_keys($headers), $filename);
865
    }
866 8
867 8
    /**
868 8
     * 登録、更新時のエラー画面表示
869 8
     *
870 8
     * @param FormInterface $form
871
     * @param array $headers
872
     * @param bool $rollback
873
     *
874 8
     * @return array
875
     *
876
     * @throws \Doctrine\DBAL\ConnectionException
877
     */
878 8
    protected function renderWithError($form, $headers, $rollback = true)
879
    {
880
        if ($this->hasErrors()) {
881
            if ($rollback) {
882
                $this->entityManager->getConnection()->rollback();
883
            }
884
        }
885 8
886 8
        $this->removeUploadedFile();
887
888 8
        if ($this->isSplitCsv) {
889 3
            return $this->json([
890 3
                'success' => !$this->hasErrors(),
891 3
                'success_message' => trans('admin.common.csv_upload_line_success', [
892
                    '%from%' => $this->convertLineNo(2),
893
                    '%to%' => $this->currentLineNo]),
894
                'errors' => $this->errors,
895 3
                'error_message' => trans('admin.common.csv_upload_line_error',[
896
                    '%from%' => $this->convertLineNo(2)])
897
            ]);
898
        }
899
900
        return [
901
            'form' => $form->createView(),
902
            'headers' => $headers,
903 8
            'errors' => $this->errors,
904 3
        ];
905
    }
906 5
907
    /**
908
     * 商品画像の削除、登録
909 8
     *
910
     * @param $row
911
     * @param Product $Product
912
     * @param CsvImportService $data
913 8
     * @param $headerByKey
914 4
     */
915
    protected function createProductImage($row, Product $Product, $data, $headerByKey)
916 4
    {
917 4
        if (!isset($row[$headerByKey['product_image']])) {
918 4
            return;
919 4
        }
920
        if (StringUtil::isNotBlank($row[$headerByKey['product_image']])) {
921
            // 画像の削除
922 4
            $ProductImages = $Product->getProductImage();
923
            foreach ($ProductImages as $ProductImage) {
924
                $Product->removeProductImage($ProductImage);
925
                $this->entityManager->remove($ProductImage);
926 4
            }
927
928 4
            // 画像の登録
929 4
            $images = explode(',', $row[$headerByKey['product_image']]);
930 4
931
            $sortNo = 1;
932
933
            $pattern = "/\\$|^.*.\.\\\.*|\/$|^.*.\.\/\.*/";
934
            foreach ($images as $image) {
935
                $fileName = StringUtil::trimAll($image);
936
937 8
                // 商品画像名のフォーマットチェック
938
                if (strlen($fileName) > 0 && preg_match($pattern, $fileName)) {
939
                    $message = trans('admin.common.csv_invalid_image', ['%line%' => $data->key() + 1, '%name%' => $headerByKey['product_image']]);
940
                    $this->addErrors($message);
941
                } else {
942
                    // 空文字は登録対象外
943
                    if (!empty($fileName)) {
944
                        $ProductImage = new ProductImage();
945
                        $ProductImage->setFileName($fileName);
946
                        $ProductImage->setProduct($Product);
947 8
                        $ProductImage->setSortNo($sortNo);
948 3
949 3
                        $Product->addProductImage($ProductImage);
950 3
                        $sortNo++;
951
                        $this->entityManager->persist($ProductImage);
952
                    }
953
                }
954
            }
955
        }
956
    }
957 8
958 8
    /**
959 8
     * 商品カテゴリの削除、登録
960 8
     *
961
     * @param $row
962
     * @param Product $Product
963 8
     * @param CsvImportService $data
964
     * @param $headerByKey
965
     */
966
    protected function createProductCategory($row, Product $Product, $data, $headerByKey)
967
    {
968
        if (!isset($row[$headerByKey['product_category']])) {
969
            return;
970 8
        }
971 3
        // カテゴリの削除
972 3
        $ProductCategories = $Product->getProductCategories();
973 3
        foreach ($ProductCategories as $ProductCategory) {
974
            $Product->removeProductCategory($ProductCategory);
975
            $this->entityManager->remove($ProductCategory);
976
            $this->entityManager->flush();
977
        }
978
979
        if (StringUtil::isNotBlank($row[$headerByKey['product_category']])) {
980 8
            // カテゴリの登録
981 8
            $categories = explode(',', $row[$headerByKey['product_category']]);
982 8
            $sortNo = 1;
983 8
            $categoriesIdList = [];
984
            foreach ($categories as $category) {
985 8
                $line = $data->key() + 1;
986 4
                if (preg_match('/^\d+$/', $category)) {
987
                    $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...
988
                    if (!$Category) {
989 4
                        $message = trans('admin.common.csv_invalid_not_found_target', [
990
                            '%line%' => $line,
991
                            '%name%' => $headerByKey['product_category'],
992 8
                            '%target_name%' => $category,
993 8
                        ]);
994
                        $this->addErrors($message);
995 8
                    } else {
996 View Code Duplication
                        foreach ($Category->getPath() as $ParentCategory) {
997
                            if (!isset($categoriesIdList[$ParentCategory->getId()])) {
998
                                $ProductCategory = $this->makeProductCategory($Product, $ParentCategory, $sortNo);
999
                                $this->entityManager->persist($ProductCategory);
1000
                                $sortNo++;
1001
1002
                                $Product->addProductCategory($ProductCategory);
1003
                                $categoriesIdList[$ParentCategory->getId()] = true;
1004
                            }
1005
                        }
1006
                        if (!isset($categoriesIdList[$Category->getId()])) {
1007
                            $ProductCategory = $this->makeProductCategory($Product, $Category, $sortNo);
1008 1
                            $sortNo++;
1009
                            $this->entityManager->persist($ProductCategory);
1010 1
                            $Product->addProductCategory($ProductCategory);
1011
                            $categoriesIdList[$Category->getId()] = true;
1012 1
                        }
1013 1
                    }
1014 View Code Duplication
                } else {
1015
                    $message = trans('admin.common.csv_invalid_not_found_target', [
1016
                        '%line%' => $line,
1017 1
                        '%name%' => $headerByKey['product_category'],
1018 1
                        '%target_name%' => $category,
1019 1
                    ]);
1020
                    $this->addErrors($message);
1021
                }
1022
            }
1023 1
        }
1024
    }
1025
1026
    /**
1027
     * タグの登録
1028
     *
1029
     * @param array $row
1030
     * @param Product $Product
1031
     * @param CsvImportService $data
1032 1
     */
1033 1
    protected function createProductTag($row, Product $Product, $data, $headerByKey)
1034 1
    {
1035 1
        if (!isset($row[$headerByKey['product_tag']])) {
1036
            return;
1037
        }
1038
        // タグの削除
1039 1
        $ProductTags = $Product->getProductTag();
1040
        foreach ($ProductTags as $ProductTag) {
1041
            $Product->removeProductTag($ProductTag);
1042
            $this->entityManager->remove($ProductTag);
1043
        }
1044
1045
        if (StringUtil::isNotBlank($row[$headerByKey['product_tag']])) {
1046
            // タグの登録
1047 1
            $tags = explode(',', $row[$headerByKey['product_tag']]);
1048 1
            foreach ($tags as $tag_id) {
1049 1
                $Tag = null;
1050 1
                if (preg_match('/^\d+$/', $tag_id)) {
1051
                    $Tag = $this->tagRepository->find($tag_id);
1052
1053
                    if ($Tag) {
1054 1
                        $ProductTags = new ProductTag();
1055
                        $ProductTags
1056
                            ->setProduct($Product)
1057
                            ->setTag($Tag);
1058
1059
                        $Product->addProductTag($ProductTags);
1060
1061
                        $this->entityManager->persist($ProductTags);
1062 1
                    }
1063
                }
1064 View Code Duplication
                if (!$Tag) {
1065
                    $message = trans('admin.common.csv_invalid_not_found_target', [
1066
                        '%line%' => $data->key() + 1,
1067
                        '%name%' => $headerByKey['product_tag'],
1068
                        '%target_name%' => $tag_id,
1069
                    ]);
1070
                    $this->addErrors($message);
1071
                }
1072
            }
1073
        }
1074
    }
1075
1076
    /**
1077 1
     * 商品規格分類1、商品規格分類2がnullとなる商品規格情報を作成
1078 1
     *
1079
     * @param $row
1080
     * @param Product $Product
1081
     * @param CsvImportService $data
1082
     * @param $headerByKey
1083 1
     * @param null $ClassCategory1
1084
     * @param null $ClassCategory2
1085
     *
1086
     * @return ProductClass
1087 1
     */
1088 1
    protected function createProductClass($row, Product $Product, $data, $headerByKey, $ClassCategory1 = null, $ClassCategory2 = null)
1089
    {
1090 1
        // 規格分類1、規格分類2がnullとなる商品を作成
1091
        $ProductClass = new ProductClass();
1092
        $ProductClass->setProduct($Product);
1093
        $ProductClass->setVisible(true);
1094 1
1095 1
        $line = $data->key() + 1;
1096 1 View Code Duplication
        if (isset($row[$headerByKey['sale_type']]) && StringUtil::isNotBlank($row[$headerByKey['sale_type']])) {
1097
            if (preg_match('/^\d+$/', $row[$headerByKey['sale_type']])) {
1098
                $SaleType = $this->saleTypeRepository->find($row[$headerByKey['sale_type']]);
1099 1
                if (!$SaleType) {
1100
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1101
                    $this->addErrors($message);
1102 1
                } else {
1103 1
                    $ProductClass->setSaleType($SaleType);
1104 1
                }
1105
            } else {
1106
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1107
                $this->addErrors($message);
1108
            }
1109
        } else {
1110
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1111 1
            $this->addErrors($message);
1112 1
        }
1113 1
1114 1
        $ProductClass->setClassCategory1($ClassCategory1);
1115
        $ProductClass->setClassCategory2($ClassCategory2);
1116
1117 View Code Duplication
        if (isset($row[$headerByKey['delivery_date']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_date']])) {
1118
            if (preg_match('/^\d+$/', $row[$headerByKey['delivery_date']])) {
1119
                $DeliveryDuration = $this->deliveryDurationRepository->find($row[$headerByKey['delivery_date']]);
1120
                if (!$DeliveryDuration) {
1121 1
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
1122 1
                    $this->addErrors($message);
1123 1
                } else {
1124 1
                    $ProductClass->setDeliveryDuration($DeliveryDuration);
1125
                }
1126
            } else {
1127
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
1128
                $this->addErrors($message);
1129
            }
1130
        }
1131 1
1132 View Code Duplication
        if (isset($row[$headerByKey['product_code']]) && StringUtil::isNotBlank($row[$headerByKey['product_code']])) {
1133
            $ProductClass->setCode(StringUtil::trimAll($row[$headerByKey['product_code']]));
1134
        } else {
1135 1
            $ProductClass->setCode(null);
1136 1
        }
1137 1
1138 View Code Duplication
        if (!isset($row[$headerByKey['stock_unlimited']])
1139
            || StringUtil::isBlank($row[$headerByKey['stock_unlimited']])
1140
            || $row[$headerByKey['stock_unlimited']] == (string) Constant::DISABLED
1141
        ) {
1142
            $ProductClass->setStockUnlimited(false);
1143
            // 在庫数が設定されていなければエラー
1144 1
            if (isset($row[$headerByKey['stock']]) && StringUtil::isNotBlank($row[$headerByKey['stock']])) {
1145
                $stock = str_replace(',', '', $row[$headerByKey['stock']]);
1146 1
                if (preg_match('/^\d+$/', $stock) && $stock >= 0) {
1147 1
                    $ProductClass->setStock($stock);
1148
                } else {
1149
                    $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
1150 1
                    $this->addErrors($message);
1151
                }
1152
            } else {
1153 1
                $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
1154
                $this->addErrors($message);
1155
            }
1156
        } elseif ($row[$headerByKey['stock_unlimited']] == (string) Constant::ENABLED) {
1157
            $ProductClass->setStockUnlimited(true);
1158
            $ProductClass->setStock(null);
1159 7
        } else {
1160
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock_unlimited']]);
1161 7
            $this->addErrors($message);
1162 7
        }
1163
1164 View Code Duplication
        if (isset($row[$headerByKey['sale_limit']]) && StringUtil::isNotBlank($row[$headerByKey['sale_limit']])) {
1165
            $saleLimit = str_replace(',', '', $row[$headerByKey['sale_limit']]);
1166
            if (preg_match('/^\d+$/', $saleLimit) && $saleLimit >= 0) {
1167
                $ProductClass->setSaleLimit($saleLimit);
1168 16
            } else {
1169
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['sale_limit']]);
1170 16
                $this->addErrors($message);
1171
            }
1172
        }
1173
1174
        if (isset($row[$headerByKey['price01']]) && StringUtil::isNotBlank($row[$headerByKey['price01']])) {
1175
            $price01 = str_replace(',', '', $row[$headerByKey['price01']]);
1176 16
            $errors = $this->validator->validate($price01, new GreaterThanOrEqual(['value' => 0]));
1177
            if ($errors->count() === 0) {
1178 16
                $ProductClass->setPrice01($price01);
1179
            } else {
1180
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price01']]);
1181
                $this->addErrors($message);
1182
            }
1183
        }
1184
1185 View Code Duplication
        if (isset($row[$headerByKey['price02']]) && StringUtil::isNotBlank($row[$headerByKey['price02']])) {
1186 10
            $price02 = str_replace(',', '', $row[$headerByKey['price02']]);
1187
            $errors = $this->validator->validate($price02, new GreaterThanOrEqual(['value' => 0]));
1188
            if ($errors->count() === 0) {
1189 10
                $ProductClass->setPrice02($price02);
1190
            } else {
1191
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1192
                $this->addErrors($message);
1193
            }
1194 10
        } else {
1195
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1196
            $this->addErrors($message);
1197
        }
1198
1199 10 View Code Duplication
        if ($this->BaseInfo->isOptionProductDeliveryFee()) {
1200
            if (isset($row[$headerByKey['delivery_fee']]) && StringUtil::isNotBlank($row[$headerByKey['delivery_fee']])) {
1201
                $delivery_fee = str_replace(',', '', $row[$headerByKey['delivery_fee']]);
1202
                $errors = $this->validator->validate($delivery_fee, new GreaterThanOrEqual(['value' => 0]));
1203
                if ($errors->count() === 0) {
1204 10
                    $ProductClass->setDeliveryFee($delivery_fee);
1205
                } else {
1206
                    $message = trans('admin.common.csv_invalid_greater_than_zero',
1207
                        ['%line%' => $line, '%name%' => $headerByKey['delivery_fee']]);
1208
                    $this->addErrors($message);
1209 10
                }
1210
            }
1211
        }
1212
1213
        $Product->addProductClass($ProductClass);
1214 10
        $ProductStock = new ProductStock();
1215
        $ProductClass->setProductStock($ProductStock);
1216
        $ProductStock->setProductClass($ProductClass);
1217
1218
        if (!$ProductClass->isStockUnlimited()) {
1219 10
            $ProductStock->setStock($ProductClass->getStock());
1220
        } else {
1221
            // 在庫無制限時はnullを設定
1222
            $ProductStock->setStock(null);
1223
        }
1224 10
1225
        $this->entityManager->persist($ProductClass);
1226
        $this->entityManager->persist($ProductStock);
1227
1228
        return $ProductClass;
1229 10
    }
1230
1231
    /**
1232
     * 商品規格情報を更新
1233
     *
1234 10
     * @param $row
1235
     * @param Product $Product
1236
     * @param ProductClass $ProductClass
1237
     * @param CsvImportService $data
1238
     *
1239 10
     * @return ProductClass
1240
     */
1241
    protected function updateProductClass($row, Product $Product, ProductClass $ProductClass, $data, $headerByKey)
1242
    {
1243
        $ProductClass->setProduct($Product);
1244 10
1245
        $line = $data->key() + 1;
1246 View Code Duplication
        if (!isset($row[$headerByKey['sale_type']]) || $row[$headerByKey['sale_type']] == '') {
1247
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1248
            $this->addErrors($message);
1249 10
        } else {
1250
            if (preg_match('/^\d+$/', $row[$headerByKey['sale_type']])) {
1251
                $SaleType = $this->saleTypeRepository->find($row[$headerByKey['sale_type']]);
1252
                if (!$SaleType) {
1253
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1254 10
                    $this->addErrors($message);
1255
                } else {
1256
                    $ProductClass->setSaleType($SaleType);
1257
                }
1258
            } else {
1259 10
                $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['sale_type']]);
1260
                $this->addErrors($message);
1261
            }
1262
        }
1263
1264 10
        // 規格分類1、2をそれぞれセットし作成
1265 View Code Duplication
        if (isset($row[$headerByKey['class_category1']]) && $row[$headerByKey['class_category1']] != '') {
1266
            if (preg_match('/^\d+$/', $row[$headerByKey['class_category1']])) {
1267
                $ClassCategory = $this->classCategoryRepository->find($row[$headerByKey['class_category1']]);
1268
                if (!$ClassCategory) {
1269 10
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
1270
                    $this->addErrors($message);
1271
                } else {
1272
                    $ProductClass->setClassCategory1($ClassCategory);
1273
                }
1274 10
            } else {
1275
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category1']]);
1276
                $this->addErrors($message);
1277
            }
1278
        }
1279 10
1280 View Code Duplication
        if (isset($row[$headerByKey['class_category2']]) && $row[$headerByKey['class_category2']] != '') {
1281
            if (preg_match('/^\d+$/', $row[$headerByKey['class_category2']])) {
1282
                $ClassCategory = $this->classCategoryRepository->find($row[$headerByKey['class_category2']]);
1283
                if (!$ClassCategory) {
1284 10
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
1285
                    $this->addErrors($message);
1286
                } else {
1287
                    $ProductClass->setClassCategory2($ClassCategory);
1288
                }
1289 10
            } else {
1290
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['class_category2']]);
1291
                $this->addErrors($message);
1292
            }
1293
        }
1294 10
1295 View Code Duplication
        if (isset($row[$headerByKey['delivery_date']]) && $row[$headerByKey['delivery_date']] != '') {
1296
            if (preg_match('/^\d+$/', $row[$headerByKey['delivery_date']])) {
1297
                $DeliveryDuration = $this->deliveryDurationRepository->find($row[$headerByKey['delivery_date']]);
1298
                if (!$DeliveryDuration) {
1299 10
                    $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
1300
                    $this->addErrors($message);
1301
                } else {
1302
                    $ProductClass->setDeliveryDuration($DeliveryDuration);
1303
                }
1304
            } else {
1305
                $message = trans('admin.common.csv_invalid_not_found', ['%line%' => $line, '%name%' => $headerByKey['delivery_date']]);
1306
                $this->addErrors($message);
1307
            }
1308
        }
1309
1310 6 View Code Duplication
        if (isset($row[$headerByKey['product_code']]) && StringUtil::isNotBlank($row[$headerByKey['product_code']])) {
1311
            $ProductClass->setCode(StringUtil::trimAll($row[$headerByKey['product_code']]));
1312
        } else {
1313 6
            $ProductClass->setCode(null);
1314
        }
1315
1316 View Code Duplication
        if (!isset($row[$headerByKey['stock_unlimited']])
1317
            || StringUtil::isBlank($row[$headerByKey['stock_unlimited']])
1318 6
            || $row[$headerByKey['stock_unlimited']] == (string) Constant::DISABLED
1319
        ) {
1320
            $ProductClass->setStockUnlimited(false);
1321
            // 在庫数が設定されていなければエラー
1322
            if ($row[$headerByKey['stock']] == '') {
1323 6
                $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
1324
                $this->addErrors($message);
1325
            } else {
1326
                $stock = str_replace(',', '', $row[$headerByKey['stock']]);
1327
                if (preg_match('/^\d+$/', $stock) && $stock >= 0) {
1328 6
                    $ProductClass->setStock($row[$headerByKey['stock']]);
1329
                } else {
1330
                    $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['stock']]);
1331
                    $this->addErrors($message);
1332
                }
1333
            }
1334
        } elseif ($row[$headerByKey['stock_unlimited']] == (string) Constant::ENABLED) {
1335
            $ProductClass->setStockUnlimited(true);
1336
            $ProductClass->setStock(null);
1337
        } else {
1338
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['stock_unlimited']]);
1339
            $this->addErrors($message);
1340
        }
1341
1342 View Code Duplication
        if (isset($row[$headerByKey['sale_limit']]) && $row[$headerByKey['sale_limit']] != '') {
1343
            $saleLimit = str_replace(',', '', $row[$headerByKey['sale_limit']]);
1344
            if (preg_match('/^\d+$/', $saleLimit) && $saleLimit >= 0) {
1345 4
                $ProductClass->setSaleLimit($saleLimit);
1346
            } else {
1347 4
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['sale_limit']]);
1348 4
                $this->addErrors($message);
1349 4
            }
1350 4
        }
1351 4
1352 4
        if (isset($row[$headerByKey['price01']]) && $row[$headerByKey['price01']] != '') {
1353
            $price01 = str_replace(',', '', $row[$headerByKey['price01']]);
1354 4
            $errors = $this->validator->validate($price01, new GreaterThanOrEqual(['value' => 0]));
1355
            if ($errors->count() === 0) {
1356
                $ProductClass->setPrice01($price01);
1357
            } else {
1358
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price01']]);
1359
                $this->addErrors($message);
1360
            }
1361
        }
1362
1363 View Code Duplication
        if (!isset($row[$headerByKey['price02']]) || $row[$headerByKey['price02']] == '') {
1364
            $message = trans('admin.common.csv_invalid_required', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1365
            $this->addErrors($message);
1366
        } else {
1367
            $price02 = str_replace(',', '', $row[$headerByKey['price02']]);
1368
            $errors = $this->validator->validate($price02, new GreaterThanOrEqual(['value' => 0]));
1369
            if ($errors->count() === 0) {
1370
                $ProductClass->setPrice02($price02);
1371
            } else {
1372
                $message = trans('admin.common.csv_invalid_greater_than_zero', ['%line%' => $line, '%name%' => $headerByKey['price02']]);
1373
                $this->addErrors($message);
1374
            }
1375
        }
1376
1377
        $ProductStock = $ProductClass->getProductStock();
1378
1379
        if (!$ProductClass->isStockUnlimited()) {
1380
            $ProductStock->setStock($ProductClass->getStock());
1381
        } else {
1382
            // 在庫無制限時はnullを設定
1383
            $ProductStock->setStock(null);
1384
        }
1385
1386
        return $ProductClass;
1387
    }
1388
1389
    /**
1390
     * 登録、更新時のエラー画面表示
1391
     */
1392
    protected function addErrors($message)
1393
    {
1394
        $this->errors[] = $message;
1395
    }
1396
1397
    /**
1398
     * @return array
1399
     */
1400
    protected function getErrors()
1401
    {
1402
        return $this->errors;
1403
    }
1404
1405
    /**
1406
     * @return boolean
1407
     */
1408
    protected function hasErrors()
1409
    {
1410
        return count($this->getErrors()) > 0;
1411
    }
1412
1413
    /**
1414
     * 商品登録CSVヘッダー定義
1415
     *
1416
     * @return array
1417
     */
1418
    protected function getProductCsvHeader()
1419
    {
1420
        return [
1421
            trans('admin.product.product_csv.product_id_col') => [
1422
                'id' => 'id',
1423
                'description' => 'admin.product.product_csv.product_id_description',
1424
                'required' => false,
1425
            ],
1426
            trans('admin.product.product_csv.display_status_col') => [
1427
                'id' => 'status',
1428
                'description' => 'admin.product.product_csv.display_status_description',
1429
                'required' => true,
1430
            ],
1431
            trans('admin.product.product_csv.product_name_col') => [
1432
                'id' => 'name',
1433
                'description' => 'admin.product.product_csv.product_name_description',
1434
                'required' => true,
1435
            ],
1436
            trans('admin.product.product_csv.shop_memo_col') => [
1437
                'id' => 'note',
1438
                'description' => 'admin.product.product_csv.shop_memo_description',
1439
                'required' => false,
1440
            ],
1441
            trans('admin.product.product_csv.description_list_col') => [
1442
                'id' => 'description_list',
1443
                'description' => 'admin.product.product_csv.description_list_description',
1444
                'required' => false,
1445
            ],
1446
            trans('admin.product.product_csv.description_detail_col') => [
1447
                'id' => 'description_detail',
1448
                'description' => 'admin.product.product_csv.description_detail_description',
1449
                'required' => false,
1450
            ],
1451
            trans('admin.product.product_csv.keyword_col') => [
1452
                'id' => 'search_word',
1453
                'description' => 'admin.product.product_csv.keyword_description',
1454
                'required' => false,
1455
            ],
1456
            trans('admin.product.product_csv.free_area_col') => [
1457
                'id' => 'free_area',
1458
                'description' => 'admin.product.product_csv.free_area_description',
1459
                'required' => false,
1460
            ],
1461
            trans('admin.product.product_csv.delete_flag_col') => [
1462
                'id' => 'product_del_flg',
1463
                'description' => 'admin.product.product_csv.delete_flag_description',
1464
                'required' => false,
1465
            ],
1466
            trans('admin.product.product_csv.product_image_col') => [
1467
                'id' => 'product_image',
1468
                'description' => 'admin.product.product_csv.product_image_description',
1469
                'required' => false,
1470
            ],
1471
            trans('admin.product.product_csv.category_col') => [
1472
                'id' => 'product_category',
1473
                'description' => 'admin.product.product_csv.category_description',
1474
                'required' => false,
1475
            ],
1476
            trans('admin.product.product_csv.tag_col') => [
1477
                'id' => 'product_tag',
1478
                'description' => 'admin.product.product_csv.tag_description',
1479
                'required' => false,
1480
            ],
1481
            trans('admin.product.product_csv.sale_type_col') => [
1482
                'id' => 'sale_type',
1483
                'description' => 'admin.product.product_csv.sale_type_description',
1484
                'required' => true,
1485
            ],
1486
            trans('admin.product.product_csv.class_category1_col') => [
1487
                'id' => 'class_category1',
1488
                'description' => 'admin.product.product_csv.class_category1_description',
1489
                'required' => false,
1490
            ],
1491
            trans('admin.product.product_csv.class_category2_col') => [
1492
                'id' => 'class_category2',
1493
                'description' => 'admin.product.product_csv.class_category2_description',
1494
                'required' => false,
1495
            ],
1496
            trans('admin.product.product_csv.delivery_duration_col') => [
1497
                'id' => 'delivery_date',
1498
                'description' => 'admin.product.product_csv.delivery_duration_description',
1499
                'required' => false,
1500
            ],
1501
            trans('admin.product.product_csv.product_code_col') => [
1502
                'id' => 'product_code',
1503
                'description' => 'admin.product.product_csv.product_code_description',
1504
                'required' => false,
1505
            ],
1506
            trans('admin.product.product_csv.stock_col') => [
1507
                'id' => 'stock',
1508
                'description' => 'admin.product.product_csv.stock_description',
1509
                'required' => false,
1510
            ],
1511
            trans('admin.product.product_csv.stock_unlimited_col') => [
1512
                'id' => 'stock_unlimited',
1513
                'description' => 'admin.product.product_csv.stock_unlimited_description',
1514
                'required' => false,
1515
            ],
1516
            trans('admin.product.product_csv.sale_limit_col') => [
1517
                'id' => 'sale_limit',
1518
                'description' => 'admin.product.product_csv.sale_limit_description',
1519
                'required' => false,
1520
            ],
1521
            trans('admin.product.product_csv.normal_price_col') => [
1522
                'id' => 'price01',
1523
                'description' => 'admin.product.product_csv.normal_price_description',
1524
                'required' => false,
1525
            ],
1526
            trans('admin.product.product_csv.sale_price_col') => [
1527
                'id' => 'price02',
1528
                'description' => 'admin.product.product_csv.sale_price_description',
1529
                'required' => true,
1530
            ],
1531
            trans('admin.product.product_csv.delivery_fee_col') => [
1532
                'id' => 'delivery_fee',
1533
                'description' => 'admin.product.product_csv.delivery_fee_description',
1534
                'required' => false,
1535
            ],
1536
            trans('admin.product.product_csv.tax_rate_col') => [
1537
                'id' => 'tax_rate',
1538
                'description' => 'admin.product.product_csv.tax_rate_description',
1539
                'required' => false,
1540
            ],
1541
        ];
1542
    }
1543
1544
    /**
1545
     * カテゴリCSVヘッダー定義
1546
     */
1547
    protected function getCategoryCsvHeader()
1548
    {
1549
        return [
1550
            trans('admin.product.category_csv.category_id_col') => [
1551
                'id' => 'id',
1552
                'description' => 'admin.product.category_csv.category_id_description',
1553
                'required' => false,
1554
            ],
1555
            trans('admin.product.category_csv.category_name_col') => [
1556
                'id' => 'category_name',
1557
                'description' => 'admin.product.category_csv.category_name_description',
1558
                'required' => true,
1559
            ],
1560
            trans('admin.product.category_csv.parent_category_id_col') => [
1561
                'id' => 'parent_category_id',
1562
                'description' => 'admin.product.category_csv.parent_category_id_description',
1563
                'required' => false,
1564
            ],
1565
            trans('admin.product.category_csv.delete_flag_col') => [
1566
                'id' => 'category_del_flg',
1567
                'description' => 'admin.product.category_csv.delete_flag_description',
1568
                'required' => false,
1569
            ],
1570
        ];
1571
    }
1572
1573
    /**
1574
     * ProductCategory作成
1575
     *
1576
     * @param \Eccube\Entity\Product $Product
1577
     * @param \Eccube\Entity\Category $Category
1578
     * @param int $sortNo
1579
     *
1580
     * @return ProductCategory
1581
     */
1582 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...
1583
    {
1584
        $ProductCategory = new ProductCategory();
1585
        $ProductCategory->setProduct($Product);
1586
        $ProductCategory->setProductId($Product->getId());
1587
        $ProductCategory->setCategory($Category);
1588
        $ProductCategory->setCategoryId($Category->getId());
1589
1590
        return $ProductCategory;
1591
    }
1592
1593
    /**
1594
     * @Route("/%eccube_admin_route%/product/csv_split", name="admin_product_csv_split")
1595
     * @param Request $request
1596
     * @return \Symfony\Component\HttpFoundation\JsonResponse
1597
     */
1598
    public function splitCsv(Request $request)
1599
    {
1600
        $this->isTokenValid();
1601
1602
        if (!$request->isXmlHttpRequest()) {
1603
            throw new BadRequestHttpException();
1604
        }
1605
1606
        $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm();
1607
        $form->handleRequest($request);
1608
1609
        if ($form->isSubmitted() && $form->isValid()) {
1610
1611
            $dir = $this->eccubeConfig['eccube_csv_temp_realdir'];
1612
            if (!file_exists($dir)) {
1613
                $fs = new Filesystem();
1614
                $fs->mkdir($dir);
1615
            }
1616
1617
            $data = $form['import_file']->getData();
1618
            $src = new \SplFileObject($data->getRealPath());
1619
            $src->setFlags(\SplFileObject::READ_CSV | \SplFileObject::READ_AHEAD | \SplFileObject::SKIP_EMPTY | \SplFileObject::DROP_NEW_LINE);
1620
1621
            $fileNo = 1;
1622
            $fileName = StringUtil::random(8);
1623
1624
            $dist = new \SplFileObject($dir.'/'.$fileName.$fileNo.'.csv', 'w');
1625
            $header = $src->current();
1626
            $src->next();
1627
            $dist->fputcsv($header);
1628
1629
            $i = 0;
1630
            while ($row = $src->current()) {
1631
                $dist->fputcsv($row);
1632
                $src->next();
1633
1634
                if (!$src->eof() && ++$i % $this->eccubeConfig['eccube_csv_split_lines'] === 0) {
1635
                    $fileNo++;
1636
                    $dist = new \SplFileObject($dir.'/'.$fileName.$fileNo.'.csv', 'w');
1637
                    $dist->fputcsv($header);
1638
                }
1639
            }
1640
1641
            return $this->json(['success' => true, 'file_name' => $fileName, 'max_file_no' => $fileNo]);
1642
        }
1643
1644
        return $this->json(['success' => false, 'message' => $form->getErrors(true ,true)]);
1645
    }
1646
1647
    /**
1648
     * @Route("/%eccube_admin_route%/product/csv_split_import", name="admin_product_csv_split_import")
1649
     * @param Request $request
1650
     * @return \Symfony\Component\HttpFoundation\JsonResponse
1651
     */
1652
    public function importCsv(Request $request, CsrfTokenManagerInterface $tokenManager)
1653
    {
1654
        $this->isTokenValid();
1655
1656
        if (!$request->isXmlHttpRequest()) {
1657
            throw new BadRequestHttpException();
1658
        }
1659
1660
        $choices = $this->getCsvTempFiles();
1661
1662
        $filename = $request->get('file_name');
1663
        if (!isset($choices[$filename])) {
1664
            throw new BadRequestHttpException();
1665
        }
1666
1667
        $path = $this->eccubeConfig['eccube_csv_temp_realdir'].'/'.$filename;
1668
        $request->files->set('admin_csv_import', ['import_file' => new UploadedFile(
1669
            $path,
1670
            'import.csv',
1671
            'text/csv',
1672
            filesize($path),
1673
            null,
1674
            true
1675
        )]);
1676
1677
        $request->setMethod('POST');
1678
        $request->request->set('admin_csv_import', [
1679
            Constant::TOKEN_NAME => $tokenManager->getToken('admin_csv_import')->getValue(),
1680
            'is_split_csv' => true,
1681
            'csv_file_no' => $request->get('file_no'),
1682
        ]);
1683
1684
        return $this->forwardToRoute('admin_product_csv_import');
1685
    }
1686
1687
    /**
1688
     * @Route("/%eccube_admin_route%/product/csv_split_cleanup", name="admin_product_csv_split_cleanup")
1689
     * @param Request $request
1690
     * @return \Symfony\Component\HttpFoundation\JsonResponse
1691
     */
1692
    public function cleanupSplitCsv(Request $request)
1693
    {
1694
        $this->isTokenValid();
1695
1696
        if (!$request->isXmlHttpRequest()) {
1697
            throw new BadRequestHttpException();
1698
        }
1699
1700
        $files = $request->get('files', []);
1701
        $choices = $this->getCsvTempFiles();
1702
1703
        foreach ($files as $filename) {
1704
            if (isset($choices[$filename])) {
1705
                unlink($choices[$filename]);
1706
            } else {
1707
                return $this->json(['success' => false]);
1708
            }
1709
        }
1710
1711
        return $this->json(['success' => true]);
1712
    }
1713
1714
    protected function getCsvTempFiles()
1715
    {
1716
        $files = Finder::create()
1717
            ->in($this->eccubeConfig['eccube_csv_temp_realdir'])
1718
            ->name('*.csv')
1719
            ->files();
1720
1721
        $choices = [];
1722
        foreach ($files as $file) {
1723
            $choices[$file->getBaseName()] = $file->getRealPath();
1724
        }
1725
1726
        return $choices;
1727
    }
1728
1729
    protected function convertLineNo($currentLineNo) {
1730
        if ($this->isSplitCsv) {
1731
            return ($this->eccubeConfig['eccube_csv_split_lines']) * ($this->csvFileNo - 1) + $currentLineNo;
1732
        }
1733
1734
        return $currentLineNo;
1735
    }
1736
}
1737