Failed Conditions
Push — experimental/sf ( 267a6e...28d741 )
by Ryo
1408:20 queued 1400:20
created

CsvImportController::loadCsv()   C

Complexity

Conditions 11
Paths 128

Size

Total Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 11.0295

Importance

Changes 0
Metric Value
cc 11
nc 128
nop 2
dl 0
loc 60
ccs 30
cts 32
cp 0.9375
crap 11.0295
rs 6.5393
c 0
b 0
f 0

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
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Controller\Admin\Shipping;
15
16
use Eccube\Controller\Admin\AbstractCsvImportController;
17
use Eccube\Entity\Shipping;
18
use Eccube\Form\Type\Admin\CsvImportType;
19
use Eccube\Repository\ShippingRepository;
20
use Eccube\Service\CsvImportService;
21
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
22
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
23
use Symfony\Component\HttpFoundation\Request;
24
25
class CsvImportController extends AbstractCsvImportController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
26
{
27
    /**
28
     * @var ShippingRepository
29
     */
30
    private $shippingRepository;
31
32 8
    public function __construct(ShippingRepository $shippingRepository)
33
    {
34 8
        $this->shippingRepository = $shippingRepository;
35
    }
36
37
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
38
     * 出荷CSVアップロード
39
     *
40
     * @Route("/%eccube_admin_route%/shipping/shipping_csv_upload", name="admin_shipping_csv_import")
41
     * @Template("@admin/Shipping/csv_shipping.twig")
42
     *
43
     * @throws \Doctrine\DBAL\ConnectionException
44
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
45 1
    public function csvShipping(Request $request)
46
    {
47 1
        $form = $this->formFactory->createBuilder(CsvImportType::class)->getForm();
48 1
        $columnConfig = $this->getColumnConfig();
49 1
        $errors = [];
50
51 1
        if ($request->getMethod() === 'POST') {
52 1
            $form->handleRequest($request);
53 1
            if ($form->isValid()) {
54 1
                $formFile = $form['import_file']->getData();
55
56 1
                if (!empty($formFile)) {
57 1
                    $csv = $this->getImportData($formFile);
58
59
                    try {
60 1
                        $this->entityManager->getConfiguration()->setSQLLogger(null);
61 1
                        $this->entityManager->getConnection()->beginTransaction();
62
63 1
                        $this->loadCsv($csv, $errors);
0 ignored issues
show
Security Bug introduced by
It seems like $csv defined by $this->getImportData($formFile) on line 57 can also be of type false; however, Eccube\Controller\Admin\...rtController::loadCsv() does only seem to accept object<Eccube\Service\CsvImportService>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
64
65 1
                        if ($errors) {
66
                            $this->entityManager->getConnection()->rollBack();
67
                        } else {
68 1
                            $this->entityManager->flush();
69 1
                            $this->entityManager->getConnection()->commit();
70
71 1
                            $this->addInfo('admin.shipping.csv_import.save.complete', 'admin');
72
                        }
73 1
                    } finally {
74 1
                        $this->removeUploadedFile();
75
                    }
76
                }
77
            }
78
        }
79
80
        return [
81 1
            'form' => $form->createView(),
82 1
            'headers' => $columnConfig,
83 1
            'errors' => $errors,
84
        ];
85
    }
86
87 8
    protected function loadCsv(CsvImportService $csv, &$errors)
88
    {
89 8
        $columnConfig = $this->getColumnConfig();
90
91 8
        if ($csv === false) {
92
            $errors[] = trans('csvimport.text.error.format_invalid');
93
        }
94
95
        // 必須カラムの確認
96 8
        $requiredColumns = array_map(function ($value) {
97 8
            return $value['name'];
98
        }, array_filter($columnConfig, function ($value) {
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 12 spaces, but found 8.
Loading history...
99 8
            return $value['required'];
100 8
        }));
101 8
        $csvColumns = $csv->getColumnHeaders();
102 8
        if (count(array_diff($requiredColumns, $csvColumns)) > 0) {
103 2
            $errors[] = trans('csvimport.text.error.format_invalid');
104
        }
105
106
        // 行数の確認
107 8
        $size = count($csv);
108 8
        if ($size < 1) {
109
            $errors[] = trans('csvimport.text.error.format_invalid');
110
        }
111
112 8
        $columnNames = array_combine(array_keys($columnConfig), array_column($columnConfig, 'name'));
113
114 8
        foreach ($csv as $line => $row) {
115
            // 出荷IDがなければエラー
116 8
            if (!isset($row[$columnNames['id']])) {
117 2
                $errors[] = trans('csvimportcontroller.require', ['%line%' => $line, '%name%' => $columnNames['id']]);
118 2
                continue;
119
            }
120
121
            /* @var Shipping $Shipping */
122 6
            $Shipping = is_numeric($row[$columnNames['id']]) ? $this->shippingRepository->find($row[$columnNames['id']]) : null;
123
124
            // 存在しない出荷IDはエラー
125 6
            if (is_null($Shipping)) {
126 2
                $errors[] = trans('csvimportcontroller.notfound', ['%line%' => $line, '%name%' => $columnNames['id']]);
127 2
                continue;
128
            }
129
130 4
            if (isset($row[$columnNames['tracking_number']])) {
131 4
                $Shipping->setTrackingNumber($row[$columnNames['tracking_number']]);
132
            }
133
134 4
            if (isset($row[$columnNames['shipping_date']])) {
135
                // 日付フォーマットが異なる場合はエラー
136 4
                $shippingDate = \DateTime::createFromFormat('Y-m-d', $row[$columnNames['shipping_date']]);
137 4
                if ($shippingDate === false) {
138 1
                    $errors[] = trans('csvimportcontroller.invalid_date_format', ['%line%' => $line, '%name%' => $columnNames['id']]);
139 1
                    continue;
140
                }
141
142 3
                $shippingDate->setTime(0, 0, 0);
143 3
                $Shipping->setShippingDate($shippingDate);
144
            }
145
        }
146
    }
147
148
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
149
     * アップロード用CSV雛形ファイルダウンロード
150
     *
151
     * @Route("/%eccube_admin_route%/shipping/csv_template", name="admin_shipping_csv_template")
152
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
153
    public function csvTemplate(Request $request)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
154
    {
155
        $columns = array_column($this->getColumnConfig(), 'name');
156
157
        return $this->sendTemplateResponse($request, $columns, 'shipping.csv');
158
    }
159
160 8
    protected function getColumnConfig()
161
    {
162
        return [
163 8
            'id' => [
164 8
                'name' => trans('admin.shipping.csv_shipping.id'),
165 8
                'description' => trans('admin.shipping.csv_shipping.id.description'),
166
                'required' => true,
167
            ],
168
            'tracking_number' => [
169 8
                'name' => trans('admin.shipping.csv_shipping.tracking_number'),
170 8
                'description' => trans('admin.shipping.csv_shipping.tracking_number.description'),
171
                'required' => false,
172
            ],
173
            'shipping_date' => [
174 8
                'name' => trans('admin.shipping.csv_shipping.shipping_date'),
175 8
                'description' => trans('admin.shipping.csv_shipping.shipping_date.description'),
176
                'required' => false,
177
            ],
178
        ];
179
    }
180
}
181