約12,000件の会員データを管理画面からCSVダウンロードしようとしたところ、なぜか3,000件ぐらいしかCSVデータが落ちてこない現象が起こりました。
調べてみるとメモリ不足で途中で落ちているとあったので、使えるメモリを増やしてみても結果変わらず。
(ちなみに、ID、氏名、メールアドレスぐらいにCSV出力設定で絞込んでやればダウンロードは可能でした)
同じようなこと(商品CSVダウンロードなども)で悩んでいる方が多いようですが、対処法を書いている方がいない…
それでも諦めずに調べてみると、対処法書いている方がいらっしゃった!
うわーやっぱりEC-CUBE側か~。
確かにこの設定をローカルでやってみると全件ダウンロード出来た。
ただ、出来るだけEC-CUBE本体は触りたくない。
どこに影響があるかわからないですしね。
ということで、別の対処で逃げることにしました。
<?php
namespace Customize\Controller\Admin\Customer;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use Doctrine\ORM\QueryBuilder;
use Eccube\Common\Constant;
use Eccube\Controller\AbstractController;
use Eccube\Entity\Master\CsvType;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Eccube\Form\Type\Admin\SearchCustomerType;
use Eccube\Repository\CustomerRepository;
use Eccube\Repository\Master\PageMaxRepository;
use Eccube\Repository\Master\PrefRepository;
use Eccube\Repository\Master\SexRepository;
use Eccube\Service\CsvExportService;
use Eccube\Service\MailService;
use Eccube\Util\FormUtil;
use Knp\Component\Pager\Paginator;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
class AdminCustomerController extends AbstractController
{
/**
* @var CsvExportService
*/
protected $csvExportService;
/**
* @var MailService
*/
protected $mailService;
/**
* @var PrefRepository
*/
protected $prefRepository;
/**
* @var SexRepository
*/
protected $sexRepository;
/**
* @var PageMaxRepository
*/
protected $pageMaxRepository;
/**
* @var CustomerRepository
*/
protected $customerRepository;
public function __construct(
PageMaxRepository $pageMaxRepository,
CustomerRepository $customerRepository,
SexRepository $sexRepository,
PrefRepository $prefRepository,
MailService $mailService,
CsvExportService $csvExportService
) {
$this->pageMaxRepository = $pageMaxRepository;
$this->customerRepository = $customerRepository;
$this->sexRepository = $sexRepository;
$this->prefRepository = $prefRepository;
$this->mailService = $mailService;
$this->csvExportService = $csvExportService;
}
/**
* 会員CSVの出力(全項目).
*
* @Route("/%eccube_admin_route%/customer/custom/export", name="admin_customer_custom_export")
*
* @param Request $request
*
* @return StreamedResponse
*/
public function custom_export(Request $request)
{
// タイムアウトを無効にする.
set_time_limit(0);
// sql loggerを無効にする.
$em = $this->entityManager;
$em->getConfiguration()->setSQLLogger(null);
$response = new StreamedResponse();
$response->setCallback(function () use ($request) {
// 会員データ検索用のクエリビルダを取得.
$qb = $this->csvExportService
->getCustomerQueryBuilder($request);
$Customers = $qb->getQuery()->getResult();
// ヘッダー用
$aryLists[] = [
"会員ID",
"お名前(姓)",
"お名前(名)",
"お名前(セイ)",
"お名前(メイ)",
"メールアドレス",
"会社名",
"郵便番号",
"都道府県(ID)",
"都道府県(名称)",
"住所1",
"住所2",
"TEL",
"性別(ID)",
"性別(名称)",
"職業(ID)",
"職業(名称)",
"誕生日",
"初回購入日",
"最終購入日",
"購入回数",
"ショップ用メモ欄",
"会員ステータス(ID)",
"会員ステータス(名称)",
"登録日",
"更新日",
];
foreach($Customers as $Customer) {
$aryLists[] = [
$Customer->getId(),
$Customer->getName01(),
$Customer->getName02(),
$Customer->getKana01(),
$Customer->getKana02(),
$Customer->getEmail(),
$Customer->getCompanyName(),
$Customer->getPostalCode(),
($Customer->getPref()) ? $Customer->getPref()->getId() : "",
($Customer->getPref()) ? $Customer->getPref()->getName() : "",
$Customer->getAddr01(),
$Customer->getAddr02(),
$Customer->getPhoneNumber(),
($Customer->getSex()) ? $Customer->getSex()->getId() : "",
($Customer->getSex()) ? $Customer->getSex()->getName() : "",
($Customer->getJob()) ? $Customer->getJob()->getId() : "",
($Customer->getJob()) ? $Customer->getJob()->getName() : "",
($Customer->getBirth()) ? $Customer->getBirth()->format('Y-m-d') : "",
($Customer->getFirstBuyDate()) ? $Customer->getFirstBuyDate()->format('Y-m-d H:i:s') : "",
($Customer->getLastBuyDate()) ? $Customer->getLastBuyDate()->format('Y-m-d H:i:s') : "",
$Customer->getBuyTimes(),
$Customer->getNote(),
($Customer->getStatus()) ? $Customer->getStatus()->getId() : "",
($Customer->getStatus()) ? $Customer->getStatus()->getName() : "",
$Customer->getCreateDate()->format('Y-m-d H:i:s'),
$Customer->getUpdateDate()->format('Y-m-d H:i:s'),
];
}
// fとopenの間は本来くっついていますが、
// くっつけて記事を投稿するとなぜかエラーになるのでスペース空けています。
$this->csvExportService->f open();
foreach ($aryLists as $fields) {
$this->csvExportService->fputcsv($fields);
}
$this->csvExportService->fclose();
});
$now = new \DateTime();
$filename = 'customer_'.$now->format('YmdHis').'.csv';
$response->headers->set('Content-Type', 'application/octet-stream');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
$response->send();
log_info('会員CSVファイル名', [$filename]);
return $response;
}
}
4行目から74行目辺りは
/eccube/src/Eccube/Controller/Admin/Customer/CustomerController.php
をコピーして使ってるだけですので、使用していないものも含まれています。
/eccube/src/Eccube/Controller/Admin/Customer/CustomerController.php
をコピーして使ってるだけですので、使用していないものも含まれています。
単純に直接検索したデータをCSVに出力しているだけです。
これだと現状は全件ダウンロード可能になりました。
ただ、この対処法だと管理画面でのCSV出力設定が意味がなくなります。
項目を追加したり、逆に減らしたりする時はわざわざソースを触らないといけなくなります。
EC-CUBEがバージョンアップで対応してくれることを祈ります…