Пример #1
0
 static function trashList($params = false, $asCount = false)
 {
     if ($params === false) {
         $params = array('Offset' => false, 'Limit' => false, 'SortBy' => false, 'AttributeFilter' => false);
     }
     $offset = isset($params['Offset']) && is_numeric($params['Offset']) ? $params['Offset'] : false;
     $limit = isset($params['Limit']) && is_numeric($params['Limit']) ? $params['Limit'] : false;
     $asObject = isset($params['AsObject']) ? $params['AsObject'] : true;
     $objectNameFilter = isset($params['ObjectNameFilter']) ? $params['ObjectNameFilter'] : false;
     $sortBy = isset($params['SortBy']) && is_array($params['SortBy']) ? $params['SortBy'] : array(array('name'));
     if ($asCount) {
         $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings(false);
     } else {
         $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings($sortBy, 'ezcot');
     }
     $attributeFilter = eZContentObjectTreeNode::createAttributeFilterSQLStrings($params['AttributeFilter'], $sortingInfo);
     if ($attributeFilter === false) {
         return null;
     }
     $useVersionName = true;
     $versionNameTables = eZContentObjectTreeNode::createVersionNameTablesSQLString($useVersionName);
     $versionNameTargets = eZContentObjectTreeNode::createVersionNameTargetsSQLString($useVersionName);
     $versionNameJoins = eZContentObjectTreeNode::createVersionNameJoinsSQLString($useVersionName, false, false, false, 'ezcot');
     $languageFilter = ' AND ' . eZContentLanguage::languagesSQLFilter('ezcontentobject');
     $objectNameFilterSQL = eZContentObjectTreeNode::createObjectNameFilterConditionSQLString($objectNameFilter);
     $limitation = isset($params['Limitation']) && is_array($params['Limitation']) ? $params['Limitation'] : false;
     $limitationList = eZContentObjectTreeNode::getLimitationList($limitation);
     $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL($limitationList, 'ezcontentobject_trash', 'ezcot');
     if ($asCount) {
         $query = "SELECT count(*) as count ";
     } else {
         $query = "SELECT\n                        ezcontentobject.*,\n                        ezcot.*,\n                        ezcontentclass.serialized_name_list as class_serialized_name_list,\n                        ezcontentclass.identifier as class_identifier\n                        {$versionNameTargets}\n                        {$sortingInfo['attributeTargetSQL']} ";
     }
     $query .= "FROM\n                        ezcontentobject_trash ezcot,\n                        ezcontentobject,\n                        ezcontentclass\n                        {$versionNameTables}\n                        {$sortingInfo['attributeFromSQL']}\n                        {$attributeFilter['from']}\n                        {$sqlPermissionChecking['from']}\n                   WHERE\n                        ezcontentclass.version=0 AND\n                        ezcot.contentobject_id = ezcontentobject.id  AND\n                        ezcontentclass.id = ezcontentobject.contentclass_id AND\n                        {$sortingInfo['attributeWhereSQL']}\n                        {$attributeFilter['where']}\n                        {$versionNameJoins}\n                        {$sqlPermissionChecking['where']}\n                        {$objectNameFilterSQL}\n                        {$languageFilter}\n                        ";
     if (!$asCount && $sortingInfo['sortingFields'] && strlen($sortingInfo['sortingFields']) > 5) {
         $query .= " ORDER BY {$sortingInfo['sortingFields']}";
     }
     $db = eZDB::instance();
     if (!$offset && !$limit) {
         $trashRowsArray = $db->arrayQuery($query);
     } else {
         $trashRowsArray = $db->arrayQuery($query, array('offset' => $offset, 'limit' => $limit));
     }
     // cleanup temp tables
     $db->dropTempTableList($sqlPermissionChecking['temp_tables']);
     if ($asCount) {
         return $trashRowsArray[0]['count'];
     } else {
         if ($asObject) {
             $retTrashNodes = array();
             foreach (array_keys($trashRowsArray) as $key) {
                 $trashRow =& $trashRowsArray[$key];
                 $retTrashNodes[] = new eZContentObjectTrashNode($trashRow);
             }
             return $retTrashNodes;
         } else {
             return $trashRowsArray;
         }
     }
 }
 function subTree($params, $nodeID, $countChildren = false)
 {
     $nodeListArray = array();
     // sorting params
     $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings($params['SortBy']);
     // node params
     $notEqParentString = '';
     $pathStringCond = '';
     eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings($pathStringCond, $notEqParentString, $nodeID, 1, false);
     // class filter
     $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString($params['ClassFilterType'], $params['ClassFilterArray']);
     if ($classCondition === false) {
         return $nodeListArray;
     }
     // permissions
     $limitationParams = false;
     $limitationList = eZContentObjectTreeNode::getLimitationList($limitationParams);
     if ($limitationList === false) {
         return $nodeListArray;
     }
     $permissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL($limitationList);
     // version
     $useVersionName = true;
     $versionNameTables = eZContentObjectTreeNode::createVersionNameTablesSQLString($useVersionName);
     $versionNameTargets = eZContentObjectTreeNode::createVersionNameTargetsSQLString($useVersionName);
     $versionNameJoins = eZContentObjectTreeNode::createVersionNameJoinsSQLString($useVersionName);
     // invisible nodes.
     $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString(false, $params['FetchHidden']);
     $query = '';
     if ($countChildren) {
         $query = "SELECT count(*) as count\n                          FROM\n                               ezcontentobject_tree,\n                               ezcontentobject,ezcontentclass\n                               {$versionNameTables}\n                               {$permissionChecking['from']}\n                          WHERE {$pathStringCond}\n                                {$classCondition}\n                                ezcontentclass.version=0 AND\n                                {$notEqParentString}\n                                ezcontentobject_tree.contentobject_id = ezcontentobject.id  AND\n                                ezcontentclass.id = ezcontentobject.contentclass_id\n                                {$versionNameJoins}\n                                {$permissionChecking['where']} ";
     } else {
         $query = "SELECT ezcontentobject.*,\n                             ezcontentobject_tree.*,\n                             ezcontentclass.serialized_name_list as class_serialized_name_list,\n                             ezcontentclass.identifier as class_identifier,\n                             ezcontentclass.is_container as is_container\n                             {$versionNameTargets}\n                      FROM\n                             ezcontentobject_tree,\n                             ezcontentobject,ezcontentclass\n                             {$versionNameTables}\n                             {$sortingInfo['attributeFromSQL']}\n                             {$permissionChecking['from']}\n                      WHERE\n                             {$pathStringCond}\n                             {$sortingInfo['attributeWhereSQL']}\n                             ezcontentclass.version=0 AND\n                             {$notEqParentString}\n                             ezcontentobject_tree.contentobject_id = ezcontentobject.id  AND\n                             ezcontentclass.id = ezcontentobject.contentclass_id AND\n                             {$classCondition}\n                             ezcontentobject_tree.contentobject_is_published = 1\n                             {$versionNameJoins}\n                             {$showInvisibleNodesCond}\n                             {$permissionChecking['where']}\n                      ORDER BY {$sortingInfo['sortingFields']}";
     }
     $db = eZDB::instance();
     $nodeListArray = $db->arrayQuery($query);
     // cleanup temp tables
     $db->dropTempTableList($permissionChecking['temp_tables']);
     if ($countChildren) {
         return $nodeListArray[0]['count'];
     } else {
         foreach ($nodeListArray as $key => $row) {
             $nodeListArray[$key]['path_identification_string'] = eZContentObjectTreeNode::fetch($row['node_id'])->pathWithNames();
         }
         return $nodeListArray;
     }
 }
    /**
     * Regression test for issue #16737
     * 1) Test executing the sql and verify that it doesn't have database error.
     * 2) Test the sorting in class_name, class_name with contentobject_id
     * The test should pass in mysql, postgresql and oracle
     */
    public function testIssue16737()
    {


        //test generated result of createSortingSQLStrings
        $sortList = array( array( 'class_name', true ) );
        $result = eZContentObjectTreeNode::createSortingSQLStrings( $sortList );
        $this->assertEquals( ', ezcontentclass_name.name as contentclass_name',
                            strtolower( $result['attributeTargetSQL'] ) );
        $this->assertEquals( 'contentclass_name asc', strtolower( $result['sortingFields'] ) );

        $sortListTwo = array( array( 'class_name', false ),
                              array( 'class_identifier', true ) );
        $result = eZContentObjectTreeNode::createSortingSQLStrings( $sortListTwo );
        $this->assertEquals( ', ezcontentclass_name.name as contentclass_name',
                            strtolower( $result['attributeTargetSQL'] ));
        $this->assertEquals( 'contentclass_name desc, ezcontentclass.identifier asc',
                            strtolower( $result['sortingFields'] ) );

        //test trash node with classname
        $sortBy = array( array( 'class_name', true ),
                         array( 'contentobject_id', true ) );
        $params = array( 'SortBy', $sortBy );
        $result = eZContentObjectTrashNode::trashList( $params );
        $this->assertEquals( array(), $result );
        $result = eZContentObjectTrashNode::trashList( $params, true );
        $this->assertEquals( 0, $result );  //if there is an error, there will be fatal error message

        //test subtreenode with classname
        $parent = new ezpObject( 'folder', 1 );
        $parent->publish();
        $parentNodeID = $parent->mainNode->node_id;

        $article = new ezpObject( 'article', $parentNodeID );
        $article->publish();

        $link = new ezpObject( 'link', $parentNodeID );
        $link->publish();

        $folder = new ezpObject( 'folder', $parentNodeID );
        $folder->publish();

        $folder2 = new ezpObject( 'folder', $parentNodeID );
        $folder2->publish();

        $sortBy = array( array( 'class_name', false ) );
        $params = array( 'SortBy' => $sortBy );
        $result = eZContentObjectTreeNode::subTreeByNodeID( $params, $parentNodeID );
        $this->assertEquals( $article->mainNode->node_id, $result[count( $result )-1]->attribute( 'node_id' ) );

        $sortBy = array( array( 'class_name', false ),
                         array( 'contentobject_id', false ) );
        $params = array( 'SortBy' => $sortBy );
        $result = eZContentObjectTreeNode::subTreeByNodeID( $params, $parentNodeID );
        $this->assertEquals( $folder2->mainNode->node_id, $result[1]->attribute( 'node_id' ) );
    }
 public static function fetchKeyword($alphabet, $classid, $offset, $limit, $owner = false, $sortBy = array(), $parentNodeID = false, $includeDuplicates = true, $strictMatching = false, $depth = 1)
 {
     $classIDArray = array();
     if (is_numeric($classid)) {
         $classIDArray = array($classid);
     } else {
         if (is_array($classid)) {
             $classIDArray = $classid;
         }
     }
     $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString(true, false);
     $limitation = false;
     $limitationList = eZContentObjectTreeNode::getLimitationList($limitation);
     $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL($limitationList);
     $db_params = array();
     $db_params['offset'] = $offset;
     $db_params['limit'] = $limit;
     $keywordNodeArray = array();
     $lastKeyword = '';
     $db = eZDB::instance();
     //in SELECT clause below we will use a full keyword value
     //or just a part of ezkeyword.keyword matched to $alphabet respective to $includeDuplicates parameter.
     //In the case $includeDuplicates = ture we need only a part
     //of ezkeyword.keyword to be fetched in field to allow DISTINCT to remove rows with the same node id's
     $sqlKeyword = 'ezkeyword.keyword';
     if (!$includeDuplicates) {
         $sqlKeyword = $db->subString('ezkeyword.keyword', 1, strlen($alphabet)) . ' AS keyword ';
     }
     $alphabet = $db->escapeString($alphabet);
     $sortingInfo = array();
     $sortingInfo['attributeFromSQL'] = '';
     $sqlTarget = $sqlKeyword . ',ezcontentobject_tree.node_id';
     if (is_array($sortBy) && count($sortBy) > 0) {
         switch ($sortBy[0]) {
             case 'keyword':
             case 'name':
                 $sortingString = '';
                 if ($sortBy[0] == 'name') {
                     $sortingString = 'ezcontentobject.name';
                 } elseif ($sortBy[0] == 'keyword') {
                     if ($includeDuplicates) {
                         $sortingString = 'ezkeyword.keyword';
                     } else {
                         $sortingString = 'keyword';
                     }
                 }
                 $sortOrder = true;
                 // true is ascending
                 if (isset($sortBy[1])) {
                     $sortOrder = $sortBy[1];
                 }
                 $sortingOrder = $sortOrder ? ' ASC' : ' DESC';
                 $sortingInfo['sortingFields'] = $sortingString . $sortingOrder;
                 break;
             default:
                 $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings($sortBy);
         }
         // Fixing the attributeTargetSQL
         switch ($sortBy[0]) {
             case 'keyword':
                 $sortingInfo['attributeTargetSQL'] = '';
                 break;
             case 'name':
                 $sortingInfo['attributeTargetSQL'] = ', ezcontentobject.name';
                 break;
             case 'attribute':
             case 'class_name':
                 break;
             default:
                 $sortingInfo['attributeTargetSQL'] .= ', ' . strtok($sortingInfo["sortingFields"], " ");
         }
         $sqlTarget .= $sortingInfo['attributeTargetSQL'];
     } else {
         $sortingInfo['sortingFields'] = 'ezkeyword.keyword ASC';
     }
     //Adding DISTINCT to avoid duplicates,
     //check if DISTINCT keyword was added before providing clauses for sorting.
     if (!$includeDuplicates && substr($sqlTarget, 0, 9) != 'DISTINCT ') {
         $sqlTarget = 'DISTINCT ' . $sqlTarget;
     }
     $sqlOwnerString = is_numeric($owner) ? "AND ezcontentobject.owner_id = '{$owner}'" : '';
     $parentNodeIDString = '';
     if (is_numeric($parentNodeID)) {
         $notEqParentString = '';
         // If the node(s) doesn't exist we return null.
         if (!eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings($parentNodeIDString, $notEqParentString, $parentNodeID, $depth)) {
             return null;
         }
     }
     $sqlClassIDString = '';
     if (is_array($classIDArray) and count($classIDArray)) {
         $sqlClassIDString = 'AND ' . $db->generateSQLINStatement($classIDArray, 'ezkeyword.class_id', false, false, 'int') . ' ';
     }
     // composing sql for matching tag word, it could be strict equiality or LIKE clause
     // dependent of $strictMatching parameter.
     $sqlMatching = "ezkeyword.keyword LIKE '{$alphabet}%'";
     if ($strictMatching) {
         $sqlMatching = "ezkeyword.keyword = '{$alphabet}'";
     }
     $query = "SELECT {$sqlTarget}\n                  FROM ezkeyword\n                       INNER JOIN ezkeyword_attribute_link ON (ezkeyword_attribute_link.keyword_id = ezkeyword.id)\n                       INNER JOIN ezcontentobject_attribute ON (ezcontentobject_attribute.id = ezkeyword_attribute_link.objectattribute_id)\n                       INNER JOIN ezcontentobject ON (ezcontentobject_attribute.version = ezcontentobject.current_version AND ezcontentobject_attribute.contentobject_id = ezcontentobject.id)\n                       INNER JOIN ezcontentobject_tree ON (ezcontentobject_tree.contentobject_id = ezcontentobject.id)\n                       INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id)\n                       {$sortingInfo['attributeFromSQL']}\n                       {$sqlPermissionChecking['from']}\n                  WHERE\n                  {$parentNodeIDString}\n                  {$sqlMatching}\n                  {$showInvisibleNodesCond}\n                  {$sqlPermissionChecking['where']}\n                  {$sqlClassIDString}\n                  {$sqlOwnerString}\n                  AND ezcontentclass.version = 0\n                  AND ezcontentobject.status = " . eZContentObject::STATUS_PUBLISHED . "\n                  AND ezcontentobject_tree.main_node_id = ezcontentobject_tree.node_id\n                  ORDER BY {$sortingInfo['sortingFields']}";
     $keyWords = $db->arrayQuery($query, $db_params);
     $trans = eZCharTransform::instance();
     foreach ($keyWords as $keywordArray) {
         $keyword = $keywordArray['keyword'];
         $nodeID = $keywordArray['node_id'];
         $nodeObject = eZContentObjectTreeNode::fetch($nodeID);
         if ($nodeObject != null) {
             $keywordLC = $trans->transformByGroup($keyword, 'lowercase');
             if ($lastKeyword == $keywordLC) {
                 $keywordNodeArray[] = array('keyword' => '', 'link_object' => $nodeObject);
             } else {
                 $keywordNodeArray[] = array('keyword' => $keyword, 'link_object' => $nodeObject);
             }
             $lastKeyword = $keywordLC;
         } else {
             $lastKeyword = $trans->transformByGroup($keyword, 'lowercase');
         }
     }
     return array('result' => $keywordNodeArray);
 }
    static public function fetchKeyword( $alphabet,
                           $classid,
                           $offset,
                           $limit,
                           $owner = false,
                           $sortBy = array(),
                           $parentNodeID = false,
                           $includeDuplicates = true,
                           $strictMatching = false )
    {
        $classIDArray = array();
        if ( is_numeric( $classid ) )
        {
            $classIDArray = array( $classid );
        }
        else if ( is_array( $classid ) )
        {
            $classIDArray = $classid;
        }

        $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( true, false );
        $limitation = false;
        $limitationList = eZContentObjectTreeNode::getLimitationList( $limitation );
        $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );

        $db_params = array();
        $db_params['offset'] = $offset;
        $db_params['limit'] = $limit;

        $keywordNodeArray = array();
        $lastKeyword = '';

        $db = eZDB::instance();

        //in SELECT clause below we will use a full keyword value
        //or just a part of ezkeyword.keyword matched to $alphabet respective to $includeDuplicates parameter.
        //In the case $includeDuplicates = ture we need only a part
        //of ezkeyword.keyword to be fetched in field to allow DISTINCT to remove rows with the same node id's
        $sqlKeyword = 'ezkeyword.keyword';
        if ( !$includeDuplicates )
        {
            $sqlKeyword = $db->subString('ezkeyword.keyword', 1, strlen( $alphabet ) ) . ' AS keyword ';
        }

        $alphabet = $db->escapeString( $alphabet );

        $sortingInfo = array();
        $sortingInfo['attributeFromSQL'] = ', ezcontentobject_attribute a1';
        $sortingInfo['attributeWhereSQL'] = '';
        $sqlTarget = $sqlKeyword.',ezcontentobject_tree.node_id';

        if ( is_array( $sortBy ) && count ( $sortBy ) > 0 )
        {
            switch ( $sortBy[0] )
            {
                case 'keyword':
                case 'name':
                {
                    $sortingString = '';
                    if ( $sortBy[0] == 'name' )
                    {
                        $sortingString = 'ezcontentobject.name';
                        $sortingInfo['attributeTargetSQL'] = ', ' . $sortingString;
                    }
                    elseif ( $sortBy[0] == 'keyword' )
                    {
                        if ( $includeDuplicates )
                            $sortingString = 'ezkeyword.keyword';
                        else
                            $sortingString = 'keyword';
                        $sortingInfo['attributeTargetSQL'] = '';
                    }

                    $sortOrder = true; // true is ascending
                    if ( isset( $sortBy[1] ) )
                        $sortOrder = $sortBy[1];
                    $sortingOrder = $sortOrder ? ' ASC' : ' DESC';
                    $sortingInfo['sortingFields'] = $sortingString . $sortingOrder;
                } break;
                default:
                {
                    $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings( $sortBy );

                    if ( $sortBy[0] == 'attribute' )
                    {
                        // if sort_by is 'attribute' we should add ezcontentobject_name to "FromSQL" and link to ezcontentobject
                        $sortingInfo['attributeFromSQL']  .= ', ezcontentobject_name, ezcontentobject_attribute a1';
                        $sortingInfo['attributeWhereSQL'] .= ' ezcontentobject.id = ezcontentobject_name.contentobject_id AND';
                        $sqlTarget = 'DISTINCT ezcontentobject_tree.node_id, '.$sqlKeyword;
                    }
                    else // for unique declaration
                    {
                        $sortByArray = explode( ' ', $sortingInfo['sortingFields'] );
                        $sortingInfo['attributeTargetSQL'] .= ', ' . $sortByArray[0];

                        $sortingInfo['attributeFromSQL']  .= ', ezcontentobject_attribute a1';
                    }

                } break;
            }

            $sqlTarget .= $sortingInfo['attributeTargetSQL'];
        }
        else
        {
            $sortingInfo['sortingFields'] = 'ezkeyword.keyword ASC';
        }
        $sortingInfo['attributeWhereSQL'] .= " a1.version=ezcontentobject.current_version
                                             AND a1.contentobject_id=ezcontentobject.id AND";

        //Adding DISTINCT to avoid duplicates,
        //check if DISTINCT keyword was added before providing clauses for sorting.
        if ( !$includeDuplicates && substr( $sqlTarget, 0, 9) != 'DISTINCT ' )
        {
            $sqlTarget = 'DISTINCT ' . $sqlTarget;
        }

        $sqlOwnerString = is_numeric( $owner ) ? "AND ezcontentobject.owner_id = '$owner'" : '';
        $parentNodeIDString = is_numeric( $parentNodeID ) ? "AND ezcontentobject_tree.parent_node_id = '$parentNodeID'" : '';

        $sqlClassIDString = '';
        if ( is_array( $classIDArray ) and count( $classIDArray ) )
        {
            $sqlClassIDString = 'AND ' . $db->generateSQLINStatement( $classIDArray, 'ezkeyword.class_id', false, false, 'int' ) . ' ';
        }

        // composing sql for matching tag word, it could be strict equiality or LIKE clause
        // dependent of $strictMatching parameter.
        $sqlMatching = "ezkeyword.keyword LIKE '$alphabet%'";
        if ( $strictMatching )
        {
            $sqlMatching = "ezkeyword.keyword = '$alphabet'";
        }

        $query = "SELECT $sqlTarget
                  FROM ezkeyword, ezkeyword_attribute_link,ezcontentobject_tree,ezcontentobject,ezcontentclass
                       $sortingInfo[attributeFromSQL]
                       $sqlPermissionChecking[from]
                  WHERE
                  $sortingInfo[attributeWhereSQL]
                  $sqlMatching
                  $showInvisibleNodesCond
                  $sqlPermissionChecking[where]
                  $sqlClassIDString
                  $sqlOwnerString
                  $parentNodeIDString
                  AND ezcontentclass.version=0
                  AND ezcontentobject.status=".eZContentObject::STATUS_PUBLISHED."
                  AND ezcontentobject_tree.main_node_id=ezcontentobject_tree.node_id
                  AND ezcontentobject_tree.contentobject_id = ezcontentobject.id
                  AND ezcontentclass.id = ezcontentobject.contentclass_id
                  AND a1.id=ezkeyword_attribute_link.objectattribute_id
                  AND ezkeyword_attribute_link.keyword_id = ezkeyword.id ORDER BY {$sortingInfo['sortingFields']}";

        $keyWords = $db->arrayQuery( $query, $db_params );

        $trans = eZCharTransform::instance();

        foreach ( $keyWords as $keywordArray )
        {
            $keyword = $keywordArray['keyword'];
            $nodeID = $keywordArray['node_id'];
            $nodeObject = eZContentObjectTreeNode::fetch( $nodeID );

            if ( $nodeObject != null )
            {
                $keywordLC = $trans->transformByGroup( $keyword, 'lowercase' );
                if ( $lastKeyword == $keywordLC )
                    $keywordNodeArray[] = array( 'keyword' => '', 'link_object' => $nodeObject );
                else
                    $keywordNodeArray[] = array( 'keyword' => $keyword, 'link_object' => $nodeObject );

                $lastKeyword = $keywordLC;
            }
            else
            {
                $lastKeyword = $trans->transformByGroup( $keyword, 'lowercase' );
            }
        }
        return array( 'result' => $keywordNodeArray );
    }
 static function subTreeMultiPaths($nodesParams, $listParams = NULL)
 {
     if (!is_array($nodesParams) || !count($nodesParams)) {
         eZDebug::writeWarning(__METHOD__ . ': Nodes parameter must be an array with at least one key.');
         return null;
     }
     if ($listParams === null) {
         $listParams = array('SortBy' => false, 'Offset' => false, 'Limit' => false, 'GroupBy' => false);
     }
     $offset = isset($listParams['Offset']) && is_numeric($listParams['Offset']) ? $listParams['Offset'] : false;
     $limit = isset($listParams['Limit']) && is_numeric($listParams['Limit']) ? $listParams['Limit'] : false;
     $groupBy = isset($listParams['GroupBy']) ? $listParams['GroupBy'] : false;
     if (!isset($listParams['SortBy'])) {
         $listParams['SortBy'] = false;
     }
     $sortBy = $listParams['SortBy'];
     $queryNodes = '';
     foreach ($nodesParams as $nodeParams) {
         $nodeID = $nodeParams['ParentNodeID'];
         if (!is_numeric($nodeID) && !is_array($nodeID)) {
             eZDebug::writeWarning(__METHOD__ . ': Nodes parameter must be numeric or an array with numeric values.');
             $retValue = null;
             return $retValue;
         }
         if ($nodeParams === null) {
             $nodeParams = array('Depth' => false, 'Language' => false, 'AttributeFilter' => false, 'ExtendedAttributeFilter' => false, 'ClassFilterType' => false, 'ClassFilterArray' => false);
         }
         //$onlyTranslated   = ( isset( $nodeParams['OnlyTranslated']    ) )                       ? $nodeParams['OnlyTranslated']     : false;
         $language = isset($nodeParams['Language']) ? $nodeParams['Language'] : false;
         $depth = isset($nodeParams['Depth']) && is_numeric($nodeParams['Depth']) ? $nodeParams['Depth'] : false;
         $depthOperator = isset($nodeParams['DepthOperator']) ? $nodeParams['DepthOperator'] : false;
         $asObject = isset($nodeParams['AsObject']) ? $nodeParams['AsObject'] : true;
         $mainNodeOnly = isset($nodeParams['MainNodeOnly']) ? $nodeParams['MainNodeOnly'] : false;
         $ignoreVisibility = isset($nodeParams['IgnoreVisibility']) ? $nodeParams['IgnoreVisibility'] : false;
         if (!isset($nodeParams['ClassFilterType'])) {
             $nodeParams['ClassFilterType'] = false;
         }
         $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings($sortBy);
         $attributeFilter = eZContentObjectTreeNode::createAttributeFilterSQLStrings($nodeParams['AttributeFilter'], $sortingInfo, $language);
         if ($language) {
             if (!is_array($language)) {
                 $language = array($language);
             }
             eZContentLanguage::setPrioritizedLanguages($language);
         }
         $classCondition = eZContentObjectTreeNode::createClassFilteringSQLString($nodeParams['ClassFilterType'], $nodeParams['ClassFilterArray']);
         $extendedAttributeFilter = eZContentObjectTreeNode::createExtendedAttributeFilterSQLStrings($nodeParams['ExtendedAttributeFilter']);
         $mainNodeOnlyCond = eZContentObjectTreeNode::createMainNodeConditionSQLString($mainNodeOnly);
         $pathStringCond = '';
         $notEqParentString = '';
         // If the node(s) doesn't exist we return null.
         if (!eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings($pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator)) {
             $retValue = null;
             return $retValue;
         }
         $languageFilter = ' AND ' . eZContentLanguage::languagesSQLFilter('ezcontentobject');
         if ($language) {
             eZContentLanguage::clearPrioritizedLanguages();
         }
         $limitation = isset($nodeParams['Limitation']) && is_array($nodeParams['Limitation']) ? $nodeParams['Limitation'] : false;
         $limitationList = eZContentObjectTreeNode::getLimitationList($limitation);
         $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL($limitationList);
         // Determine whether we should show invisible nodes.
         $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString(!$ignoreVisibility);
         $queryNodes .= " (\n                          {$pathStringCond}\n                          {$extendedAttributeFilter['joins']}\n                          {$sortingInfo['attributeWhereSQL']}\n                          {$attributeFilter['where']}\n                          ezcontentclass.version=0 AND\n                          {$notEqParentString}\n                          {$mainNodeOnlyCond}\n                          {$classCondition}\n                          " . eZContentLanguage::sqlFilter('ezcontentobject_name', 'ezcontentobject') . "\n                          {$showInvisibleNodesCond}\n                          {$sqlPermissionChecking['where']}\n                          {$languageFilter}\n                      )\n                      OR";
     }
     $groupBySelectText = '';
     $groupBySQL = $extendedAttributeFilter['group_by'];
     if (!$groupBySQL) {
         eZContentObjectTreeNode::createGroupBySQLStrings($groupBySelectText, $groupBySQL, $groupBy);
     } else {
         if ($groupBy) {
             eZDebug::writeError("Cannot use group_by parameter together with extended attribute filter which sets group_by!", __METHOD__);
         }
     }
     $query = "SELECT DISTINCT " . "ezcontentobject.contentclass_id, ezcontentobject.current_version, ezcontentobject.id, ezcontentobject.initial_language_id, ezcontentobject.language_mask, " . "ezcontentobject.modified, ezcontentobject.owner_id, ezcontentobject.published, ezcontentobject.remote_id AS object_remote_id, " . "ezcontentobject.section_id, ezcontentobject.status, ezcontentobject_tree.contentobject_is_published, ezcontentobject_tree.contentobject_version, " . "ezcontentobject_tree.depth, ezcontentobject_tree.is_hidden, ezcontentobject_tree.is_invisible, ezcontentobject_tree.main_node_id, ezcontentobject_tree.modified_subnode, " . "ezcontentobject_tree.node_id, ezcontentobject_tree.parent_node_id, ezcontentobject_tree.path_identification_string, ezcontentobject_tree.path_string, " . "ezcontentobject_tree.priority, ezcontentobject_tree.remote_id, ezcontentobject_tree.sort_field, ezcontentobject_tree.sort_order, ezcontentclass.serialized_name_list as class_serialized_name_list, " . "ezcontentclass.identifier as class_identifier, ezcontentclass.is_container {$groupBySelectText}, ezcontentobject_name.name, ezcontentobject_name.real_translation " . "{$sortingInfo['attributeTargetSQL']}, {$nodeParams['ResultID']} AS resultid " . "FROM ezcontentobject_tree " . "INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id) " . "INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id) " . "INNER JOIN ezcontentobject_name ON ( " . "    ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND " . "    ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version " . ") " . "{$sortingInfo['attributeFromSQL']} " . "{$attributeFilter['from']} " . "{$extendedAttributeFilter['tables']} " . "{$sqlPermissionChecking['from']} " . "WHERE " . substr($queryNodes, 0, -2) . " " . $groupBySQL;
     if ($sortingInfo['sortingFields']) {
         $query .= " ORDER BY {$sortingInfo['sortingFields']}";
     }
     $db = eZDB::instance();
     $server = count($sqlPermissionChecking['temp_tables']) > 0 ? eZDBInterface::SERVER_SLAVE : false;
     if (!$offset && !$limit) {
         $nodeListArray = $db->arrayQuery($query, array(), $server);
     } else {
         $nodeListArray = $db->arrayQuery($query, array('offset' => $offset, 'limit' => $limit), $server);
     }
     if ($asObject) {
         $retNodeList = eZContentObjectTreeNode::makeObjectsArray($nodeListArray);
     } else {
         $retNodeList = $nodeListArray;
     }
     // cleanup temp tables
     $db->dropTempTableList($sqlPermissionChecking['temp_tables']);
     return $retNodeList;
 }
    /**
     * Returns related or reverse related objects
     *
     * @param int|bool $fromObjectVersion   If omitted, the current version will be used
     * @param int|bool $objectID        If omitted, the current object will be used
     * @param int|bool $attributeID     makes sense only when $params['AllRelations'] not set or eZContentObject::RELATION_ATTRIBUTE
     *                                  $attributeID = 0|false ( $params['AllRelations'] is eZContentObject::RELATION_ATTRIBUTE )
     *                                      - return relations made with any attributes
     *                                  $attributeID > 0
     *                                      - return relations made with attribute ID ( "related object(s)" datatype )
     *                                  $attributeID = false ( $params['AllRelations'] not set )
     *                                      - return ALL relations (deprecated, use "$params['AllRelations'] = true" instead)
     * @param bool $groupByAttribute    This parameter makes sense only when $attributeID == false or $params['AllRelations'] = true
     *                                  $groupByAttribute = false
     *                                      - return all relations as an array of content objects
     *                                  $groupByAttribute = true
     *                                      - return all relations groupped by attribute ID
     * @param array|bool $params        Other parameters from template fetch function
     *                                  $params['AllRelations'] = true
     *                                      - return ALL relations, including attribute-level
     *                                  $params['AllRelations'] = false
     *                                      - return objec level relations only
     *                                  $params['AllRelations'] = int > 0
     *                                      - bit mask of EZ_CONTENT_OBJECT_RELATION_* values
     *                                  $params['SortBy']
     *                                      - Possible values:
     *                                          "class_identifier", "class_name", "modified",
     *                                          "name", "published", "section"
     *                                  $params['IgnoreVisibility'] = true
     *                                      - Include related objects with a 'hidden' state
     *                                  $params['IgnoreVisibility'] = false
     *                                      - Exclude related objects with a 'hidden' state
     *                                  $params['RelatedClassIdentifiers'] = array
     *                                      - limit returned relations to objects of the specified class identifiers
     * @param bool $reverseRelatedObjects   true -> returns reverse related objects
     *                                      false -> returns related objects
     * @return eZContentObject[]|array eZContentObject[], if $params['AsObject'] is set to true (default), array otherwise
     */
    function relatedObjects( $fromObjectVersion = false,
                             $objectID = false,
                             $attributeID = 0,
                             $groupByAttribute = false,
                             $params = false,
                             $reverseRelatedObjects = false )
    {
        if ( $fromObjectVersion == false )
            $fromObjectVersion = isset( $this->CurrentVersion ) ? $this->CurrentVersion : false;
        $fromObjectVersion =(int) $fromObjectVersion;
        if( !$objectID )
            $objectID = $this->ID;
        $objectID =(int) $objectID;

        $limit            = ( isset( $params['Limit']  ) && is_numeric( $params['Limit']  ) ) ? $params['Limit']              : false;
        $offset           = ( isset( $params['Offset'] ) && is_numeric( $params['Offset'] ) ) ? $params['Offset']             : false;
        $asObject         = ( isset( $params['AsObject']          ) )                         ? $params['AsObject']           : true;
        $loadDataMap      = ( isset( $params['LoadDataMap'] ) )                               ? $params['LoadDataMap']        : false;


        $db = eZDB::instance();
        $sortingString = '';
        $sortingInfo = array( 'attributeFromSQL' => '',
                              'attributeWhereSQL' => '',
                              'attributeTargetSQL' => '' );
        $relatedClassIdentifiersSQL = '';
        $showInvisibleNodesCond = '';
        // process params (only SortBy and IgnoreVisibility currently supported):
        // Supported sort_by modes:
        //   class_identifier, class_name, modified, name, published, section
        if ( is_array( $params ) )
        {
            if ( isset( $params['SortBy'] ) )
            {
                $validSortBy = array( 'class_identifier', 'class_name', 'modified', 'name', 'published', 'section' );
                $sortByParam = array();
                if ( is_array( $params['SortBy'] ) )
                {
                    // only one SortBy, as a simple array
                    if ( !is_array( $params['SortBy'][0] ) )
                    {
                        if ( !in_array( $params['SortBy'][0], $validSortBy ) )
                            eZDebug::writeWarning( "Unsupported sort_by parameter {$params['SortBy'][0]}; check the online documentation for the list of supported sort types", __METHOD__ );
                        else
                            $sortByParam[] = $params['SortBy'];
                    }
                    // multiple SortBy, check each of them one by one, and keep valid ones
                    else
                    {
                        $invalidSortBy = array();
                        foreach( $params['SortBy'] as $sortByTuple )
                        {
                            if ( !in_array( $sortByTuple[0], $validSortBy ) )
                                $invalidSortBy[] = $sortByTuple[0];
                            else
                                $sortByParam[] = $sortByTuple;
                        }
                        if ( count( $invalidSortBy ) > 0 )
                        {
                            eZDebug::writeWarning( "Unsupported sort_by parameter(s) " . implode( ', ', $invalidSortBy ) . "; check the online documentation for the list of supported sort types", __METHOD__ );
                        }
                    }
                }
                if ( count( $sortByParam ) > 0 )
                {
                    $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings( $sortByParam );
                    $sortingString = ' ORDER BY ' . $sortingInfo['sortingFields'];
                }
            }
            if ( isset( $params['IgnoreVisibility'] ) )
            {
                $showInvisibleNodesCond = self::createFilterByVisibilitySQLString( $params['IgnoreVisibility'] );
            }

            // related class identifier filter
            $relatedClassIdentifiersSQL = '';
            if ( isset( $params['RelatedClassIdentifiers'] ) && is_array( $params['RelatedClassIdentifiers'] ) )
            {
                $relatedClassIdentifiers = array();
                foreach( $params['RelatedClassIdentifiers'] as $classIdentifier )
                {
                    $relatedClassIdentifiers[] = "'" . $db->escapeString( $classIdentifier ) . "'";
                }
                $relatedClassIdentifiersSQL = $db->generateSQLINStatement( $relatedClassIdentifiers, 'ezcontentclass.identifier', false, true, 'string' ). " AND";
                unset( $classIdentifier, $relatedClassIdentifiers );
            }
        }

        $relationTypeMasking = '';
        $relationTypeMask = isset( $params['AllRelations'] ) ? $params['AllRelations'] : ( $attributeID === false );
        if ( $attributeID && ( $relationTypeMask === false || $relationTypeMask === eZContentObject::RELATION_ATTRIBUTE ) )
        {
            $attributeID =(int) $attributeID;
            $relationTypeMasking .= " contentclassattribute_id=$attributeID AND ";
            $relationTypeMask = eZContentObject::RELATION_ATTRIBUTE;
        }
        elseif ( is_bool( $relationTypeMask ) )
        {
            $relationTypeMask = eZContentObject::relationTypeMask( $relationTypeMask );
        }

        if ( $db->databaseName() == 'oracle' )
        {
            $relationTypeMasking .= " bitand( relation_type, $relationTypeMask ) <> 0 ";
        }
        else
        {
            $relationTypeMasking .= " ( relation_type & $relationTypeMask ) <> 0 ";
        }

        // Create SQL
        $fromOrToContentObjectID = $reverseRelatedObjects == false ? " AND ezcontentobject.id=ezcontentobject_link.to_contentobject_id AND
                                                                      ezcontentobject_link.from_contentobject_id='$objectID' AND
                                                                      ezcontentobject_link.from_contentobject_version='$fromObjectVersion' "
                                                                   : " AND ezcontentobject.id=ezcontentobject_link.from_contentobject_id AND
                                                                      ezcontentobject_link.to_contentobject_id=$objectID AND
                                                                      ezcontentobject_link.from_contentobject_version=ezcontentobject.current_version ";
            $query = "SELECT ";

            if ( $groupByAttribute )
            {
                $query .= "ezcontentobject_link.contentclassattribute_id, ";
            }
            $query .= "
                        ezcontentclass.serialized_name_list AS class_serialized_name_list,
                        ezcontentclass.identifier as contentclass_identifier,
                        ezcontentclass.is_container as is_container,
                        ezcontentobject.*, ezcontentobject_name.name as name, ezcontentobject_name.real_translation
                        $sortingInfo[attributeTargetSQL]
                     FROM
                        ezcontentclass,
                        ezcontentobject,
                        ezcontentobject_link,
                        ezcontentobject_name
                        $sortingInfo[attributeFromSQL]
                     WHERE
                        ezcontentclass.id=ezcontentobject.contentclass_id AND
                        ezcontentclass.version=0 AND
                        ezcontentobject.status=" . eZContentObject::STATUS_PUBLISHED . " AND
                        $sortingInfo[attributeWhereSQL]
                        $relatedClassIdentifiersSQL
                        $relationTypeMasking
                        $fromOrToContentObjectID
                        $showInvisibleNodesCond AND
                        ezcontentobject.id = ezcontentobject_name.contentobject_id AND
                        ezcontentobject.current_version = ezcontentobject_name.content_version AND
                        " . eZContentLanguage::sqlFilter( 'ezcontentobject_name', 'ezcontentobject' ) . "
                        $sortingString";
        if ( !$offset && !$limit )
        {
            $relatedObjects = $db->arrayQuery( $query );
        }
        else
        {
            $relatedObjects = $db->arrayQuery( $query, array( 'offset' => $offset,
                                                             'limit'  => $limit ) );
        }

        $ret = array();
        $tmp = array();
        foreach ( $relatedObjects as $object )
        {
            if ( $asObject )
            {
                $obj = new eZContentObject( $object );
                $obj->ClassName = eZContentClass::nameFromSerializedString( $object['class_serialized_name_list'] );
            }
            else
            {
                $obj = $object;
            }

            $tmp[] = $obj;

            if ( !$groupByAttribute )
            {
                $ret[] = $obj;
            }
            else
            {
                $classAttrID = $object['contentclassattribute_id'];

                if ( !isset( $ret[$classAttrID] ) )
                    $ret[$classAttrID] = array();

                $ret[$classAttrID][] = $obj;
            }
        }
        if ( $loadDataMap && $asObject )
            eZContentObject::fillNodeListAttributes( $tmp );
        return $ret;
    }
Пример #8
0
 function relatedObjects($fromObjectVersion = false, $objectID = false, $attributeID = 0, $groupByAttribute = false, $params = false, $reverseRelatedObjects = false)
 {
     if ($fromObjectVersion == false) {
         $fromObjectVersion = isset($this->CurrentVersion) ? $this->CurrentVersion : false;
     }
     $fromObjectVersion = (int) $fromObjectVersion;
     if (!$objectID) {
         $objectID = $this->ID;
     }
     $objectID = (int) $objectID;
     $limit = isset($params['Limit']) && is_numeric($params['Limit']) ? $params['Limit'] : false;
     $offset = isset($params['Offset']) && is_numeric($params['Offset']) ? $params['Offset'] : false;
     $asObject = isset($params['AsObject']) ? $params['AsObject'] : true;
     $loadDataMap = isset($params['LoadDataMap']) ? $params['LoadDataMap'] : false;
     $db = eZDB::instance();
     $sortingString = '';
     $sortingInfo = array('attributeFromSQL' => '', 'attributeWhereSQL' => '');
     $showInvisibleNodesCond = '';
     // process params (only SortBy and IgnoreVisibility currently supported):
     // Supported sort_by modes:
     //   class_identifier, class_name, modified, name, published, section
     if (is_array($params)) {
         if (isset($params['SortBy'])) {
             if (!in_array($params['SortBy'], array('class_identifier', 'class_name', 'modified', 'name', 'published', 'section'))) {
                 eZDebug::writeWarning("Unsupported sort_by parameter {$params['SortBy']}; check the online documentation for the list of supported sort types", __METHOD__);
             } else {
                 $sortingInfo = eZContentObjectTreeNode::createSortingSQLStrings($params['SortBy']);
                 $sortingString = ' ORDER BY ' . $sortingInfo['sortingFields'];
             }
         }
         if (isset($params['IgnoreVisibility'])) {
             $showInvisibleNodesCond = self::createFilterByVisibilitySQLString($params['IgnoreVisibility']);
         }
     }
     $relationTypeMasking = '';
     $relationTypeMask = isset($params['AllRelations']) ? $params['AllRelations'] : $attributeID === false;
     if ($attributeID && ($relationTypeMask === false || $relationTypeMask === eZContentObject::RELATION_ATTRIBUTE)) {
         $attributeID = (int) $attributeID;
         $relationTypeMasking .= " AND contentclassattribute_id={$attributeID} ";
         $relationTypeMask = eZContentObject::RELATION_ATTRIBUTE;
     } elseif (is_bool($relationTypeMask)) {
         $relationTypeMask = eZContentObject::relationTypeMask($relationTypeMask);
     }
     if ($db->databaseName() == 'oracle') {
         $relationTypeMasking .= " AND bitand( relation_type, {$relationTypeMask} ) <> 0 ";
     } else {
         $relationTypeMasking .= " AND ( relation_type & {$relationTypeMask} ) <> 0 ";
     }
     // Create SQL
     $versionNameTables = ', ezcontentobject_name ';
     $versionNameTargets = ', ezcontentobject_name.name as name,  ezcontentobject_name.real_translation ';
     $versionNameJoins = " AND ezcontentobject.id = ezcontentobject_name.contentobject_id AND\n                                 ezcontentobject.current_version = ezcontentobject_name.content_version AND ";
     $versionNameJoins .= eZContentLanguage::sqlFilter('ezcontentobject_name', 'ezcontentobject');
     $fromOrToContentObjectID = $reverseRelatedObjects == false ? " AND ezcontentobject.id=ezcontentobject_link.to_contentobject_id AND\n                                                                      ezcontentobject_link.from_contentobject_id='{$objectID}' AND\n                                                                      ezcontentobject_link.from_contentobject_version='{$fromObjectVersion}' " : " AND ezcontentobject.id=ezcontentobject_link.from_contentobject_id AND\n                                                                      ezcontentobject_link.to_contentobject_id={$objectID} AND\n                                                                      ezcontentobject_link.from_contentobject_version=ezcontentobject.current_version ";
     $query = "SELECT ";
     if ($groupByAttribute) {
         $query .= "ezcontentobject_link.contentclassattribute_id, ";
     }
     $query .= "\n                        ezcontentclass.serialized_name_list AS class_serialized_name_list,\n                        ezcontentclass.identifier as contentclass_identifier,\n                        ezcontentclass.is_container as is_container,\n                        ezcontentobject.* {$versionNameTargets}\n                     FROM\n                        ezcontentclass,\n                        ezcontentobject,\n                        ezcontentobject_link\n                        {$versionNameTables}\n                        {$sortingInfo['attributeFromSQL']}\n                     WHERE\n                        ezcontentclass.id=ezcontentobject.contentclass_id AND\n                        ezcontentclass.version=0 AND\n                        ezcontentobject.status=" . eZContentObject::STATUS_PUBLISHED . " AND\n                        {$sortingInfo['attributeWhereSQL']}\n                        ezcontentobject_link.op_code='0'\n                        {$relationTypeMasking}\n                        {$fromOrToContentObjectID}\n                        {$showInvisibleNodesCond}\n                        {$versionNameJoins}\n                        {$sortingString}";
     if (!$offset && !$limit) {
         $relatedObjects = $db->arrayQuery($query);
     } else {
         $relatedObjects = $db->arrayQuery($query, array('offset' => $offset, 'limit' => $limit));
     }
     $ret = array();
     $tmp = array();
     foreach ($relatedObjects as $object) {
         if ($asObject) {
             $obj = new eZContentObject($object);
             $obj->ClassName = eZContentClass::nameFromSerializedString($object['class_serialized_name_list']);
         } else {
             $obj = $object;
         }
         $tmp[] = $obj;
         if (!$groupByAttribute) {
             $ret[] = $obj;
         } else {
             $classAttrID = $object['contentclassattribute_id'];
             if (!isset($ret[$classAttrID])) {
                 $ret[$classAttrID] = array();
             }
             $ret[$classAttrID][] = $obj;
         }
     }
     if ($loadDataMap && $asObject) {
         eZContentObject::fillNodeListAttributes($tmp);
     }
     return $ret;
 }
    static function subTreeMultiPaths( $nodesParams, $listParams = NULL )
    {
        if( !is_array( $nodesParams ) || !count( $nodesParams ) )
        {
            eZDebug::writeWarning( __METHOD__.': Nodes parameter must be an array with at least one key.' );
            return null;
        }

        if( $listParams === null )
        {
            $listParams = array(
                             'SortBy'                   => false,
                             'Offset'                   => false,
                             'Limit'                    => false,
                             'SortBy'                   => false,
                             'GroupBy'                  => false );
        }

        $offset           = ( isset( $listParams['Offset'] ) && is_numeric( $listParams['Offset'] ) ) ? $listParams['Offset']             : false;
        $limit            = ( isset( $listParams['Limit']  ) && is_numeric( $listParams['Limit']  ) ) ? $listParams['Limit']              : false;
        $groupBy          = ( isset( $listParams['GroupBy']                                       ) ) ? $listParams['GroupBy']            : false;
        if ( !isset( $listParams['SortBy'] ) )
        {
            $listParams['SortBy'] = false;
        }
        $sortBy = $listParams['SortBy'];

        $queryNodes = '';

        foreach( $nodesParams as $nodeParams )
        {
            $nodeID = $nodeParams['ParentNodeID'];

            if ( !is_numeric( $nodeID ) && !is_array( $nodeID ) )
            {
                eZDebug::writeWarning( __METHOD__.': Nodes parameter must be numeric or an array with numeric values.' );
                $retValue = null;
                return $retValue;
            }

            if ( $nodeParams === null )
            {
                $nodeParams = array(
                                 'Depth'                    => false,
                                 //'OnlyTranslated'           => false,
                                 'Language'                 => false,
                                 'AttributeFilter'          => false,
                                 'ExtendedAttributeFilter'  => false,
                                 'ClassFilterType'          => false,
                                 'ClassFilterArray'         => false );
            }

            //$onlyTranslated   = ( isset( $nodeParams['OnlyTranslated']    ) )                       ? $nodeParams['OnlyTranslated']     : false;
            $language         = ( isset( $nodeParams['Language']          ) )                             ? $nodeParams['Language']           : false;
            $depth            = ( isset( $nodeParams['Depth']  ) && is_numeric( $nodeParams['Depth']  ) ) ? $nodeParams['Depth']              : false;
            $depthOperator    = ( isset( $nodeParams['DepthOperator']     ) )                         ? $nodeParams['DepthOperator']      : false;
            $asObject         = ( isset( $nodeParams['AsObject']          ) )                         ? $nodeParams['AsObject']           : true;
            $mainNodeOnly     = ( isset( $nodeParams['MainNodeOnly']      ) )                         ? $nodeParams['MainNodeOnly']       : false;
            $ignoreVisibility = ( isset( $nodeParams['IgnoreVisibility']  ) )                         ? $nodeParams['IgnoreVisibility']   : false;
            if ( !isset( $nodeParams['ClassFilterType'] ) )
            {
                $nodeParams['ClassFilterType'] = false;
            }

            if ( $language )
            {
                if ( !is_array( $language ) )
                {
                    $language = array( $language );
                }
                eZContentLanguage::setPrioritizedLanguages( $language );
            }

            $sortingInfo             = eZContentObjectTreeNode::createSortingSQLStrings( $sortBy );
            $classCondition          = eZContentObjectTreeNode::createClassFilteringSQLString( $nodeParams['ClassFilterType'], $nodeParams['ClassFilterArray'] );
            $attributeFilter         = eZContentObjectTreeNode::createAttributeFilterSQLStrings( $nodeParams['AttributeFilter'], $sortingInfo );
            $extendedAttributeFilter = eZContentObjectTreeNode::createExtendedAttributeFilterSQLStrings( $nodeParams['ExtendedAttributeFilter'] );
            $mainNodeOnlyCond        = eZContentObjectTreeNode::createMainNodeConditionSQLString( $mainNodeOnly );

            $pathStringCond     = '';
            $notEqParentString  = '';
            // If the node(s) doesn't exist we return null.

            if ( !eZContentObjectTreeNode::createPathConditionAndNotEqParentSQLStrings( $pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator ) )
            {
                $retValue = null;
                return $retValue;
            }

            $useVersionName     = true;
            $versionNameTables  = eZContentObjectTreeNode::createVersionNameTablesSQLString ( $useVersionName );
            $versionNameTargets = eZContentObjectTreeNode::createVersionNameTargetsSQLString( $useVersionName );
            $versionNameJoins   = eZContentObjectTreeNode::createVersionNameJoinsSQLString  ( $useVersionName, false );

            $languageFilter = ' AND ' . eZContentLanguage::languagesSQLFilter( 'ezcontentobject' );

            if ( $language )
            {
                eZContentLanguage::clearPrioritizedLanguages();
            }

            $limitation = ( isset( $nodeParams['Limitation']  ) && is_array( $nodeParams['Limitation']  ) ) ? $nodeParams['Limitation']: false;
            $limitationList = eZContentObjectTreeNode::getLimitationList( $limitation );
            $sqlPermissionChecking = eZContentObjectTreeNode::createPermissionCheckingSQL( $limitationList );

            // Determine whether we should show invisible nodes.
            $showInvisibleNodesCond = eZContentObjectTreeNode::createShowInvisibleSQLString( !$ignoreVisibility );

            $queryNodes .= " (
                          $pathStringCond
                          $extendedAttributeFilter[joins]
                          $sortingInfo[attributeWhereSQL]
                          $attributeFilter[where]
                          ezcontentclass.version=0 AND
                          $notEqParentString
                          ezcontentobject_tree.contentobject_id = ezcontentobject.id  AND
                          ezcontentclass.id = ezcontentobject.contentclass_id AND
                          $mainNodeOnlyCond
                          $classCondition
                          $versionNameJoins
                          $showInvisibleNodesCond
                          $sqlPermissionChecking[where]
                          $languageFilter
                      )
                      OR";
        }

        $groupBySelectText  = '';
        $groupBySQL         = $extendedAttributeFilter['group_by'];
        if ( !$groupBySQL )
        {
            eZContentObjectTreeNode::createGroupBySQLStrings( $groupBySelectText, $groupBySQL, $groupBy );
        }
        else if ( $groupBy )
        {
            eZDebug::writeError( "Cannot use group_by parameter together with extended attribute filter which sets group_by!", __METHOD__ );
        }

        $query = "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
                       $groupBySelectText
                       $versionNameTargets
                       $sortingInfo[attributeTargetSQL]
                       , ".$nodeParams['ResultID']." AS resultid
                   FROM
                      ezcontentobject_tree,
                      ezcontentobject,ezcontentclass
                      $versionNameTables
                      $sortingInfo[attributeFromSQL]
                      $attributeFilter[from]
                      $extendedAttributeFilter[tables]
                      $sqlPermissionChecking[from]
                   WHERE
                      ".substr($queryNodes, 0, -2)."
                $groupBySQL";

        if ( $sortingInfo['sortingFields'] )
        {
            $query .= " ORDER BY $sortingInfo[sortingFields]";
        }

        $db = eZDB::instance();

        $server = count( $sqlPermissionChecking['temp_tables'] ) > 0 ? eZDBInterface::SERVER_SLAVE : false;

        if ( !$offset && !$limit )
        {
            $nodeListArray = $db->arrayQuery( $query, array(), $server );
        }
        else
        {
            $nodeListArray = $db->arrayQuery( $query, array( 'offset' => $offset,
                                                              'limit'  => $limit ),
                                                      $server );
        }

        if ( $asObject )
        {
            $retNodeList = eZContentObjectTreeNode::makeObjectsArray( $nodeListArray );
        }
        else
        {
            $retNodeList = $nodeListArray;
        }

        // cleanup temp tables
        $db->dropTempTableList( $sqlPermissionChecking['temp_tables'] );

        return $retNodeList;
    }