Issues (2366)

Branch: master

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 (1 issue)

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