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()); | |
| } | |
| } | |
| } | |
| } |