Issues (2687)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Admin/Product/ProductClassController.php (12 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 Doctrine\Common\Collections\ArrayCollection;
28
use Eccube\Application;
29
use Eccube\Common\Constant;
30
use Eccube\Entity\ClassName;
31
use Eccube\Entity\Product;
32
use Eccube\Entity\ProductClass;
33
use Eccube\Entity\ProductStock;
34
use Eccube\Entity\TaxRule;
35
use Eccube\Event\EccubeEvents;
36
use Eccube\Event\EventArgs;
37
use Symfony\Component\Form\FormBuilder;
38
use Symfony\Component\Form\FormError;
39
use Symfony\Component\HttpFoundation\RedirectResponse;
40
use Symfony\Component\HttpFoundation\Request;
41
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
42
use Symfony\Component\Validator\Constraints as Assert;
43
44
class ProductClassController
45
{
46
    /**
47
     * 商品規格が登録されていなければ新規登録、登録されていれば更新画面を表示する
48
     */
49 11
    public function index(Application $app, Request $request, $id)
50
    {
51
        /** @var $Product \Eccube\Entity\Product */
52 11
        $Product = $app['eccube.repository.product']->find($id);
53 11
        $hasClassCategoryFlg = false;
54
55 11
        if (!$Product) {
56
            throw new NotFoundHttpException('商品が存在しません');
57
        }
58
59
        // 商品規格情報が存在しなければ新規登録させる
60 11
        if (!$Product->hasProductClass()) {
61
            // 登録画面を表示
62
63 6
            log_info('商品規格新規登録表示', array($id));
64
65 6
            $builder = $app['form.factory']->createBuilder();
66
67
            $builder
68 6
                ->add('class_name1', 'entity', array(
69 6
                    'class' => 'Eccube\Entity\ClassName',
70 6
                    'property' => 'name',
71 6
                    'empty_value' => '規格1を選択',
72
                    'constraints' => array(
73 6
                        new Assert\NotBlank(),
74
                    ),
75
                ))
76 6
                ->add('class_name2', 'entity', array(
77 6
                    'class' => 'Eccube\Entity\ClassName',
78
                    'property' => 'name',
79
                    'empty_value' => '規格2を選択',
80
                    'required' => false,
81
                ));
82
83 6
            $event = new EventArgs(
84
                array(
85 6
                    'builder' => $builder,
86 6
                    'Product' => $Product,
87
                ),
88
                $request
89
            );
90 6
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_INDEX_INITIALIZE, $event);
91
92 6
            $form = $builder->getForm();
93
94 6
            $productClassForm = null;
95
96 6
            if ('POST' === $request->getMethod()) {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
97
98 4
                $form->handleRequest($request);
99
100 4
                if ($form->isValid()) {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
101
102 4
                    $data = $form->getData();
103
104 4
                    $ClassName1 = $data['class_name1'];
105 4
                    $ClassName2 = $data['class_name2'];
106
107 4
                    log_info('選択された商品規格', array($ClassName1, $ClassName2));
108
109
                    // 各規格が選択されている際に、分類を保有しているか確認
110 4
                    $class1Valied = $this->isValiedCategory($ClassName1);
111 4
                    $class2Valied = $this->isValiedCategory($ClassName2);
112
113
                    // 規格が選択されていないか、選択された状態で分類が保有されていれば、画面表示
114 4
                    if($class1Valied && $class2Valied){
115 4
                        $hasClassCategoryFlg = true;
116
                    }
117
118 4
                    if (!is_null($ClassName2) && $ClassName1->getId() == $ClassName2->getId()) {
119
                        // 規格1と規格2が同じ値はエラー
120
                        $form['class_name2']->addError(new FormError('規格1と規格2は、同じ値を使用できません。'));
121
                    } else {
122
                        // 規格分類が設定されていない商品規格を取得
123 4
                        $orgProductClasses = $Product->getProductClasses();
124 4
                        $sourceProduct = $orgProductClasses[0];
125
126
                        // 規格分類が組み合わされた商品規格を取得
127 4
                        $ProductClasses = $this->createProductClasses($app, $Product, $ClassName1, $ClassName2);
128
129
                        // 組み合わされた商品規格にデフォルト値をセット
130 4
                        foreach ($ProductClasses as $productClass) {
131 4
                            $this->setDefualtProductClass($app, $productClass, $sourceProduct);
132
                        }
133
134 4
                        $builder = $app['form.factory']->createBuilder();
135
136
                        $builder
137 4
                            ->add('product_classes', 'collection', array(
138 4
                                'type' => 'admin_product_class',
139
                                'allow_add' => true,
140
                                'allow_delete' => true,
141 4
                                'data' => $ProductClasses,
142
                             ));
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 28 spaces, but found 29.
Loading history...
143
144 4
                        $event = new EventArgs(
145
                            array(
146 4
                                'builder' => $builder,
147 4
                                'Product' => $Product,
148 4
                                'ProductClasses' => $ProductClasses,
149
                            ),
150
                            $request
151
                        );
152 4
                        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_INDEX_CLASSES, $event);
153
154 4
                        $productClassForm = $builder->getForm()->createView();
155
0 ignored issues
show
Blank line found at end of control structure
Loading history...
156
                    }
157
0 ignored issues
show
Blank line found at end of control structure
Loading history...
158
                }
159
            }
160
161 6
            return $app->render('Product/product_class.twig', array(
162 6
                'form' => $form->createView(),
163 6
                'classForm' => $productClassForm,
164 6
                'Product' => $Product,
165
                'not_product_class' => true,
166
                'error' => null,
167 6
                'has_class_category_flg' => $hasClassCategoryFlg,
168
            ));
169
        } else {
170
            // 既に商品規格が登録されている場合、商品規格画面を表示する
171
172 6
            log_info('商品規格登録済表示', array($id));
173
174
            // 既に登録されている商品規格を取得
175 6
            $ProductClasses = $this->getProductClassesExcludeNonClass($Product);
176
177
            // 設定されている規格分類1、2を取得(商品規格の規格分類には必ず同じ値がセットされている)
178 6
            $ProductClass = $ProductClasses[0];
179 6
            $ClassName1 = $ProductClass->getClassCategory1()->getClassName();
180 6
            $ClassName2 = null;
181 6
            if (!is_null($ProductClass->getClassCategory2())) {
182 5
                $ClassName2 = $ProductClass->getClassCategory2()->getClassName();
183
            }
184
185
            // 規格分類が組み合わされた空の商品規格を取得
186 6
            $createProductClasses = $this->createProductClasses($app, $Product, $ClassName1, $ClassName2);
187
188 6
            $mergeProductClasses = array();
189
190
            // 商品税率が設定されている場合、商品税率を項目に設定
191 6
            $BaseInfo = $app['eccube.repository.base_info']->get();
192 6 View Code Duplication
            if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
193 6
                foreach ($ProductClasses as $class) {
194 6
                    if ($class->getTaxRule() && !$class->getTaxRule()->getDelFlg()) {
195 6
                        $class->setTaxRate($class->getTaxRule()->getTaxRate());
196
                    }
197
                }
198
            }
199
200
            // 登録済み商品規格と空の商品規格をマージ
201 6
            $flag = false;
202 6
            foreach ($createProductClasses as $createProductClass) {
203
                // 既に登録済みの商品規格にチェックボックスを設定
204 6
                foreach ($ProductClasses as $productClass) {
205 6
                    if ($productClass->getClassCategory1() == $createProductClass->getClassCategory1() &&
206 6
                            $productClass->getClassCategory2() == $createProductClass->getClassCategory2()) {
207
                                // チェックボックスを追加
208 6
                                $productClass->setAdd(true);
209 6
                                $flag = true;
210 6
                                break;
211
                    }
212
                }
213
214 6
                if (!$flag) {
215
                    $mergeProductClasses[] = $createProductClass;
216
                }
217
218 6
                $flag = false;
219
            }
220
221
            // 登録済み商品規格と空の商品規格をマージ
222 6
            foreach ($mergeProductClasses as $mergeProductClass) {
223
                // 空の商品規格にデフォルト値を設定
224
                $this->setDefualtProductClass($app, $mergeProductClass, $ProductClass);
225 6
                $ProductClasses->add($mergeProductClass);
226
            }
227
228 6
            $builder = $app['form.factory']->createBuilder();
229
230
            $builder
231 6
                ->add('product_classes', 'collection', array(
232 6
                    'type' => 'admin_product_class',
233
                    'allow_add' => true,
234
                    'allow_delete' => true,
235 6
                    'data' => $ProductClasses,
236
                ));
237
238 6
            $event = new EventArgs(
239
                array(
240 6
                    'builder' => $builder,
241 6
                    'Product' => $Product,
242 6
                    'ProductClasses' => $ProductClasses,
243
                ),
244
                $request
245
            );
246 6
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_INDEX_CLASSES, $event);
247
248 6
            $productClassForm = $builder->getForm()->createView();
249
250 6
            return $app->render('Product/product_class.twig', array(
251 6
                'classForm' => $productClassForm,
252 6
                'Product' => $Product,
253 6
                'class_name1' => $ClassName1,
254 6
                'class_name2' => $ClassName2,
255
                'not_product_class' => false,
256
                'error' => null,
257
                'has_class_category_flg' => true,
258
            ));
259
        }
260
    }
261
262
    /**
263
     * 商品規格の登録、更新、削除を行う
264
     *
265
     * @param Application $app
266
     * @param Request     $request
267
     * @param int         $id
268
     * @return RedirectResponse
269
     */
270 12
    public function edit(Application $app, Request $request, $id)
271
    {
272
273
        /* @var $softDeleteFilter \Eccube\Doctrine\Filter\SoftDeleteFilter */
274 12
        $softDeleteFilter = $app['orm.em']->getFilters()->getFilter('soft_delete');
275 12
        $softDeleteFilter->setExcludes(array(
276 12
            'Eccube\Entity\TaxRule',
277
        ));
278
279
        /** @var $Product \Eccube\Entity\Product */
280 12
        $Product = $app['eccube.repository.product']->find($id);
281
282 12
        if (!$Product) {
283
            throw new NotFoundHttpException('商品が存在しません');
284
        }
285
286
        /* @var FormBuilder $builder */
287 12
        $builder = $app['form.factory']->createBuilder();
288 12
        $builder->add('product_classes', 'collection', array(
289 12
                    'type' => 'admin_product_class',
290
                    'allow_add' => true,
291
                    'allow_delete' => true,
292
        ));
293
294 12
        $event = new EventArgs(
295
            array(
296 12
                'builder' => $builder,
297 12
                'Product' => $Product,
298
            ),
299
            $request
300
        );
301 12
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_INITIALIZE, $event);
302
303 12
        $form = $builder->getForm();
304
305 12
        $ProductClasses = $this->getProductClassesExcludeNonClass($Product);
306
307 12
        $form->handleRequest($request);
308 12
        if ($form->isSubmitted()) {
309 10
            switch ($request->get('mode')) {
310 10
                case 'edit':
311
                    // 新規登録
312 4
                    log_info('商品規格新規登録開始', array($id));
313
314 4 View Code Duplication
                    if (count($ProductClasses) > 0) {
315
                        // 既に登録されていれば最初の画面に戻す
316
                        log_info('商品規格登録済', array($id));
317
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
318
                    }
319
320 4
                    $addProductClasses = array();
321
322 4
                    $tmpProductClass = null;
323 4 View Code Duplication
                    foreach ($form->get('product_classes') as $formData) {
324
                        // 追加対象の行をvalidate
325 4
                        $ProductClass = $formData->getData();
326
327 4
                        if ($ProductClass->getAdd()) {
328 4
                            if ($formData->isValid()) {
329 3
                                $addProductClasses[] = $ProductClass;
330
                            } else {
331
                                // 対象行のエラー
332 1
                                return $this->render($app, $Product, $ProductClass, true, $form);
333
                            }
334
                        }
335 3
                        $tmpProductClass = $ProductClass;
336
                    }
337
338 3 View Code Duplication
                    if (count($addProductClasses) == 0) {
339
                        // 対象がなければエラー
340
                        log_info('商品規格が未選択', array($id));
341
                        $error = array('message' => '商品規格が選択されていません。');
342
                        return $this->render($app, $Product, $tmpProductClass, true, $form, $error);
343
                    }
344
345
                    // 選択された商品規格を登録
346 3
                    $this->insertProductClass($app, $Product, $addProductClasses);
347
348
                    // デフォルトの商品規格を更新
349 3
                    $defaultProductClass = $app['eccube.repository.product_class']
350 3
                            ->findOneBy(array('Product' => $Product, 'ClassCategory1' => null, 'ClassCategory2' => null));
351
352 3
                    $defaultProductClass->setDelFlg(Constant::ENABLED);
353
354 3
                    $app['orm.em']->flush();
355
356 3
                    log_info('商品規格新規登録完了', array($id));
357
358 3
                    $event = new EventArgs(
359
                        array(
360 3
                            'form' => $form,
361 3
                            'Product' => $Product,
362 3
                            'defaultProductClass' => $defaultProductClass,
363
                        ),
364
                        $request
365
                    );
366 3
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_COMPLETE, $event);
367
368 3
                    $app->addSuccess('admin.product.product_class.save.complete', 'admin');
369
370 3
                    break;
371 6
                case 'update':
372
                    // 更新
373 5
                    log_info('商品規格更新開始', array($id));
374
375 5 View Code Duplication
                    if (count($ProductClasses) == 0) {
376
                        // 商品規格が0件であれば最初の画面に戻す
377
                        log_info('商品規格が存在しません', array($id));
378
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
379
                    }
380
381 5
                    $checkProductClasses = array();
382 5
                    $removeProductClasses = array();
383
384 5
                    $tempProductClass = null;
385 5 View Code Duplication
                    foreach ($form->get('product_classes') as $formData) {
386
                        // 追加対象の行をvalidate
387 5
                        $ProductClass = $formData->getData();
388
389 5
                        if ($ProductClass->getAdd()) {
390 5
                            if ($formData->isValid()) {
391 4
                                $checkProductClasses[] = $ProductClass;
392
                            } else {
393 5
                                return $this->render($app, $Product, $ProductClass, false, $form);
394
                            }
395
                        } else {
396
                            // 削除対象の行
397 1
                            $removeProductClasses[] = $ProductClass;
398
                        }
399 4
                        $tempProductClass = $ProductClass;
400
                    }
401
402 4 View Code Duplication
                    if (count($checkProductClasses) == 0) {
403
                        // 対象がなければエラー
404
                        log_info('商品規格が存在しません', array($id));
405
                        $error = array('message' => '商品規格が選択されていません。');
406
                        return $this->render($app, $Product, $tempProductClass, false, $form, $error);
407
                    }
408
409
410
                    // 登録対象と更新対象の行か判断する
411 4
                    $addProductClasses = array();
412 4
                    $updateProductClasses = array();
413 4
                    foreach ($checkProductClasses as $cp) {
414 4
                        $flag = false;
415
416
                        // 既に登録済みの商品規格か確認
417 4
                        foreach ($ProductClasses as $productClass) {
418 4
                            if ($productClass->getProduct()->getId() == $id &&
419 4
                                    $productClass->getClassCategory1() == $cp->getClassCategory1() &&
420 4
                                    $productClass->getClassCategory2() == $cp->getClassCategory2()) {
421 4
                                $updateProductClasses[] = $cp;
422
423
                                // 商品情報
424 4
                                $cp->setProduct($Product);
425
                                // 商品在庫
426 4
                                $productStock = $productClass->getProductStock();
427 4
                                if (!$cp->getStockUnlimited()) {
428 1
                                    $productStock->setStock($cp->getStock());
429
                                } else {
430 3
                                    $productStock->setStock(null);
431
                                }
432 4
                                $this->setDefualtProductClass($app, $productClass, $cp);
433 4
                                $flag = true;
434 4
                                break;
435
                            }
436
                        }
437 4
                        if (!$flag) {
438 4
                            $addProductClasses[] = $cp;
439
                        }
440
                    }
441
442 4
                    foreach ($removeProductClasses as $rc) {
443
                        // 登録されている商品規格に削除フラグをセット
444 1
                        foreach ($ProductClasses as $productClass) {
445 1
                            if ($productClass->getProduct()->getId() == $id &&
446 1
                                    $productClass->getClassCategory1() == $rc->getClassCategory1() &&
447 1
                                    $productClass->getClassCategory2() == $rc->getClassCategory2()) {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
448
449 1
                                $productClass->setDelFlg(Constant::ENABLED);
450 4
                                break;
451
                            }
452
                        }
453
                    }
454
455
                    // 選択された商品規格を登録
456 4
                    $this->insertProductClass($app, $Product, $addProductClasses);
457
458 4
                    $app['orm.em']->flush();
459
460 4
                    log_info('商品規格更新完了', array($id));
461
462 4
                    $event = new EventArgs(
463
                        array(
464 4
                            'form' => $form,
465 4
                            'Product' => $Product,
466 4
                            'updateProductClasses' => $updateProductClasses,
467 4
                            'addProductClasses' => $addProductClasses,
468
                        ),
469
                        $request
470
                    );
471 4
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_UPDATE, $event);
472
473 4
                    $app->addSuccess('admin.product.product_class.update.complete', 'admin');
474
475 4
                    break;
476
477 1
                case 'delete':
478
                    // 削除
479 1
                    log_info('商品規格削除開始', array($id));
480
481 1 View Code Duplication
                    if (count($ProductClasses) == 0) {
482
                        // 既に商品が削除されていれば元の画面に戻す
483
                        log_info('商品規格が存在しません', array($id));
484
                        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
485
                    }
486
487 1
                    foreach ($ProductClasses as $ProductClass) {
488
                        // 登録されている商品規格に削除フラグをセット
489 1
                        $ProductClass->setDelFlg(Constant::ENABLED);
490
                    }
491
492
                    /* @var $softDeleteFilter \Eccube\Doctrine\Filter\SoftDeleteFilter */
493 1
                    $softDeleteFilter = $app['orm.em']->getFilters()->getFilter('soft_delete');
494 1
                    $softDeleteFilter->setExcludes(array(
495
                        'Eccube\Entity\ProductClass'
496 1
                    ));
497
498
                    // デフォルトの商品規格を更新
499 1
                    $defaultProductClass = $app['eccube.repository.product_class']
500 1
                            ->findOneBy(array('Product' => $Product, 'ClassCategory1' => null, 'ClassCategory2' => null, 'del_flg' => Constant::ENABLED));
501
502 1
                    $defaultProductClass->setDelFlg(Constant::DISABLED);
503
504 1
                    $app['orm.em']->flush();
505 1
                    log_info('商品規格削除完了', array($id));
506
507 1
                    $event = new EventArgs(
508
                        array(
509 1
                            'form' => $form,
510 1
                            'Product' => $Product,
511 1
                            'defaultProductClass' => $defaultProductClass,
512
                        ),
513
                        $request
514
                    );
515 1
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_PRODUCT_CLASS_EDIT_DELETE, $event);
516
517 1
                    $app->addSuccess('admin.product.product_class.delete.complete', 'admin');
518
519 1
                    break;
520
                default:
521 8
                    break;
522
            }
523
0 ignored issues
show
Blank line found at end of control structure
Loading history...
524
        }
525
526 10
        return $app->redirect($app->url('admin_product_product_class', array('id' => $id)));
527
    }
528
529
    /**
530
     * 登録、更新時のエラー画面表示
531
     *
532
     */
533 2
    protected function render($app, $Product, $ProductClass, $not_product_class, $classForm, $error = null)
534
    {
535
536 2
        $ClassName1 = null;
537 2
        $ClassName2 = null;
538
        // 規格を取得
539 2
        if (isset($ProductClass)) {
540 2
            $ClassCategory1 = $ProductClass->getClassCategory1();
541 2
            if ($ClassCategory1) {
542 2
                $ClassName1 = $ClassCategory1->getClassName();
543
            }
544 2
            $ClassCategory2 = $ProductClass->getClassCategory2();
545 2
            if ($ClassCategory2) {
546 1
                $ClassName2 = $ClassCategory2->getClassName();
547
            }
548
        }
549
550 2
        $form = $app->form()
551 2
            ->add('class_name1', 'entity', array(
552 2
                'class' => 'Eccube\Entity\ClassName',
553 2
                'property' => 'name',
554 2
                'empty_value' => '規格1を選択',
555 2
                'data' => $ClassName1,
556
            ))
557 2
            ->add('class_name2', 'entity', array(
558 2
                'class' => 'Eccube\Entity\ClassName',
559 2
                'property' => 'name',
560 2
                'empty_value' => '規格2を選択',
561 2
                'data' => $ClassName2,
562
            ))
563 2
            ->getForm();
564
565 2
        log_info('商品規格登録エラー');
566
567
568 2
        return $app->render('Product/product_class.twig', array(
569 2
            'form' => $form->createView(),
570 2
            'classForm' => $classForm->createView(),
571 2
            'Product' => $Product,
572 2
            'class_name1' => $ClassName1,
573 2
            'class_name2' => $ClassName2,
574 2
            'not_product_class' => $not_product_class,
575 2
            'error' => $error,
576
            'has_class_category_flg' => true,
577
        ));
578
    }
579
580
581
    /**
582
     * 規格1と規格2を組み合わせた商品規格を作成
583
     */
584 10
    private function createProductClasses($app, Product $Product, ClassName $ClassName1 = null, ClassName $ClassName2 = null)
585
    {
586
587 10
        $ClassCategories1 = array();
588 10
        if ($ClassName1) {
589 10
            $ClassCategories1 = $app['eccube.repository.class_category']->findBy(array('ClassName' => $ClassName1));
590
        }
591
592 10
        $ClassCategories2 = array();
593 10
        if ($ClassName2) {
594 5
            $ClassCategories2 = $app['eccube.repository.class_category']->findBy(array('ClassName' => $ClassName2));
595
        }
596
597 10
        $ProductClasses = array();
598 10
        foreach ($ClassCategories1 as $ClassCategory1) {
599 10
            if ($ClassCategories2) {
600 5
                foreach ($ClassCategories2 as $ClassCategory2) {
601 5
                    $ProductClass = $this->newProductClass($app);
602 5
                    $ProductClass->setProduct($Product);
603 5
                    $ProductClass->setClassCategory1($ClassCategory1);
604 5
                    $ProductClass->setClassCategory2($ClassCategory2);
605 5
                    $ProductClass->setTaxRate(null);
606 5
                    $ProductClass->setDelFlg(Constant::DISABLED);
607 5
                    $ProductClasses[] = $ProductClass;
608
                }
609
            } else {
610 5
                $ProductClass = $this->newProductClass($app);
611 5
                $ProductClass->setProduct($Product);
612 5
                $ProductClass->setClassCategory1($ClassCategory1);
613 5
                $ProductClass->setTaxRate(null);
614 5
                $ProductClass->setDelFlg(Constant::DISABLED);
615 10
                $ProductClasses[] = $ProductClass;
616
            }
617
0 ignored issues
show
Blank line found at end of control structure
Loading history...
618
        }
619 10
        return $ProductClasses;
620
    }
621
622
    /**
623
     * 新しい商品規格を作成
624
     */
625 10
    private function newProductClass(Application $app)
626
    {
627 10
        $ProductType = $app['eccube.repository.master.product_type']->find($app['config']['product_type_normal']);
628
629 10
        $ProductClass = new ProductClass();
630 10
        $ProductClass->setProductType($ProductType);
631 10
        return $ProductClass;
632
    }
633
634
    /**
635
     * 商品規格のコピーを取得.
636
     *
637
     * @see http://symfony.com/doc/current/cookbook/form/form_collections.html
638
     * @param Product $Product
639
     * @return \Eccube\Entity\ProductClass[]
640
     */
641
    private function getProductClassesOriginal(Product $Product)
642
    {
643
        $ProductClasses = $Product->getProductClasses();
644
        return $ProductClasses->filter(function($ProductClass) {
0 ignored issues
show
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
645
            return true;
646
        });
647
    }
648
649
    /**
650
     * 規格なし商品を除いて商品規格を取得.
651
     *
652
     * @param Product $Product
653
     * @return \Eccube\Entity\ProductClass[]
654
     */
655 12
    private function getProductClassesExcludeNonClass(Product $Product)
656
    {
657 12
        $ProductClasses = $Product->getProductClasses();
658 12
        return $ProductClasses->filter(function($ProductClass) {
0 ignored issues
show
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
659 11
            $ClassCategory1 = $ProductClass->getClassCategory1();
660 11
            $ClassCategory2 = $ProductClass->getClassCategory2();
661 11
            return ($ClassCategory1 || $ClassCategory2);
662 12
        });
663
    }
664
665
    /**
666
     * デフォルトとなる商品規格を設定
667
     *
668
     * @param $productClassDest コピー先となる商品規格
669
     * @param $productClassOrig コピー元となる商品規格
670
     */
671 8
    private function setDefualtProductClass($app, $productClassDest, $productClassOrig) {
672 8
        $productClassDest->setDeliveryDate($productClassOrig->getDeliveryDate());
673 8
        $productClassDest->setProduct($productClassOrig->getProduct());
674 8
        $productClassDest->setProductType($productClassOrig->getProductType());
675 8
        $productClassDest->setCode($productClassOrig->getCode());
676 8
        $productClassDest->setStock($productClassOrig->getStock());
677 8
        $productClassDest->setStockUnlimited($productClassOrig->getStockUnlimited());
678 8
        $productClassDest->setSaleLimit($productClassOrig->getSaleLimit());
679 8
        $productClassDest->setPrice01($productClassOrig->getPrice01());
680 8
        $productClassDest->setPrice02($productClassOrig->getPrice02());
681 8
        $productClassDest->setDeliveryFee($productClassOrig->getDeliveryFee());
682
        
683
        // 個別消費税
684 8
        $BaseInfo = $app['eccube.repository.base_info']->get();
685 8
        if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
686 8
            if ($productClassOrig->getTaxRate() !== false && $productClassOrig->getTaxRate() !== null) {
687 3
                $productClassDest->setTaxRate($productClassOrig->getTaxRate());
688 3 View Code Duplication
                if ($productClassDest->getTaxRule()) {
689
                    $productClassDest->getTaxRule()->setTaxRate($productClassOrig->getTaxRate());
690
                    $productClassDest->getTaxRule()->setDelFlg(Constant::DISABLED);
691
                } else {
692 3
                    $taxrule = $app['eccube.repository.tax_rule']->newTaxRule();
693 3
                    $taxrule->setTaxRate($productClassOrig->getTaxRate());
694 3
                    $taxrule->setApplyDate(new \DateTime());
695 3
                    $taxrule->setProduct($productClassDest->getProduct());
696 3
                    $taxrule->setProductClass($productClassDest);
697 3
                    $productClassDest->setTaxRule($taxrule);
698
                }
699
            } else {
700 8
                if ($productClassDest->getTaxRule()) {
701
                    $productClassDest->getTaxRule()->setDelFlg(Constant::ENABLED);
702
                }
703
            }
704
        }
705
    }
706
707
708
    /**
709
     * 商品規格を登録
710
     *
711
     * @param Application     $app
712
     * @param Product         $Product
713
     * @param ArrayCollection $ProductClasses 登録される商品規格
714
     */
715 7
    private function insertProductClass($app, $Product, $ProductClasses) {
716
717 7
        $BaseInfo = $app['eccube.repository.base_info']->get();
718
719
        // 選択された商品を登録
720 7
        foreach ($ProductClasses as $ProductClass) {
0 ignored issues
show
Blank line found at start of control structure
Loading history...
721
722 3
            $ProductClass->setDelFlg(Constant::DISABLED);
723 3
            $ProductClass->setProduct($Product);
724 3
            $app['orm.em']->persist($ProductClass);
725
726
            // 在庫情報を作成
727 3
            $ProductStock = new ProductStock();
728 3
            $ProductClass->setProductStock($ProductStock);
729 3
            $ProductStock->setProductClass($ProductClass);
730 3
            if (!$ProductClass->getStockUnlimited()) {
731 3
                $ProductStock->setStock($ProductClass->getStock());
732
            } else {
733
                // 在庫無制限時はnullを設定
734
                $ProductStock->setStock(null);
735
            }
736 7
            $app['orm.em']->persist($ProductStock);
737
0 ignored issues
show
Blank line found at end of control structure
Loading history...
738
        }
739
740
        // 商品税率が設定されている場合、商品税率をセット
741 7
        if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
742
            // 初期設定の税設定.
743 7
            $TaxRule = $app['eccube.repository.tax_rule']->find(TaxRule::DEFAULT_TAX_RULE_ID);
744
            // 初期税率設定の計算方法を設定する
745 7
            $CalcRule = $TaxRule->getCalcRule();
746 7
            foreach ($ProductClasses as $ProductClass) {
747 3
                if ($ProductClass && is_numeric($taxRate = $ProductClass->getTaxRate())) {
748 2
                    $TaxRule = new TaxRule();
749 2
                    $TaxRule->setProduct($Product);
750 2
                    $TaxRule->setProductClass($ProductClass);
751 2
                    $TaxRule->setCalcRule($CalcRule);
752 2
                    $TaxRule->setTaxRate($taxRate);
753 2
                    $TaxRule->setTaxAdjust(0);
754 2
                    $TaxRule->setApplyDate(new \DateTime());
755 2
                    $TaxRule->setDelFlg(Constant::DISABLED);
756 7
                    $app['orm.em']->persist($TaxRule);
757
                }
758
            }
759
        }
760
761
    }
762
763
    /**
764
     * 規格の分類判定
765
     *
766
     * @param $class_name
767
     * @return boolean
768
     */
769 4
    private function isValiedCategory($class_name)
770
    {
771 4
        if (empty($class_name)) {
772 4
            return true;
773
        }
774 4
        if (count($class_name->getClassCategories()) < 1) {
775
            return false;
776
        }
777 4
        return true;
778
    }
779
}
780