Completed
Push — support-coverage ( 9b57a3...b5dae6 )
by Kentaro
41:38
created

CsvExportService::setConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
introduced by
Superfluous parameter comment
Loading history...
379
     */
380 6
    public function fputcsv($row)
381
    {
382 6
        if (is_null($this->convertEncodingCallBack)) {
383 6
            $this->convertEncodingCallBack = $this->getConvertEncodhingCallback();
384
        }
385
386 6
        fputcsv($this->fp, array_map($this->convertEncodingCallBack, $row), $this->eccubeConfig['eccube_csv_export_separator']);
387
    }
388
389 6
    public function fclose()
390
    {
391 6
        if (!$this->closed) {
392 6
            fclose($this->fp);
393 6
            $this->closed = true;
394
        }
395
    }
396
397
    /**
398
     * 受注検索用のクエリビルダを返す.
399
     *
400
     * @param Request $request
401
     *
402
     * @return \Doctrine\ORM\QueryBuilder
403
     */
404 1 View Code Duplication
    public function getOrderQueryBuilder(Request $request)
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...
405
    {
406 1
        $session = $request->getSession();
407 1
        if ($session->has('eccube.admin.order.search')) {
408 1
            $searchData = $session->get('eccube.admin.order.search');
409 1
            $this->findDeserializeObjects($searchData);
410
        } else {
411
            $searchData = [];
412
        }
413
414
        // 受注データのクエリビルダを構築.
415 1
        $qb = $this->orderRepository
416 1
            ->getQueryBuilderBySearchDataForAdmin($searchData);
417
418 1
        return $qb;
419
    }
420
421
    /**
422
     * 出荷検索用のクエリビルダを返す.
423
     *
424
     * @param Request $request
425
     *
426
     * @return \Doctrine\ORM\QueryBuilder
427
     */
428 1
    public function getShippingQueryBuilder(Request $request)
429
    {
430 1
        $session = $request->getSession();
431 1
        $form = $this->formFactory->create(SearchShippingType::class);
432 1
        $searchData = FormUtil::submitAndGetData($form, $session->get('eccube.admin.shipping.search', []));
433
434
        // 出荷データのクエリビルダを構築.
435 1
        $qb = $this->shippingRepository
436 1
            ->getQueryBuilderBySearchDataForAdmin($searchData);
437
438 1
        return $qb;
439
    }
440
441
    /**
442
     * 会員検索用のクエリビルダを返す.
443
     *
444
     * @param Request $request
445
     *
446
     * @return \Doctrine\ORM\QueryBuilder
447
     */
448 1 View Code Duplication
    public function getCustomerQueryBuilder(Request $request)
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...
449
    {
450 1
        $session = $request->getSession();
451 1
        if ($session->has('eccube.admin.customer.search')) {
452
            $searchData = $session->get('eccube.admin.customer.search');
453
            $this->findDeserializeObjects($searchData);
454
        } else {
455 1
            $searchData = [];
456
        }
457
458
        // 会員データのクエリビルダを構築.
459 1
        $qb = $this->customerRepository
460 1
            ->getQueryBuilderBySearchData($searchData);
461
462 1
        return $qb;
463
    }
464
465
    /**
466
     * 商品検索用のクエリビルダを返す.
467
     *
468
     * @param Request $request
469
     *
470
     * @return \Doctrine\ORM\QueryBuilder
471
     */
472 View Code Duplication
    public function getProductQueryBuilder(Request $request)
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...
473
    {
474
        $session = $request->getSession();
475
        if ($session->has('eccube.admin.product.search')) {
476
            $searchData = $session->get('eccube.admin.product.search');
477
            $this->findDeserializeObjects($searchData);
478
        } else {
479
            $searchData = [];
480
        }
481
        // 商品データのクエリビルダを構築.
482
        $qb = $this->productRepository
483
            ->getQueryBuilderBySearchDataForAdmin($searchData);
484
485
        return $qb;
486
    }
487
488
    /**
489
     * セッションでシリアライズされた Doctrine のオブジェクトを取得し直す.
490
     *
491
     * XXX self::setExportQueryBuilder() をコールする前に EntityManager を取得したいので、引数で渡している
492
     *
493
     * @param array $searchData セッションから取得した検索条件の配列
494
     */
495 1
    protected function findDeserializeObjects(array &$searchData)
496
    {
497 1
        $em = $this->getEntityManager();
498 1
        foreach ($searchData as &$Conditions) {
499 1
            if ($Conditions instanceof ArrayCollection) {
500
                $Conditions = new ArrayCollection(
501
                    array_map(
502
                        function ($Entity) use ($em) {
503
                            return $em->getRepository(get_class($Entity))->find($Entity->getId());
504
                        }, $Conditions->toArray()
505
                    )
506
                );
507 1
            } elseif ($Conditions instanceof \Eccube\Entity\AbstractEntity) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\AbstractEntity 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...
508 1
                $Conditions = $em->getRepository(get_class($Conditions))->find($Conditions->getId());
509
            }
510
        }
511
    }
512
}
513