EC-CUBE3 拡張テーブルを一覧画面に反映する

EC-CUBEは株式会社ロックオンの商標です

既存テーブルを一方的に参照する拡張テーブルを新規作成した。参照元の既存テーブルのEntityにマッピングを定義しなくても、doctrineのDQLのWITHを使用することでJOINが可能。

        $join = new Expr\Join(
                Expr\Join::INNER_JOIN, 'Plugin\ProductExtend\Entity\ProductExtend', 'pe', Expr\Join::WITH, 'p = pe.product', null
        );
        $qb->add('join', array('p' => $join), true);
        $qb->innerJoin('Plugin\ProductExtend\Entity\ProductExtend', 'pe', Expr\Join::WITH, 'p.id = pe.product');        
        $qb->innerJoin('Plugin\ProductExtend\Entity\ProductExtend', 'pe', Expr\Join::WITH, 'p = pe.product');

14. Doctrine Query Language — Doctrine 2 ORM 2 documentation – http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#dql-select-examples

DQLのJOIN WITH構文を使えば、無用な関係を定義せずにテーブルの結合ができる – http://blog.tai2.net/doctrine-join-with-syntax.html

しかし、マッピングせずに、WITHでJOINすると結果Entityが複数になる。それ自体は問題にならないのだけど、ページャに影響が及ぶらしく、エラーが出る。

Cannot count query which selects two FROM components, cannot make distinction

既存コントローラのpaginate処理を呼び出している箇所を確認したところ、件数を取得するクエリは用意していなかったので、ページャが自動で上手いことしてくれるのだと思う。ただそのためにはEntityが単体である必要があるのだろう。

調べたら確かにそんな話が出てきた。

symfony2 – Doctrine : Pagination with left Joins – Stack Overflow – http://stackoverflow.com/questions/12785143/doctrine-pagination-with-left-joins

件数を取得するクエリを別途渡して上げれば解決するらしい。

だけど残念ながらEC-CUBE3.0.12-p1でこの対応をしようとすると既存ソースを改変するしかない。プラグインではコントロールできない。

まず呼び出し前のフックポイントが無い。さらに、ページャ自体がイベントを持っているので、それを利用して無理やりオプションを改変できるかとも思ったが、呼び出し方の都合からリスナーを登録することもできない。別の手段としてページャを継承したクラスを用意しても
呼び出し方を変えないと結局どうしようもない。

結論:既存ソースを修正するしかない。

コントローラを修正するか、エンティティにマッピングを追加するか…。EC-CUBE3はEC-CUBE2よりプラグインでカスタマイズできる範囲が広いそうですが、手が届かない箇所が意外とあるので諦めが必要ですね。

以上!