0

eZPublish フェッチをフィルタリングしようとしています。

オブジェクトの関係属性を持つクラスがあります。私のフィルターでは、オブジェクト関係属性によってフィルター処理されたこのクラスのオブジェクトを取得できます。

Enhanced Object Relations Filtering 拡張 ( http://projects.ez.no/index.php/enhanced_object_relation_filter ) の使用を開始しましたが、これは「AND」条件でのみ機能し、「OR」が必要です。

ファイルを編集して「OR」ロジックを追加することができました。これが得られたものです。

<?php
class EORExtendedFilter
{

    function CreateSqlParts( $params )
    {
        $db =& eZDB::instance();

        $tables = array();
        $joins  = array();

        // foreach filtered attribute, we add a join the relation table and filter
        // on the attribute ID + object ID
        foreach( $params as $param )
        {
            if ( !is_array( $param ) )
                continue;

            if ( !is_numeric( $param[0] ) )
            {
                $classAttributeId = eZContentObjectTreeNode::classAttributeIDByIdentifier( $param[0] );
            }
            else
            {
                $classAttributeId = $param[0];
            }

            // multiple objects ids
            if ( is_array($param[1]) )
            {
                foreach( $param[1] as $objectId )
                {
                    $join = array(); // 'OR' logic

                    if ( is_numeric( $objectId ) )
                    {
                        $tableName = 'eor_link_' . $objectId;
                        $tables[] = 'ezcontentobject_link ' . $tableName;

                        $join[]  = $tableName . '.from_contentobject_id = ezcontentobject.id';
                        $join[]  = $tableName . '.from_contentobject_version = ezcontentobject.current_version';
                        $join[]  = $tableName . '.contentclassattribute_id = ' . $classAttributeId;
                        $join[]  = $tableName . '.to_contentobject_id = ' . $objectId;
                    }

                    // 'OR' logic
                    $joins[] = $join;

                }
            }
            // single object id
            else
            {
                $objectId = $param[1];

                $tableName = 'eor_link_' . $objectId;
                $tables[] = 'ezcontentobject_link ' . $tableName;

                $joins[]  = $tableName . '.from_contentobject_id = ezcontentobject.id';
                $joins[]  = $tableName . '.from_contentobject_version = ezcontentobject.current_version';
                $joins[]  = $tableName . '.contentclassattribute_id = ' . $classAttributeId;
                $joins[]  = $tableName . '.to_contentobject_id = ' . $objectId;
            }
        }

        if ( !count( $tables ) or !count( $joins ) )
        {
            $tables = $joins = '';
        }
        else
        {
            $tables = "\n, "    . implode( "\n, ", $tables );

            // 'OR' logic
            if ( is_array($param[1]) )
            {
                $andClauses = array();
                foreach ($joins as $attr)
                {
                    $andClauses[] = implode( " AND\n ", $attr );
                }

                $joins =  implode( " OR\n ", $andClauses ) . " AND\n ";               
            }
            else
            {
                $joins =  implode( " AND\n ", $joins ) . " AND\n ";
            }

        }

        return array( 'tables' => $tables, 'joins' => $joins );
    }
}

この拡張属性フィルターは、次の文字列を生成します。

eor_link_126.from_contentobject_id = ezcontentobject.id AND eor_link_126.from_contentobject_version = ezcontentobject.current_version AND eor_link_126.contentclassattribute_id = 537 AND eor_link_126.to_contentobject_id = 126 OR (eor_link_127.from_contentobject_id = ezcontentobject.id AND eor_link_127.from_contentobject_version = ezcontentobject.current_version AND eor_link_127.contentclassattribute_id = 537 AND eor_link_127.to_contentobject_id = 127 AND

いくつかの括弧が欠けていることはわかっているので、文字列を編集して phpMyAdmin で直接テストしました。これはクエリです:

SELECT DISTINCT
                       ezcontentobject.*,
                       ezcontentobject_tree.*,
                       ezcontentclass.serialized_name_list as class_serialized_name_list,
                       ezcontentclass.identifier as class_identifier,
                       ezcontentclass.is_container as is_container

                       , ezcontentobject_name.name as name,  ezcontentobject_name.real_translation 
                       , a0.sort_key_int

                   FROM
                      ezcontentobject_tree,
                      ezcontentobject,ezcontentclass
                      , ezcontentobject_name 
                      , ezcontentobject_attribute a0


, ezcontentobject_link eor_link_126
, ezcontentobject_link eor_link_127

                   WHERE
                      ezcontentobject_tree.parent_node_id = 1443 and
                      ((eor_link_126.from_contentobject_id = ezcontentobject.id AND
 eor_link_126.from_contentobject_version = ezcontentobject.current_version AND
 eor_link_126.contentclassattribute_id = 537 AND
 eor_link_126.to_contentobject_id = 126) OR
 (eor_link_127.from_contentobject_id = ezcontentobject.id AND
 eor_link_127.from_contentobject_version = ezcontentobject.current_version AND
 eor_link_127.contentclassattribute_id = 537 AND
 eor_link_127.to_contentobject_id = 127)) AND


                                   a0.contentobject_id = ezcontentobject.id AND
                                   a0.contentclassattribute_id = 191 AND
                                   a0.version = ezcontentobject_name.content_version AND
 ( a0.language_id & ezcontentobject.language_mask > 0 AND
     ( (   ezcontentobject.language_mask - ( ezcontentobject.language_mask & a0.language_id ) ) & 1 )
   + ( ( ( ezcontentobject.language_mask - ( ezcontentobject.language_mask & a0.language_id ) ) & 2 ) )
   <
     ( a0.language_id & 1 )
   + ( ( a0.language_id & 2 ) )
 ) 
 AND 

                      ezcontentclass.version=0 AND

                      ezcontentobject_tree.contentobject_id = ezcontentobject.id  AND
                      ezcontentclass.id = ezcontentobject.contentclass_id AND

                         ezcontentobject.contentclass_id  IN  ( 17 ) AND
                       ezcontentobject_tree.contentobject_id = ezcontentobject_name.contentobject_id and
                                   ezcontentobject_tree.contentobject_version = ezcontentobject_name.content_version and 
 ( ezcontentobject_name.language_id & ezcontentobject.language_mask > 0 AND
     ( (   ezcontentobject.language_mask - ( ezcontentobject.language_mask & ezcontentobject_name.language_id ) ) & 1 )
   + ( ( ( ezcontentobject.language_mask - ( ezcontentobject.language_mask & ezcontentobject_name.language_id ) ) & 2 ) )
   <
     ( ezcontentobject_name.language_id & 1 )
   + ( ( ezcontentobject_name.language_id & 2 ) )
 ) 

                      AND ezcontentobject_tree.is_invisible = 0


                       AND 
 ezcontentobject.language_mask & 3 > 0 

                 ORDER BY a0.sort_key_int DESC
LIMIT 0, 10

問題は、上記のクエリを実行すると、クエリが停止しないため、何も返されないことです。CPU が 100% に達し、mysql を再起動する必要があります。これは、構文の問題ではないことを意味します。

クエリの説明は次のとおりです。

MySQLの説明

誰かがこれについて手がかりを持っているなら、それは非常に役に立ちます。

4

1 に答える 1

0

を使用してすべてを書き直すことで解決しましたeZPersistentObject::fetchObjectList()

于 2012-12-12T15:26:23.737 に答える