Failed Conditions
Pull Request — master (#1968)
by
unknown
162:08 queued 155:21
created

ProductController::index()   D

Complexity

Conditions 13
Paths 29

Size

Total Lines 142
Code Lines 91

Duplication

Lines 7
Ratio 4.93 %

Code Coverage

Tests 64
CRAP Score 13.4167

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 13
eloc 91
c 2
b 0
f 0
nc 29
nop 3
dl 7
loc 142
ccs 64
cts 74
cp 0.8649
crap 13.4167
rs 4.9922

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 Symfony\Component\Filesystem\Filesystem;
35
use Symfony\Component\HttpFoundation\File\File;
36
use Symfony\Component\HttpFoundation\Request;
37
use Symfony\Component\HttpFoundation\StreamedResponse;
38
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
39
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
40
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
41
42
class ProductController extends AbstractController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
43
{
44 8
    public function index(Application $app, Request $request, $page_no = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
45
    {
46
47 8
        $session = $app['session'];
48
49 8
        $builder = $app['form.factory']
50 8
            ->createBuilder('admin_search_product');
51
52 8
        $event = new EventArgs(
53
            array(
54 8
                'builder' => $builder,
55
            ),
56
            $request
57
        );
58 8
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_INITIALIZE, $event);
59
60 8
        $searchForm = $builder->getForm();
61
62 8
        $pagination = array();
63
64 8
        $disps = $app['eccube.repository.master.disp']->findAll();
65 8
        $pageMaxis = $app['eccube.repository.master.page_max']->findAll();
66 8
        $page_count = $app['config']['default_page_count'];
67 8
        $page_status = null;
68 8
        $active = false;
69
70 8
        if ('POST' === $request->getMethod()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
71
72 5
            $searchForm->handleRequest($request);
73
74 5
            if ($searchForm->isValid()) {
75 5
                $searchData = $searchForm->getData();
76
77
                // paginator
78 5
                $qb = $app['eccube.repository.product']->getQueryBuilderBySearchDataForAdmin($searchData);
79 5
                $page_no = 1;
80
81 5
                $event = new EventArgs(
82
                    array(
83 5
                        'qb' => $qb,
84 5
                        'searchData' => $searchData,
85
                    ),
86
                    $request
87
                );
88 5
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH, $event);
89 5
                $searchData = $event->getArgument('searchData');
90
91 5
                $pagination = $app['paginator']()->paginate(
92
                    $qb,
93
                    $page_no,
94
                    $page_count,
95 5
                    array('wrap-queries' => true)
96
                );
97
98
                // sessionのデータ保持
99 5
                $session->set('eccube.admin.product.search', $searchData);
100 5
                $session->set('eccube.admin.product.search.page_no', $page_no);
101
            }
102
        } else {
103 3
            if (is_null($page_no) && $request->get('resume') != Constant::ENABLED) {
104
                // sessionを削除
105 2
                $session->remove('eccube.admin.product.search');
106 2
                $session->remove('eccube.admin.product.search.page_no');
107
            } else {
108
                // pagingなどの処理
109 1
                $searchData = $session->get('eccube.admin.product.search');
110 1
                if (is_null($page_no)) {
111
                    $page_no = intval($session->get('eccube.admin.product.search.page_no'));
112
                } else {
113 1
                    $session->set('eccube.admin.product.search.page_no', $page_no);
114
                }
115 1
                if (!is_null($searchData)) {
116
                    // 公開ステータス
117
                    // 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...
118 1
                    $status = $request->get('status');
119 1
                    if (!empty($status)) {
120 1
                        if ($status != $app['config']['admin_product_stock_status']) {
121
                            $searchData['link_status'] = $app['eccube.repository.master.disp']->find($status);
122
                            $searchData['stock_status'] = null;
123
                        } else {
124
                            // 在庫なし
125 1
                            $searchData['link_status'] = null;
126 1
                            $searchData['stock_status'] = Constant::DISABLED;
127
                        }
128 1
                        $page_status = $status;
129
                    } else {
130
                        $searchData['link_status'] = null;
131
                        $searchData['stock_status'] = null;
132
                    }
133 1
                    $session->set('eccube.admin.product.search', $searchData);
134
135
                    // 表示件数
136 1
                    $page_count = $request->get('page_count', $page_count);
137
138 1
                    $qb = $app['eccube.repository.product']->getQueryBuilderBySearchDataForAdmin($searchData);
139
140 1
                    $event = new EventArgs(
141
                        array(
142 1
                            'qb' => $qb,
143 1
                            'searchData' => $searchData,
144
                        ),
145
                        $request
146
                    );
147 1
                    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH, $event);
148 1
                    $searchData = $event->getArgument('searchData');
149
150 1
                    $pagination = $app['paginator']()->paginate(
151
                        $qb,
152
                        $page_no,
153
                        $page_count,
154 1
                        array('wrap-queries' => true)
155
                    );
156
157
                    // セッションから検索条件を復元(カテゴリ)
158 1
                    if (!empty($searchData['category_id'])) {
159
                        $searchData['category_id'] = $app['eccube.repository.category']->find($searchData['category_id']);
160
                    }
161
162
                    // セッションから検索条件を復元(スーテタス)
163 1 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...
164
                        $status_ids = array();
165
                        foreach ($searchData['status'] as $Status) {
166
                            $status_ids[] = $Status->getId();
167
                        }
168
                        $searchData['status'] = $app['eccube.repository.master.disp']->findBy(array('id' => $status_ids));
169
                    }
170 1
                    $searchForm->setData($searchData);
171
                }
172
            }
173
        }
174
175 8
        return $app->render('Product/index.twig', array(
176 8
            'searchForm' => $searchForm->createView(),
177 8
            'pagination' => $pagination,
178 8
            'disps' => $disps,
179 8
            'pageMaxis' => $pageMaxis,
180 8
            'page_no' => $page_no,
181 8
            'page_status' => $page_status,
182 8
            'page_count' => $page_count,
183 8
            'active' => $active,
184
        ));
185
    }
186
187
    public function addImage(Application $app, Request $request)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
188
    {
189
        if (!$request->isXmlHttpRequest()) {
190
            throw new BadRequestHttpException('リクエストが不正です');
191
        }
192
193
        $images = $request->files->get('admin_product');
194
195
        $files = array();
196
        if (count($images) > 0) {
197
            foreach ($images as $img) {
198
                foreach ($img as $image) {
199
                    //ファイルフォーマット検証
200
                    $mimeType = $image->getMimeType();
201
                    if (0 !== strpos($mimeType, 'image')) {
202
                        throw new UnsupportedMediaTypeHttpException('ファイル形式が不正です');
203
                    }
204
205
                    $extension = $image->getClientOriginalExtension();
206
                    $filename = date('mdHis') . uniqid('_') . '.' . $extension;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
207
                    $image->move($app['config']['image_temp_realdir'], $filename);
208
                    $files[] = $filename;
209
                }
210
            }
211
        }
212
213
        $event = new EventArgs(
214
            array(
215
                'images' => $images,
216
                'files' => $files,
217
            ),
218
            $request
219
        );
220
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_ADD_IMAGE_COMPLETE, $event);
221
        $files = $event->getArgument('files');
222
223
        return $app->json(array('files' => $files), 200);
224
    }
225
226 19
    public function edit(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
227
    {
228 19
        $has_class = false;
229 19
        if (is_null($id)) {
230 6
            $Product = new \Eccube\Entity\Product();
231 6
            $ProductClass = new \Eccube\Entity\ProductClass();
232 6
            $Disp = $app['eccube.repository.master.disp']->find(\Eccube\Entity\Master\Disp::DISPLAY_HIDE);
233
            $Product
234 6
                ->setDelFlg(Constant::DISABLED)
235 6
                ->addProductClass($ProductClass)
236 6
                ->setStatus($Disp);
237
            $ProductClass
238 6
                ->setDelFlg(Constant::DISABLED)
239 6
                ->setStockUnlimited(true)
240 6
                ->setProduct($Product);
241 6
            $ProductStock = new \Eccube\Entity\ProductStock();
242 6
            $ProductClass->setProductStock($ProductStock);
243 6
            $ProductStock->setProductClass($ProductClass);
244
        } else {
245 13
            $Product = $app['eccube.repository.product']->find($id);
246 13
            if (!$Product) {
247
                throw new NotFoundHttpException();
248
            }
249
            // 規格あり商品か
250 13
            $has_class = $Product->hasProductClass();
251 13
            if (!$has_class) {
252 11
                $ProductClasses = $Product->getProductClasses();
253 11
                $ProductClass = $ProductClasses[0];
254 11
                $BaseInfo = $app['eccube.repository.base_info']->get();
255 11 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...
256 6
                    $ProductClass->setTaxRate($ProductClass->getTaxRule()->getTaxRate());
257
                }
258 11
                $ProductStock = $ProductClasses[0]->getProductStock();
259
            }
260
        }
261
262 19
        $builder = $app['form.factory']
263 19
            ->createBuilder('admin_product', $Product);
264
265
        // 規格あり商品の場合、規格関連情報をFormから除外
266 19
        if ($has_class) {
267 2
            $builder->remove('class');
268
        }
269
270 19
        $event = new EventArgs(
271
            array(
272 19
                'builder' => $builder,
273 19
                'Product' => $Product,
274
            ),
275
            $request
276
        );
277 19
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_INITIALIZE, $event);
278
279 19
        $form = $builder->getForm();
280
281 19
        if (!$has_class) {
282 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...
283 17
            $form['class']->setData($ProductClass);
284
        }
285
286
        // ファイルの登録
287 19
        $images = array();
288 19
        $ProductImages = $Product->getProductImage();
289 19
        foreach ($ProductImages as $ProductImage) {
290 19
            $images[] = $ProductImage->getFileName();
291
        }
292 19
        $form['images']->setData($images);
293
294 19
        $categories = array();
295 19
        $ProductCategories = $Product->getProductCategories();
296 19
        foreach ($ProductCategories as $ProductCategory) {
297
            /* @var $ProductCategory \Eccube\Entity\ProductCategory */
298 19
            $categories[] = $ProductCategory->getCategory();
299
        }
300 19
        $form['Category']->setData($categories);
301
302 19
        $Tags = array();
303 19
        $ProductTags = $Product->getProductTag();
304 19
        foreach ($ProductTags as $ProductTag) {
305 19
            $Tags[] = $ProductTag->getTag();
306
        }
307 19
        $form['Tag']->setData($Tags);
308
309 19
        if ('POST' === $request->getMethod()) {
310 14
            $form->handleRequest($request);
311 14
            if ($form->isValid()) {
312 14
                log_info('商品登録開始', array($id));
313 14
                $Product = $form->getData();
314
315 14
                if (!$has_class) {
316 14
                    $ProductClass = $form['class']->getData();
317
318
                    // 個別消費税
319 14
                    $BaseInfo = $app['eccube.repository.base_info']->get();
320 14
                    if ($BaseInfo->getOptionProductTaxRule() == Constant::ENABLED) {
321 12
                        if ($ProductClass->getTaxRate() !== null) {
322 8 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...
323 4
                                if ($ProductClass->getTaxRule()->getDelFlg() == Constant::ENABLED) {
324
                                    $ProductClass->getTaxRule()->setDelFlg(Constant::DISABLED);
325
                                }
326
327 4
                                $ProductClass->getTaxRule()->setTaxRate($ProductClass->getTaxRate());
328
                            } else {
329 4
                                $taxrule = $app['eccube.repository.tax_rule']->newTaxRule();
330 4
                                $taxrule->setTaxRate($ProductClass->getTaxRate());
331 4
                                $taxrule->setApplyDate(new \DateTime());
332 4
                                $taxrule->setProduct($Product);
333 4
                                $taxrule->setProductClass($ProductClass);
334 8
                                $ProductClass->setTaxRule($taxrule);
335
                            }
336
                        } else {
337 4
                            if ($ProductClass->getTaxRule()) {
338 2
                                $ProductClass->getTaxRule()->setDelFlg(Constant::ENABLED);
339
                            }
340
                        }
341
                    }
342 14
                    $app['orm.em']->persist($ProductClass);
343
344
                    // 在庫情報を作成
345 14
                    if (!$ProductClass->getStockUnlimited()) {
346
                        $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...
347
                    } else {
348
                        // 在庫無制限時はnullを設定
349 14
                        $ProductStock->setStock(null);
350
                    }
351 14
                    $app['orm.em']->persist($ProductStock);
352
                }
353
354
                // カテゴリの登録
355
                // 一度クリア
356
                /* @var $Product \Eccube\Entity\Product */
357 14
                foreach ($Product->getProductCategories() as $ProductCategory) {
358 11
                    $Product->removeProductCategory($ProductCategory);
359 14
                    $app['orm.em']->remove($ProductCategory);
360
                }
361 14
                $app['orm.em']->persist($Product);
362 14
                $app['orm.em']->flush();
363
364 14
                $count = 1;
365 14
                $Categories = $form->get('Category')->getData();
366 14
                $categoriesIdList = array();
367 14
                foreach ($Categories as $Category) {
368 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...
369
                        if (!isset($categoriesIdList[$ParentCategory->getId()])){
370
                            $ProductCategory = $this->createProductCategory($Product, $ParentCategory, $count);
371
                            $app['orm.em']->persist($ProductCategory);
372
                            $count++;
373
                            /* @var $Product \Eccube\Entity\Product */
374
                            $Product->addProductCategory($ProductCategory);
375
                            $categoriesIdList[$ParentCategory->getId()] = true;
376
                        }
377
                    }
378
                    if (!isset($categoriesIdList[$Category->getId()])){
379
                        $ProductCategory = $this->createProductCategory($Product, $Category, $count);
380
                        $app['orm.em']->persist($ProductCategory);
381
                        $count++;
382
                        /* @var $Product \Eccube\Entity\Product */
383
                        $Product->addProductCategory($ProductCategory);
384 14
                        $categoriesIdList[$Category->getId()] = true;
385
                    }
386
                }
387
388
                // 画像の登録
389 14
                $add_images = $form->get('add_images')->getData();
390 14
                foreach ($add_images as $add_image) {
391
                    $ProductImage = new \Eccube\Entity\ProductImage();
392
                    $ProductImage
393
                        ->setFileName($add_image)
394
                        ->setProduct($Product)
395
                        ->setRank(1);
396
                    $Product->addProductImage($ProductImage);
397
                    $app['orm.em']->persist($ProductImage);
398
399
                    // 移動
400
                    $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...
401 14
                    $file->move($app['config']['image_save_realdir']);
402
                }
403
404
                // 画像の削除
405 14
                $delete_images = $form->get('delete_images')->getData();
406 14
                foreach ($delete_images as $delete_image) {
407
                    $ProductImage = $app['eccube.repository.product_image']
408
                        ->findOneBy(array('file_name' => $delete_image));
409
410
                    // 追加してすぐに削除した画像は、Entityに追加されない
411
                    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...
412
                        $Product->removeProductImage($ProductImage);
413
                        $app['orm.em']->remove($ProductImage);
414
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
415
                    }
416
                    $app['orm.em']->persist($Product);
417
418
                    // 削除
419
                    $fs = new Filesystem();
420 14
                    $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...
421
                }
422 14
                $app['orm.em']->persist($Product);
423 14
                $app['orm.em']->flush();
424
425
426 14
                $ranks = $request->get('rank_images');
427 14
                if ($ranks) {
428
                    foreach ($ranks as $rank) {
429
                        list($filename, $rank_val) = explode('//', $rank);
430
                        $ProductImage = $app['eccube.repository.product_image']
431
                            ->findOneBy(array(
432
                                'file_name' => $filename,
433
                                'Product' => $Product,
434
                            ));
435
                        $ProductImage->setRank($rank_val);
436
                        $app['orm.em']->persist($ProductImage);
437
                    }
438
                }
439 14
                $app['orm.em']->flush();
440
441
                // 商品タグの登録
442
                // 商品タグを一度クリア
443 14
                $ProductTags = $Product->getProductTag();
444 14
                foreach ($ProductTags as $ProductTag) {
445
                    $Product->removeProductTag($ProductTag);
446 14
                    $app['orm.em']->remove($ProductTag);
447
                }
448
449
                // 商品タグの登録
450 14
                $Tags = $form->get('Tag')->getData();
451 14
                foreach ($Tags as $Tag) {
452 14
                    $ProductTag = new ProductTag();
453
                    $ProductTag
454 14
                        ->setProduct($Product)
455 14
                        ->setTag($Tag);
456 14
                    $Product->addProductTag($ProductTag);
457 14
                    $app['orm.em']->persist($ProductTag);
458
                }
459
460 14
                $Product->setUpdateDate(new \DateTime());
461 14
                $app['orm.em']->flush();
462
463 14
                log_info('商品登録完了', array($id));
464
465 14
                $event = new EventArgs(
466
                    array(
467 14
                        'form' => $form,
468 14
                        'Product' => $Product,
469
                    ),
470
                    $request
471
                );
472 14
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_COMPLETE, $event);
473
474 14
                $app->addSuccess('admin.register.complete', 'admin');
475
476 14
                return $app->redirect($app->url('admin_product_product_edit', array('id' => $Product->getId())));
477
            } else {
478
                log_info('商品登録チェックエラー', array($id));
479
                $app->addError('admin.register.failed', 'admin');
480
            }
481
        }
482
483
        // 検索結果の保持
484 5
        $builder = $app['form.factory']
485 5
            ->createBuilder('admin_search_product');
486
487 5
        $event = new EventArgs(
488
            array(
489 5
                'builder' => $builder,
490 5
                'Product' => $Product,
491
            ),
492
            $request
493
        );
494 5
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_SEARCH, $event);
495
496 5
        $searchForm = $builder->getForm();
497
498 5
        if ('POST' === $request->getMethod()) {
499
            $searchForm->handleRequest($request);
500
        }
501
502 5
        return $app->render('Product/product.twig', array(
503 5
            'Product' => $Product,
504 5
            'form' => $form->createView(),
505 5
            'searchForm' => $searchForm->createView(),
506 5
            'has_class' => $has_class,
507 5
            'id' => $id,
508
        ));
509
    }
510
511 2
    public function delete(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
512
    {
513 2
        $this->isTokenValid($app);
514 2
        $session = $request->getSession();
515 2
        $page_no = intval($session->get('eccube.admin.product.search.page_no'));
516 2
        $page_no = $page_no ? $page_no : Constant::ENABLED;
517
518 2
        if (!is_null($id)) {
519
            /* @var $Product \Eccube\Entity\Product */
520 2
            $Product = $app['eccube.repository.product']->find($id);
521 2
            if (!$Product) {
522
                $app->deleteMessage();
523
                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...
524
            }
525
526 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...
527 2
                log_info('商品削除開始', array($id));
528
529 2
                $Product->setDelFlg(Constant::ENABLED);
530
531 2
                $ProductClasses = $Product->getProductClasses();
532 2
                $deleteImages = array();
533 2
                foreach ($ProductClasses as $ProductClass) {
534 2
                    $ProductClass->setDelFlg(Constant::ENABLED);
535 2
                    $Product->removeProductClass($ProductClass);
536
537 2
                    $ProductClasses = $Product->getProductClasses();
538 2
                    foreach ($ProductClasses as $ProductClass) {
539 2
                        $ProductClass->setDelFlg(Constant::ENABLED);
540 2
                        $Product->removeProductClass($ProductClass);
541
542 2
                        $ProductStock = $ProductClass->getProductStock();
543 2
                        $app['orm.em']->remove($ProductStock);
544
                    }
545
546 2
                    $ProductImages = $Product->getProductImage();
547 2
                    foreach ($ProductImages as $ProductImage) {
548 2
                        $Product->removeProductImage($ProductImage);
549 2
                        $deleteImages[] = $ProductImage->getFileName();
550 2
                        $app['orm.em']->remove($ProductImage);
551
                    }
552
553 2
                    $ProductCategories = $Product->getProductCategories();
554 2
                    foreach ($ProductCategories as $ProductCategory) {
555 2
                        $Product->removeProductCategory($ProductCategory);
556 2
                        $app['orm.em']->remove($ProductCategory);
557
                    }
558
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
559
                }
560
561 2
                $app['orm.em']->persist($Product);
562
563 2
                $app['orm.em']->flush();
564
565 2
                $event = new EventArgs(
566
                    array(
567 2
                        'Product' => $Product,
568 2
                        'ProductClass' => $ProductClasses,
569 2
                        'deleteImages' => $deleteImages,
570
                    ),
571
                    $request
572
                );
573 2
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_DELETE_COMPLETE, $event);
574 2
                $deleteImages = $event->getArgument('deleteImages');
575
576
                // 画像ファイルの削除(commit後に削除させる)
577 2
                foreach ($deleteImages as $deleteImage) {
578
                    try {
579 2
                        $fs = new Filesystem();
580 2
                        $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...
581 2
                    } catch (\Exception $e) {
582
                        // エラーが発生しても無視する
583
                    }
584
                }
585
586 2
                log_info('商品削除完了', array($id));
587
588 2
                $app->addSuccess('admin.delete.complete', 'admin');
589
            } else {
590
                log_info('商品削除エラー', array($id));
591 2
                $app->addError('admin.delete.failed', 'admin');
592
            }
593
        } else {
594
            log_info('商品削除エラー', array($id));
595
            $app->addError('admin.delete.failed', 'admin');
596
        }
597
598 2
        return $app->redirect($app->url('admin_product_page', array('page_no' => $page_no)).'?resume='.Constant::ENABLED);
599
    }
600
601 2
    public function copy(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
602
    {
603 2
        $this->isTokenValid($app);
604
605 2
        if (!is_null($id)) {
606 2
            $Product = $app['eccube.repository.product']->find($id);
607 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...
608 2
                $CopyProduct = clone $Product;
609 2
                $CopyProduct->copy();
610 2
                $Disp = $app['eccube.repository.master.disp']->find(\Eccube\Entity\Master\Disp::DISPLAY_HIDE);
611 2
                $CopyProduct->setStatus($Disp);
612
613 2
                $CopyProductCategories = $CopyProduct->getProductCategories();
614 2
                foreach ($CopyProductCategories as $Category) {
615 2
                    $app['orm.em']->persist($Category);
616
                }
617
618
                // 規格あり商品の場合は, デフォルトの商品規格を取得し登録する.
619 2
                if ($CopyProduct->hasProductClass()) {
620 2
                    $softDeleteFilter = $app['orm.em']->getFilters()->getFilter('soft_delete');
621 2
                    $softDeleteFilter->setExcludes(array(
0 ignored issues
show
introduced by
Add a comma after each item in a multi-line array
Loading history...
622
                        'Eccube\Entity\ProductClass'
623 2
                    ));
624 2
                    $dummyClass = $app['eccube.repository.product_class']->findOneBy(array(
625 2
                        'del_flg' => \Eccube\Common\Constant::ENABLED,
626
                        'ClassCategory1' => null,
627
                        'ClassCategory2' => null,
628 2
                        'Product' => $Product,
629
                    ));
630 2
                    $dummyClass = clone $dummyClass;
631 2
                    $dummyClass->setProduct($CopyProduct);
632 2
                    $CopyProduct->addProductClass($dummyClass);
633 2
                    $softDeleteFilter->setExcludes(array());
634
                }
635
636 2
                $CopyProductClasses = $CopyProduct->getProductClasses();
637 2
                foreach ($CopyProductClasses as $Class) {
638 2
                    $Stock = $Class->getProductStock();
639 2
                    $CopyStock = clone $Stock;
640 2
                    $CopyStock->setProductClass($Class);
641 2
                    $app['orm.em']->persist($CopyStock);
642
643 2
                    $app['orm.em']->persist($Class);
644
                }
645 2
                $Images = $CopyProduct->getProductImage();
646 2
                foreach ($Images as $Image) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
647
648
                    // 画像ファイルを新規作成
649 2
                    $extension = pathinfo($Image->getFileName(), PATHINFO_EXTENSION);
650 2
                    $filename = date('mdHis') . uniqid('_') . '.' . $extension;
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
651
                    try {
652 2
                        $fs = new Filesystem();
653 2
                        $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...
654 2
                    } catch (\Exception $e) {
655
                        // エラーが発生しても無視する
656
                    }
657 2
                    $Image->setFileName($filename);
658
659 2
                    $app['orm.em']->persist($Image);
660
                }
661 2
                $Tags = $CopyProduct->getProductTag();
662 2
                foreach ($Tags as $Tag) {
663 2
                    $app['orm.em']->persist($Tag);
664
                }
665
666 2
                $app['orm.em']->persist($CopyProduct);
667
668 2
                $app['orm.em']->flush();
669
670 2
                $event = new EventArgs(
671
                    array(
672 2
                        'Product' => $Product,
673 2
                        'CopyProduct' => $CopyProduct,
674 2
                        'CopyProductCategories' => $CopyProductCategories,
675 2
                        'CopyProductClasses' => $CopyProductClasses,
676 2
                        'images' => $Images,
677 2
                        'Tags' => $Tags,
678
                    ),
679
                    $request
680
                );
681 2
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_COPY_COMPLETE, $event);
682
683 2
                $app->addSuccess('admin.product.copy.complete', 'admin');
684
685 2
                return $app->redirect($app->url('admin_product_product_edit', array('id' => $CopyProduct->getId())));
686
            } else {
687
                $app->addError('admin.product.copy.failed', 'admin');
688
            }
689
        } else {
690
            $app->addError('admin.product.copy.failed', 'admin');
691
        }
692
693
        return $app->redirect($app->url('admin_product'));
694
    }
695
696 1
    public function display(Application $app, Request $request, $id = null)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
697
    {
698 1
        $event = new EventArgs(
699 1
            array(),
700
            $request
701
        );
702 1
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::ADMIN_PRODUCT_DISPLAY_COMPLETE, $event);
703
704 1
        if (!is_null($id)) {
705 1
            return $app->redirect($app->url('product_detail', array('id' => $id, 'admin' => '1')));
706
        }
707
708
        return $app->redirect($app->url('admin_product'));
709
    }
710
711
    /**
712
     * 商品CSVの出力.
713
     *
714
     * @param Application $app
715
     * @param Request $request
0 ignored issues
show
introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
716
     * @return StreamedResponse
717
     */
718
    public function export(Application $app, Request $request)
719
    {
720
        // タイムアウトを無効にする.
721
        set_time_limit(0);
722
723
        // sql loggerを無効にする.
724
        $em = $app['orm.em'];
725
        $em->getConfiguration()->setSQLLogger(null);
726
727
        $response = new StreamedResponse();
728
        $response->setCallback(function () use ($app, $request) {
729
730
            // CSV種別を元に初期化.
731
            $app['eccube.service.csv.export']->initCsvType(CsvType::CSV_TYPE_PRODUCT);
732
733
            // ヘッダ行の出力.
734
            $app['eccube.service.csv.export']->exportHeader();
735
736
            // 商品データ検索用のクエリビルダを取得.
737
            $qb = $app['eccube.service.csv.export']
738
                ->getProductQueryBuilder($request);
739
740
            // joinする場合はiterateが使えないため, select句をdistinctする.
741
            // http://qiita.com/suin/items/2b1e98105fa3ef89beb7
742
            // distinctのmysqlとpgsqlの挙動をあわせる.
743
            // http://uedatakeshi.blogspot.jp/2010/04/distinct-oeder-by-postgresmysql.html
744
            $qb->resetDQLPart('select')
745
                ->resetDQLPart('orderBy')
746
                ->select('p')
747
                ->orderBy('p.update_date', 'DESC')
748
                ->distinct();
749
750
            // データ行の出力.
751
            $app['eccube.service.csv.export']->setExportQueryBuilder($qb);
752 View Code Duplication
            $app['eccube.service.csv.export']->exportData(function ($entity, $csvService) {
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...
753
754
                $Csvs = $csvService->getCsvs();
755
756
                /** @var $Product \Eccube\Entity\Product */
757
                $Product = $entity;
758
759
                /** @var $Product \Eccube\Entity\ProductClass[] */
760
                $ProductClassess = $Product->getProductClasses();
0 ignored issues
show
Bug introduced by
The method getProductClasses cannot be called on $Product (of type array<integer,object<Eccube\Entity\ProductClass>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
761
762
                foreach ($ProductClassess as $ProductClass) {
763
                    $row = array();
764
765
                    // CSV出力項目と合致するデータを取得.
766
                    foreach ($Csvs as $Csv) {
767
                        // 商品データを検索.
768
                        $data = $csvService->getData($Csv, $Product);
769
                        if (is_null($data)) {
770
                            // 商品規格情報を検索.
771
                            $data = $csvService->getData($Csv, $ProductClass);
772
                        }
773
                        $row[] = $data;
774
                    }
775
776
                    //$row[] = number_format(memory_get_usage(true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
777
                    // 出力.
778
                    $csvService->fputcsv($row);
779
                }
780
            });
781
        });
782
783
        $now = new \DateTime();
784
        $filename = 'product_' . $now->format('YmdHis') . '.csv';
0 ignored issues
show
Coding Style introduced by
Concat operator must not be surrounded by spaces
Loading history...
785
        $response->headers->set('Content-Type', 'application/octet-stream');
786
        $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...
787
        $response->send();
788
789
        log_info('商品CSV出力ファイル名', array($filename));
790
791
        return $response;
792
    }
793
    
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
794
    /**
795
     * ProductCategory作成
796
     * @param \Eccube\Entity\Product $Product
797
     * @param \Eccube\Entity\Category $Category
798
     * @return \Eccube\Entity\ProductCategory
799
     */
800 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...
801
    {
802
        $ProductCategory = new \Eccube\Entity\ProductCategory();
803
        $ProductCategory->setProduct($Product);
804
        $ProductCategory->setProductId($Product->getId());
805
        $ProductCategory->setCategory($Category);
806
        $ProductCategory->setCategoryId($Category->getId());
807
        $ProductCategory->setRank($count);
808
        
0 ignored issues
show
introduced by
Please trim any trailing whitespace
Loading history...
809
        return $ProductCategory;
810
    }
811
}
812