Example #1
0
 /**
  * _performSearch
  *
  * Performs the search from the global search field.
  *
  * @param  $query   string what we are searching for
  * @param  $modules array  modules we are searching in
  * @param  $offset  int   search result offset
  * @param  $limit  int    search limit
  * @return array
  */
 protected function _performSearch($query, $modules, $offset = -1, $limit = 20)
 {
     if (empty($query)) {
         return array();
     }
     $primary_module = '';
     $results = array();
     require_once 'include/SearchForm/SearchForm2.php';
     $where = '';
     $searchEmail = preg_match('/^([^%]|%)*@([^%]|%)*$/', $query);
     // bug49650 - strip out asterisks from query in case
     // user thinks asterisk is a wildcard value
     $query = str_replace('*', '', $query);
     $limit = !empty($GLOBALS['sugar_config']['max_spotresults_initial']) ? $GLOBALS['sugar_config']['max_spotresults_initial'] : 5;
     if ($offset !== -1) {
         $limit = !empty($GLOBALS['sugar_config']['max_spotresults_more']) ? $GLOBALS['sugar_config']['max_spotresults_more'] : 20;
     }
     $totalCounted = empty($GLOBALS['sugar_config']['disable_count_query']);
     foreach ($modules as $moduleName) {
         if (empty($primary_module)) {
             $primary_module = $moduleName;
         }
         $searchFields = SugarSpot::getSearchFields($moduleName);
         if (empty($searchFields[$moduleName])) {
             continue;
         }
         $class = $GLOBALS['beanList'][$moduleName];
         $return_fields = array();
         $seed = new $class();
         if (!$seed->ACLAccess('ListView')) {
             continue;
         }
         if ($class == 'aCase') {
             $class = 'Case';
         }
         foreach ($searchFields[$moduleName] as $k => $v) {
             $keep = false;
             $searchFields[$moduleName][$k]['value'] = $query;
             if (!empty($searchFields[$moduleName][$k]['force_unifiedsearch'])) {
                 continue;
             }
             if (!empty($GLOBALS['dictionary'][$class]['unified_search'])) {
                 if (empty($GLOBALS['dictionary'][$class]['fields'][$k]['unified_search'])) {
                     if (isset($searchFields[$moduleName][$k]['db_field'])) {
                         foreach ($searchFields[$moduleName][$k]['db_field'] as $field) {
                             if (!empty($GLOBALS['dictionary'][$class]['fields'][$field]['unified_search'])) {
                                 if (isset($GLOBALS['dictionary'][$class]['fields'][$field]['type'])) {
                                     if (!$this->filterSearchType($GLOBALS['dictionary'][$class]['fields'][$field]['type'], $query)) {
                                         unset($searchFields[$moduleName][$k]);
                                         continue;
                                     }
                                 }
                                 $keep = true;
                             }
                         }
                         //foreach
                     }
                     # Bug 42961 Spot search for custom fields
                     if (!$keep && (isset($v['force_unifiedsearch']) == false || $v['force_unifiedsearch'] != true)) {
                         if (strpos($k, 'email') === false || !$searchEmail) {
                             unset($searchFields[$moduleName][$k]);
                         }
                     }
                 } else {
                     if ($GLOBALS['dictionary'][$class]['fields'][$k]['type'] == 'int' && !is_numeric($query)) {
                         unset($searchFields[$moduleName][$k]);
                     }
                 }
             } else {
                 if (empty($GLOBALS['dictionary'][$class]['fields'][$k])) {
                     //If module did not have unified_search defined, then check the exception for an email search before we unset
                     if (strpos($k, 'email') === false || !$searchEmail) {
                         unset($searchFields[$moduleName][$k]);
                     }
                 } else {
                     if (!$this->filterSearchType($GLOBALS['dictionary'][$class]['fields'][$k]['type'], $query)) {
                         unset($searchFields[$moduleName][$k]);
                     }
                 }
             }
         }
         //foreach
         //If no search field criteria matched then continue to next module
         if (empty($searchFields[$moduleName])) {
             continue;
         }
         if (empty($searchFields[$moduleName])) {
             continue;
         }
         if (isset($seed->field_defs['name'])) {
             $return_fields['name'] = $seed->field_defs['name'];
         }
         foreach ($seed->field_defs as $k => $v) {
             if (isset($seed->field_defs[$k]['type']) && $seed->field_defs[$k]['type'] == 'name' && !isset($return_fields[$k])) {
                 $return_fields[$k] = $seed->field_defs[$k];
             }
         }
         if (!isset($return_fields['name'])) {
             // if we couldn't find any name fields, try search fields that have name in it
             foreach ($searchFields[$moduleName] as $k => $v) {
                 if (strpos($k, 'name') != -1 && isset($seed->field_defs[$k]) && !isset($seed->field_defs[$k]['source'])) {
                     $return_fields[$k] = $seed->field_defs[$k];
                     break;
                 }
             }
         }
         if (!isset($return_fields['name'])) {
             // last resort - any fields that have 'name' in their name
             foreach ($seed->field_defs as $k => $v) {
                 if (strpos($k, 'name') != -1 && isset($seed->field_defs[$k]) && !isset($seed->field_defs[$k]['source'])) {
                     $return_fields[$k] = $seed->field_defs[$k];
                     break;
                 }
             }
         }
         if (!isset($return_fields['name'])) {
             // FAIL: couldn't find id & name for the module
             $GLOBALS['log']->error("Unable to find name for module {$moduleName}");
             continue;
         }
         if (isset($return_fields['name']['fields'])) {
             // some names are composite
             foreach ($return_fields['name']['fields'] as $field) {
                 $return_fields[$field] = $seed->field_defs[$field];
             }
         }
         $searchForm = new SearchForm($seed, $moduleName);
         $searchForm->setup(array($moduleName => array()), $searchFields, '', 'saved_views');
         $where_clauses = $searchForm->generateSearchWhere();
         if (empty($where_clauses)) {
             continue;
         }
         if (count($where_clauses) > 1) {
             $query_parts = array();
             $ret_array_start = $seed->create_new_list_query('', '', $return_fields, array(), 0, '', true, $seed, true);
             $search_keys = array_keys($searchFields[$moduleName]);
             foreach ($where_clauses as $n => $clause) {
                 $allfields = $return_fields;
                 $skey = $search_keys[$n];
                 if (isset($seed->field_defs[$skey])) {
                     // Joins for foreign fields aren't produced unless the field is in result, hence the merge
                     $allfields[$skey] = $seed->field_defs[$skey];
                 }
                 $ret_array = $seed->create_new_list_query('', $clause, $allfields, array(), 0, '', true, $seed, true);
                 $query_parts[] = $ret_array_start['select'] . $ret_array['from'] . $ret_array['where'] . $ret_array['order_by'];
             }
             $main_query = "(" . join(") UNION (", $query_parts) . ")";
         } else {
             foreach ($searchFields[$moduleName] as $k => $v) {
                 if (isset($seed->field_defs[$k])) {
                     $return_fields[$k] = $seed->field_defs[$k];
                 }
             }
             $ret_array = $seed->create_new_list_query('', $where_clauses[0], $return_fields, array(), 0, '', true, $seed, true);
             $main_query = $ret_array['select'] . $ret_array['from'] . $ret_array['where'] . $ret_array['order_by'];
         }
         $totalCount = null;
         if ($limit < -1) {
             $result = $seed->db->query($main_query);
         } else {
             if ($limit == -1) {
                 $limit = $GLOBALS['sugar_config']['list_max_entries_per_page'];
             }
             if ($offset == 'end') {
                 $totalCount = $this->_getCount($seed, $main_query);
                 if ($totalCount) {
                     $offset = floor(($totalCount - 1) / $limit) * $limit;
                 } else {
                     $offset = 0;
                 }
             }
             $result = $seed->db->limitQuery($main_query, $offset, $limit + 1);
         }
         $data = array();
         $count = 0;
         while ($count < $limit && ($row = $seed->db->fetchByAssoc($result))) {
             $temp = clone $seed;
             $temp->setupCustomFields($temp->module_dir);
             $temp->loadFromRow($row);
             $data[] = $temp->get_list_view_data($return_fields);
             $count++;
         }
         $nextOffset = -1;
         $prevOffset = -1;
         $endOffset = -1;
         if ($count >= $limit) {
             $nextOffset = $offset + $limit;
         }
         if ($offset > 0) {
             $prevOffset = $offset - $limit;
             if ($prevOffset < 0) {
                 $prevOffset = 0;
             }
         }
         if ($count >= $limit && $totalCounted) {
             if (!isset($totalCount)) {
                 $totalCount = $this->_getCount($seed, $main_query);
             }
         } else {
             $totalCount = $count + $offset;
         }
         $pageData['offsets'] = array('current' => $offset, 'next' => $nextOffset, 'prev' => $prevOffset, 'end' => $endOffset, 'total' => $totalCount, 'totalCounted' => $totalCounted);
         $pageData['bean'] = array('objectName' => $seed->object_name, 'moduleDir' => $seed->module_dir);
         $results[$moduleName] = array("data" => $data, "pageData" => $pageData);
     }
     return $results;
 }
Example #2
0
 function getTestSearchFields($moduleName)
 {
     return parent::getSearchFields($moduleName);
 }
Example #3
0
 /**
  * Performs the search
  *
  * @param  $query   string what we are searching for
  * @param  $modules array  modules we are searching in
  * @param  $offset  int    search result offset
  * @return array
  */
 protected function _performSearch($query, $modules, $offset = -1)
 {
     $primary_module = '';
     $results = array();
     require_once 'include/SearchForm/SearchForm2.php';
     $where = '';
     $searchEmail = preg_match("/^([^\\%]|\\%)*@([^\\%]|\\%)*\$/", $query);
     foreach ($modules as $moduleName) {
         if (empty($primary_module)) {
             $primary_module = $moduleName;
         }
         $searchFields = SugarSpot::getSearchFields($moduleName);
         $class = $GLOBALS['beanList'][$moduleName];
         $return_fields = array();
         $seed = new $class();
         if (empty($searchFields[$moduleName])) {
             continue;
         }
         if ($class == 'aCase') {
             $class = 'Case';
         }
         foreach ($searchFields[$moduleName] as $k => $v) {
             $keep = false;
             $searchFields[$moduleName][$k]['value'] = $query;
             if (!empty($GLOBALS['dictionary'][$class]['unified_search'])) {
                 if (empty($GLOBALS['dictionary'][$class]['fields'][$k]['unified_search'])) {
                     if (isset($searchFields[$moduleName][$k]['db_field'])) {
                         foreach ($searchFields[$moduleName][$k]['db_field'] as $field) {
                             if (!empty($GLOBALS['dictionary'][$class]['fields'][$field]['unified_search'])) {
                                 $return_fields[] = $field;
                                 $keep = true;
                             }
                         }
                     }
                     if (!$keep) {
                         if (strpos($k, 'email') === false || !$searchEmail) {
                             unset($searchFields[$moduleName][$k]);
                         }
                     }
                 } else {
                     $return_fields[] = $k;
                 }
             } else {
                 if (empty($GLOBALS['dictionary'][$class]['fields'][$k])) {
                     unset($searchFields[$moduleName][$k]);
                 } else {
                     switch ($GLOBALS['dictionary'][$class]['fields'][$k]['type']) {
                         case 'id':
                         case 'date':
                         case 'datetime':
                         case 'bool':
                             unset($searchFields[$moduleName][$k]);
                         default:
                             $return_fields[] = $k;
                     }
                 }
             }
         }
         $searchForm = new SearchForm($seed, $moduleName);
         $searchForm->setup(array($moduleName => array()), $searchFields, '', 'saved_views');
         $where_clauses = $searchForm->generateSearchWhere();
         $where = "";
         if (count($where_clauses) > 0) {
             $where = '((' . implode(' ) OR ( ', $where_clauses) . '))';
         }
         $lvd = new ListViewData();
         $lvd->additionalDetails = false;
         $max = !empty($sugar_config['max_spotresults_initial']) ? $sugar_config['max_spotresults_initial'] : 5;
         if ($offset !== -1) {
             $max = !empty($sugar_config['max_spotresults_more']) ? $sugar_config['max_spotresults_more'] : 20;
         }
         $params = array();
         if ($moduleName == 'Reports') {
             $params['overrideOrder'] = true;
             $params['orderBy'] = 'name';
         }
         $results[$moduleName] = $lvd->getListViewData($seed, $where, $offset, $max, $return_fields, $params, 'id');
     }
     return $results;
 }
Example #4
0
 public function filterSearchType($type, $query)
 {
     return parent::filterSearchType($type, $query);
 }
 public function search($query, $offset = 0, $limit = 20, $options = array())
 {
     $sugarSpot = new SugarSpot();
     return $sugarSpot->search($query, $offset, $limit, $options);
 }
Example #6
0
 /**
  * _performSearch
  *
  * Performs the search from the global search field.
  *
  * @param  $query   string what we are searching for
  * @param  $modules array  modules we are searching in
  * @param  $offset  int   search result offset
  * @param  $limit  int    search limit
  * @param  $options array  An array of options to better control how the result set is generated
  * @return array
  */
 protected function _performSearch($query, $modules, $offset = -1, $limit = 20, $options = array())
 {
     if (empty($query)) {
         if (!(isset($options['my_items']) && $options['my_items'] == true || isset($options['favorites']) && $options['favorites'] == 2 || isset($options['allowEmptySearch']) && $options['allowEmptySearch'] == true)) {
             // Make sure we aren't just searching for my items or favorites
             return array();
         }
     }
     $primary_module = '';
     $results = array();
     require_once 'include/SearchForm/SearchForm2.php';
     $where = '';
     $searchEmail = preg_match('/^([^%]|%)*@([^%]|%)*$/', $query);
     // bug49650 - strip out asterisks from query in case
     // user thinks asterisk is a wildcard value
     $query = str_replace('*', '', $query);
     $limit = !empty($GLOBALS['sugar_config']['max_spotresults_initial']) ? $GLOBALS['sugar_config']['max_spotresults_initial'] : 5;
     if ($offset !== -1) {
         $limit = !empty($GLOBALS['sugar_config']['max_spotresults_more']) ? $GLOBALS['sugar_config']['max_spotresults_more'] : 20;
     }
     $totalCounted = empty($GLOBALS['sugar_config']['disable_count_query']);
     if (empty($options['orderBy'])) {
         $orderBy = "date_modified DESC";
     } else {
         $orderBy = $options['orderBy'];
     }
     foreach ($modules as $moduleName) {
         if (empty($primary_module)) {
             $primary_module = $moduleName;
         }
         $searchFields = SugarSpot::getSearchFields($moduleName);
         if (empty($searchFields[$moduleName])) {
             continue;
         }
         $seed = BeanFactory::getBean($moduleName);
         if (!$seed->ACLAccess('ListView')) {
             continue;
         }
         foreach ($searchFields[$moduleName] as $k => $v) {
             /*
              * Restrict Bool searches from free-form text searches.
              * Reasoning: cases.status is unified_search = true
              * searching for New will all open_only cases due to open_only being set as well
              * see: modules/Cases/metadata/Searchform.php
              * This would cause incorrect search results due to the open only returning more than only status like New%
              */
             if (isset($v['type']) && !empty($v['type']) && $v['type'] == 'bool') {
                 unset($searchFields[$moduleName][$k]);
                 continue;
             }
             $keep = false;
             $searchFields[$moduleName][$k]['value'] = $query;
             if (!empty($searchFields[$moduleName][$k]['force_unifiedsearch'])) {
                 continue;
             }
             if (!empty($GLOBALS['dictionary'][$seed->object_name]['unified_search'])) {
                 if (empty($GLOBALS['dictionary'][$seed->object_name]['fields'][$k]['unified_search'])) {
                     if (isset($searchFields[$moduleName][$k]['db_field'])) {
                         foreach ($searchFields[$moduleName][$k]['db_field'] as $field) {
                             if (!empty($GLOBALS['dictionary'][$seed->object_name]['fields'][$field]['unified_search'])) {
                                 if (isset($GLOBALS['dictionary'][$seed->object_name]['fields'][$field]['type'])) {
                                     if (!$this->filterSearchType($GLOBALS['dictionary'][$seed->object_name]['fields'][$field]['type'], $query)) {
                                         unset($searchFields[$moduleName][$k]);
                                         continue;
                                     }
                                 }
                                 $keep = true;
                             }
                         }
                         //foreach
                     }
                     # Bug 42961 Spot search for custom fields
                     if (!$keep && (isset($v['force_unifiedsearch']) == false || $v['force_unifiedsearch'] != true)) {
                         if (strpos($k, 'email') === false || !$searchEmail) {
                             unset($searchFields[$moduleName][$k]);
                         }
                     }
                 } else {
                     if ($GLOBALS['dictionary'][$seed->object_name]['fields'][$k]['type'] == 'int' && !is_numeric($query)) {
                         unset($searchFields[$moduleName][$k]);
                     }
                 }
             } else {
                 if (empty($GLOBALS['dictionary'][$seed->object_name]['fields'][$k])) {
                     //If module did not have unified_search defined, then check the exception for an email search before we unset
                     if (strpos($k, 'email') === false || !$searchEmail) {
                         unset($searchFields[$moduleName][$k]);
                     }
                 } else {
                     if (!$this->filterSearchType($GLOBALS['dictionary'][$seed->object_name]['fields'][$k]['type'], $query)) {
                         unset($searchFields[$moduleName][$k]);
                     }
                 }
             }
         }
         //foreach
         // setup the custom query options
         // reset these each time so we don't append my_items calls for tables not in the query
         // this would happen in global search
         $custom_select = $this->getOption($options, 'custom_select', $moduleName);
         $custom_from = $this->getOption($options, 'custom_from', $moduleName);
         $custom_where = $this->getOption($options, 'custom_where', $moduleName);
         if (isset($options['custom_where_module'][$moduleName])) {
             if (!empty($custom_where)) {
                 $custom_where .= " AND {$options['custom_where_module'][$moduleName]}";
             } else {
                 $custom_where = $options['custom_where_module'][$moduleName];
             }
         }
         $allowBlankSearch = false;
         // Add an extra search filter for my items
         // Verify the bean has assigned_user_id before we blindly assume it does
         if (!empty($options['my_items']) && $options['my_items'] == true && isset($seed->field_defs['assigned_user_id'])) {
             if (!empty($custom_where)) {
                 $custom_where .= " AND ";
             }
             $custom_where .= "{$seed->table_name}.assigned_user_id = '{$GLOBALS['current_user']->id}'";
             $allowBlankSearch = true;
         }
         if (!empty($options['untouched']) && $options['untouched'] !== false && isset($GLOBALS['dictionary'][$class]['fields']['last_activity_date'])) {
             if (!empty($custom_where)) {
                 $custom_where .= " AND ";
             }
             $days = (int) $options['untouched'];
             $lastActivityDate = gmdate('Y-m-d', time() - $days * 24 * 60 * 60);
             $custom_where .= "{$seed->table_name}.last_activity_date <= '{$lastActivityDate}'";
             if (isset($GLOBALS['dictionary'][$class]['fields']['sales_stage'])) {
                 $custom_where .= " AND {$seed->table_name}.sales_stage != 'Closed Won' AND {$seed->table_name}.sales_stage != 'Closed Lost'";
             }
             if (isset($GLOBALS['dictionary'][$class]['fields']['date_closed'])) {
                 $next30days = gmdate('Y-m-d', time() + 30 * 24 * 60 * 60);
                 $custom_where .= "AND {$seed->table_name}.date_closed <= '{$next30days}'";
             }
             $allowBlankSearch = true;
         }
         // If we are just searching by favorites, add a no-op query parameter so we still search
         if (!empty($options['favorites']) && $options['favorites'] == 2) {
             $allowBlankSearch = true;
         }
         if (!empty($options['allowEmptySearch']) && $options['allowEmptySearch'] == true) {
             $allowBlankSearch = true;
         }
         //If no search field criteria matched then continue to next module
         if (empty($searchFields[$moduleName]) && !$allowBlankSearch) {
             continue;
         }
         if (isset($seed->field_defs['name'])) {
             $return_fields['name'] = $seed->field_defs['name'];
         }
         foreach ($seed->field_defs as $k => $v) {
             if (isset($seed->field_defs[$k]['type']) && $seed->field_defs[$k]['type'] == 'name' && !isset($return_fields[$k])) {
                 $return_fields[$k] = $seed->field_defs[$k];
             }
         }
         if (!isset($return_fields['name'])) {
             // if we couldn't find any name fields, try search fields that have name in it
             foreach ($searchFields[$moduleName] as $k => $v) {
                 if (strpos($k, 'name') != -1 && isset($seed->field_defs[$k]) && !isset($seed->field_defs[$k]['source'])) {
                     $return_fields[$k] = $seed->field_defs[$k];
                     break;
                 }
             }
         }
         if (!isset($return_fields['name'])) {
             // last resort - any fields that have 'name' in their name
             foreach ($seed->field_defs as $k => $v) {
                 if (strpos($k, 'name') != -1 && isset($seed->field_defs[$k]) && !isset($seed->field_defs[$k]['source'])) {
                     $return_fields[$k] = $seed->field_defs[$k];
                     break;
                 }
             }
         }
         if (!isset($return_fields['name'])) {
             // FAIL: couldn't find id & name for the module
             $GLOBALS['log']->error("Unable to find name for module {$moduleName}");
             continue;
         }
         if (isset($return_fields['name']['fields'])) {
             // some names are composite name fields (e.g. last_name, first_name), add these to return list
             foreach ($return_fields['name']['fields'] as $field) {
                 $return_fields[$field] = $seed->field_defs[$field];
             }
         }
         if (!empty($options['fields'])) {
             $extraFields = array();
             if (!empty($options['fields'][$moduleName])) {
                 $extraFields = $options['fields'][$moduleName];
             } else {
                 if (!empty($options['fields']['_default'])) {
                     $extraFields = $options['fields']['_default'];
                 }
             }
             if (empty($extraFields)) {
                 // We set the 'fields' parameter, but left it blank, we should fetch all fields
                 $return_fields = '';
             } else {
                 foreach ($extraFields as $extraField) {
                     if ($extraField == 'id') {
                         // Already in the list of fields it will return
                         continue;
                     }
                     if (isset($seed->field_defs[$extraField]) && !isset($return_fields[$extraField])) {
                         $return_fields[$extraField] = $seed->field_defs[$extraField];
                     }
                 }
             }
         }
         SugarAutoLoader::requireWithCustom('include/SearchForm/SearchForm2.php');
         $searchFormClass = SugarAutoLoader::customClass('SearchForm');
         $searchForm = new $searchFormClass($seed, $moduleName);
         $searchForm->setup(array($moduleName => array()), $searchFields, '', 'saved_views');
         $where_clauses = $searchForm->generateSearchWhere();
         $orderBy = '';
         if (isset($options['orderBy'])) {
             $orderBy = $options['orderBy'];
         }
         $selectFields = '';
         if (!empty($options['selectFields'])) {
             foreach ($options['selectFields'] as $selectField) {
                 $selectFields .= $seed->table_name . "." . $selectField . " " . $selectField . ", ";
             }
             $selectFields = rtrim($selectFields, ', ');
         }
         $showDeleted = isset($options['deleted']) ? $options['deleted'] : 0;
         if (empty($where_clauses)) {
             if ($allowBlankSearch) {
                 $ret_array = $seed->create_new_list_query($orderBy, '', $return_fields, $options, $showDeleted, '', true, $seed, true);
                 if (!empty($selectFields)) {
                     $ret_array['select'] = "SELECT DISTINCT " . $selectFields;
                 }
                 if (!empty($custom_select)) {
                     $ret_array['select'] .= $custom_select;
                 }
                 if (!empty($custom_from)) {
                     $ret_array['from'] .= $custom_from;
                 }
                 if (!empty($custom_where)) {
                     if (!empty($ret_array['where'])) {
                         $ret_array['where'] .= " AND ";
                     }
                     // If there are no where clauses but there is a custom
                     // where but there is no return array where clause add
                     // an AND, otherwise you will get a situation where there
                     // is a where condition without an adjoining clause. This
                     // happens in Unified Search where there is team security
                     // added to the query.
                     // - rgonzalez
                     if (stripos($ret_array['where'], 'where') === false) {
                         $ret_array['where'] .= ' AND ';
                     }
                     $ret_array['where'] .= $custom_where;
                 }
                 $main_query = $ret_array['select'] . $ret_array['from'] . $ret_array['where'] . $ret_array['order_by'];
             } else {
                 continue;
             }
         } else {
             if (count($where_clauses) > 1) {
                 $query_parts = array();
                 $ret_array_start = $seed->create_new_list_query($orderBy, '', $return_fields, $options, $showDeleted, '', true, $seed, true);
                 $search_keys = array_keys($searchFields[$moduleName]);
                 foreach ($where_clauses as $n => $clause) {
                     $allfields = $return_fields;
                     if (!empty($return_fields)) {
                         // We don't have any specific return_fields, so leaving this blank will include everything in the query
                         $skey = $search_keys[$n];
                         if (isset($seed->field_defs[$skey])) {
                             // Joins for foreign fields aren't produced unless the field is in result, hence the merge
                             $allfields[$skey] = $seed->field_defs[$skey];
                         }
                     }
                     // Individual UNION's don't allow order by
                     $ret_array = $seed->create_new_list_query('', $clause, $allfields, $options, $showDeleted, '', true, $seed, true);
                     if (!empty($selectFields)) {
                         $ret_array_start['select'] = "SELECT DISTINCT " . $selectFields;
                     }
                     if (!empty($custom_select)) {
                         $ret_array_start['select'] .= $custom_select;
                     }
                     if (!empty($custom_from)) {
                         $ret_array['from'] .= $custom_from;
                     }
                     if (!empty($custom_where)) {
                         if (!empty($ret_array['where'])) {
                             $ret_array['where'] .= " AND ";
                         }
                         $ret_array['where'] .= $custom_where;
                     }
                     $query_parts[] = $ret_array_start['select'] . $ret_array['from'] . $ret_array['where'];
                 }
                 // So we add it to the output of all of the unions
                 $main_query = "(" . join(")\n UNION (", $query_parts) . ")";
                 if (!empty($orderBy)) {
                     $main_query .= " ORDER BY " . $orderBy;
                 }
             } else {
                 foreach ($searchFields[$moduleName] as $k => $v) {
                     if (isset($seed->field_defs[$k])) {
                         $return_fields[$k] = $seed->field_defs[$k];
                     }
                 }
                 $ret_array = $seed->create_new_list_query($orderBy, $where_clauses[0], $return_fields, $options, $showDeleted, '', true, $seed, true);
                 if (!empty($selectFields)) {
                     $ret_array['select'] = "SELECT DISTINCT " . $selectFields;
                 }
                 if (!empty($custom_select)) {
                     $ret_array['select'] .= $custom_select;
                 }
                 if (!empty($custom_from)) {
                     $ret_array['from'] .= $custom_from;
                 }
                 if (!empty($custom_where)) {
                     if (!empty($ret_array['where'])) {
                         $ret_array['where'] .= " AND ";
                     }
                     $ret_array['where'] .= $custom_where;
                 }
                 $main_query = $ret_array['select'] . $ret_array['from'] . $ret_array['where'] . $ret_array['order_by'];
             }
         }
         $totalCount = null;
         if ($limit < -1) {
             $result = $seed->db->query($main_query);
         } else {
             if ($limit == -1) {
                 $limit = $GLOBALS['sugar_config']['list_max_entries_per_page'];
             }
             if ($offset === 'end') {
                 $totalCount = $this->_getCount($seed, $main_query);
                 if ($totalCount) {
                     $offset = floor(($totalCount - 1) / $limit) * $limit;
                 } else {
                     $offset = 0;
                 }
             }
             if (isset($options['limitPerModule'])) {
                 $limit = $options['limitPerModule'] - 1;
             }
             $result = $seed->db->limitQuery($main_query, $offset, $limit + 1);
         }
         $data = array();
         $count = 0;
         while ($count < $limit && ($row = $seed->db->fetchByAssoc($result))) {
             $temp = $seed->getCleanCopy();
             $temp->setupCustomFields($temp->module_dir);
             $temp->loadFromRow($row);
             // need to reload the seed because not all the fields will be filled in, for instance in bugs, all fields are wanted but the query does
             // not contain description, so the loadFromRow will not load it
             $temp->retrieve($temp->id, true, false);
             // this may be a deleted record
             if (isset($options['return_beans']) && $options['return_beans']) {
                 $data[] = $temp;
             } else {
                 $data[] = $temp->get_list_view_data($return_fields);
             }
             if (isset($options['limitPerModule'])) {
                 // Don't keep track of the counted records if we are already applying per-module limits
                 $count = 0;
             } else {
                 $count++;
             }
         }
         $nextOffset = -1;
         $prevOffset = -1;
         $endOffset = -1;
         if (!isset($options['limitPerModule']) || !$options['limitPerModule']) {
             // Don't worry about the offsets if we are running a per-module limit
             if ($count >= $limit) {
                 $nextOffset = $offset + $limit;
             }
             if ($offset > 0) {
                 $prevOffset = $offset - $limit;
                 if ($prevOffset < 0) {
                     $prevOffset = 0;
                 }
             }
             if ($count >= $limit && $totalCounted) {
                 if (!isset($totalCount)) {
                     $totalCount = $this->_getCount($seed, $main_query);
                 }
             } else {
                 $totalCount = $count + $offset;
             }
         }
         $pageData['offsets'] = array('current' => $offset, 'next' => $nextOffset, 'prev' => $prevOffset, 'end' => $endOffset, 'total' => $totalCount, 'totalCounted' => $totalCounted);
         $pageData['bean'] = array('objectName' => $seed->object_name, 'moduleDir' => $seed->module_dir);
         $results[$moduleName] = array("data" => $data, "pageData" => $pageData);
     }
     return $results;
 }