Failed Conditions
Pull Request — 4.0 (#3791)
by Ryo
07:54
created

CsvExportService::setCsvRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
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\Service;
15
16
use Doctrine\Common\Util\ClassUtils;
17
use Doctrine\ORM\EntityManagerInterface;
18
use Doctrine\ORM\QueryBuilder;
19
use Eccube\Common\EccubeConfig;
20
use Eccube\Entity\Csv;
21
use Eccube\Entity\Master\CsvType;
22
use Eccube\Form\Type\Admin\SearchCustomerType;
23
use Eccube\Form\Type\Admin\SearchOrderType;
24
use Eccube\Form\Type\Admin\SearchProductType;
25
use Eccube\Repository\CsvRepository;
26
use Eccube\Repository\CustomerRepository;
27
use Eccube\Repository\Master\CsvTypeRepository;
28
use Eccube\Repository\OrderRepository;
29
use Eccube\Repository\ProductRepository;
30
use Eccube\Repository\ShippingRepository;
31
use Eccube\Util\EntityUtil;
32
use Eccube\Util\FormUtil;
33
use Symfony\Component\Form\FormFactoryInterface;
34
use Symfony\Component\HttpFoundation\Request;
35
36
class CsvExportService
37
{
38
    /**
39
     * @var resource
40
     */
41
    protected $fp;
42
43
    /**
44
     * @var boolean
45
     */
46
    protected $closed = false;
47
48
    /**
49
     * @var \Closure
50
     */
51
    protected $convertEncodingCallBack;
52
53
    /**
54
     * @var EntityManagerInterface
55
     */
56
    protected $entityManager;
57
58
    /**
59
     * @var QueryBuilder;
60
     */
61
    protected $qb;
62
63
    /**
64
     * @var EccubeConfig
65
     */
66
    protected $eccubeConfig;
67
68
    /**
69
     * @var CsvType
70
     */
71
    protected $CsvType;
72
73
    /**
74
     * @var Csv[]
75
     */
76
    protected $Csvs;
77
78
    /**
79
     * @var CsvRepository
80
     */
81
    protected $csvRepository;
82
83
    /**
84
     * @var CsvTypeRepository
85
     */
86
    protected $csvTypeRepository;
87
88
    /**
89
     * @var OrderRepository
90
     */
91
    protected $orderRepository;
92
93
    /**
94
     * @var ShippingRepository
95
     */
96
    protected $shippingRepository;
97
98
    /**
99
     * @var CustomerRepository
100
     */
101
    protected $customerRepository;
102
103
    /**
104
     * @var ProductRepository
105
     */
106
    protected $productRepository;
107
108
    /**
109
     * @var FormFactoryInterface
110
     */
111
    protected $formFactory;
112
113
    /**
114
     * CsvExportService constructor.
115
     *
116
     * @param EntityManagerInterface $entityManager
117
     * @param CsvRepository $csvRepository
118
     * @param CsvTypeRepository $csvTypeRepository
119
     * @param OrderRepository $orderRepository
120
     * @param CustomerRepository $customerRepository
121
     * @param EccubeConfig $eccubeConfig
122 76
     */
123
    public function __construct(
124
        EntityManagerInterface $entityManager,
125
        CsvRepository $csvRepository,
126
        CsvTypeRepository $csvTypeRepository,
127
        OrderRepository $orderRepository,
128
        ShippingRepository $shippingRepository,
129
        CustomerRepository $customerRepository,
130
        ProductRepository $productRepository,
131
        EccubeConfig $eccubeConfig,
132
        FormFactoryInterface $formFactory
133 76
    ) {
134 76
        $this->entityManager = $entityManager;
135 76
        $this->csvRepository = $csvRepository;
136 76
        $this->csvTypeRepository = $csvTypeRepository;
137 76
        $this->orderRepository = $orderRepository;
138 76
        $this->shippingRepository = $shippingRepository;
139 76
        $this->customerRepository = $customerRepository;
140 76
        $this->eccubeConfig = $eccubeConfig;
141 76
        $this->productRepository = $productRepository;
142
        $this->formFactory = $formFactory;
143
    }
144
145
    /**
146
     * @param $config
147
     */
148
    public function setConfig($config)
149
    {
150
        $this->eccubeConfig = $config;
151
    }
152
153
    /**
154
     * @param CsvRepository $csvRepository
155
     */
156
    public function setCsvRepository(CsvRepository $csvRepository)
157
    {
158
        $this->csvRepository = $csvRepository;
159
    }
160
161
    /**
162
     * @param CsvTypeRepository $csvTypeRepository
163
     */
164
    public function setCsvTypeRepository(CsvTypeRepository $csvTypeRepository)
165
    {
166
        $this->csvTypeRepository = $csvTypeRepository;
167
    }
168
169
    /**
170
     * @param OrderRepository $orderRepository
171
     */
172
    public function setOrderRepository(OrderRepository $orderRepository)
173
    {
174
        $this->orderRepository = $orderRepository;
175
    }
176
177
    /**
178
     * @param CustomerRepository $customerRepository
179
     */
180
    public function setCustomerRepository(CustomerRepository $customerRepository)
181
    {
182
        $this->customerRepository = $customerRepository;
183
    }
184
185
    /**
186
     * @param ProductRepository $productRepository
187
     */
188
    public function setProductRepository(ProductRepository $productRepository)
189
    {
190
        $this->productRepository = $productRepository;
191
    }
192
193
    /**
194
     * @param EntityManagerInterface $entityManager
195
     */
196
    public function setEntityManager(EntityManagerInterface $entityManager)
197
    {
198
        $this->entityManager = $entityManager;
199
    }
200
201
    /**
202
     * @return EntityManagerInterface
203
     */
204
    public function getEntityManager()
205
    {
206
        return $this->entityManager;
207
    }
208
209
    /**
210
     * @param QueryBuilder $qb
211 4
     */
212
    public function setExportQueryBuilder(QueryBuilder $qb)
213 4
    {
214
        $this->qb = $qb;
215
    }
216
217
    /**
218
     * Csv種別からServiceの初期化を行う.
219
     *
220
     * @param $CsvType|integer
221 5
     */
222
    public function initCsvType($CsvType)
223 5
    {
224
        if ($CsvType instanceof CsvType) {
225
            $this->CsvType = $CsvType;
226 5
        } else {
227
            $this->CsvType = $this->csvTypeRepository->find($CsvType);
228
        }
229
230 5
        $criteria = [
231
            'CsvType' => $CsvType,
232
            'enabled' => true,
233
        ];
234 5
        $orderBy = [
235
            'sort_no' => 'ASC',
236 5
        ];
237
        $this->Csvs = $this->csvRepository->findBy($criteria, $orderBy);
238
    }
239
240
    /**
241
     * @return Csv[]
242 4
     */
243
    public function getCsvs()
244 4
    {
245
        return $this->Csvs;
246
    }
247
248
    /**
249
     * ヘッダ行を出力する.
250
     * このメソッドを使う場合は, 事前にinitCsvType($CsvType)で初期化しておく必要がある.
251 4
     */
252
    public function exportHeader()
253 4
    {
254
        if (is_null($this->CsvType) || is_null($this->Csvs)) {
255
            throw new \LogicException('init csv type incomplete.');
256
        }
257 4
258 4
        $row = [];
259 4
        foreach ($this->Csvs as $Csv) {
260
            $row[] = $Csv->getDispName();
261
        }
262 4
263 4
        $this->fopen();
264 4
        $this->fputcsv($row);
265
        $this->fclose();
266
    }
267
268
    /**
269
     * クエリビルダにもとづいてデータ行を出力する.
270
     * このメソッドを使う場合は, 事前にsetExportQueryBuilder($qb)で出力対象のクエリビルダをわたしておく必要がある.
271
     *
272
     * @param \Closure $closure
273 4
     */
274
    public function exportData(\Closure $closure)
275 4
    {
276
        if (is_null($this->qb) || is_null($this->entityManager)) {
277
            throw new \LogicException('query builder not set.');
278
        }
279 4
280
        $this->fopen();
281 4
282 4
        $query = $this->qb->getQuery();
283 4
        foreach ($query->getResult() as $iterableResult) {
284 4
            $closure($iterableResult, $this);
285 4
            $this->entityManager->detach($iterableResult);
286 4
            $query->free();
287
            flush();
288
        }
289 4
290
        $this->fclose();
291
    }
292
293
    /**
294
     * CSV出力項目と比較し, 合致するデータを返す.
295
     *
296
     * @param \Eccube\Entity\Csv $Csv
297
     * @param $entity
298
     *
299
     * @return string|null
300 4
     */
301
    public function getData(Csv $Csv, $entity)
302
    {
303 4
        // エンティティ名が一致するかどうかチェック.
304 4
        $csvEntityName = str_replace('\\\\', '\\', $Csv->getEntityName());
305 4
        $entityName = ClassUtils::getClass($entity);
306 2
        if ($csvEntityName !== $entityName) {
307
            return null;
308
        }
309
310 4
        // カラム名がエンティティに存在するかどうかをチェック.
311 2
        if (!$entity->offsetExists($Csv->getFieldName())) {
312
            return null;
313
        }
314
315 4
        // データを取得.
316
        $data = $entity->offsetGet($Csv->getFieldName());
317
318 4
        // one to one の場合は, dtb_csv.reference_field_name, 合致する結果を取得する.
319 4
        if ($data instanceof \Eccube\Entity\AbstractEntity) {
320 4
            if (EntityUtil::isNotEmpty($data)) {
321
                return $data->offsetGet($Csv->getReferenceFieldName());
322 4
            }
323
        } elseif ($data instanceof \Doctrine\Common\Collections\Collection) {
324
            // one to manyの場合は, カンマ区切りに変換する.
325
            $array = [];
326
            foreach ($data as $elem) {
327
                if (EntityUtil::isNotEmpty($elem)) {
328
                    $array[] = $elem->offsetGet($Csv->getReferenceFieldName());
329
                }
330
            }
331
332 4
            return implode($this->eccubeConfig['eccube_csv_export_multidata_separator'], $array);
333
        } elseif ($data instanceof \DateTime) {
334 3
            // datetimeの場合は文字列に変換する.
335
            return $data->format($this->eccubeConfig['eccube_csv_export_date_format']);
336
        } else {
337 4
            // スカラ値の場合はそのまま.
338
            return $data;
339
        }
340
341
        return null;
342
    }
343
344
    /**
345
     * 文字エンコーディングの変換を行うコールバック関数を返す.
346
     *
347
     * @return \Closure
348 5
     */
349
    public function getConvertEncodingCallback()
350 5
    {
351
        $config = $this->eccubeConfig;
352 5
353 5
        return function ($value) use ($config) {
354 5
            return mb_convert_encoding(
355
                (string) $value, $config['eccube_csv_export_encoding'], 'UTF-8'
356 5
            );
357
        };
358
    }
359 5
360
    public function fopen()
361 5
    {
362 3
        if (is_null($this->fp) || $this->closed) {
363
            $this->fp = fopen('php://output', 'w');
364
        }
365
    }
366
367
    /**
368
     * @param $row
369 5
     */
370
    public function fputcsv($row)
371 5
    {
372 5
        if (is_null($this->convertEncodingCallBack)) {
373
            $this->convertEncodingCallBack = $this->getConvertEncodhingCallback();
0 ignored issues
show
Bug introduced by
The method getConvertEncodhingCallback() does not exist on Eccube\Service\CsvExportService. Did you maybe mean getConvertEncodingCallback()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
374
        }
375 5
376
        fputcsv($this->fp, array_map($this->convertEncodingCallBack, $row), $this->eccubeConfig['eccube_csv_export_separator']);
377
    }
378 5
379
    public function fclose()
380 5
    {
381 5
        if (!$this->closed) {
382 5
            fclose($this->fp);
383
            $this->closed = true;
384
        }
385
    }
386
387
    /**
388
     * 受注検索用のクエリビルダを返す.
389
     *
390
     * @param Request $request
391
     *
392
     * @return \Doctrine\ORM\QueryBuilder
393 1
     */
394
    public function getOrderQueryBuilder(Request $request)
395 1
    {
396 1
        $session = $request->getSession();
397 1
        $builder = $this->formFactory
398 1
            ->createBuilder(SearchOrderType::class);
399
        $searchForm = $builder->getForm();
400 1
401 1
        $viewData = $session->get('eccube.admin.order.search', []);
402
        $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
403
404 1
        // 受注データのクエリビルダを構築.
405 1
        $qb = $this->orderRepository
406
            ->getQueryBuilderBySearchDataForAdmin($searchData);
407 1
408
        return $qb;
409
    }
410
411
    /**
412
     * 会員検索用のクエリビルダを返す.
413
     *
414
     * @param Request $request
415
     *
416
     * @return \Doctrine\ORM\QueryBuilder
417 1
     */
418
    public function getCustomerQueryBuilder(Request $request)
419 1
    {
420 1
        $session = $request->getSession();
421 1
        $builder = $this->formFactory
422 1
            ->createBuilder(SearchCustomerType::class);
423
        $searchForm = $builder->getForm();
424 1
425 1
        $viewData = $session->get('eccube.admin.customer.search', []);
426
        $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
427
428 1
        // 会員データのクエリビルダを構築.
429 1
        $qb = $this->customerRepository
430
            ->getQueryBuilderBySearchData($searchData);
431 1
432
        return $qb;
433
    }
434
435
    /**
436
     * 商品検索用のクエリビルダを返す.
437
     *
438
     * @param Request $request
439
     *
440
     * @return \Doctrine\ORM\QueryBuilder
441
     */
442
    public function getProductQueryBuilder(Request $request)
443
    {
444
        $session = $request->getSession();
445
        $builder = $this->formFactory
446
            ->createBuilder(SearchProductType::class);
447
        $searchForm = $builder->getForm();
448
449
        $viewData = $session->get('eccube.admin.product.search', []);
450
        $searchData = FormUtil::submitAndGetData($searchForm, $viewData);
451
452
        // 商品データのクエリビルダを構築.
453
        $qb = $this->productRepository
454
            ->getQueryBuilderBySearchDataForAdmin($searchData);
455
456
        return $qb;
457
    }
458
}
459