Completed
Push — master ( d8324b...c53dd7 )
by chihiro
23s
created

CsvImportController   D

Complexity

Total Complexity 191

Size/Duplication

Total Lines 1097
Duplicated Lines 18.32 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 72.61%

Importance

Changes 0
Metric Value
wmc 191
lcom 1
cbo 9
dl 201
loc 1097
ccs 493
cts 679
cp 0.7261
rs 4.4112
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
B csvTemplate() 0 36 4
B render() 0 24 5
F csvProduct() 63 343 70
D csvCategory() 34 131 21
B getImportData() 0 39 6
B createProductImage() 0 27 4
B createProductCategory() 0 41 6
C createProductTag() 0 35 7
F createProductClass() 52 136 30
F updateProductClass() 52 141 33
A addErrors() 0 5 1
A getErrors() 0 4 1
A hasErrors() 0 4 1
B getProductCsvHeader() 0 29 1
A getCategoryCsvHeader() 0 8 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

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

Complex classes like CsvImportController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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

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

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Controller\Admin\Product;
26
27
use Eccube\Application;
28
use Eccube\Common\Constant;
29
use Eccube\Entity\Category;
30
use Eccube\Entity\Product;
31
use Eccube\Entity\ProductCategory;
32
use Eccube\Entity\ProductClass;
33
use Eccube\Entity\ProductImage;
34
use Eccube\Entity\ProductStock;
35
use Eccube\Entity\ProductTag;
36
use Eccube\Exception\CsvImportException;
37
use Eccube\Service\CsvImportService;
38
use Eccube\Util\Str;
39
use Symfony\Component\Filesystem\Filesystem;
40
use Symfony\Component\HttpFoundation\Request;
41
use Symfony\Component\HttpFoundation\StreamedResponse;
42
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
43
44
class CsvImportController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
45
{
46
47
    private $errors = array();
48
49
    private $fileName;
50
51
    private $em;
52
53
    private $productTwig = 'Product/csv_product.twig';
54
55
    private $categoryTwig = 'Product/csv_category.twig';
56
57
58
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
59
     * 商品登録CSVアップロード
60
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
61 5
    public function csvProduct(Application $app, Request $request)
62
    {
63 3
        $form = $app['form.factory']->createBuilder('admin_csv_import')->getForm();
64
65 3
        $headers = $this->getProductCsvHeader();
66
67 3
        if ('POST' === $request->getMethod()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
68
69 3
            $form->handleRequest($request);
70
71 3
            if ($form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
72
73 3
                $formFile = $form['import_file']->getData();
74
75 3
                if (!empty($formFile)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
76
77 3
                    $data = $this->getImportData($app, $formFile);
78 3 View Code Duplication
                    if ($data === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
79
                        $this->addErrors('CSVのフォーマットが一致しません。');
80
                        return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
81
                    }
82
83 3
                    $keys = array_keys($headers);
84 3
                    $columnHeaders = $data->getColumnHeaders();
85 3
                    if ($keys !== $columnHeaders) {
86
                        $this->addErrors('CSVのフォーマットが一致しません。');
87
                        return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
88
                    }
89
90 3
                    $size = count($data);
91 3
                    if ($size < 1) {
92
                        $this->addErrors('CSVデータが存在しません。');
93
                        return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
94
                    }
95
96 3
                    $headerSize = count($keys);
97
98 3
                    $this->em = $app['orm.em'];
99 3
                    $this->em->getConfiguration()->setSQLLogger(null);
100
101 3
                    $this->em->getConnection()->beginTransaction();
102
103 3
                    $BaseInfo = $app['eccube.repository.base_info']->get();
104
105
                    // CSVファイルの登録処理
106 3
                    foreach ($data as $row) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
107
108 3
                        if ($headerSize != count($row)) {
109
                            $this->addErrors(($data->key() + 1) . '行目のCSVフォーマットが一致しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
110
                            return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
111
                        }
112
113 3
                        if ($row['商品ID'] == '') {
114 2
                            $Product = new Product();
115 2
                            $this->em->persist($Product);
116 2
                        } else {
117 2
                            if (preg_match('/^\d+$/', $row['商品ID'])) {
118 2
                                $Product = $app['eccube.repository.product']->find($row['商品ID']);
119 2
                                if (!$Product) {
120
                                    $this->addErrors(($data->key() + 1) . '行目の商品IDが存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
121
                                    return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
122
                                }
123 2 View Code Duplication
                            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
124
                                $this->addErrors(($data->key() + 1) . '行目の商品IDが存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
125
                                return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
126
                            }
127
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
128
                        }
129
130 3
                        if ($row['公開ステータス(ID)'] == '') {
131
                            $this->addErrors(($data->key() + 1) . '行目の公開ステータス(ID)が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
132
                        } else {
133 3
                            if (preg_match('/^\d+$/', $row['公開ステータス(ID)'])) {
134 3
                                $Disp = $app['eccube.repository.master.disp']->find($row['公開ステータス(ID)']);
135 3
                                if (!$Disp) {
136
                                    $this->addErrors(($data->key() + 1) . '行目の公開ステータス(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
137
                                } else {
138 3
                                    $Product->setStatus($Disp);
139
                                }
140 3
                            } else {
141
                                $this->addErrors(($data->key() + 1) . '行目の公開ステータス(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
142
                            }
143
                        }
144
145 3 View Code Duplication
                        if (Str::isBlank($row['商品名'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
146
                            $this->addErrors(($data->key() + 1) . '行目の商品名が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
147
                            return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
148
                        } else {
149 3
                            $Product->setName(Str::trimAll($row['商品名']));
150
                        }
151
152 3 View Code Duplication
                        if (Str::isNotBlank($row['ショップ用メモ欄'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
153 2
                            $Product->setNote(Str::trimAll($row['ショップ用メモ欄']));
154 2
                        } else {
155 1
                            $Product->setNote(null);
156
                        }
157
158 3 View Code Duplication
                        if (Str::isNotBlank($row['商品説明(一覧)'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
159 3
                            $Product->setDescriptionList(Str::trimAll($row['商品説明(一覧)']));
160 3
                        } else {
161 1
                            $Product->setDescriptionList(null);
162
                        }
163
164 3 View Code Duplication
                        if (Str::isNotBlank($row['商品説明(詳細)'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
165 3
                            $Product->setDescriptionDetail(Str::trimAll($row['商品説明(詳細)']));
166 3
                        } else {
167
                            $Product->setDescriptionDetail(null);
168
                        }
169
170 3 View Code Duplication
                        if (Str::isNotBlank($row['検索ワード'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
171 2
                            $Product->setSearchWord(Str::trimAll($row['検索ワード']));
172 2
                        } else {
173 1
                            $Product->setSearchWord(null);
174
                        }
175
176 3 View Code Duplication
                        if (Str::isNotBlank($row['フリーエリア'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
177 2
                            $Product->setFreeArea(Str::trimAll($row['フリーエリア']));
178 2
                        } else {
179 1
                            $Product->setFreeArea(null);
180
                        }
181
182 3
                        if ($row['商品削除フラグ'] == '') {
183
                            $Product->setDelFlg(Constant::DISABLED);
184
                        } else {
185 3
                            if ($row['商品削除フラグ'] == (string)Constant::DISABLED || $row['商品削除フラグ'] == (string)Constant::ENABLED) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, a cast statement should be followed by a single space.
Loading history...
186 3
                                $Product->setDelFlg($row['商品削除フラグ']);
187 3 View Code Duplication
                            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
188
                                $this->addErrors(($data->key() + 1) . '行目の商品削除フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
189
                                return $this->render($app, $form, $headers, $this->productTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
190
                            }
191
                        }
192
193
                        // 商品画像登録
194 3
                        $this->createProductImage($row, $Product);
195
196 3
                        $this->em->flush($Product);
197
198
                        // 商品カテゴリ登録
199 3
                        $this->createProductCategory($row, $Product, $app, $data);
200
201
                        //タグ登録
202 3
                        $this->createProductTag($row, $Product, $app, $data);
203
204
                        // 商品規格が存在しなければ新規登録
205 3
                        $ProductClasses = $Product->getProductClasses();
206 3
                        if ($ProductClasses->count() < 1) {
207
                            // 規格分類1(ID)がセットされていると規格なし商品、規格あり商品を作成
208 2
                            $ProductClassOrg = $this->createProductClass($row, $Product, $app, $data);
209 2
                            if ($BaseInfo->getOptionProductDeliveryFee() == Constant::ENABLED) {
210
                                if ($row['送料'] != '') {
211
                                    $deliveryFee = str_replace(',', '', $row['送料']);
212
                                    if (preg_match('/^\d+$/', $deliveryFee) && $deliveryFee >= 0) {
213
                                        $ProductClassOrg->setDeliveryFee($deliveryFee);
214
                                    } else {
215
                                        $this->addErrors(($data->key() + 1) . '行目の送料は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
216
                                    }
217
                                }
218
                            }
219
220 2
                            if ($row['規格分類1(ID)'] != '') {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
221
222 1
                                if ($row['規格分類1(ID)'] == $row['規格分類2(ID)']) {
223
                                    $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)と規格分類2(ID)には同じ値を使用できません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
224
                                } else {
225
                                    // 商品規格あり
226
                                    // 企画分類あり商品を作成
227 1
                                    $ProductClass = clone $ProductClassOrg;
228 1
                                    $ProductStock = clone $ProductClassOrg->getProductStock();
229
230
                                    // 規格分類1、規格分類2がnullであるデータの削除フラグを1にセット
231 1
                                    $ProductClassOrg->setDelFlg(Constant::ENABLED);
232
233
                                    // 規格分類1、2をそれぞれセットし作成
234 1
                                    $ClassCategory1 = null;
235 1
                                    if (preg_match('/^\d+$/', $row['規格分類1(ID)'])) {
236 1
                                        $ClassCategory1 = $app['eccube.repository.class_category']->find($row['規格分類1(ID)']);
237 1
                                        if (!$ClassCategory1) {
238
                                            $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
239 5
                                        } else {
240 1
                                            $ProductClass->setClassCategory1($ClassCategory1);
241 5
                                        }
242 1
                                    } else {
243
                                        $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
244
                                    }
245
246 1
                                    if ($row['規格分類2(ID)'] != '') {
247 1
                                        if (preg_match('/^\d+$/', $row['規格分類2(ID)'])) {
248 1
                                            $ClassCategory2 = $app['eccube.repository.class_category']->find($row['規格分類2(ID)']);
249 1 View Code Duplication
                                            if (!$ClassCategory2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
250
                                                $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
251
                                            } else {
252 1
                                                if ($ClassCategory1 &&
253 1
                                                    ($ClassCategory1->getClassName()->getId() == $ClassCategory2->getClassName()->getId())
254 1
                                                ) {
255
                                                    $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)と規格分類2(ID)の規格名が同じです。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
256
                                                } else {
257 1
                                                    $ProductClass->setClassCategory2($ClassCategory2);
258
                                                }
259
                                            }
260 1
                                        } else {
261
                                            $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
262
                                        }
263 1
                                    }
264 1
                                    $ProductClass->setProductStock($ProductStock);
265 1
                                    $ProductStock->setProductClass($ProductClass);
266
267 1
                                    $this->em->persist($ProductClass);
268 1
                                    $this->em->persist($ProductStock);
269
                                }
270
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
271 1
                            } else {
272 1
                                if ($row['規格分類2(ID)'] != '') {
273
                                    $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
274
                                }
275
                            }
276
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
277 2
                        } else {
278
                            // 商品規格の更新
279
280 2
                            $flag = false;
281 2
                            $classCategoryId1 = $row['規格分類1(ID)'] == '' ? null : $row['規格分類1(ID)'];
282 2
                            $classCategoryId2 = $row['規格分類2(ID)'] == '' ? null : $row['規格分類2(ID)'];
283
284 2
                            foreach ($ProductClasses as $pc) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
285
286 2
                                $classCategory1 = is_null($pc->getClassCategory1()) ? null : $pc->getClassCategory1()->getId();
287 2
                                $classCategory2 = is_null($pc->getClassCategory2()) ? null : $pc->getClassCategory2()->getId();
288
289
                                // 登録されている商品規格を更新
290 2
                                if ($classCategory1 == $classCategoryId1 &&
291
                                    $classCategory2 == $classCategoryId2
292 2
                                ) {
293 1
                                    $this->updateProductClass($row, $Product, $pc, $app, $data);
294
295 1
                                    if ($BaseInfo->getOptionProductDeliveryFee() == Constant::ENABLED) {
296
                                        if ($row['送料'] != '') {
297
                                            $deliveryFee = str_replace(',', '', $row['送料']);
298
                                            if (preg_match('/^\d+$/', $deliveryFee) && $deliveryFee >= 0) {
299
                                                $pc->setDeliveryFee($deliveryFee);
300
                                            } else {
301
                                                $this->addErrors(($data->key() + 1) . '行目の送料は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
302
                                            }
303
                                        }
304
                                    }
305
306 1
                                    $flag = true;
307 1
                                    break;
308
                                }
309 2
                            }
310
311
                            // 商品規格を登録
312 2
                            if (!$flag) {
313 1
                                $pc = $ProductClasses[0];
314 1
                                if ($pc->getClassCategory1() == null &&
315 1
                                    $pc->getClassCategory2() == null
316 1
                                ) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
317
318
                                    // 規格分類1、規格分類2がnullであるデータの削除フラグを1にセット
319 1
                                    $pc->setDelFlg(Constant::ENABLED);
320 1
                                }
321
322 1
                                if ($row['規格分類1(ID)'] == $row['規格分類2(ID)']) {
323
                                    $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)と規格分類2(ID)には同じ値を使用できません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
324
                                } else {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
325
326
                                    // 必ず規格分類1がセットされている
327
                                    // 規格分類1、2をそれぞれセットし作成
328 1
                                    $ClassCategory1 = null;
329 1
                                    if (preg_match('/^\d+$/', $classCategoryId1)) {
330 1
                                        $ClassCategory1 = $app['eccube.repository.class_category']->find($classCategoryId1);
331 1
                                        if (!$ClassCategory1) {
332
                                            $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
333
                                        }
334 1
                                    } else {
335
                                        $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
336
                                    }
337
338 1
                                    $ClassCategory2 = null;
339 1
                                    if ($row['規格分類2(ID)'] != '') {
340 1
                                        if ($pc->getClassCategory1() != null && $pc->getClassCategory2() == null) {
341
                                            $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)は設定できません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
342
                                        } else {
343 1
                                            if (preg_match('/^\d+$/', $classCategoryId2)) {
344 1
                                                $ClassCategory2 = $app['eccube.repository.class_category']->find($classCategoryId2);
345 1 View Code Duplication
                                                if (!$ClassCategory2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
346
                                                    $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
347
                                                } else {
348 1
                                                    if ($ClassCategory1 &&
349 1
                                                        ($ClassCategory1->getClassName()->getId() == $ClassCategory2->getClassName()->getId())
350 1
                                                    ) {
351
                                                        $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)と規格分類2(ID)の規格名が同じです。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
352
                                                    }
353
                                                }
354 1
                                            } else {
355
                                                $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
356
                                            }
357
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
358
                                        }
359 1
                                    } else {
360
                                        if ($pc->getClassCategory1() != null && $pc->getClassCategory2() != null) {
361
                                            $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)に値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
362
                                        }
363
                                    }
364 1
                                    $ProductClass = $this->createProductClass($row, $Product, $app, $data, $ClassCategory1, $ClassCategory2);
365
366 1
                                    if ($BaseInfo->getOptionProductDeliveryFee() == Constant::ENABLED) {
367
                                        if ($row['送料'] != '') {
368
                                            $deliveryFee = str_replace(',', '', $row['送料']);
369
                                            if (preg_match('/^\d+$/', $deliveryFee) && $deliveryFee >= 0) {
370
                                                $ProductClass->setDeliveryFee($deliveryFee);
371
                                            } else {
372
                                                $this->addErrors(($data->key() + 1) . '行目の送料は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
373
                                            }
374
                                        }
375
                                    }
376
377 1
                                    $Product->addProductClass($ProductClass);
378
                                }
379
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
380 1
                            }
381
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
382
                        }
383
384
385 3
                        if ($this->hasErrors()) {
386
                            return $this->render($app, $form, $headers, $this->productTwig);
387
                        }
388
389 3
                        $this->em->persist($Product);
390
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
391 3
                    }
392
393 3
                    $this->em->flush();
394 3
                    $this->em->getConnection()->commit();
395
396 3
                    $app->addSuccess('admin.product.csv_import.save.complete', 'admin');
397 3
                }
398
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
399 3
            }
400 3
        }
401
402 3
        return $this->render($app, $form, $headers, $this->productTwig);
403
    }
404
405
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
406
     * カテゴリ登録CSVアップロード
407
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
408 2
    public function csvCategory(Application $app, Request $request)
409
    {
410
411 2
        $form = $app['form.factory']->createBuilder('admin_csv_import')->getForm();
412
413 2
        $headers = $this->getCategoryCsvHeader();
414
415 2
        if ('POST' === $request->getMethod()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
416
417 2
            $form->handleRequest($request);
418
419 2
            if ($form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
420
421 2
                $formFile = $form['import_file']->getData();
422
423 2
                if (!empty($formFile)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
424
425 2
                    $data = $this->getImportData($app, $formFile);
426 2 View Code Duplication
                    if ($data === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
427
                        $this->addErrors('CSVのフォーマットが一致しません。');
428
                        return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
429
                    }
430
431 2
                    $keys = array_keys($headers);
432 2
                    $columnHeaders = $data->getColumnHeaders();
433 2
                    if ($keys !== $columnHeaders) {
434
                        $this->addErrors('CSVのフォーマットが一致しません。');
435
                        return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
436
                    }
437
438 2
                    $size = count($data);
439 2
                    if ($size < 1) {
440
                        $this->addErrors('CSVデータが存在しません。');
441
                        return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
442
                    }
443
444 2
                    $headerSize = count($keys);
445
446 2
                    $this->em = $app['orm.em'];
447 2
                    $this->em->getConfiguration()->setSQLLogger(null);
448
449 2
                    $this->em->getConnection()->beginTransaction();
450
451
                    // CSVファイルの登録処理
452 2
                    foreach ($data as $row) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
453
454 2
                        if ($headerSize != count($row)) {
455
                            $this->addErrors(($data->key() + 1) . '行目のCSVフォーマットが一致しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
456
                            return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
457
                        }
458
459 2
                        if ($row['カテゴリID'] == '') {
460 1
                            $Category = new Category();
461 1
                        } else {
462 1 View Code Duplication
                            if (!preg_match('/^\d+$/', $row['カテゴリID'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
463
                                $this->addErrors(($data->key() + 1) . '行目のカテゴリIDが存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
464
                                return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
465
                            }
466 1
                            $Category = $app['eccube.repository.category']->find($row['カテゴリID']);
467 1 View Code Duplication
                            if (!$Category) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
468
                                $this->addErrors(($data->key() + 1) . '行目のカテゴリIDが存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
469
                                return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
470
                            }
471 1 View Code Duplication
                            if ($row['カテゴリID'] == $row['親カテゴリID']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
472
                                $this->addErrors(($data->key() + 1) . '行目のカテゴリIDと親カテゴリIDが同じです。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
473
                                return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
474
                            }
475
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
476
                        }
477
478 2 View Code Duplication
                        if (Str::isBlank($row['カテゴリ名'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
479
                            $this->addErrors(($data->key() + 1) . '行目のカテゴリ名が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
480
                            return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
481
                        } else {
482 2
                            $Category->setName(Str::trimAll($row['カテゴリ名']));
483
                        }
484
485 2
                        if ($row['親カテゴリID'] != '') {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
486
487 1 View Code Duplication
                            if (!preg_match('/^\d+$/', $row['親カテゴリID'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
488
                                $this->addErrors(($data->key() + 1) . '行目の親カテゴリIDが存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
489
                                return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
490
                            }
491
492 1
                            $ParentCategory = $app['eccube.repository.category']->find($row['親カテゴリID']);
493 1 View Code Duplication
                            if (!$ParentCategory) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
494
                                $this->addErrors(($data->key() + 1) . '行目の親カテゴリIDが存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
495
                                return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
496
                            }
497
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
498 1
                        } else {
499 2
                            $ParentCategory = null;
500
                        }
501
502 2
                        $Category->setParent($ParentCategory);
503 2
                        if ($ParentCategory) {
504 1
                            $Category->setLevel($ParentCategory->getLevel() + 1);
505 1
                        } else {
506 2
                            $Category->setLevel(1);
507
                        }
508
509 2 View Code Duplication
                        if ($app['config']['category_nest_level'] < $Category->getLevel()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
510
                            $this->addErrors(($data->key() + 1) . '行目のカテゴリが最大レベルを超えているため設定できません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
511
                            return $this->render($app, $form, $headers, $this->categoryTwig);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
512
                        }
513
514 2
                        $status = $app['eccube.repository.category']->save($Category);
515
516 2
                        if (!$status) {
517
                            $this->addErrors(($data->key() + 1) . '行目のカテゴリが設定できません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
518
                        }
519
520 2
                        if ($this->hasErrors()) {
521
                            return $this->render($app, $form, $headers, $this->categoryTwig);
522
                        }
523
524 2
                        $this->em->persist($Category);
525
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
526 2
                    }
527
528 2
                    $this->em->flush();
529 2
                    $this->em->getConnection()->commit();
530
531 2
                    $app->addSuccess('admin.category.csv_import.save.complete', 'admin');
532 2
                }
533
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
534 2
            }
535 2
        }
536
537 2
        return $this->render($app, $form, $headers, $this->categoryTwig);
538
    }
539
540
541
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$type" missing
Loading history...
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
542
     * アップロード用CSV雛形ファイルダウンロード
543
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
544 2
    public function csvTemplate(Application $app, Request $request, $type)
545
    {
546 2
        set_time_limit(0);
547
548 2
        $response = new StreamedResponse();
549
550 2
        if ($type == 'product') {
551 1
            $headers = $this->getProductCsvHeader();
552 1
            $filename = 'product.csv';
553 2
        } else if ($type == 'category') {
554 1
            $headers = $this->getCategoryCsvHeader();
555 1
            $filename = 'category.csv';
556 1
        } else {
557
            throw new NotFoundHttpException();
558
        }
559
560 2
        $response->setCallback(function () use ($app, $request, $headers) {
561
562
            // ヘッダ行の出力
563 2
            $row = array();
564 2
            foreach ($headers as $key => $value) {
565 2
                $row[] = mb_convert_encoding($key, $app['config']['csv_export_encoding'], 'UTF-8');
566 2
            }
567
568 2
            $fp = fopen('php://output', 'w');
569 2
            fputcsv($fp, $row, $app['config']['csv_export_separator']);
570 2
            fclose($fp);
571
572 2
        });
573
574 2
        $response->headers->set('Content-Type', 'application/octet-stream');
575 2
        $response->headers->set('Content-Disposition', 'attachment; filename=' . $filename);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
576 2
        $response->send();
577
578 2
        return $response;
579
    }
580
581
582
    /**
583
     * 登録、更新時のエラー画面表示
584
     *
585
     */
586 5
    protected function render($app, $form, $headers, $twig)
587
    {
588
589 5
        if ($this->hasErrors()) {
590
            if ($this->em) {
591
                $this->em->getConnection()->rollback();
592
            }
593
        }
594
595 5
        if (!empty($this->fileName)) {
596
            try {
597 5
                $fs = new Filesystem();
598 5
                $fs->remove($app['config']['csv_temp_realdir'] . '/' . $this->fileName);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
599 5
            } catch (\Exception $e) {
600
                // エラーが発生しても無視する
601
            }
602 5
        }
603
604 5
        return $app->render($twig, array(
605 5
            'form' => $form->createView(),
606 5
            'headers' => $headers,
607 5
            'errors' => $this->errors,
608 5
        ));
609
    }
610
611
612
    /**
613
     * アップロードされたCSVファイルの行ごとの処理
614
     *
615
     * @param $formFile
616
     * @return CsvImportService
617
     */
618 5
    protected function getImportData($app, $formFile)
619
    {
620
        // アップロードされたCSVファイルを一時ディレクトリに保存
621 5
        $this->fileName = 'upload_' . Str::random() . '.' . $formFile->getClientOriginalExtension();
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
622 5
        $formFile->move($app['config']['csv_temp_realdir'], $this->fileName);
623
624 5
        $file = file_get_contents($app['config']['csv_temp_realdir'] . '/' . $this->fileName);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
625
626 5
        if ('\\' === DIRECTORY_SEPARATOR && PHP_VERSION_ID >= 70000) {
627
            // Windows 環境の PHP7 の場合はファイルエンコーディングを CP932 に合わせる
628
            // see https://github.com/EC-CUBE/ec-cube/issues/1780
629
            setlocale(LC_ALL, ''); // 既定のロケールに設定
630
            if (mb_detect_encoding($file) === 'UTF-8') { // UTF-8 を検出したら SJIS-win に変換
631
                $file = mb_convert_encoding($file, 'SJIS-win', 'UTF-8');
632
            }
633
        } else {
634
            // アップロードされたファイルがUTF-8以外は文字コード変換を行う
635 5
            $encode = Str::characterEncoding(substr($file, 0, 6));
636 5
            if ($encode != 'UTF-8') {
637 2
                $file = mb_convert_encoding($file, 'UTF-8', $encode);
638 2
            }
639
        }
640 5
        $file = Str::convertLineFeed($file);
641
642 5
        $tmp = tmpfile();
643 5
        fwrite($tmp, $file);
644 5
        rewind($tmp);
645 5
        $meta = stream_get_meta_data($tmp);
646 5
        $file = new \SplFileObject($meta['uri']);
647
648 5
        set_time_limit(0);
649
650
        // アップロードされたCSVファイルを行ごとに取得
651 5
        $data = new CsvImportService($file, $app['config']['csv_import_delimiter'], $app['config']['csv_import_enclosure']);
652
653 5
        $ret = $data->setHeaderRowNumber(0);
654
655 5
        return ($ret !== false) ? $data : false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $ret !== false ? $data : false; of type Eccube\Service\CsvImportService|false adds false to the return on line 655 which is incompatible with the return type documented by Eccube\Controller\Admin\...ntroller::getImportData of type Eccube\Service\CsvImportService. It seems like you forgot to handle an error condition.
Loading history...
656
    }
657
658
659
    /**
660
     * 商品画像の削除、登録
661
     */
662 3
    protected function createProductImage($row, Product $Product)
663
    {
664 3
        if ($row['商品画像'] != '') {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
665
666
            // 画像の削除
667 3
            $ProductImages = $Product->getProductImage();
668 3
            foreach ($ProductImages as $ProductImage) {
669 2
                $Product->removeProductImage($ProductImage);
670 2
                $this->em->remove($ProductImage);
671 3
            }
672
673
            // 画像の登録
674 3
            $images = explode(',', $row['商品画像']);
675 3
            $rank = 1;
676 3
            foreach ($images as $image) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
677
678 3
                $ProductImage = new ProductImage();
679 3
                $ProductImage->setFileName(Str::trimAll($image));
680 3
                $ProductImage->setProduct($Product);
681 3
                $ProductImage->setRank($rank);
682
683 3
                $Product->addProductImage($ProductImage);
684 3
                $rank++;
685 3
                $this->em->persist($ProductImage);
686 3
            }
687 3
        }
688 3
    }
689
690
691
    /**
692
     * 商品カテゴリの削除、登録
693
     */
694 3
    protected function createProductCategory($row, Product $Product, $app, $data)
695
    {
696
        // カテゴリの削除
697 3
        $ProductCategories = $Product->getProductCategories();
698 3
        foreach ($ProductCategories as $ProductCategory) {
699 2
            $Product->removeProductCategory($ProductCategory);
700 2
            $this->em->remove($ProductCategory);
701 2
            $this->em->flush($ProductCategory);
702 3
        }
703
704 3
        if ($row['商品カテゴリ(ID)'] == '') {
705
            // 入力されていなければ削除のみ
706
            return;
707
        }
708
709
        // カテゴリの登録
710 3
        $categories = explode(',', $row['商品カテゴリ(ID)']);
711 3
        $rank = 1;
712 3
        foreach ($categories as $category) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
713
714 3
            if (preg_match('/^\d+$/', $category)) {
715 3
                $Category = $app['eccube.repository.category']->find($category);
716 3
                if (!$Category) {
717
                    $this->addErrors(($data->key() + 1).'行目の商品カテゴリ(ID)「'.$category.'」が存在しません。');
718
                } else {
719 3
                    $ProductCategory = new ProductCategory();
720 3
                    $ProductCategory->setProductId($Product->getId());
721 3
                    $ProductCategory->setCategoryId($Category->getId());
722 3
                    $ProductCategory->setProduct($Product);
723 3
                    $ProductCategory->setCategory($Category);
724 3
                    $ProductCategory->setRank($rank);
725 3
                    $Product->addProductCategory($ProductCategory);
726 3
                    $rank++;
727 3
                    $this->em->persist($ProductCategory);
728
                }
729 3
            } else {
730
                $this->addErrors(($data->key() + 1).'行目の商品カテゴリ(ID)「'.$category.'」が存在しません。');
731
            }
732 3
        }
733
734 3
    }
735
736
737
    /**
738
     * タグの登録
739
     *
740
     * @param array $row
741
     * @param Product $Product
742
     * @param Application $app
743
     * @param CsvImportService $data
744
     */
745 3
    protected function createProductTag($row, Product $Product, $app, $data)
746
    {
747
        // タグの削除
748 3
        $ProductTags = $Product->getProductTag();
749 3
        foreach ($ProductTags as $ProductTags) {
750 1
            $Product->removeProductTag($ProductTags);
751 1
            $this->em->remove($ProductTags);
752 3
        }
753
754 3
        if ($row['タグ(ID)'] == '') {
755
            return;
756
        }
757
758
        // タグの登録
759 3
        $tags = explode(',', $row['タグ(ID)']);
760 3
        foreach ($tags as $tag_id) {
761 3
            $Tag = null;
762 3
            if (preg_match('/^\d+$/', $tag_id)) {
763 3
                $Tag = $app['eccube.repository.master.tag']->find($tag_id);
764 3
                if ($Tag) {
765 3
                    $ProductTags = new ProductTag();
766
                    $ProductTags
767 3
                        ->setProduct($Product)
768 3
                        ->setTag($Tag);
769
770 3
                    $Product->addProductTag($ProductTags);
771
772 3
                    $this->em->persist($ProductTags);
773 3
                }
774 3
            }
775 3
            if (!$Tag) {
776
                $this->addErrors(($data->key() + 1) . '行目のタグ(ID)「' . $tag_id . '」が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
777
            }
778 3
        }
779 3
    }
780
781
782
    /**
783
     * 商品規格分類1、商品規格分類2がnullとなる商品規格情報を作成
784
     */
785 3
    protected function createProductClass($row, Product $Product, $app, $data, $ClassCategory1 = null, $ClassCategory2 = null)
786
    {
787
        // 規格分類1、規格分類2がnullとなる商品を作成
788
789 3
        $ProductClass = new ProductClass();
790 3
        $ProductClass->setProduct($Product);
791
792
793 3 View Code Duplication
        if ($row['商品種別(ID)'] == '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
794
            $this->addErrors(($data->key() + 1) . '行目の商品種別(ID)が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
795
        } else {
796 3
            if (preg_match('/^\d+$/', $row['商品種別(ID)'])) {
797 3
                $ProductType = $app['eccube.repository.master.product_type']->find($row['商品種別(ID)']);
798 3
                if (!$ProductType) {
799
                    $this->addErrors(($data->key() + 1) . '行目の商品種別(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
800
                } else {
801 3
                    $ProductClass->setProductType($ProductType);
802
                }
803 3
            } else {
804
                $this->addErrors(($data->key() + 1) . '行目の商品種別(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
805
            }
806
        }
807
808 3
        $ProductClass->setClassCategory1($ClassCategory1);
809 3
        $ProductClass->setClassCategory2($ClassCategory2);
810
811 3
        if ($row['発送日目安(ID)'] != '') {
812 2
            if (preg_match('/^\d+$/', $row['発送日目安(ID)'])) {
813 2
                $DeliveryDate = $app['eccube.repository.delivery_date']->find($row['発送日目安(ID)']);
814 2
                if (!$DeliveryDate) {
815
                    $this->addErrors(($data->key() + 1) . '行目の発送日目安(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
816
                } else {
817 3
                    $ProductClass->setDeliveryDate($DeliveryDate);
818
                }
819 2
            } else {
820
                $this->addErrors(($data->key() + 1) . '行目の発送日目安(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
821
            }
822 2
        }
823
824 3 View Code Duplication
        if (Str::isNotBlank($row['商品コード'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
825 2
            $ProductClass->setCode(Str::trimAll($row['商品コード']));
826 2
        } else {
827 1
            $ProductClass->setCode(null);
828
        }
829
830 3 View Code Duplication
        if ($row['在庫数無制限フラグ'] == '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
831
            $this->addErrors(($data->key() + 1) . '行目の在庫数無制限フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
832
        } else {
833 3
            if ($row['在庫数無制限フラグ'] == (string) Constant::DISABLED) {
834 3
                $ProductClass->setStockUnlimited(Constant::DISABLED);
835
                // 在庫数が設定されていなければエラー
836 3
                if ($row['在庫数'] == '') {
837
                    $this->addErrors(($data->key() + 1) . '行目の在庫数が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
838
                } else {
839 3
                    $stock = str_replace(',', '', $row['在庫数']);
840 3
                    if (preg_match('/^\d+$/', $stock) && $stock >= 0) {
841 3
                        $ProductClass->setStock($stock);
842 3
                    } else {
843
                        $this->addErrors(($data->key() + 1) . '行目の在庫数は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
844
                    }
845
                }
846
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
847 3
            } else if ($row['在庫数無制限フラグ'] == (string) Constant::ENABLED) {
848
                $ProductClass->setStockUnlimited(Constant::ENABLED);
849
                $ProductClass->setStock(null);
850
            } else {
851
                $this->addErrors(($data->key() + 1) . '行目の在庫数無制限フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
852
            }
853
        }
854
855 3
        if ($row['販売制限数'] != '') {
856
            $saleLimit = str_replace(',', '', $row['販売制限数']);
857
            if (preg_match('/^\d+$/', $saleLimit) && $saleLimit >= 0) {
858
                $ProductClass->setSaleLimit($saleLimit);
859
            } else {
860
                $this->addErrors(($data->key() + 1) . '行目の販売制限数は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
861
            }
862
        }
863
864 3
        if ($row['通常価格'] != '') {
865 2
            $price01 = str_replace(',', '', $row['通常価格']);
866 2
            if (preg_match('/^\d+$/', $price01) && $price01 >= 0) {
867 2
                $ProductClass->setPrice01($price01);
868 2
            } else {
869
                $this->addErrors(($data->key() + 1) . '行目の通常価格は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
870
            }
871 2
        }
872
873 3
        if ($row['販売価格'] == '') {
874
            $this->addErrors(($data->key() + 1) . '行目の販売価格が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
875
        } else {
876 3
            $price02 = str_replace(',', '', $row['販売価格']);
877 3
            if (preg_match('/^\d+$/', $price02) && $price02 >= 0) {
878 3
                $ProductClass->setPrice02($price02);
879 3
            } else {
880
                $this->addErrors(($data->key() + 1) . '行目の販売価格は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
881
            }
882
        }
883
884 3
        if ($row['送料'] != '') {
885 2
            $delivery_fee = str_replace(',', '', $row['送料']);
886 2
            if (preg_match('/^\d+$/', $delivery_fee) && $delivery_fee >= 0) {
887 2
                $ProductClass->setDeliveryFee($delivery_fee);
888 2
            } else {
889
                $this->addErrors(($data->key() + 1) . '行目の送料は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
890
            }
891 2
        }
892
893 3 View Code Duplication
        if ($row['商品規格削除フラグ'] == '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
894
            $ProductClass->setDelFlg(Constant::DISABLED);
895
        } else {
896 3
            if ($row['商品規格削除フラグ'] == (string) Constant::DISABLED || $row['商品規格削除フラグ'] == (string) Constant::ENABLED) {
897 3
                $ProductClass->setDelFlg($row['商品規格削除フラグ']);
898 3
            } else {
899
                $this->addErrors(($data->key() + 1) . '行目の商品規格削除フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
900
            }
901
        }
902
903 3
        $Product->addProductClass($ProductClass);
904 3
        $ProductStock = new ProductStock();
905 3
        $ProductClass->setProductStock($ProductStock);
906 3
        $ProductStock->setProductClass($ProductClass);
907
908 3
        if (!$ProductClass->getStockUnlimited()) {
909 3
            $ProductStock->setStock($ProductClass->getStock());
910 3
        } else {
911
            // 在庫無制限時はnullを設定
912
            $ProductStock->setStock(null);
913
        }
914
915 3
        $this->em->persist($ProductClass);
916 3
        $this->em->persist($ProductStock);
917
918 3
        return $ProductClass;
919
920
    }
921
922
923
    /**
924
     * 商品規格情報を更新
925
     */
926 5
    protected function updateProductClass($row, Product $Product, ProductClass $ProductClass, $app, $data)
927
    {
928
929 1
        $ProductClass->setProduct($Product);
930
931 1 View Code Duplication
        if ($row['商品種別(ID)'] == '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
932
            $this->addErrors(($data->key() + 1) . '行目の商品種別(ID)が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
933
        } else {
934 1
            if (preg_match('/^\d+$/', $row['商品種別(ID)'])) {
935 1
                $ProductType = $app['eccube.repository.master.product_type']->find($row['商品種別(ID)']);
936 1
                if (!$ProductType) {
937
                    $this->addErrors(($data->key() + 1) . '行目の商品種別(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
938
                } else {
939 1
                    $ProductClass->setProductType($ProductType);
940
                }
941 1
            } else {
942
                $this->addErrors(($data->key() + 1) . '行目の商品種別(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
943
            }
944
        }
945
946
        // 規格分類1、2をそれぞれセットし作成
947 1
        if ($row['規格分類1(ID)'] != '') {
948 1
            if (preg_match('/^\d+$/', $row['規格分類1(ID)'])) {
949 1
                $ClassCategory = $app['eccube.repository.class_category']->find($row['規格分類1(ID)']);
950 1
                if (!$ClassCategory) {
951 3
                    $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
952
                } else {
953 1
                    $ProductClass->setClassCategory1($ClassCategory);
954
                }
955 1
            } else {
956
                $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
957
            }
958 1
        }
959
960 1
        if ($row['規格分類2(ID)'] != '') {
961 1
            if (preg_match('/^\d+$/', $row['規格分類2(ID)'])) {
962 1
                $ClassCategory = $app['eccube.repository.class_category']->find($row['規格分類2(ID)']);
963 1
                if (!$ClassCategory) {
964
                    $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
965
                } else {
966 1
                    $ProductClass->setClassCategory2($ClassCategory);
967
                }
968 1
            } else {
969
                $this->addErrors(($data->key() + 1) . '行目の規格分類2(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
970
            }
971 1
        }
972
973 1
        if ($row['発送日目安(ID)'] != '') {
974
            if (preg_match('/^\d+$/', $row['発送日目安(ID)'])) {
975
                $DeliveryDate = $app['eccube.repository.delivery_date']->find($row['発送日目安(ID)']);
976
                if (!$DeliveryDate) {
977
                    $this->addErrors(($data->key() + 1) . '行目の発送日目安(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
978
                } else {
979
                    $ProductClass->setDeliveryDate($DeliveryDate);
980
                }
981
            } else {
982
                $this->addErrors(($data->key() + 1) . '行目の発送日目安(ID)が存在しません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
983
            }
984
        }
985
986 1 View Code Duplication
        if (Str::isNotBlank($row['商品コード'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
987 1
            $ProductClass->setCode(Str::trimAll($row['商品コード']));
988 1
        } else {
989
            $ProductClass->setCode(null);
990
        }
991
992 1 View Code Duplication
        if ($row['在庫数無制限フラグ'] == '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
993 3
            $this->addErrors(($data->key() + 1) . '行目の在庫数無制限フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
994
        } else {
995 1
            if ($row['在庫数無制限フラグ'] == (string) Constant::DISABLED) {
996 1
                $ProductClass->setStockUnlimited(Constant::DISABLED);
997
                // 在庫数が設定されていなければエラー
998 1
                if ($row['在庫数'] == '') {
999
                    $this->addErrors(($data->key() + 1) . '行目の在庫数が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1000
                } else {
1001 1
                    $stock = str_replace(',', '', $row['在庫数']);
1002 1
                    if (preg_match('/^\d+$/', $stock) && $stock >= 0) {
1003 1
                        $ProductClass->setStock($row['在庫数']);
1004 1
                    } else {
1005
                        $this->addErrors(($data->key() + 1) . '行目の在庫数は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1006
                    }
1007
                }
1008
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
1009 1
            } else if ($row['在庫数無制限フラグ'] == (string) Constant::ENABLED) {
1010 1
                $ProductClass->setStockUnlimited(Constant::ENABLED);
1011 1
                $ProductClass->setStock(null);
1012 1
            } else {
1013
                $this->addErrors(($data->key() + 1) . '行目の在庫数無制限フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1014
            }
1015
        }
1016
1017 1
        if ($row['販売制限数'] != '') {
1018 1
            $saleLimit = str_replace(',', '', $row['販売制限数']);
1019 1
            if (preg_match('/^\d+$/', $saleLimit) && $saleLimit >= 0) {
1020 1
                $ProductClass->setSaleLimit($saleLimit);
1021 1
            } else {
1022
                $this->addErrors(($data->key() + 1) . '行目の販売制限数は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1023
            }
1024 1
        }
1025
1026 1
        if ($row['通常価格'] != '') {
1027 1
            $price01 = str_replace(',', '', $row['通常価格']);
1028 1
            if (preg_match('/^\d+$/', $price01) && $price01 >= 0) {
1029 1
                $ProductClass->setPrice01($price01);
1030 1
            } else {
1031
                $this->addErrors(($data->key() + 1) . '行目の通常価格は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1032
            }
1033 1
        }
1034
1035 1
        if ($row['販売価格'] == '') {
1036
            $this->addErrors(($data->key() + 1) . '行目の販売価格が設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1037
        } else {
1038 1
            $price02 = str_replace(',', '', $row['販売価格']);
1039 1
            if (preg_match('/^\d+$/', $price02) && $price02 >= 0) {
1040 1
                $ProductClass->setPrice02($price02);
1041 1
            } else {
1042
                $this->addErrors(($data->key() + 1) . '行目の販売価格は0以上の数値を設定してください。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1043
            }
1044
        }
1045
1046 1 View Code Duplication
        if ($row['商品規格削除フラグ'] == '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1047
            $ProductClass->setDelFlg(Constant::DISABLED);
1048
        } else {
1049 1
            if ($row['商品規格削除フラグ'] == (string) Constant::DISABLED || $row['商品規格削除フラグ'] == (string) Constant::ENABLED) {
1050 1
                $ProductClass->setDelFlg($row['商品規格削除フラグ']);
1051 1
            } else {
1052
                $this->addErrors(($data->key() + 1) . '行目の商品規格削除フラグが設定されていません。');
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
1053
            }
1054
        }
1055
1056 1
        $ProductStock = $ProductClass->getProductStock();
1057
1058 1
        if (!$ProductClass->getStockUnlimited()) {
1059 1
            $ProductStock->setStock($ProductClass->getStock());
1060 1
        } else {
1061
            // 在庫無制限時はnullを設定
1062 1
            $ProductStock->setStock(null);
1063 5
        }
1064
1065 1
        return $ProductClass;
1066
    }
1067
1068
    /**
1069
     * 登録、更新時のエラー画面表示
1070
     *
1071
     */
1072
    protected function addErrors($message)
1073
    {
1074
        $e = new CsvImportException($message);
1075
        $this->errors[] = $e;
1076
    }
1077
1078
    /**
1079
     * @return array
1080
     */
1081 5
    protected function getErrors()
1082
    {
1083 5
        return $this->errors;
1084
    }
1085
1086
    /**
1087
     *
1088
     * @return boolean
1089
     */
1090 5
    protected function hasErrors()
1091
    {
1092 5
        return count($this->getErrors()) > 0;
1093
    }
1094
1095
    /**
1096
     * 商品登録CSVヘッダー定義
1097
     */
1098 4
    private function getProductCsvHeader()
1099
    {
1100
        return array(
1101 4
            '商品ID' => 'id',
1102 4
            '公開ステータス(ID)' => 'status',
1103 4
            '商品名' => 'name',
1104 4
            'ショップ用メモ欄' => 'note',
1105 4
            '商品説明(一覧)' => 'description_list',
1106 4
            '商品説明(詳細)' => 'description_detail',
1107 4
            '検索ワード' => 'search_word',
1108 4
            'フリーエリア' => 'free_area',
1109 4
            '商品削除フラグ' => 'product_del_flg',
1110 4
            '商品画像' => 'product_image',
1111 4
            '商品カテゴリ(ID)' => 'product_category',
1112 4
            'タグ(ID)' => 'product_tag',
1113 4
            '商品種別(ID)' => 'product_type',
1114 4
            '規格分類1(ID)' => 'class_category1',
1115 4
            '規格分類2(ID)' => 'class_category2',
1116 4
            '発送日目安(ID)' => 'deliveryFee',
1117 4
            '商品コード' => 'product_code',
1118 4
            '在庫数' => 'stock',
1119 4
            '在庫数無制限フラグ' => 'stock_unlimited',
1120 4
            '販売制限数' => 'sale_limit',
1121 4
            '通常価格' => 'price01',
1122 4
            '販売価格' => 'price02',
1123 4
            '送料' => 'delivery_fee',
1124 4
            '商品規格削除フラグ' => 'product_class_del_flg',
1125 4
        );
1126
    }
1127
1128
1129
    /**
1130
     * カテゴリCSVヘッダー定義
1131
     */
1132 3
    private function getCategoryCsvHeader()
1133
    {
1134
        return array(
1135 3
            'カテゴリID' => 'id',
1136 3
            'カテゴリ名' => 'category_name',
1137 3
            '親カテゴリID' => 'parent_category_id',
1138 3
        );
1139
    }
1140
}
1141