バージョン選択

フォーラム

メニュー

オンライン状況

29 人のユーザが現在オンラインです。 (22 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 29
もっと...

PR

デザインテンプレート EC-CUBE3.0版が登場!
広告掲載について

サイト内検索

プラグイン > 開発について > リポジトリメソッドのエンティティ名に指定するのは?

開発について

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
h_tanaka
投稿日時: 2017/6/16 12:42
対応状況: −−−
長老
登録日: 2016/7/22
居住地: 愛媛県
投稿: 275
リポジトリメソッドのエンティティ名に指定するのは?
EC-CUBE 3.0.14

SQLのリポジトリメソッドで、findBy() で指定idのエンティティが取得できますが、これの否定版として、指定id以外のエンティティを取得する findByNot() を作成しようとしています。

以下のサイトを参考にしてメソッドを追加したのですが、うまく動作しません。

https://stackoverflow.com/questions/14085946/doctrine-findby-does-not-equal

app/Plugin/Test/Repository/TestRepository.php
    /**
     * Finds entities by a set not of criteria.
     *
     * @param array      $criteria
     * @param array|null $orderBy
     * @param int|null   $limit
     * @param int|null   $offset
     *
     * @return array The objects.
     */
    public function findByNot( array $criteria, array $orderBy = null, $limit = null, $offset = null )
    {
        $qb = $this->getEntityManager()->createQueryBuilder();
        $expr = $this->getEntityManager()->getExpressionBuilder();

        $qb->select( 'entity' )
            ->from( $this->getEntityName(), 'entity' );

        foreach ( $criteria as $field => $value ) {

            $qb->andWhere( $expr->neq( 'entity.' . $field, $value ) );
        }

        if ( $orderBy ) {

            foreach ( $orderBy as $field => $order ) {

                $qb->addOrderBy( 'entity.' . $field, $order );
            }
        }

        if ( $limit )
            $qb->setMaxResults( $limit );

        if ( $offset )
            $qb->setFirstResult( $offset );

        return $qb->getQuery()
            ->getResult();
    }


おそらく 'entity' にあたる部分を変更しないといけないのだと思うのですが、ここの仕組みがよくわかっていません。
Product なら 'p' 、Order なら 'o' でいいのでしょうが、プラグイン独自で指定した 'plg_test' というテーブル名の場合は何を指定すればいいのでしょうか?
試しに 'plg_test' を指定してみましたが、結果は empty になりました。


----------------
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

h_tanaka
投稿日時: 2017/6/16 14:56
対応状況: −−−
長老
登録日: 2016/7/22
居住地: 愛媛県
投稿: 275
Re: リポジトリメソッドのエンティティ名に指定するのは?
上記のやり方での解決方法がわからなかったため、findAll() で全件検索して1件ずつ判定するやり方に変更しました。
件数が多いテーブルの場合は好ましくないやり方ですが。。

なので、本件はクローズせずにしておきます。
引き続き解決方法のご回答お待ちしています。


----------------
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

hata
投稿日時: 2017/6/16 15:43
対応状況: −−−
一人前
登録日: 2015/8/3
居住地: 宮城県
投稿: 118
Re: リポジトリメソッドのエンティティ名に指定するのは?
別の手ですが...

findByのあたりのソースをみたところcriteriaに色々指定できるようでそれを使ってできないかな?
と思ったら、matching()を使う方式のこのスレッドを見つけました。
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=18109&forum=14&post_id=78348

対象が複数あるとダメっぽく結局はcreateQueryBuilderで対応したようですが...欲しい情報はこれにないですかね?

こちらのソースをみるとnotInとかあるので複数対象でもmatchingでできそうな...
vendor/doctrine/orm/lib/Doctrine/ORM/Query/Expr.php

まあ参考まで
h_tanaka
投稿日時: 2017/6/16 16:48
対応状況: −−−
長老
登録日: 2016/7/22
居住地: 愛媛県
投稿: 275
Re: リポジトリメソッドのエンティティ名に指定するのは?
hata さん
ありがとうございます。

ご提示のスレッドにメソッドの記載があったのでそのまま使えそうです。
ただ、対象のメソッドを含むリポジトリの記述方法がわからないです。

どこまで合っているのわかりませんが、試した実装を以下に記載します。

まず、配送方法テーブルに対して NOT IN 検索したかったので、リポジトリを拡張しようとしました。
findNotContainsBy() メソッド内はご提示のスレッドにおけるnanasessさんのご回答からの引用です。

app/Plugin/Test/Repository/ExtendedDeliveryRepository.php
class ExtendedDeliveryRepository extends DeliveryRepository
{
    /**
     * NOT IN で検索する.
     *
     * @param array $criteria
     * @param array $orderBy
     * @param integer $limit
     * @param integer $offset
     * @return array
     * @see EntityRepository::findBy()
     */
    public function findNotContainsBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $qb = $this->createQueryBuilder('d');

        foreach ($criteria as $col => $val) {
            $qb->andWhere($qb->expr()->notIn('d.'.$col, ':'.$col))
                ->setParameter($col, (array)$val);
        }

        if (is_array($orderBy)) {
            foreach ($orderBy as $sort => $order) {
                if (array_values($orderBy) === $orderBy) { // 配列 or 連想配列
                    $sort = $order;
                    $order = 'ASC';
                }
                $qb->orderBy('d.'.$sort, $order);
            }
        }

        if ($limit > 0) {
            $qb->setMaxResults($limit);
        }
        if ($offset > 0) {
            $qb->setFirstResult($offset);
        }

        return $qb->getQuery()->getResult();
    }
}


次に、FormEvents::POST_SET_DATA にてメソッドを使用したかったので、拡張フォームの addEventListener() で呼び出そうとしました。
しかし、ここでつまりました。。

app/Plugin/Test/Form/Extension/ShoppingTypeExtension.php
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $app = $this->app;
        if ($app->isGranted('ROLE_ADMIN')) {
            return;
        }

        // カート内商品のブランド以外の配送方法を非表示
        $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($app) {
            $form = $event->getForm();

            findNotContainsBy();  // ★ どうやって呼び出す?
        });
    }

    public function getExtendedType()
    {
        return 'shopping';
    }


----------------
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

hata
投稿日時: 2017/6/16 18:10
対応状況: −−−
一人前
登録日: 2015/8/3
居住地: 宮城県
投稿: 118
Re: リポジトリメソッドのエンティティ名に指定するのは?
ちょっとよくわからなくなってきたので口を挟むのはここまでにしますが、配送業者からいくつか特定のIDを除いて
エンティティを取り出すだけならこれでいいと思います。
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->notIn('id', array(1, 3, 5)★ここを除外したいIDの配列で指定する));
$result = $app['eccube.repository.delivery']->matching($criteria);
「カート内商品のブランド」と「配送業者」のところの関連性が良くわかっていないのでこれじゃダメなのかも知れませんが。。。
h_tanaka
投稿日時: 2017/6/19 10:59
対応状況: −−−
長老
登録日: 2016/7/22
居住地: 愛媛県
投稿: 275
Re: リポジトリメソッドのエンティティ名に指定するのは?
ご提示の実装そのまま使えました。
ありがとうございます!

Criteria も勉強して使えるようにならないとですね...!


----------------
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

 



ログイン


EC-CUBEガイドブック

統計情報

総メンバー数は19,515名です
総投稿数は81,788件です

投稿数ランキング

1
seasoft
7331
2
AMUAMU
2712
3
nanasess
1623
4
yuh
1346
5
red
1052
6
fukap
907
7
shutta
827
8 ramrun 789
9
tsuji
782
10
umebius
671
11
tao_s
646
12 sumida 638
13
homan
633
14 karin 609
15 DELIGHT 571
16
468
570
17
patapata
502
18
flealog
483
19 tonton 436
20
ecbg
387


ネットショップの壺

EC-CUBEガイドブック
Copyright© LOCKON CO.,LTD. All Rights Reserved.