#はじめに
前回のFormType編に続き、Controller編をやっていきます。
Controllerとは・・・説明が難しいです。簡単にぐぐってみると「ModelとViewを制御する」みたいな説明をよく見ます。
必要なデータを取得してviewに渡したり、ユーザーが入力したデータによって振る舞いが変わったりしてると思います。
そういう難しい事は置いといて、Controller編ではEC-CUBEのカスタマイズの一例として新しく一覧ページを作成する方法を説明します。
#Controllerの作成例
今回参考にする本体ソースはEC-CUBEの中でもシンプル(個人的見解)な会員処理を見てみます。
参考にする本体ソース:Eccube/Controller/Admin/Customer/CustomerController.php
参考ソースを元に必要最低限な部分を取り出してみます。
登録メールの再送やデータ削除、CSVダウンロードなどの関数もありますが、ここでは一覧を表示するindex
のみ取り出します。
namespace Eccube\Controller\Admin\Customer;
use Doctrine\ORM\QueryBuilder;
use Eccube\Controller\AbstractController;
use Eccube\Form\Type\Admin\SearchCustomerType;
use Eccube\Repository\CustomerRepository;
use Eccube\Repository\Master\PageMaxRepository;
use Eccube\Util\FormUtil;
use Knp\Component\Pager\PaginatorInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class CustomerController extends AbstractController
{
/**
* @var PageMaxRepository
*/
protected $pageMaxRepository;
/**
* @var CustomerRepository
*/
protected $customerRepository;
public function __construct(
PageMaxRepository $pageMaxRepository,
CustomerRepository $customerRepository
) {
$this->pageMaxRepository = $pageMaxRepository;
$this->customerRepository = $customerRepository;
}
/**
* @Route("/%eccube_admin_route%/customer", name="admin_customer", methods={"GET", "POST"})
* @Route("/%eccube_admin_route%/customer/page/{page_no}", requirements={"page_no" = "\d+"}, name="admin_customer_page", methods={"GET", "POST"})
* @Template("@admin/Customer/index.twig")
*/
public function index(Request $request, $page_no = null, PaginatorInterface $paginator)
{
$session = $this->session;
$builder = $this->formFactory->createBuilder(SearchCustomerType::class);
$searchForm = $builder->getForm();
$pageMaxis = $this->pageMaxRepository->findAll();
$pageCount = $session->get('eccube.admin.customer.search.page_count', $this->eccubeConfig['eccube_default_page_count']);
$pageCountParam = $request->get('page_count');
if ($pageCountParam && is_numeric($pageCountParam)) {
foreach ($pageMaxis as $pageMax) {
if ($pageCountParam == $pageMax->getName()) {
$pageCount = $pageMax->getName();
$session->set('eccube.admin.customer.search.page_count', $pageCount);
break;
}
}
}
if ('POST' === $request->getMethod()) {
$searchForm->handleRequest($request);
if ($searchForm->isValid()) {
$searchData = $searchForm->getData();
$page_no = 1;
$session->set('eccube.admin.customer.search', FormUtil::getViewData($searchForm));
$session->set('eccube.admin.customer.search.page_no', $page_no);
} else {
return [
'searchForm' => $searchForm->createView(),
'pagination' => [],
'pageMaxis' => $pageMaxis,
'page_no' => $page_no,
'page_count' => $pageCount,
'has_errors' => true,
];
}
} else {
if (null !== $page_no || $request->get('resume')) {
if ($page_no) {
$session->set('eccube.admin.customer.search.page_no', (int) $page_no);
} else {
$page_no = $session->get('eccube.admin.customer.search.page_no', 1);
}
$viewData = $session->get('eccube.admin.customer.search', []);
} else {
$page_no = 1;
$viewData = FormUtil::getViewData($searchForm);
$session->set('eccube.admin.customer.search', $viewData);
$session->set('eccube.admin.customer.search.page_no', $page_no);
}
$searchData = FormUtil::submitAndGetData($searchForm, $viewData);
}
$qb = $this->customerRepository->getQueryBuilderBySearchData($searchData);
$pagination = $paginator->paginate(
$qb,
$page_no,
$pageCount
);
return [
'searchForm' => $searchForm->createView(),
'pagination' => $pagination,
'pageMaxis' => $pageMaxis,
'page_no' => $page_no,
'page_count' => $pageCount,
'has_errors' => false,
];
}
}
表示件数、検索条件、表示するページNoの処理がほとんどです。
初期アクセス、ページ送り、他画面から戻った時(編集ページなどから)といった操作に合わせてsessionからデータを取得したり記録したりしています。
このコードを基本に、session名やRepository名といった部分を変更し、RepositoryにgetQueryBuilderBySearchData
のような絞り込み処理を用意すれば、一覧ページのControllerが完成します。
(namespaceなども変更してくださいね。)
ProductやOrderの一覧処理と比べてみてください。
大きな違いは無いと思います。
このように、本体のコードを参考にすれば、ゼロからControllerを作るより簡単ですし、本体のコードを読む練習にもなると思います。
ですので、同じようなページを作りたい場合は、本体のコードをコピーしてこねくり回し、作成してみてください。
#他のページは?
一覧以外に必須なのは、新規登録・編集やに削除処理は必須だと思います。
それぞれの処理も本体コピーして作成するのが良いと思いますが、商品や受注処理を参考にするのはオススメしないです。
商品や受注処理は、結構特殊な作りになっているので、参考にはならないです。
EC-CUBEでCRUDを作成する場合は、会員管理の処理を参考にするのが一番良いと思います。
#Controllerのカスタマイズについて
CustomizeフォルダでControllerを作成する場合は、新規Routeを追加する場合のみ利用した方が良いです。
既存のルーティングを上書きする事もできますが、それをやってしまうとアップデートが大変になります。(アップデート時の変更が反映しないなど。)
どうしても既存ルーティングをカスタマイズしたい場合は、本体ソースを変更しgit管理するのが良いと思います。
#最後に
ControllerはEC-CUBE本体を参考にして作成し、経験を積むしかないと思っています。
特に登録編集処理などが難しい部分だと思いますが、この辺はデータを送信してバリデーションする処理を理解する必要もあります。
会員の登録編集、お問合せの送信辺りの処理はフォーム処理はシンプルで、理解するのに最適な部分だと思ってます。
Controllerはある程度処理の形もありますが、発想と閃きも必要になってくると思うので、本体ソースを読んで色んな処理方法をみて、理解するのが上級者への道だと思います。