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

CsvImportController   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 91.18%

Importance

Changes 0
Metric Value
dl 0
loc 156
ccs 62
cts 68
cp 0.9118
rs 10
c 0
b 0
f 0
wmc 19
lcom 1
cbo 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B csvShipping() 0 41 5
C loadCsv() 0 60 11
A csvTemplate() 0 6 1
A getColumnConfig() 0 20 1
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