static function calendar($params = false, $nodeID = 0)
 {
     if (!is_numeric($nodeID) and !is_array($nodeID)) {
         return array();
     }
     if ($params === false) {
         $params = array('Depth' => false, 'Offset' => false, 'Limit' => false, 'AttributeFilter' => false, 'ExtendedAttributeFilter' => false, 'ClassFilterType' => false, 'ClassFilterArray' => false, 'GroupBy' => false);
     }
     $offset = isset($params['Offset']) && is_numeric($params['Offset']) ? $params['Offset'] : false;
     $limit = isset($params['Limit']) && is_numeric($params['Limit']) ? $params['Limit'] : false;
     $depth = isset($params['Depth']) && is_numeric($params['Depth']) ? $params['Depth'] : false;
     $depthOperator = isset($params['DepthOperator']) ? $params['DepthOperator'] : false;
     $groupBy = isset($params['GroupBy']) ? $params['GroupBy'] : false;
     $mainNodeOnly = isset($params['MainNodeOnly']) ? $params['MainNodeOnly'] : false;
     $ignoreVisibility = isset($params['IgnoreVisibility']) ? $params['IgnoreVisibility'] : false;
     if (!isset($params['ClassFilterType'])) {
         $params['ClassFilterType'] = false;
     }
     $classCondition = eZContentObjectTreeNodeNoLanguage::createClassFilteringSQLString($params['ClassFilterType'], $params['ClassFilterArray']);
     $attributeFilter = eZContentObjectTreeNodeNoLanguage::createAttributeFilterSQLStrings($params['AttributeFilter'], $sortingInfo);
     $extendedAttributeFilter = eZContentObjectTreeNodeNoLanguage::createExtendedAttributeFilterSQLStrings($params['ExtendedAttributeFilter']);
     $mainNodeOnlyCond = eZContentObjectTreeNodeNoLanguage::createMainNodeConditionSQLString($mainNodeOnly);
     $pathStringCond = '';
     $notEqParentString = '';
     eZContentObjectTreeNodeNoLanguage::createPathConditionAndNotEqParentSQLStrings($pathStringCond, $notEqParentString, $nodeID, $depth, $depthOperator);
     $groupBySelectText = '';
     $groupBySQL = $extendedAttributeFilter['group_by'];
     if (!$groupBySQL) {
         eZContentObjectTreeNodeNoLanguage::createGroupBySQLStrings($groupBySelectText, $groupBySQL, $groupBy);
     } else {
         if ($groupBy) {
             eZDebug::writeError("Cannot use group_by parameter together with extended attribute filter which sets group_by!", __METHOD__);
         }
     }
     $limitation = isset($params['Limitation']) && is_array($params['Limitation']) ? $params['Limitation'] : false;
     $limitationList = eZContentObjectTreeNodeNoLanguage::getLimitationList($limitation);
     $sqlPermissionChecking = eZContentObjectTreeNodeNoLanguage::createPermissionCheckingSQL($limitationList);
     // Determine whether we should show invisible nodes.
     $showInvisibleNodesCond = eZContentObjectTreeNodeNoLanguage::createShowInvisibleSQLString(!$ignoreVisibility);
     $query = "SELECT DISTINCT\n                         ezcontentobject.published as published\n                         {$groupBySelectText}\n                   FROM\n                      ezcontentobject_tree\n                      INNER JOIN ezcontentobject ON (ezcontentobject.id = ezcontentobject_tree.contentobject_id)\n                      INNER JOIN ezcontentclass ON (ezcontentclass.id = ezcontentobject.contentclass_id)\n                      INNER JOIN ezcontentobject_name ON (\n                          ezcontentobject_name.contentobject_id = ezcontentobject_tree.contentobject_id AND\n                          ezcontentobject_name.content_version = ezcontentobject_tree.contentobject_version\n                      )\n\n                      {$attributeFilter['from']}\n                      {$extendedAttributeFilter['tables']}\n                      {$sqlPermissionChecking['from']}\n                   WHERE\n                      {$pathStringCond}\n                      {$extendedAttributeFilter['joins']}\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                {$groupBySQL}";
     $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);
     }
     // cleanup temp tables
     $db->dropTempTableList($sqlPermissionChecking['temp_tables']);
     return $nodeListArray;
 }