Failed Conditions
Pull Request — experimental/3.1 (#2159)
by Kentaro
88:02
created

ProductController::display()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 4
cts 5
cp 0.8
rs 9.4285
cc 2
eloc 8
nc 2
nop 3
crap 2.032
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\Controller\AbstractController;
30
use Eccube\Entity\Master\CsvType;
31
use Eccube\Entity\ProductTag;
32
use Eccube\Event\EccubeEvents;
33
use Eccube\Event\EventArgs;
34
use Eccube\Form\Type\Admin\ProductType;
35
use Eccube\Form\Type\Admin\SearchProductType;
36
use Eccube\Service\CsvExportService;
37
use Symfony\Component\Filesystem\Filesystem;
38
use Symfony\Component\HttpFoundation\File\File;
39
use Symfony\Component\HttpFoundation\Request;
40
use Symfony\Component\HttpFoundation\StreamedResponse;
41
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
42
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
43
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
44
45
class ProductController extends AbstractController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
46 2
{
47
    public function index(Application $app, Request $request, $page_no = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
48
    {
49 2
50
        $session = $app['session'];
51 2
52 2
        $builder = $app['form.factory']
53
            ->createBuilder(SearchProductType::class);
54 2
55
        $event = new EventArgs(
56 2
            array(
57
                'builder' => $builder,
58
            ),
59
            $request
60 2
        );
61
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_INITIALIZE, $event);
62 2
63
        $searchForm = $builder->getForm();
64 2
65
        $pagination = array();
66 2
67 2
        $disps = $app['eccube.repository.master.disp']->findAll();
68 2
        $pageMaxis = $app['eccube.repository.master.page_max']->findAll();
69 2
        $page_count = $app['config']['default_page_count'];
70 2
        $page_status = null;
71
        $active = false;
72 2
73
        if ('POST' === $request->getMethod()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
74
75
            $searchForm->handleRequest($request);
76
77
            if ($searchForm->isValid()) {
78
                $searchData = $searchForm->getData();
79
80
                // paginator
81
                $qb = $app['eccube.repository.product']->getQueryBuilderBySearchDataForAdmin($searchData);
82
                $page_no = 1;
83
84
                $event = new EventArgs(
85
                    array(
86
                        'qb' => $qb,
87
                        'searchData' => $searchData,
88
                    ),
89
                    $request
90
                );
91
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH, $event);
92
                $searchData = $event->getArgument('searchData');
93
94
                $pagination = $app['paginator']()->paginate(
95
                    $qb,
96
                    $page_no,
97
                    $page_count,
98
                    array('wrap-queries' => true)
99
                );
100
101
                // sessionのデータ保持
102
                $session->set('eccube.admin.product.search', $searchData);
103
                $session->set('eccube.admin.product.search.page_no', $page_no);
104
            }
105 2
        } else {
106
            if (is_null($page_no) && $request->get('resume') != Constant::ENABLED) {
107 2
                // sessionを削除
108 2
                $session->remove('eccube.admin.product.search');
109
                $session->remove('eccube.admin.product.search.page_no');
110
            } else {
111
                // pagingなどの処理
112
                $searchData = $session->get('eccube.admin.product.search');
113
                if (is_null($page_no)) {
114
                    $page_no = intval($session->get('eccube.admin.product.search.page_no'));
115
                } else {
116
                    $session->set('eccube.admin.product.search.page_no', $page_no);
117
                }
118
                if (!is_null($searchData)) {
119
                    // 公開ステータス
120
                    // 1:公開, 2:非公開, 3:在庫なし
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
121
                    $status = $request->get('status');
122
                    if (empty($status)) {
123
                        $searchData['link_status'] = null;
124
                        $searchData['stock_status'] = null;
125
                    } else {
126
                        $searchData['link_status'] = $app['eccube.repository.master.disp']->find($status);
127
                        $searchData['stock_status'] = null;
128
                        if ($status == $app['config']['admin_product_stock_status']) {
129
                            // 在庫なし
130
                            $searchData['link_status'] = null;
131
                            $searchData['stock_status'] = Constant::DISABLED;
132
                        }
133
                        $page_status = $status;
134
                    }
135
                    $session->set('eccube.admin.product.search', $searchData);
136
137
                    // 表示件数
138
                    $page_count = $request->get('page_count', $page_count);
139
140
                    $qb = $app['eccube.repository.product']->getQueryBuilderBySearchDataForAdmin($searchData);
141
142
                    $event = new EventArgs(
143
                        array(
144
                            'qb' => $qb,
145
                            'searchData' => $searchData,
146
                        ),
147
                        $request
148
                    );
149
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH, $event);
150
                    $searchData = $event->getArgument('searchData');
151
152
                    $pagination = $app['paginator']()->paginate(
153
                        $qb,
154
                        $page_no,
155
                        $page_count,
156
                        array('wrap-queries' => true)
157
                    );
158
159
                    // セッションから検索条件を復元(カテゴリ)
160
                    if (!empty($searchData['category_id'])) {
161
                        $searchData['category_id'] = $app['eccube.repository.category']->find($searchData['category_id']);
162
                    }
163
164
                    // セッションから検索条件を復元(スーテタス)
165 View Code Duplication
                    if (isset($searchData['status']) && count($searchData['status']) > 0) {
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...
166
                        $status_ids = array();
167
                        foreach ($searchData['status'] as $Status) {
168
                            $status_ids[] = $Status->getId();
169
                        }
170
                        $searchData['status'] = $app['eccube.repository.master.disp']->findBy(array('id' => $status_ids));
171
                    }
172
                    $searchForm->setData($searchData);
173
                }
174
            }
175
        }
176 2
177 2
        return $app->render('Product/index.twig', array(
178 2
            'searchForm' => $searchForm->createView(),
179 2
            'pagination' => $pagination,
180 2
            'disps' => $disps,
181 2
            'pageMaxis' => $pageMaxis,
182 2
            'page_no' => $page_no,
183 2
            'page_status' => $page_status,
184 2
            'page_count' => $page_count,
185
            'active' => $active,
186
        ));
187
    }
188
189
    public function addImage(Application $app, Request $request)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
190
    {
191
        if (!$request->isXmlHttpRequest()) {
192
            throw new BadRequestHttpException('リクエストが不正です');
193
        }
194
195
        $images = $request->files->get('admin_product');
196
197
        $files = array();
198
        if (count($images) > 0) {
199
            foreach ($images as $img) {
200
                foreach ($img as $image) {
201
                    //ファイルフォーマット検証
202
                    $mimeType = $image->getMimeType();
203
                    if (0 !== strpos($mimeType, 'image')) {
204
                        throw new UnsupportedMediaTypeHttpException('ファイル形式が不正です');
205
                    }
206
207
                    $extension = $image->getClientOriginalExtension();
208
                    $filename = date('mdHis') . uniqid('_') . '.' . $extension;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
209
                    $image->move($app['config']['image_temp_realdir'], $filename);
210
                    $files[] = $filename;
211
                }
212
            }
213
        }
214
215
        $event = new EventArgs(
216
            array(
217
                'images' => $images,
218
                'files' => $files,
219
            ),
220
            $request
221
        );
222
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_ADD_IMAGE_COMPLETE, $event);
223
        $files = $event->getArgument('files');
224
225
        return $app->json(array('files' => $files), 200);
226
    }
227 19
228
    public function edit(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
229 19
    {
230 19
        $has_class = false;
231 6
        if (is_null($id)) {
232 6
            $Product = new \Eccube\Entity\Product();
233 6
            $ProductClass = new \Eccube\Entity\ProductClass();
234
            $Disp = $app['eccube.repository.master.disp']->find(\Eccube\Entity\Master\Disp::DISPLAY_HIDE);
235 6
            $Product
236 6
                ->setDelFlg(Constant::DISABLED)
237 6
                ->addProductClass($ProductClass)
238
                ->setStatus($Disp);
239 6
            $ProductClass
240 6
                ->setDelFlg(Constant::DISABLED)
241 6
                ->setStockUnlimited(true)
242 6
                ->setProduct($Product);
243 6
            $ProductStock = new \Eccube\Entity\ProductStock();
244 6
            $ProductClass->setProductStock($ProductStock);
245
            $ProductStock->setProductClass($ProductClass);
246 13
        } else {
247 13
            $Product = $app['eccube.repository.product']->find($id);
248
            if (!$Product) {
249
                throw new NotFoundHttpException();
250
            }
251 13
            // 規格あり商品か
252 13
            $has_class = $Product->hasProductClass();
253 11
            if (!$has_class) {
254 11
                $ProductClasses = $Product->getProductClasses();
255 11
                $ProductClass = $ProductClasses[0];
256 11
                $BaseInfo = $app['eccube.repository.base_info']->get();
257 6 View Code Duplication
                if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED && $ProductClass->getTaxRule() && !$ProductClass->getTaxRule()->getDelFlg()) {
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...
258
                    $ProductClass->setTaxRate($ProductClass->getTaxRule()->getTaxRate());
259 11
                }
260
                $ProductStock = $ProductClasses[0]->getProductStock();
261
            }
262
        }
263 19
264 19
        $builder = $app['form.factory']
265
            ->createBuilder(ProductType::class, $Product);
266
267 19
        // 規格あり商品の場合、規格関連情報をFormから除外
268 2
        if ($has_class) {
269
            $builder->remove('class');
270
        }
271 19
272
        $event = new EventArgs(
273 19
            array(
274 19
                'builder' => $builder,
275
                'Product' => $Product,
276
            ),
277
            $request
278 19
        );
279
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_INITIALIZE, $event);
280 19
281
        $form = $builder->getForm();
282 19
283 17
        if (!$has_class) {
284 17
            $ProductClass->setStockUnlimited((boolean)$ProductClass->getStockUnlimited());
0 ignored issues
show
Bug introduced by
The variable $ProductClass does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Coding Style introduced by
As per coding-style, a cast statement should be followed by a single space.
Loading history...
285
            $form['class']->setData($ProductClass);
286
        }
287
288 19
        // ファイルの登録
289 19
        $images = array();
290 19
        $ProductImages = $Product->getProductImage();
291 19
        foreach ($ProductImages as $ProductImage) {
292
            $images[] = $ProductImage->getFileName();
293 19
        }
294
        $form['images']->setData($images);
295 19
296 19
        $categories = array();
297 19
        $ProductCategories = $Product->getProductCategories();
298
        foreach ($ProductCategories as $ProductCategory) {
299 19
            /* @var $ProductCategory \Eccube\Entity\ProductCategory */
300
            $categories[] = $ProductCategory->getCategory();
301 19
        }
302
        $form['Category']->setData($categories);
303 19
304 19
        $Tags = array();
305 19
        $ProductTags = $Product->getProductTag();
306 19
        foreach ($ProductTags as $ProductTag) {
307
            $Tags[] = $ProductTag->getTag();
308 19
        }
309
        $form['Tag']->setData($Tags);
310 19
311 14
        if ('POST' === $request->getMethod()) {
312 14
            $form->handleRequest($request);
313 14
            if ($form->isValid()) {
314 14
                log_info('商品登録開始', array($id));
315
                $Product = $form->getData();
316 14
317 14
                if (!$has_class) {
318
                    $ProductClass = $form['class']->getData();
319
320 14
                    // 個別消費税
321 14
                    $BaseInfo = $app['eccube.repository.base_info']->get();
322 12
                    if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
323 8
                        if ($ProductClass->getTaxRate() !== null) {
324 4 View Code Duplication
                            if ($ProductClass->getTaxRule()) {
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...
325
                                if ($ProductClass->getTaxRule()->getDelFlg() == Constant::ENABLED) {
326
                                    $ProductClass->getTaxRule()->setDelFlg(Constant::DISABLED);
327
                                }
328 4
329
                                $ProductClass->getTaxRule()->setTaxRate($ProductClass->getTaxRate());
330 4
                            } else {
331 4
                                $taxrule = $app['eccube.repository.tax_rule']->newTaxRule();
332 4
                                $taxrule->setTaxRate($ProductClass->getTaxRate());
333 4
                                $taxrule->setApplyDate(new \DateTime());
334 4
                                $taxrule->setProduct($Product);
335 8
                                $taxrule->setProductClass($ProductClass);
336
                                $ProductClass->setTaxRule($taxrule);
337
                            }
338 4
                        } else {
339 2
                            if ($ProductClass->getTaxRule()) {
340
                                $ProductClass->getTaxRule()->setDelFlg(Constant::ENABLED);
341
                            }
342
                        }
343 14
                    }
344
                    $app['orm.em']->persist($ProductClass);
345
346 14
                    // 在庫情報を作成
347
                    if (!$ProductClass->getStockUnlimited()) {
348
                        $ProductStock->setStock($ProductClass->getStock());
0 ignored issues
show
Bug introduced by
The variable $ProductStock does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
349
                    } else {
350 14
                        // 在庫無制限時はnullを設定
351
                        $ProductStock->setStock(null);
352 14
                    }
353
                    $app['orm.em']->persist($ProductStock);
354
                }
355
356
                // カテゴリの登録
357
                // 一度クリア
358 14
                /* @var $Product \Eccube\Entity\Product */
359 11
                foreach ($Product->getProductCategories() as $ProductCategory) {
360 14
                    $Product->removeProductCategory($ProductCategory);
361
                    $app['orm.em']->remove($ProductCategory);
362 14
                }
363 14
                $app['orm.em']->persist($Product);
364
                $app['orm.em']->flush();
365 14
366 14
                $count = 1;
367 14
                $Categories = $form->get('Category')->getData();
368 14
                $categoriesIdList = array();
369
                foreach ($Categories as $Category) {
370 View Code Duplication
                    foreach($Category->getPath() as $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...
371
                        if (!isset($categoriesIdList[$ParentCategory->getId()])){
372
                            $ProductCategory = $this->createProductCategory($Product, $ParentCategory, $count);
373
                            $app['orm.em']->persist($ProductCategory);
374
                            $count++;
375
                            /* @var $Product \Eccube\Entity\Product */
376
                            $Product->addProductCategory($ProductCategory);
377
                            $categoriesIdList[$ParentCategory->getId()] = true;
378
                        }
379
                    }
380
                    if (!isset($categoriesIdList[$Category->getId()])){
381
                        $ProductCategory = $this->createProductCategory($Product, $Category, $count);
382
                        $app['orm.em']->persist($ProductCategory);
383
                        $count++;
384
                        /* @var $Product \Eccube\Entity\Product */
385 14
                        $Product->addProductCategory($ProductCategory);
386
                        $categoriesIdList[$Category->getId()] = true;
387
                    }
388
                }
389
390 14
                // 画像の登録
391 14
                $add_images = $form->get('add_images')->getData();
392
                foreach ($add_images as $add_image) {
393
                    $ProductImage = new \Eccube\Entity\ProductImage();
394
                    $ProductImage
395
                        ->setFileName($add_image)
396
                        ->setProduct($Product)
397
                        ->setRank(1);
398
                    $Product->addProductImage($ProductImage);
399
                    $app['orm.em']->persist($ProductImage);
400
401
                    // 移動
402 14
                    $file = new File($app['config']['image_temp_realdir'] . '/' . $add_image);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
403
                    $file->move($app['config']['image_save_realdir']);
404
                }
405
406 14
                // 画像の削除
407 14
                $delete_images = $form->get('delete_images')->getData();
408
                foreach ($delete_images as $delete_image) {
409
                    $ProductImage = $app['eccube.repository.product_image']
410
                        ->findOneBy(array('file_name' => $delete_image));
411
412
                    // 追加してすぐに削除した画像は、Entityに追加されない
413
                    if ($ProductImage instanceof \Eccube\Entity\ProductImage) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\ProductImage does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
414
                        $Product->removeProductImage($ProductImage);
415
                        $app['orm.em']->remove($ProductImage);
416
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
417
                    }
418
                    $app['orm.em']->persist($Product);
419
420
                    // 削除
421 14
                    $fs = new Filesystem();
422
                    $fs->remove($app['config']['image_save_realdir'] . '/' . $delete_image);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
423 14
                }
424 14
                $app['orm.em']->persist($Product);
425
                $app['orm.em']->flush();
426
427 14
428 14
                $ranks = $request->get('rank_images');
429
                if ($ranks) {
430
                    foreach ($ranks as $rank) {
431
                        list($filename, $rank_val) = explode('//', $rank);
432
                        $ProductImage = $app['eccube.repository.product_image']
433
                            ->findOneBy(array(
434
                                'file_name' => $filename,
435
                                'Product' => $Product,
436
                            ));
437
                        $ProductImage->setRank($rank_val);
438
                        $app['orm.em']->persist($ProductImage);
439
                    }
440 14
                }
441
                $app['orm.em']->flush();
442
443
                // 商品タグの登録
444 14
                // 商品タグを一度クリア
445 14
                $ProductTags = $Product->getProductTag();
446
                foreach ($ProductTags as $ProductTag) {
447 14
                    $Product->removeProductTag($ProductTag);
448
                    $app['orm.em']->remove($ProductTag);
449
                }
450
451 14
                // 商品タグの登録
452 14
                $Tags = $form->get('Tag')->getData();
453 14
                foreach ($Tags as $Tag) {
454
                    $ProductTag = new ProductTag();
455 14
                    $ProductTag
456 14
                        ->setProduct($Product)
457 14
                        ->setTag($Tag);
458 14
                    $Product->addProductTag($ProductTag);
459
                    $app['orm.em']->persist($ProductTag);
460 14
                }
461
462 14
                $Product->setUpdateDate(new \DateTime());
463
                $app['orm.em']->flush();
464 14
465
                log_info('商品登録完了', array($id));
466 14
467 14
                $event = new EventArgs(
468
                    array(
469
                        'form' => $form,
470
                        'Product' => $Product,
471 14
                    ),
472
                    $request
473 14
                );
474
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_COMPLETE, $event);
475 14
476
                $app->addSuccess('admin.register.complete', 'admin');
477
478
                return $app->redirect($app->url('admin_product_product_edit', array('id' => $Product->getId())));
479
            } else {
480
                log_info('商品登録チェックエラー', array($id));
481
                $app->addError('admin.register.failed', 'admin');
482
            }
483 5
        }
484 5
485
        // 検索結果の保持
486 5
        $builder = $app['form.factory']
487
            ->createBuilder(SearchProductType::class);
488 5
489 5
        $event = new EventArgs(
490
            array(
491
                'builder' => $builder,
492
                'Product' => $Product,
493 5
            ),
494
            $request
495 5
        );
496
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_SEARCH, $event);
497 5
498
        $searchForm = $builder->getForm();
499
500
        if ('POST' === $request->getMethod()) {
501 5
            $searchForm->handleRequest($request);
502 5
        }
503 5
504 5
        return $app->render('Product/product.twig', array(
505 5
            'Product' => $Product,
506 5
            'form' => $form->createView(),
507
            'searchForm' => $searchForm->createView(),
508
            'has_class' => $has_class,
509
            'id' => $id,
510 2
        ));
511
    }
512 2
513 2
    public function delete(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
514 2
    {
515 2
        $this->isTokenValid($app);
516
        $session = $request->getSession();
517 2
        $page_no = intval($session->get('eccube.admin.product.search.page_no'));
518
        $page_no = $page_no ? $page_no : Constant::ENABLED;
519 2
520 2
        if (!is_null($id)) {
521
            /* @var $Product \Eccube\Entity\Product */
522
            $Product = $app['eccube.repository.product']->find($id);
523
            if (!$Product) {
524
                $app->deleteMessage();
525 2
                return $app->redirect($app->url('admin_product_page', array('page_no' => $page_no)).'?resume='.Constant::ENABLED);
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
526 2
            }
527
528 2
            if ($Product instanceof \Eccube\Entity\Product) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\Product does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
529
                log_info('商品削除開始', array($id));
530 2
531 2
                $Product->setDelFlg(Constant::ENABLED);
532 2
533 2
                $ProductClasses = $Product->getProductClasses();
534 2
                $deleteImages = array();
535
                foreach ($ProductClasses as $ProductClass) {
536 2
                    $ProductClass->setDelFlg(Constant::ENABLED);
537 2
                    $Product->removeProductClass($ProductClass);
538 2
539 2
                    $ProductClasses = $Product->getProductClasses();
540
                    foreach ($ProductClasses as $ProductClass) {
541 2
                        $ProductClass->setDelFlg(Constant::ENABLED);
542 2
                        $Product->removeProductClass($ProductClass);
543
544
                        $ProductStock = $ProductClass->getProductStock();
545 2
                        $app['orm.em']->remove($ProductStock);
546 2
                    }
547 2
548 2
                    $ProductImages = $Product->getProductImage();
549 2
                    foreach ($ProductImages as $ProductImage) {
550
                        $Product->removeProductImage($ProductImage);
551
                        $deleteImages[] = $ProductImage->getFileName();
552 2
                        $app['orm.em']->remove($ProductImage);
553 2
                    }
554 2
555 2
                    $ProductCategories = $Product->getProductCategories();
556
                    foreach ($ProductCategories as $ProductCategory) {
557
                        $Product->removeProductCategory($ProductCategory);
558
                        $app['orm.em']->remove($ProductCategory);
559
                    }
560 2
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
561
                }
562 2
563
                $app['orm.em']->persist($Product);
564 2
565
                $app['orm.em']->flush();
566 2
567 2
                $event = new EventArgs(
568 2
                    array(
569
                        'Product' => $Product,
570
                        'ProductClass' => $ProductClasses,
571
                        'deleteImages' => $deleteImages,
572 2
                    ),
573 2
                    $request
574
                );
575
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_DELETE_COMPLETE, $event);
576 2
                $deleteImages = $event->getArgument('deleteImages');
577
578 2
                // 画像ファイルの削除(commit後に削除させる)
579 2
                foreach ($deleteImages as $deleteImage) {
580 2
                    try {
581
                        $fs = new Filesystem();
582
                        $fs->remove($app['config']['image_save_realdir'] . '/' . $deleteImage);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
583
                    } catch (\Exception $e) {
584
                        // エラーが発生しても無視する
585 2
                    }
586
                }
587 2
588
                log_info('商品削除完了', array($id));
589
590 2
                $app->addSuccess('admin.delete.complete', 'admin');
591
            } else {
592
                log_info('商品削除エラー', array($id));
593
                $app->addError('admin.delete.failed', 'admin');
594
            }
595
        } else {
596
            log_info('商品削除エラー', array($id));
597 2
            $app->addError('admin.delete.failed', 'admin');
598
        }
599
600 2
        return $app->redirect($app->url('admin_product_page', array('page_no' => $page_no)).'?resume='.Constant::ENABLED);
601
    }
602 2
603
    public function copy(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
604 2
    {
605 2
        $this->isTokenValid($app);
606 2
607 2
        if (!is_null($id)) {
608 2
            $Product = $app['eccube.repository.product']->find($id);
609 2
            if ($Product instanceof \Eccube\Entity\Product) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\Product does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
610 2
                $CopyProduct = clone $Product;
611
                $CopyProduct->copy();
612 2
                $Disp = $app['eccube.repository.master.disp']->find(\Eccube\Entity\Master\Disp::DISPLAY_HIDE);
613 2
                $CopyProduct->setStatus($Disp);
614 2
615
                $CopyProductCategories = $CopyProduct->getProductCategories();
616
                foreach ($CopyProductCategories as $Category) {
617
                    $app['orm.em']->persist($Category);
618 2
                }
619 2
620 2
                // 規格あり商品の場合は, デフォルトの商品規格を取得し登録する.
621
                if ($CopyProduct->hasProductClass()) {
622 2
                    $softDeleteFilter = $app['orm.em']->getFilters()->getFilter('soft_delete');
623 2
                    $softDeleteFilter->setExcludes(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
624 2
                        'Eccube\Entity\ProductClass'
625
                    ));
626
                    $dummyClass = $app['eccube.repository.product_class']->findOneBy(array(
627 2
                        'del_flg' => \Eccube\Common\Constant::ENABLED,
628
                        'ClassCategory1' => null,
629 2
                        'ClassCategory2' => null,
630 2
                        'Product' => $Product,
631 2
                    ));
632 2
                    $dummyClass = clone $dummyClass;
633
                    $dummyClass->setProduct($CopyProduct);
634
                    $CopyProduct->addProductClass($dummyClass);
635 2
                    $softDeleteFilter->setExcludes(array());
636 2
                }
637 2
638 2
                $CopyProductClasses = $CopyProduct->getProductClasses();
639 2
                foreach ($CopyProductClasses as $Class) {
640 2
                    $Stock = $Class->getProductStock();
641
                    $CopyStock = clone $Stock;
642 2
                    $CopyStock->setProductClass($Class);
643
                    $app['orm.em']->persist($CopyStock);
644 2
645 2
                    $app['orm.em']->persist($Class);
646
                }
647
                $Images = $CopyProduct->getProductImage();
648 2
                foreach ($Images as $Image) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
649 2
650
                    // 画像ファイルを新規作成
651 2
                    $extension = pathinfo($Image->getFileName(), PATHINFO_EXTENSION);
652 2
                    $filename = date('mdHis') . uniqid('_') . '.' . $extension;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
653 2
                    try {
654
                        $fs = new Filesystem();
655
                        $fs->copy($app['config']['image_save_realdir'] . '/' . $Image->getFileName(), $app['config']['image_save_realdir'] . '/' . $filename);
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
656 2
                    } catch (\Exception $e) {
657
                        // エラーが発生しても無視する
658 2
                    }
659
                    $Image->setFileName($filename);
660 2
661 2
                    $app['orm.em']->persist($Image);
662 2
                }
663
                $Tags = $CopyProduct->getProductTag();
664
                foreach ($Tags as $Tag) {
665 2
                    $app['orm.em']->persist($Tag);
666
                }
667 2
668
                $app['orm.em']->persist($CopyProduct);
669 2
670
                $app['orm.em']->flush();
671 2
672 2
                $event = new EventArgs(
673 2
                    array(
674 2
                        'Product' => $Product,
675 2
                        'CopyProduct' => $CopyProduct,
676 2
                        'CopyProductCategories' => $CopyProductCategories,
677
                        'CopyProductClasses' => $CopyProductClasses,
678
                        'images' => $Images,
679
                        'Tags' => $Tags,
680 2
                    ),
681
                    $request
682 2
                );
683
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_COPY_COMPLETE, $event);
684 2
685
                $app->addSuccess('admin.product.copy.complete', 'admin');
686
687
                return $app->redirect($app->url('admin_product_product_edit', array('id' => $CopyProduct->getId())));
688
            } else {
689
                $app->addError('admin.product.copy.failed', 'admin');
690
            }
691
        } else {
692
            $app->addError('admin.product.copy.failed', 'admin');
693
        }
694
695 1
        return $app->redirect($app->url('admin_product'));
696
    }
697 1
698 1
    public function display(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
699
    {
700
        $event = new EventArgs(
701 1
            array(),
702
            $request
703 1
        );
704 1
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_DISPLAY_COMPLETE, $event);
705
706
        if (!is_null($id)) {
707
            return $app->redirect($app->url('product_detail', array('id' => $id, 'admin' => '1')));
708
        }
709
710
        return $app->redirect($app->url('admin_product'));
711
    }
712
713
    /**
714
     * 商品CSVの出力.
715
     *
716
     * @param Application $app
717
     * @param Request $request
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
718
     * @return StreamedResponse
719
     */
720
    public function export(Application $app, Request $request)
721
    {
722
        // タイムアウトを無効にする.
723
        set_time_limit(0);
724
725
        // sql loggerを無効にする.
726
        $em = $app['orm.em'];
727
        $em->getConfiguration()->setSQLLogger(null);
728
729
        $response = new StreamedResponse();
730
        $response->setCallback(function () use ($app, $request) {
731
732
            // CSV種別を元に初期化.
733
            $app['eccube.service.csv.export']->initCsvType(CsvType::CSV_TYPE_PRODUCT);
734
735
            // ヘッダ行の出力.
736
            $app['eccube.service.csv.export']->exportHeader();
737
738
            // 商品データ検索用のクエリビルダを取得.
739
            $qb = $app['eccube.service.csv.export']
740
                ->getProductQueryBuilder($request);
741
742
            // Get stock status
743
            $isOutOfStock = 0;
744
            $session = $request->getSession();
745
            if ($session->has('eccube.admin.product.search')) {
746
                $searchData = $session->get('eccube.admin.product.search', array());
747
                if (isset($searchData['stock_status']) && $searchData['stock_status'] === 0) {
748
                    $isOutOfStock = 1;
749
                }
750
            }
751
752
            // joinする場合はiterateが使えないため, select句をdistinctする.
753
            // http://qiita.com/suin/items/2b1e98105fa3ef89beb7
754
            // distinctのmysqlとpgsqlの挙動をあわせる.
755
            // http://uedatakeshi.blogspot.jp/2010/04/distinct-oeder-by-postgresmysql.html
756
            $qb->resetDQLPart('select')
757
                ->resetDQLPart('orderBy')
758
                ->orderBy('p.update_date', 'DESC');
759
760
            if ($isOutOfStock) {
761
                $qb->select('p, pc')
762
                    ->distinct();
763
            } else {
764
                $qb->select('p')
765
                    ->distinct();
766
            }
767
            // データ行の出力.
768
            $app['eccube.service.csv.export']->setExportQueryBuilder($qb);
769
770 View Code Duplication
            $app['eccube.service.csv.export']->exportData(function ($entity, CsvExportService $csvService) use ($app, $request) {
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...
771
                $Csvs = $csvService->getCsvs();
772
773
                /** @var $Product \Eccube\Entity\Product */
774
                $Product = $entity;
775
776
                /** @var $ProductClassess \Eccube\Entity\ProductClass[] */
777
                $ProductClassess = $Product->getProductClasses();
778
779
                foreach ($ProductClassess as $ProductClass) {
780
                    $ExportCsvRow = new \Eccube\Entity\ExportCsvRow();
781
782
                    // CSV出力項目と合致するデータを取得.
783
                    foreach ($Csvs as $Csv) {
784
                        // 商品データを検索.
785
                        $ExportCsvRow->setData($csvService->getData($Csv, $Product));
786
                        if ($ExportCsvRow->isDataNull()) {
787
                            // 商品規格情報を検索.
788
                            $ExportCsvRow->setData($csvService->getData($Csv, $ProductClass));
789
                        }
790
791
                        $event = new EventArgs(
792
                            array(
793
                                'csvService' => $csvService,
794
                                'Csv' => $Csv,
795
                                'ProductClass' => $ProductClass,
796
                                'ExportCsvRow' => $ExportCsvRow,
797
                            ),
798
                            $request
799
                        );
800
                        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_CSV_EXPORT, $event);
801
802
                        $ExportCsvRow->pushData();
803
                    }
804
805
                    // $row[] = number_format(memory_get_usage(true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
806
                    // 出力.
807
                    $csvService->fputcsv($ExportCsvRow->getRow());
808
                }
809
            });
810
        });
811
812
        $now = new \DateTime();
813
        $filename = 'product_' . $now->format('YmdHis') . '.csv';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
814
        $response->headers->set('Content-Type', 'application/octet-stream');
815
        $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...
816
        $response->send();
817
818
        log_info('商品CSV出力ファイル名', array($filename));
819
820
        return $response;
821
    }
822
    
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
823
    /**
824
     * ProductCategory作成
825
     * @param \Eccube\Entity\Product $Product
826
     * @param \Eccube\Entity\Category $Category
827
     * @return \Eccube\Entity\ProductCategory
828
     */
829 View Code Duplication
    private function createProductCategory($Product, $Category, $count)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
830
    {
831
        $ProductCategory = new \Eccube\Entity\ProductCategory();
832
        $ProductCategory->setProduct($Product);
833
        $ProductCategory->setProductId($Product->getId());
834
        $ProductCategory->setCategory($Category);
835
        $ProductCategory->setCategoryId($Category->getId());
836
        $ProductCategory->setRank($count);
837
        
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
838
        return $ProductCategory;
839
    }
840
}
841