]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/ListView/ListViewData.php
Release 6.5.11
[Github/sugarcrm.git] / include / ListView / ListViewData.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 require_once('include/EditView/SugarVCR.php');
40 /**
41  * Data set for ListView
42  * @api
43  */
44 class ListViewData {
45
46         var $additionalDetails = true;
47     var $listviewName = null;
48         var $additionalDetailsAllow = null;
49     var $additionalDetailsAjax = true; // leave this true when using filter fields
50     var $additionalDetailsFieldToAdd = 'NAME'; // where the span will be attached to
51     var $base_url = null;
52     /*
53      * If you want overwrite the query for the count of the listview set this to your query
54      * otherwise leave it empty and it will use SugarBean::create_list_count_query
55      */
56     var $count_query = '';
57
58         /**
59          * Constructor sets the limitName to look up the limit in $sugar_config
60          *
61          * @return ListViewData
62          */
63         function ListViewData() {
64                 $this->limitName = 'list_max_entries_per_page';
65                 $this->db = &DBManagerFactory::getInstance('listviews');
66         }
67
68         /**
69          * checks the request for the order by and if that is not set then it checks the session for it
70          *
71          * @return array containing the keys orderBy => field being ordered off of and sortOrder => the sort order of that field
72          */
73         function getOrderBy($orderBy = '', $direction = '') {
74                 if (!empty($orderBy) || !empty($_REQUEST[$this->var_order_by])) {
75             if(!empty($_REQUEST[$this->var_order_by])) {
76                         $direction = 'ASC';
77                         $orderBy = $_REQUEST[$this->var_order_by];
78                         if(!empty($_REQUEST['lvso']) && (empty($_SESSION['lvd']['last_ob']) || strcmp($orderBy, $_SESSION['lvd']['last_ob']) == 0) ){
79                                 $direction = $_REQUEST['lvso'];
80                         }
81             }
82             $_SESSION[$this->var_order_by] = array('orderBy'=>$orderBy, 'direction'=> $direction);
83             $_SESSION['lvd']['last_ob'] = $orderBy;
84         }
85                 else {
86             $userPreferenceOrder = $GLOBALS['current_user']->getPreference('listviewOrder', $this->var_name);
87                         if(!empty($_SESSION[$this->var_order_by])) {
88                                 $orderBy = $_SESSION[$this->var_order_by]['orderBy'];
89                                 $direction = $_SESSION[$this->var_order_by]['direction'];
90             } elseif (!empty($userPreferenceOrder)) {
91                 $orderBy = $userPreferenceOrder['orderBy'];
92                 $direction = $userPreferenceOrder['sortOrder'];
93             } else {
94                                 $orderBy = 'date_entered';
95                                 $direction = 'DESC';
96                         }
97                 }
98                 if(!empty($direction)) {
99                 if(strtolower($direction) == "desc") {
100                     $direction = 'DESC';
101                 } else {
102                     $direction = 'ASC';
103                 }
104                 }
105                 return array('orderBy' => $orderBy, 'sortOrder' => $direction);
106         }
107
108         /**
109          * gets the reverse of the sort order for use on links to reverse a sort order from what is currently used
110          *
111          * @param STRING (ASC or DESC) $current_order
112          * @return  STRING (ASC or DESC)
113          */
114         function getReverseSortOrder($current_order){
115                 return (strcmp(strtolower($current_order), 'asc') == 0)?'DESC':'ASC';
116         }
117         /**
118          * gets the limit of how many rows to show per page
119          *
120          * @return INT (the limit)
121          */
122         function getLimit() {
123                 return $GLOBALS['sugar_config'][$this->limitName];
124         }
125
126         /**
127          * returns the current offset
128          *
129          * @return INT (current offset)
130          */
131         function getOffset() {
132                 return (!empty($_REQUEST[$this->var_offset])) ? $_REQUEST[$this->var_offset] : 0;
133         }
134
135     /**
136      * generates the base url without
137      * any files in the block variables will not be part of the url
138      *
139      * @return Array (the base url as an array)
140      */
141     protected function getBaseQuery()
142     {
143         global $beanList;
144
145         $blockVariables = array('mass', 'uid', 'massupdate', 'delete', 'merge', 'selectCount',$this->var_order_by, $this->var_offset, 'lvso', 'sortOrder', 'orderBy', 'request_data', 'current_query_by_page');
146         foreach($beanList as $bean)
147         {
148             $blockVariables[] = 'Home2_'.strtoupper($bean).'_ORDER_BY';
149         }
150         $blockVariables[] = 'Home2_CASE_ORDER_BY';
151
152         // Added mostly for the unit test runners, which may not have these superglobals defined
153         $params = array_merge($_POST, $_GET);
154         $params = array_diff_key($params, array_flip($blockVariables));
155
156         return $params;
157     }
158
159         /**
160          * based off of a base name it sets base, offset, and order by variable names to retrieve them from requests and sessions
161          *
162          * @param unknown_type $baseName
163          */
164         function setVariableName($baseName, $where, $listviewName = null){
165         global $timedate;
166         $module = (!empty($listviewName)) ? $listviewName: $_REQUEST['module'];
167         $this->var_name = $module .'2_'. strtoupper($baseName);
168
169                 $this->var_order_by = $this->var_name .'_ORDER_BY';
170                 $this->var_offset = $this->var_name . '_offset';
171         $timestamp = sugar_microtime();
172         $this->stamp = $timestamp;
173
174         $_SESSION[$module .'2_QUERY_QUERY'] = $where;
175
176         $_SESSION[strtoupper($baseName) . "_FROM_LIST_VIEW"] = $timestamp;
177         $_SESSION[strtoupper($baseName) . "_DETAIL_NAV_HISTORY"] = false;
178         }
179
180         function getTotalCount($main_query){
181                 if(!empty($this->count_query)){
182                     $count_query = $this->count_query;
183                 }else{
184                 $count_query = SugarBean::create_list_count_query($main_query);
185             }
186                 $result = $this->db->query($count_query);
187                 if($row = $this->db->fetchByAssoc($result)){
188                         return $row['c'];
189                 }
190                 return 0;
191         }
192
193         /**
194          * takes in a seed and creates the list view query based off of that seed
195          * if the $limit value is set to -1 then it will use the default limit and offset values
196          *
197          * it will return an array with two key values
198          *      1. 'data'=> this is an array of row data
199          *  2. 'pageData'=> this is an array containg three values
200          *                      a.'ordering'=> array('orderBy'=> the field being ordered by , 'sortOrder'=> 'ASC' or 'DESC')
201          *                      b.'urls'=>array('baseURL'=>url used to generate other urls ,
202          *                                                      'orderBy'=> the base url for order by
203          *                                                      //the following may not be set (so check empty to see if they are set)
204          *                                                      'nextPage'=> the url for the next group of results,
205          *                                                      'prevPage'=> the url for the prev group of results,
206          *                                                      'startPage'=> the url for the start of the group,
207          *                                                      'endPage'=> the url for the last set of results in the group
208          *                      c.'offsets'=>array(
209          *                                                              'current'=>current offset
210          *                                                              'next'=> next group offset
211          *                                                              'prev'=> prev group offset
212          *                                                              'end'=> the offset of the last group
213          *                                                              'total'=> the total count (only accurate if totalCounted = true otherwise it is either the total count if less than the limit or the total count + 1 )
214          *                                                              'totalCounted'=> if a count query was used to get the total count
215          *
216          * @param SugarBean $seed
217          * @param string $where
218          * @param int:0 $offset
219          * @param int:-1 $limit
220          * @param string[]:array() $filter_fields
221          * @param array:array() $params
222          *      Potential $params are
223                 $params['distinct'] = use distinct key word
224                 $params['include_custom_fields'] = (on by default)
225         $params['custom_XXXX'] = append custom statements to query
226          * @param string:'id' $id_field
227          * @return array('data'=> row data, 'pageData' => page data information, 'query' => original query string)
228          */
229         function getListViewData($seed, $where, $offset=-1, $limit = -1, $filter_fields=array(),$params=array(),$id_field = 'id',$singleSelect=true) {
230         global $current_user;
231         SugarVCR::erase($seed->module_dir);
232         $this->seed =& $seed;
233         $totalCounted = empty($GLOBALS['sugar_config']['disable_count_query']);
234         $_SESSION['MAILMERGE_MODULE_FROM_LISTVIEW'] = $seed->module_dir;
235         if(empty($_REQUEST['action']) || $_REQUEST['action'] != 'Popup'){
236             $_SESSION['MAILMERGE_MODULE'] = $seed->module_dir;
237         }
238
239         $this->setVariableName($seed->object_name, $where, $this->listviewName);
240
241                 $this->seed->id = '[SELECT_ID_LIST]';
242
243         // if $params tell us to override all ordering
244         if(!empty($params['overrideOrder']) && !empty($params['orderBy'])) {
245             $order = $this->getOrderBy(strtolower($params['orderBy']), (empty($params['sortOrder']) ? '' : $params['sortOrder'])); // retreive from $_REQUEST
246         }
247         else {
248             $order = $this->getOrderBy(); // retreive from $_REQUEST
249         }
250
251         // still empty? try to use settings passed in $param
252         if(empty($order['orderBy']) && !empty($params['orderBy'])) {
253             $order['orderBy'] = $params['orderBy'];
254             $order['sortOrder'] =  (empty($params['sortOrder']) ? '' : $params['sortOrder']);
255         }
256
257         //rrs - bug: 21788. Do not use Order by stmts with fields that are not in the query.
258         // Bug 22740 - Tweak this check to strip off the table name off the order by parameter.
259         // Samir Gandhi : Do not remove the report_cache.date_modified condition as the report list view is broken
260         $orderby = $order['orderBy'];
261         if (strpos($order['orderBy'],'.') && ($order['orderBy'] != "report_cache.date_modified")) {
262             $orderby = substr($order['orderBy'],strpos($order['orderBy'],'.')+1);
263         }
264         if ($orderby != 'date_entered' && !in_array($orderby, array_keys($filter_fields))) {
265                 $order['orderBy'] = '';
266                 $order['sortOrder'] = '';
267         }
268
269                 if (empty($order['orderBy'])) {
270             $orderBy = '';
271         } else {
272             $orderBy = $order['orderBy'] . ' ' . $order['sortOrder'];
273             //wdong, Bug 25476, fix the sorting problem of Oracle.
274             if (isset($params['custom_order_by_override']['ori_code']) && $order['orderBy'] == $params['custom_order_by_override']['ori_code'])
275                 $orderBy = $params['custom_order_by_override']['custom_code'] . ' ' . $order['sortOrder'];
276         }
277
278         if (empty($params['skipOrderSave'])) { // don't save preferences if told so
279             $current_user->setPreference('listviewOrder', $order, 0, $this->var_name); // save preference
280         }
281
282                 // If $params tells us to override for the special last_name, first_name sorting
283                 if (!empty($params['overrideLastNameOrder']) && $order['orderBy'] == 'last_name') {
284                         $orderBy = 'last_name '.$order['sortOrder'].', first_name '.$order['sortOrder'];
285                 }
286
287                 $ret_array = $seed->create_new_list_query($orderBy, $where, $filter_fields, $params, 0, '', true, $seed, $singleSelect);
288         $ret_array['inner_join'] = '';
289         if (!empty($this->seed->listview_inner_join)) {
290             $ret_array['inner_join'] = ' ' . implode(' ', $this->seed->listview_inner_join) . ' ';
291         }
292
293                 if(!is_array($params)) $params = array();
294         if(!isset($params['custom_select'])) $params['custom_select'] = '';
295         if(!isset($params['custom_from'])) $params['custom_from'] = '';
296         if(!isset($params['custom_where'])) $params['custom_where'] = '';
297         if(!isset($params['custom_order_by'])) $params['custom_order_by'] = '';
298                 $main_query = $ret_array['select'] . $params['custom_select'] . $ret_array['from'] . $params['custom_from'] . $ret_array['inner_join']. $ret_array['where'] . $params['custom_where'] . $ret_array['order_by'] . $params['custom_order_by'];
299                 //C.L. - Fix for 23461
300                 if(empty($_REQUEST['action']) || $_REQUEST['action'] != 'Popup') {
301                    $_SESSION['export_where'] = $ret_array['where'];
302                 }
303                 if($limit < -1) {
304                         $result = $this->db->query($main_query);
305                 }
306                 else {
307                         if($limit == -1) {
308                                 $limit = $this->getLimit();
309             }
310                         $dyn_offset = $this->getOffset();
311                         if($dyn_offset > 0 || !is_int($dyn_offset))$offset = $dyn_offset;
312
313             if(strcmp($offset, 'end') == 0){
314                 $totalCount = $this->getTotalCount($main_query);
315                 $offset = (floor(($totalCount -1) / $limit)) * $limit;
316             }
317             if($this->seed->ACLAccess('ListView')) {
318                 $result = $this->db->limitQuery($main_query, $offset, $limit + 1);
319             }
320             else {
321                 $result = array();
322             }
323
324                 }
325
326                 $data = array();
327
328                 $temp = clone $seed;
329
330                 $rows = array();
331                 $count = 0;
332         $idIndex = array();
333         $id_list = '';
334
335                 while(($row = $this->db->fetchByAssoc($result)) != null)
336         {
337                         if($count < $limit)
338             {
339                                 $id_list .= ',\''.$row[$id_field].'\'';
340                                 $idIndex[$row[$id_field]][] = count($rows);
341                                 $rows[] = $seed->convertRow($row);
342                         }
343                         $count++;
344                 }
345
346         if (!empty($id_list))
347         {
348             $id_list = '('.substr($id_list, 1).')';
349         }
350
351         SugarVCR::store($this->seed->module_dir,  $main_query);
352                 if($count != 0) {
353                         //NOW HANDLE SECONDARY QUERIES
354                         if(!empty($ret_array['secondary_select'])) {
355                                 $secondary_query = $ret_array['secondary_select'] . $ret_array['secondary_from'] . ' WHERE '.$this->seed->table_name.'.id IN ' .$id_list;
356                 if(isset($ret_array['order_by']))
357                 {
358                     $secondary_query .= ' ' . $ret_array['order_by'];
359                 }
360
361                 $secondary_result = $this->db->query($secondary_query);
362
363                 $ref_id_count = array();
364                                 while($row = $this->db->fetchByAssoc($secondary_result)) {
365
366                     $ref_id_count[$row['ref_id']][] = true;
367                                         foreach($row as $name=>$value) {
368                                                 //add it to every row with the given id
369                                                 foreach($idIndex[$row['ref_id']] as $index){
370                                                     $rows[$index][$name]=$value;
371                                                 }
372                                         }
373                                 }
374
375                 $rows_keys = array_keys($rows);
376                 foreach($rows_keys as $key)
377                 {
378                     $rows[$key]['secondary_select_count'] = count($ref_id_count[$rows[$key]['ref_id']]);
379                 }
380                         }
381
382             // retrieve parent names
383             if(!empty($filter_fields['parent_name']) && !empty($filter_fields['parent_id']) && !empty($filter_fields['parent_type'])) {
384                 foreach($idIndex as $id => $rowIndex) {
385                     if(!isset($post_retrieve[$rows[$rowIndex[0]]['parent_type']])) {
386                         $post_retrieve[$rows[$rowIndex[0]]['parent_type']] = array();
387                     }
388                     if(!empty($rows[$rowIndex[0]]['parent_id'])) $post_retrieve[$rows[$rowIndex[0]]['parent_type']][] = array('child_id' => $id , 'parent_id'=> $rows[$rowIndex[0]]['parent_id'], 'parent_type' => $rows[$rowIndex[0]]['parent_type'], 'type' => 'parent');
389                 }
390                 if(isset($post_retrieve)) {
391                     $parent_fields = $seed->retrieve_parent_fields($post_retrieve);
392                     foreach($parent_fields as $child_id => $parent_data) {
393                         //add it to every row with the given id
394                                                 foreach($idIndex[$child_id] as $index){
395                                                     $rows[$index]['parent_name']= $parent_data['parent_name'];
396                                                 }
397                     }
398                 }
399             }
400
401                         $pageData = array();
402
403                         reset($rows);
404                         while($row = current($rows)){
405
406                 $temp = clone $seed;
407                             $dataIndex = count($data);
408
409                             $temp->setupCustomFields($temp->module_dir);
410                                 $temp->loadFromRow($row);
411                                 if (empty($this->seed->assigned_user_id) && !empty($temp->assigned_user_id)) {
412                                     $this->seed->assigned_user_id = $temp->assigned_user_id;
413                                 }
414                                 if($idIndex[$row[$id_field]][0] == $dataIndex){
415                                     $pageData['tag'][$dataIndex] = $temp->listviewACLHelper();
416                                 }else{
417                                     $pageData['tag'][$dataIndex] = $pageData['tag'][$idIndex[$row[$id_field]][0]];
418                                 }
419                                 $data[$dataIndex] = $temp->get_list_view_data($filter_fields);
420                 $detailViewAccess = $temp->ACLAccess('DetailView');
421                 $editViewAccess = $temp->ACLAccess('EditView');
422                 $pageData['rowAccess'][$dataIndex] = array('view' => $detailViewAccess, 'edit' => $editViewAccess);
423                 $additionalDetailsAllow = $this->additionalDetails && $detailViewAccess && (file_exists(
424                          'modules/' . $temp->module_dir . '/metadata/additionalDetails.php'
425                      ) || file_exists('custom/modules/' . $temp->module_dir . '/metadata/additionalDetails.php'));
426                 $additionalDetailsEdit = $editViewAccess;
427                 if($additionalDetailsAllow) {
428                     if($this->additionalDetailsAjax) {
429                                            $ar = $this->getAdditionalDetailsAjax($data[$dataIndex]['ID']);
430                     }
431                     else {
432                         $additionalDetailsFile = 'modules/' . $this->seed->module_dir . '/metadata/additionalDetails.php';
433                         if(file_exists('custom/modules/' . $this->seed->module_dir . '/metadata/additionalDetails.php')){
434                                 $additionalDetailsFile = 'custom/modules/' . $this->seed->module_dir . '/metadata/additionalDetails.php';
435                         }
436                         require_once($additionalDetailsFile);
437                         $ar = $this->getAdditionalDetails($data[$dataIndex],
438                                     (empty($this->additionalDetailsFunction) ? 'additionalDetails' : $this->additionalDetailsFunction) . $this->seed->object_name,
439                                     $additionalDetailsEdit);
440                     }
441                     $pageData['additionalDetails'][$dataIndex] = $ar['string'];
442                     $pageData['additionalDetails']['fieldToAddTo'] = $ar['fieldToAddTo'];
443                                 }
444                                 next($rows);
445                         }
446                 }
447                 $nextOffset = -1;
448                 $prevOffset = -1;
449                 $endOffset = -1;
450                 if($count > $limit) {
451                         $nextOffset = $offset + $limit;
452                 }
453
454                 if($offset > 0) {
455                         $prevOffset = $offset - $limit;
456                         if($prevOffset < 0)$prevOffset = 0;
457                 }
458                 $totalCount = $count + $offset;
459
460                 if( $count >= $limit && $totalCounted){
461                         $totalCount  = $this->getTotalCount($main_query);
462                 }
463                 SugarVCR::recordIDs($this->seed->module_dir, array_keys($idIndex), $offset, $totalCount);
464         $module_names = array(
465             'Prospects' => 'Targets'
466         );
467                 $endOffset = (floor(($totalCount - 1) / $limit)) * $limit;
468                 $pageData['ordering'] = $order;
469                 $pageData['ordering']['sortOrder'] = $this->getReverseSortOrder($pageData['ordering']['sortOrder']);
470         //get url parameters as an array
471         $pageData['queries'] = $this->generateQueries($pageData['ordering']['sortOrder'], $offset, $prevOffset, $nextOffset,  $endOffset, $totalCounted);
472         //join url parameters from array to a string
473         $pageData['urls'] = $this->generateURLS($pageData['queries']);
474                 $pageData['offsets'] = array( 'current'=>$offset, 'next'=>$nextOffset, 'prev'=>$prevOffset, 'end'=>$endOffset, 'total'=>$totalCount, 'totalCounted'=>$totalCounted);
475                 $pageData['bean'] = array('objectName' => $seed->object_name, 'moduleDir' => $seed->module_dir, 'moduleName' => strtr($seed->module_dir, $module_names));
476         $pageData['stamp'] = $this->stamp;
477         $pageData['access'] = array('view' => $this->seed->ACLAccess('DetailView'), 'edit' => $this->seed->ACLAccess('EditView'));
478                 $pageData['idIndex'] = $idIndex;
479         if(!$this->seed->ACLAccess('ListView')) {
480             $pageData['error'] = 'ACL restricted access';
481         }
482
483         $queryString = '';
484
485         if( isset($_REQUEST["searchFormTab"]) && $_REQUEST["searchFormTab"] == "advanced_search" ||
486                 isset($_REQUEST["type_basic"]) && (count($_REQUEST["type_basic"] > 1) || $_REQUEST["type_basic"][0] != "") ||
487                 isset($_REQUEST["module"]) && $_REQUEST["module"] == "MergeRecords")
488         {
489             $queryString = "-advanced_search";
490         }
491         else if (isset($_REQUEST["searchFormTab"]) && $_REQUEST["searchFormTab"] == "basic_search")
492         {
493             if($seed->module_dir == "Reports") $searchMetaData = SearchFormReports::retrieveReportsSearchDefs();
494             else $searchMetaData = SearchForm::retrieveSearchDefs($seed->module_dir);
495
496             $basicSearchFields = array();
497
498             if( isset($searchMetaData['searchdefs']) && isset($searchMetaData['searchdefs'][$seed->module_dir]['layout']['basic_search']) )
499                 $basicSearchFields = $searchMetaData['searchdefs'][$seed->module_dir]['layout']['basic_search'];
500
501             foreach( $basicSearchFields as $basicSearchField)
502             {
503                 $field_name = (is_array($basicSearchField) && isset($basicSearchField['name'])) ? $basicSearchField['name'] : $basicSearchField;
504                 $field_name .= "_basic";
505                 if( isset($_REQUEST[$field_name])  && ( !is_array($basicSearchField) || !isset($basicSearchField['type']) || $basicSearchField['type'] == 'text' || $basicSearchField['type'] == 'name') )
506                 {
507                     $queryString = htmlentities($_REQUEST[$field_name]);
508                     break;
509                 }
510             }
511         }
512
513
514                 return array('data'=>$data , 'pageData'=>$pageData, 'query' => $queryString);
515         }
516
517
518     /**
519      * generates urls as a string for use by the display layer
520      *
521      * @param array $queries
522      * @return array of urls orderBy and baseURL are always returned the others are only returned  according to values passed in.
523      */
524     protected function generateURLS($queries)
525     {
526         foreach ($queries as $name => $value)
527         {
528             $queries[$name] = 'index.php?' . http_build_query($value);
529         }
530         $this->base_url = $queries['baseURL'];
531         return $queries;
532     }
533
534     /**
535      * generates queries for use by the display layer
536      *
537      * @param int $sortOrder
538      * @param int $offset
539      * @param int $prevOffset
540      * @param int $nextOffset
541      * @param int $endOffset
542      * @param int $totalCounted
543      * @return array of queries orderBy and baseURL are always returned the others are only returned  according to values passed in.
544      */
545     protected function generateQueries($sortOrder, $offset, $prevOffset, $nextOffset, $endOffset, $totalCounted)
546     {
547         $queries = array();
548         $queries['baseURL'] = $this->getBaseQuery();
549         $queries['baseURL']['lvso'] = $sortOrder;
550
551         $queries['orderBy'] = $queries['baseURL'];
552         $queries['orderBy'][$this->var_order_by] = '';
553
554         if($nextOffset > -1)
555         {
556             $queries['nextPage'] = $queries['baseURL'];
557             $queries['nextPage'][$this->var_offset] = $nextOffset;
558         }
559         if($offset > 0)
560         {
561             $queries['startPage'] = $queries['baseURL'];
562             $queries['startPage'][$this->var_offset] = 0;
563         }
564         if($prevOffset > -1)
565         {
566             $queries['prevPage'] = $queries['baseURL'];
567             $queries['prevPage'][$this->var_offset] = $prevOffset;
568         }
569         if($totalCounted)
570         {
571             $queries['endPage'] = $queries['baseURL'];
572             $queries['endPage'][$this->var_offset] = $endOffset;
573         }
574         else
575         {
576             $queries['endPage'] = $queries['baseURL'];
577             $queries['endPage'][$this->var_offset] = 'end';
578         }
579         return $queries;
580     }
581
582         /**
583          * generates the additional details span to be retrieved via ajax
584          *
585          * @param GUID id id of the record
586          * @return array string to attach to field
587          */
588         function getAdditionalDetailsAjax($id)
589     {
590         global $app_strings;
591
592         $jscalendarImage = SugarThemeRegistry::current()->getImageURL('info_inline.gif');
593
594         $extra = "<span id='adspan_" . $id . "' "
595                 . "onclick=\"lvg_dtails('$id')\" "
596                                 . " style='position: relative;'><!--not_in_theme!--><img vertical-align='middle' class='info' border='0' alt='".$app_strings['LBL_ADDITIONAL_DETAILS']."' src='$jscalendarImage'></span>";
597
598         return array('fieldToAddTo' => $this->additionalDetailsFieldToAdd, 'string' => $extra);
599         }
600
601     /**
602      * generates the additional details values
603      *
604      * @param unknown_type $fields
605      * @param unknown_type $adFunction
606      * @param unknown_type $editAccess
607      * @return array string to attach to field
608      */
609     function getAdditionalDetails($fields, $adFunction, $editAccess)
610     {
611         global $app_strings;
612         global $mod_strings;
613
614         $results = $adFunction($fields);
615
616         $results['string'] = str_replace(array("&#039", "'"), '\&#039', $results['string']); // no xss!
617
618         if(trim($results['string']) == '')
619         {
620             $results['string'] = $app_strings['LBL_NONE'];
621         }
622                 $close = false;
623             $extra = "<img alt='{$app_strings['LBL_INFOINLINE']}' style='padding: 0px 5px 0px 2px' border='0' onclick=\"SUGAR.util.getStaticAdditionalDetails(this,'";
624
625             $extra .= str_replace(array("\rn", "\r", "\n"), array('','','<br />'), $results['string']) ;
626             $extra .= "','<div style=\'float:left\'>{$app_strings['LBL_ADDITIONAL_DETAILS']}</div><div style=\'float: right\'>";
627
628                 if($editAccess && !empty($results['editLink']))
629                 {
630                     $extra .=  "<a title=\'{$app_strings['LBL_EDIT_BUTTON']}\' href={$results['editLink']}><img style=\'margin-left: 2px;\' border=\'0\' src=\'".SugarThemeRegistry::current()->getImageURL('edit_inline.png')."\'></a>";
631                     $close = true;
632                 }
633                 $close = (!empty($results['viewLink'])) ? true : $close;
634                 $extra .= (!empty($results['viewLink']) ? "<a title=\'{$app_strings['LBL_VIEW_BUTTON']}\' href={$results['viewLink']}><img style=\'margin-left: 2px;\' border=\'0\' src=".SugarThemeRegistry::current()->getImageURL('view_inline.png')."></a>" : '');
635
636             if($close == true) {
637                 $closeVal = "true";
638                 $extra .=  "<a title=\'{$app_strings['LBL_ADDITIONAL_DETAILS_CLOSE_TITLE']}\' href=\'javascript: SUGAR.util.closeStaticAdditionalDetails();\'><img style=\'margin-left: 2px;\' border=\'0\' src=\'".SugarThemeRegistry::current()->getImageURL('close.png')."\'></a>";
639             } else {
640                 $closeVal = "false";
641             }
642             $extra .= "',".$closeVal.")\" src='".SugarThemeRegistry::current()->getImageURL('info_inline.png')."' class='info'>";
643
644         return array('fieldToAddTo' => $results['fieldToAddTo'], 'string' => $extra);
645     }
646
647 }