2

次の要件を持つ Expression Engine サイトがあります。

一致するフィールドのペアによってチャネル エントリの結果セットをフィルタリングできる必要があります。たとえば、エントリには field_a と field_b があります。これらのフィールドが一致する場合、返される結果セットの一部にする必要があります。結果のカウントが正しくないため、フロントエンドでこのチェックを行うことはできません。フックを使用して、フィールドを exp:channel:entries タグに渡し、返されたデータを変更できると考えていました。

これは理にかなっているように見えますか?もしそうなら、そのデータの操作に関する詳細を知っている人はいますか? ドキュメントを見ると、「channel_entries_query_result」フックを使用したいと思いますが、実際にデータを操作する方法がわかりません。正常に起動するフックを作成しました。テンプレート tag_data などを確認できますが、次にどこに行けばよいかわかりません。

ありがとう

4

3 に答える 3

2

独自のモジュールを記述して、チャネル エントリ ループを拡張できます。

次のように使用します。

{exp:custom_module:entries}

このメソッドは、すべてのデフォルト パラメータをサポートします。

モジュール内のメソッドは次のようになります。

public function entries()
{
    if( ! class_exists('Channel'))
    {
        require_once PATH_MOD.'channel/mod.channel.php';
    }

    // queries grabbing entry ids you want
    ....

    $this->EE->TMPL->tagparams['entry_id'] = implode('|', $entry_ids);

    $channel = new Channel();
    $tagdata = $channel->entries();

    return $tagdata;
 }
于 2012-10-28T22:19:23.730 に答える
0

これにはカスタムクエリが必要なようです。これを実現するためにEEフックを使用しないでください。

独自のプラグイン/モジュールを作成するか、EEのネイティブクエリモジュールを使用することができます。

2つの列をクエリと比較するだけです。例えば:

SELECT
    *
FROM
    some_table
WHERE
    col1 = col2
于 2012-05-25T12:14:56.667 に答える
0

これがどのように行われたかに興味がある他の人のために、ここにコードがあります。フック ルートを下って、次のコードで「channel_entries_query_result」フックにバインドしました。

public function query_result_filtered($c, $res){
    # maybe this can be done better? Grabs the tag data for this template call
    $tags = $c->EE->TMPL->tag_data;

    foreach($tags as $tag):
        # We're only interested in exp:channel:entries
        if($tag['class'] == 'channel' && $tag['method'] == 'entries'):
            # We're only interested if the tag has a param of matching, e.g. {exp:channel:entries matching="field_1|field_2"}
            if(isset($tag['params']['matching'])):
                $res = $this->_parse_results($res, $tag['params']['matching']);
            endif;
        endif;
    endforeach;

    return $res;
}

private function _parse_results($res, $fields){

    $ret = array();
    $fields = explode('|', $fields);

    //If we dont have multiple tags to match against, return the result set as is
    if(!is_array($fields)):
        return $res;
    endif;

    # Get the field id's and count how many fields we're checking against
    $fields = $this->_get_field_ids($fields);
    $field_count = count($fields);

    foreach($res as $row):
        # Value to match against (just use the first value)
        $tomatch = $row[$fields[0]];
        # Keep a count on how many matches, so we can check that they all match
        $match = 0;

        foreach($fields as $field):
            # If the current field matches that of the first field then we have a match, increment the count
            if($row[$field] == $tomatch):
                $match++;
            endif;
        endforeach;

        # If we have matched all fields then add this row to the returned array
        if($match == $field_count):
            $ret[] = $row;
        endif;

    endforeach;

    return $ret;
}

private function _get_field_ids($fields){

    $ret = array();

    # Loop through the fields given and find their ID's (this could be better and check site id for multisite compatibility)
    foreach($fields as $field):
        $q = $this->EE->db->select('field_id')->where('field_name', $field)->get('exp_channel_fields');
        # Create a nice name that we can use as an array key when we check each rows value
        $ret[] = 'field_id_' . $q->row('field_id');
    endforeach;

    return $ret;
}

特にエレガントではありませんが、うまくいきました。他の誰かがより良い解決策を持っているなら、私はそれについて聞きたいです. ありがとう

于 2012-05-25T18:51:18.613 に答える