Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
56.52% |
13 / 23 |
CRAP | |
57.02% |
65 / 114 |
CsvExportService | |
0.00% |
0 / 1 |
|
56.52% |
13 / 23 |
239.66 | |
57.02% |
65 / 114 |
setConfig | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setCsvRepository | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setCsvTypeRepository | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setOrderRepository | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setCustomerRepository | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setProductRepository | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setEntityManager | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getEntityManager | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
setExportQueryBuilder | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
initCsvType | |
0.00% |
0 / 1 |
2.01 | |
85.71% |
6 / 7 |
|||
getCsvs | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
exportHeader | |
0.00% |
0 / 1 |
4.02 | |
88.89% |
8 / 9 |
|||
exportData | |
0.00% |
0 / 1 |
4.01 | |
90.91% |
10 / 11 |
|||
getData | |
0.00% |
0 / 1 |
30.63 | |
40.91% |
9 / 22 |
|||
getConvertEncodhingCallback | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
anonymous function | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
fopen | |
100.00% |
1 / 1 |
3 | |
100.00% |
3 / 3 |
|||
fputcsv | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
fclose | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
getOrderQueryBuilder | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 8 |
|||
getCustomerQueryBuilder | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 8 |
|||
getProductQueryBuilder | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 8 |
|||
findDeserializeObjects | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 4 |
<?php | |
/* | |
* This file is part of EC-CUBE | |
* | |
* Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved. | |
* | |
* http://www.lockon.co.jp/ | |
* | |
* This program is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU General Public License | |
* as published by the Free Software Foundation; either version 2 | |
* of the License, or (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
*/ | |
namespace Eccube\Service; | |
use Eccube\Common\Constant; | |
use Eccube\Util\EntityUtil; | |
use Symfony\Component\Form\FormFactory; | |
use Symfony\Component\HttpFoundation\Request; | |
use Doctrine\Common\Collections\ArrayCollection; | |
class CsvExportService | |
{ | |
/** | |
* @var | |
*/ | |
protected $fp; | |
/** | |
* @var | |
*/ | |
protected $closed = false; | |
/** | |
* @var \Closure | |
*/ | |
protected $convertEncodingCallBack; | |
/** | |
* @var \Doctrine\ORM\EntityManager | |
*/ | |
protected $em; | |
/** | |
* @var \Doctrine\ORM\QueryBuilder; | |
*/ | |
protected $qb; | |
/** | |
* @var array | |
*/ | |
protected $config; | |
/** | |
* @var \Eccube\Entity\Master\CsvType | |
*/ | |
protected $CsvType; | |
/** | |
* @var \Eccube\Entity\Csv[] | |
*/ | |
protected $Csvs; | |
/** | |
* @var \Eccube\Repository\CsvRepository | |
*/ | |
protected $csvRepository; | |
/** | |
* @var \Eccube\Repository\Master\CsvTypeRepository | |
*/ | |
protected $csvTypeRepository; | |
/** | |
* @var \Eccube\Repository\OrderRepository | |
*/ | |
protected $orderRepository; | |
/** | |
* @var \Eccube\Repository\CustomerRepository | |
*/ | |
protected $customerRepository; | |
/** | |
* @var \Eccube\Repository\ProductRepository | |
*/ | |
protected $productRepository; | |
/** | |
* @param $config | |
*/ | |
public function setConfig($config) | |
{ | |
$this->config = $config; | |
} | |
/** | |
* @param \Eccube\Repository\CsvRepository $csvRepository | |
*/ | |
public function setCsvRepository(\Eccube\Repository\CsvRepository $csvRepository) | |
{ | |
$this->csvRepository = $csvRepository; | |
} | |
/** | |
* @param \Eccube\Repository\Master\CsvTypeRepository $csvTypeRepository | |
*/ | |
public function setCsvTypeRepository(\Eccube\Repository\Master\CsvTypeRepository $csvTypeRepository) | |
{ | |
$this->csvTypeRepository = $csvTypeRepository; | |
} | |
/** | |
* @param \Eccube\Repository\OrderRepository $orderRepository | |
*/ | |
public function setOrderRepository(\Eccube\Repository\OrderRepository $orderRepository) | |
{ | |
$this->orderRepository = $orderRepository; | |
} | |
/** | |
* @param \Eccube\Repository\CustomerRepository $customerRepository | |
*/ | |
public function setCustomerRepository(\Eccube\Repository\CustomerRepository $customerRepository) | |
{ | |
$this->customerRepository = $customerRepository; | |
} | |
/** | |
* @param \Eccube\Repository\ProductRepository $productRepository | |
*/ | |
public function setProductRepository(\Eccube\Repository\ProductRepository $productRepository) | |
{ | |
$this->productRepository = $productRepository; | |
} | |
/** | |
* @param \Doctrine\ORM\EntityManager $em | |
*/ | |
public function setEntityManager(\Doctrine\ORM\EntityManager $em) | |
{ | |
$this->em = $em; | |
} | |
/** | |
* @return \Doctrine\ORM\EntityManager | |
*/ | |
public function getEntityManager() | |
{ | |
return $this->em; | |
} | |
/** | |
* @param \Doctrine\ORM\QueryBuilder $qb | |
*/ | |
public function setExportQueryBuilder(\Doctrine\ORM\QueryBuilder $qb) | |
{ | |
$this->qb = $qb; | |
} | |
/** | |
* Csv種別からServiceの初期化を行う. | |
* | |
* @param $CsvType|integer | |
*/ | |
public function initCsvType($CsvType) | |
{ | |
if ($CsvType instanceof \Eccube\Entity\Master\CsvType) { | |
$this->CsvType = $CsvType; | |
} else { | |
$this->CsvType = $this->csvTypeRepository->find($CsvType); | |
} | |
$criteria = array( | |
'CsvType' => $CsvType, | |
'enable_flg' => Constant::ENABLED | |
); | |
$orderBy = array( | |
'rank' => 'ASC' | |
); | |
$this->Csvs = $this->csvRepository->findBy($criteria, $orderBy); | |
} | |
/** | |
* @return \Eccube\Entity\Csv[] | |
*/ | |
public function getCsvs() | |
{ | |
return $this->Csvs; | |
} | |
/** | |
* ヘッダ行を出力する. | |
* このメソッドを使う場合は, 事前にinitCsvType($CsvType)で初期化しておく必要がある. | |
*/ | |
public function exportHeader() | |
{ | |
if (is_null($this->CsvType) || is_null($this->Csvs)) { | |
throw new \LogicException('init csv type incomplete.'); | |
} | |
$row = array(); | |
foreach ($this->Csvs as $Csv) { | |
$row[] = $Csv->getDispName(); | |
} | |
$this->fopen(); | |
$this->fputcsv($row); | |
$this->fclose(); | |
} | |
/** | |
* クエリビルダにもとづいてデータ行を出力する. | |
* このメソッドを使う場合は, 事前にsetExportQueryBuilder($qb)で出力対象のクエリビルダをわたしておく必要がある. | |
* | |
* @param \Closure $closure | |
*/ | |
public function exportData(\Closure $closure) | |
{ | |
if (is_null($this->qb) || is_null($this->em)) { | |
throw new \LogicException('query builder not set.'); | |
} | |
$this->fopen(); | |
$query = $this->qb->getQuery(); | |
foreach ($query->getResult() as $iteratableResult) { | |
$closure($iteratableResult, $this); | |
$this->em->detach($iteratableResult); | |
$query->free(); | |
flush(); | |
} | |
$this->fclose(); | |
} | |
/** | |
* CSV出力項目と比較し, 合致するデータを返す. | |
* | |
* @param \Eccube\Entity\Csv $Csv | |
* @param $entity | |
* @return mixed|null|string|void | |
*/ | |
public function getData(\Eccube\Entity\Csv $Csv, $entity) | |
{ | |
// エンティティ名が一致するかどうかチェック. | |
$csvEntityName = str_replace('\\\\', '\\', $Csv->getEntityName()); | |
$entityName = str_replace('\\\\', '\\', get_class($entity)); | |
if ($csvEntityName !== $entityName) { | |
$entityName = str_replace('DoctrineProxy\\__CG__\\', '', $entityName); | |
if ($csvEntityName !== $entityName) { | |
return null; | |
} | |
} | |
// カラム名がエンティティに存在するかどうかをチェック. | |
if (!$entity->offsetExists($Csv->getFieldName())) { | |
return null; | |
} | |
// データを取得. | |
$data = $entity->offsetGet($Csv->getFieldName()); | |
// one to one の場合は, dtb_csv.referece_field_nameと比較し, 合致する結果を取得する. | |
if ($data instanceof \Eccube\Entity\AbstractEntity) { | |
if (EntityUtil::isNotEmpty($data)) { | |
return $data->offsetGet($Csv->getReferenceFieldName()); | |
} | |
} elseif ($data instanceof \Doctrine\Common\Collections\Collection) { | |
// one to manyの場合は, カンマ区切りに変換する. | |
$array = array(); | |
foreach ($data as $elem) { | |
if (EntityUtil::isNotEmpty($elem)) { | |
$array[] = $elem->offsetGet($Csv->getReferenceFieldName()); | |
} | |
} | |
return implode($this->config['csv_export_multidata_separator'], $array); | |
} elseif ($data instanceof \DateTime) { | |
// datetimeの場合は文字列に変換する. | |
return $data->format($this->config['csv_export_date_format']); | |
} else { | |
// スカラ値の場合はそのまま. | |
return $data; | |
} | |
return null; | |
} | |
/** | |
* 文字エンコーディングの変換を行うコールバック関数を返す. | |
* | |
* @return \Closure | |
*/ | |
public function getConvertEncodhingCallback() | |
{ | |
$config = $this->config; | |
return function ($value) use ($config) { | |
return mb_convert_encoding( | |
(string) $value, $config['csv_export_encoding'], 'UTF-8' | |
); | |
}; | |
} | |
/** | |
* | |
*/ | |
public function fopen() | |
{ | |
if (is_null($this->fp) || $this->closed) { | |
$this->fp = fopen('php://output', 'w'); | |
} | |
} | |
/** | |
* @param $row | |
* @param null $callback | |
*/ | |
public function fputcsv($row) | |
{ | |
if (is_null($this->convertEncodingCallBack)) { | |
$this->convertEncodingCallBack = $this->getConvertEncodhingCallback(); | |
} | |
fputcsv($this->fp, array_map($this->convertEncodingCallBack, $row), $this->config['csv_export_separator']); | |
} | |
/** | |
* | |
*/ | |
public function fclose() | |
{ | |
if (!$this->closed) { | |
fclose($this->fp); | |
$this->closed = true; | |
} | |
} | |
/** | |
* 受注検索用のクエリビルダを返す. | |
* | |
* @param Request $request | |
* @return \Doctrine\ORM\QueryBuilder | |
*/ | |
public function getOrderQueryBuilder(Request $request) | |
{ | |
$session = $request->getSession(); | |
if ($session->has('eccube.admin.order.search')) { | |
$searchData = $session->get('eccube.admin.order.search'); | |
$this->findDeserializeObjects($searchData); | |
} else { | |
$searchData = array(); | |
} | |
// 受注データのクエリビルダを構築. | |
$qb = $this->orderRepository | |
->getQueryBuilderBySearchDataForAdmin($searchData); | |
return $qb; | |
} | |
/** | |
* 会員検索用のクエリビルダを返す. | |
* | |
* @param Request $request | |
* @return \Doctrine\ORM\QueryBuilder | |
*/ | |
public function getCustomerQueryBuilder(Request $request) | |
{ | |
$session = $request->getSession(); | |
if ($session->has('eccube.admin.customer.search')) { | |
$searchData = $session->get('eccube.admin.customer.search'); | |
$this->findDeserializeObjects($searchData); | |
} else { | |
$searchData = array(); | |
} | |
// 会員データのクエリビルダを構築. | |
$qb = $this->customerRepository | |
->getQueryBuilderBySearchData($searchData); | |
return $qb; | |
} | |
/** | |
* 商品検索用のクエリビルダを返す. | |
* | |
* @param Request $request | |
* @return \Doctrine\ORM\QueryBuilder | |
*/ | |
public function getProductQueryBuilder(Request $request) | |
{ | |
$session = $request->getSession(); | |
if ($session->has('eccube.admin.product.search')) { | |
$searchData = $session->get('eccube.admin.product.search'); | |
$this->findDeserializeObjects($searchData); | |
} else { | |
$searchData = array(); | |
} | |
// 商品データのクエリビルダを構築. | |
$qb = $this->productRepository | |
->getQueryBuilderBySearchDataForAdmin($searchData); | |
return $qb; | |
} | |
/** | |
* セッションでシリアライズされた Doctrine のオブジェクトを取得し直す. | |
* | |
* XXX self::setExportQueryBuilder() をコールする前に EntityManager を取得したいので、引数で渡している | |
* | |
* @param array $searchData セッションから取得した検索条件の配列 | |
* @param EntityManager $em | |
*/ | |
protected function findDeserializeObjects(array &$searchData) | |
{ | |
$em = $this->getEntityManager(); | |
foreach ($searchData as &$Conditions) { | |
if ($Conditions instanceof ArrayCollection) { | |
$Conditions = new ArrayCollection( | |
array_map( | |
function ($Entity) use ($em) { | |
return $em->getRepository(get_class($Entity))->find($Entity->getId()); | |
}, $Conditions->toArray() | |
) | |
); | |
} elseif ($Conditions instanceof \Eccube\Entity\AbstractEntity) { | |
$Conditions = $em->getRepository(get_class($Conditions))->find($Conditions->getId()); | |
} | |
} | |
} | |
} |