]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/ListView/ListViewData.php
Release 6.5.5
[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-2012 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                         if(!empty($_SESSION[$this->var_order_by])) {
87                                 $orderBy = $_SESSION[$this->var_order_by]['orderBy'];
88                                 $direction = $_SESSION[$this->var_order_by]['direction'];
89                         }
90                         else{
91                                 $orderBy = 'date_entered';
92                                 $direction = 'DESC';
93                         }
94                 }
95                 if(!empty($direction)) {
96                 if(strtolower($direction) == "desc") {
97                     $direction = 'DESC';
98                 } else {
99                     $direction = 'ASC';
100                 }
101                 }
102                 return array('orderBy' => $orderBy, 'sortOrder' => $direction);
103         }
104
105         /**
106          * gets the reverse of the sort order for use on links to reverse a sort order from what is currently used
107          *
108          * @param STRING (ASC or DESC) $current_order
109          * @return  STRING (ASC or DESC)
110          */
111         function getReverseSortOrder($current_order){
112                 return (strcmp(strtolower($current_order), 'asc') == 0)?'DESC':'ASC';
113         }
114         /**
115          * gets the limit of how many rows to show per page
116          *
117          * @return INT (the limit)
118          */
119         function getLimit() {
120                 return $GLOBALS['sugar_config'][$this->limitName];
121         }
122
123         /**
124          * returns the current offset
125          *
126          * @return INT (current offset)
127          */
128         function getOffset() {
129                 return (!empty($_REQUEST[$this->var_offset])) ? $_REQUEST[$this->var_offset] : 0;
130         }
131
132         /**
133          * generates the base url without
134          * any files in the block variables will not be part of the url
135          *
136          *
137          * @return STRING (the base url)
138          */
139         function getBaseURL() {
140         global $beanList;
141                 if(empty($this->base_url)) {
142             $blockVariables = array('mass', 'uid', 'massupdate', 'delete', 'merge', 'selectCount',$this->var_order_by, $this->var_offset, 'lvso', 'sortOrder', 'orderBy', 'request_data', 'current_query_by_page');
143             $base_url = 'index.php?';
144             foreach($beanList as $bean) {
145                 $blockVariables[] = 'Home2_'.strtoupper($bean).'_ORDER_BY';
146             }
147             $blockVariables[] = 'Home2_CASE_ORDER_BY';
148             // Added mostly for the unit test runners, which may not have these superglobals defined
149             $params = array();
150             if ( isset($_POST) && is_array($_POST) ) {
151                 $params = array_merge($params,$_POST);
152             }
153             if ( isset($_GET) && is_array($_GET) ) {
154                 $params = array_merge($params,$_GET);
155             }
156             foreach($params as $name=>$value) {
157                 if(!in_array($name, $blockVariables)){
158                                         if(is_array($value)) {
159                                                 foreach($value as $v) {
160                             $base_url .= $name.urlencode('[]').'='.urlencode($v) . '&';
161                         }
162                     }
163                     else {
164                                                 $base_url .= $name.'='.urlencode($value) . '&';
165                     }
166                 }
167             }
168             $this->base_url = $base_url;
169         }
170                 return $this->base_url;
171         }
172         /**
173          * based off of a base name it sets base, offset, and order by variable names to retrieve them from requests and sessions
174          *
175          * @param unknown_type $baseName
176          */
177         function setVariableName($baseName, $where, $listviewName = null){
178         global $timedate;
179         $module = (!empty($listviewName)) ? $listviewName: $_REQUEST['module'];
180         $this->var_name = $module .'2_'. strtoupper($baseName);
181
182                 $this->var_order_by = $this->var_name .'_ORDER_BY';
183                 $this->var_offset = $this->var_name . '_offset';
184         $timestamp = sugar_microtime();
185         $this->stamp = $timestamp;
186
187         $_SESSION[$module .'2_QUERY_QUERY'] = $where;
188
189         $_SESSION[strtoupper($baseName) . "_FROM_LIST_VIEW"] = $timestamp;
190         $_SESSION[strtoupper($baseName) . "_DETAIL_NAV_HISTORY"] = false;
191         }
192
193         function getTotalCount($main_query){
194                 if(!empty($this->count_query)){
195                     $count_query = $this->count_query;
196                 }else{
197                 $count_query = SugarBean::create_list_count_query($main_query);
198             }
199                 $result = $this->db->query($count_query);
200                 if($row = $this->db->fetchByAssoc($result)){
201                         return $row['c'];
202                 }
203                 return 0;
204         }
205
206         /**
207          * takes in a seed and creates the list view query based off of that seed
208          * if the $limit value is set to -1 then it will use the default limit and offset values
209          *
210          * it will return an array with two key values
211          *      1. 'data'=> this is an array of row data
212          *  2. 'pageData'=> this is an array containg three values
213          *                      a.'ordering'=> array('orderBy'=> the field being ordered by , 'sortOrder'=> 'ASC' or 'DESC')
214          *                      b.'urls'=>array('baseURL'=>url used to generate other urls ,
215          *                                                      'orderBy'=> the base url for order by
216          *                                                      //the following may not be set (so check empty to see if they are set)
217          *                                                      'nextPage'=> the url for the next group of results,
218          *                                                      'prevPage'=> the url for the prev group of results,
219          *                                                      'startPage'=> the url for the start of the group,
220          *                                                      'endPage'=> the url for the last set of results in the group
221          *                      c.'offsets'=>array(
222          *                                                              'current'=>current offset
223          *                                                              'next'=> next group offset
224          *                                                              'prev'=> prev group offset
225          *                                                              'end'=> the offset of the last group
226          *                                                              '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 )
227          *                                                              'totalCounted'=> if a count query was used to get the total count
228          *
229          * @param SugarBean $seed
230          * @param string $where
231          * @param int:0 $offset
232          * @param int:-1 $limit
233          * @param string[]:array() $filter_fields
234          * @param array:array() $params
235          *      Potential $params are
236                 $params['distinct'] = use distinct key word
237                 $params['include_custom_fields'] = (on by default)
238         $params['custom_XXXX'] = append custom statements to query
239          * @param string:'id' $id_field
240          * @return array('data'=> row data, 'pageData' => page data information, 'query' => original query string)
241          */
242         function getListViewData($seed, $where, $offset=-1, $limit = -1, $filter_fields=array(),$params=array(),$id_field = 'id',$singleSelect=true) {
243         global $current_user;
244         SugarVCR::erase($seed->module_dir);
245         $this->seed =& $seed;
246         $totalCounted = empty($GLOBALS['sugar_config']['disable_count_query']);
247         $_SESSION['MAILMERGE_MODULE_FROM_LISTVIEW'] = $seed->module_dir;
248         if(empty($_REQUEST['action']) || $_REQUEST['action'] != 'Popup'){
249             $_SESSION['MAILMERGE_MODULE'] = $seed->module_dir;
250         }
251
252         $this->setVariableName($seed->object_name, $where, $this->listviewName);
253
254                 $this->seed->id = '[SELECT_ID_LIST]';
255
256         // if $params tell us to override all ordering
257         if(!empty($params['overrideOrder']) && !empty($params['orderBy'])) {
258             $order = $this->getOrderBy(strtolower($params['orderBy']), (empty($params['sortOrder']) ? '' : $params['sortOrder'])); // retreive from $_REQUEST
259         }
260         else {
261             $order = $this->getOrderBy(); // retreive from $_REQUEST
262         }
263
264         // else use stored preference
265         $userPreferenceOrder = $current_user->getPreference('listviewOrder', $this->var_name);
266
267         if(empty($order['orderBy']) && !empty($userPreferenceOrder)) {
268             $order = $userPreferenceOrder;
269         }
270         // still empty? try to use settings passed in $param
271         if(empty($order['orderBy']) && !empty($params['orderBy'])) {
272             $order['orderBy'] = $params['orderBy'];
273             $order['sortOrder'] =  (empty($params['sortOrder']) ? '' : $params['sortOrder']);
274         }
275
276         //rrs - bug: 21788. Do not use Order by stmts with fields that are not in the query.
277         // Bug 22740 - Tweak this check to strip off the table name off the order by parameter.
278         // Samir Gandhi : Do not remove the report_cache.date_modified condition as the report list view is broken
279         $orderby = $order['orderBy'];
280         if (strpos($order['orderBy'],'.') && ($order['orderBy'] != "report_cache.date_modified")) {
281             $orderby = substr($order['orderBy'],strpos($order['orderBy'],'.')+1);
282         }
283         if ($orderby != 'date_entered' && !in_array($orderby, array_keys($filter_fields))) {
284                 $order['orderBy'] = '';
285                 $order['sortOrder'] = '';
286         }
287
288                 if (empty($order['orderBy'])) {
289             $orderBy = '';
290         } else {
291             $orderBy = $order['orderBy'] . ' ' . $order['sortOrder'];
292             //wdong, Bug 25476, fix the sorting problem of Oracle.
293             if (isset($params['custom_order_by_override']['ori_code']) && $order['orderBy'] == $params['custom_order_by_override']['ori_code'])
294                 $orderBy = $params['custom_order_by_override']['custom_code'] . ' ' . $order['sortOrder'];
295         }
296
297         if (empty($params['skipOrderSave'])) { // don't save preferences if told so
298             $current_user->setPreference('listviewOrder', $order, 0, $this->var_name); // save preference
299         }
300
301                 // If $params tells us to override for the special last_name, first_name sorting
302                 if (!empty($params['overrideLastNameOrder']) && $order['orderBy'] == 'last_name') {
303                         $orderBy = 'last_name '.$order['sortOrder'].', first_name '.$order['sortOrder'];
304                 }
305
306                 $ret_array = $seed->create_new_list_query($orderBy, $where, $filter_fields, $params, 0, '', true, $seed, $singleSelect);
307         $ret_array['inner_join'] = '';
308         if (!empty($this->seed->listview_inner_join)) {
309             $ret_array['inner_join'] = ' ' . implode(' ', $this->seed->listview_inner_join) . ' ';
310         }
311
312                 if(!is_array($params)) $params = array();
313         if(!isset($params['custom_select'])) $params['custom_select'] = '';
314         if(!isset($params['custom_from'])) $params['custom_from'] = '';
315         if(!isset($params['custom_where'])) $params['custom_where'] = '';
316         if(!isset($params['custom_order_by'])) $params['custom_order_by'] = '';
317                 $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'];
318                 //C.L. - Fix for 23461
319                 if(empty($_REQUEST['action']) || $_REQUEST['action'] != 'Popup') {
320                    $_SESSION['export_where'] = $ret_array['where'];
321                 }
322                 if($limit < -1) {
323                         $result = $this->db->query($main_query);
324                 }
325                 else {
326                         if($limit == -1) {
327                                 $limit = $this->getLimit();
328             }
329                         $dyn_offset = $this->getOffset();
330                         if($dyn_offset > 0 || !is_int($dyn_offset))$offset = $dyn_offset;
331
332             if(strcmp($offset, 'end') == 0){
333                 $totalCount = $this->getTotalCount($main_query);
334                 $offset = (floor(($totalCount -1) / $limit)) * $limit;
335             }
336             if($this->seed->ACLAccess('ListView')) {
337                 $result = $this->db->limitQuery($main_query, $offset, $limit + 1);
338             }
339             else {
340                 $result = array();
341             }
342
343                 }
344
345                 $data = array();
346
347                 $temp = clone $seed;
348
349                 $rows = array();
350                 $count = 0;
351         $idIndex = array();
352         $id_list = '';
353
354                 while(($row = $this->db->fetchByAssoc($result)) != null)
355         {
356                         if($count < $limit)
357             {
358                                 $id_list .= ',\''.$row[$id_field].'\'';
359                                 $idIndex[$row[$id_field]][] = count($rows);
360                                 $rows[] = $seed->convertRow($row);
361                         }
362                         $count++;
363                 }
364
365         if (!empty($id_list))
366         {
367             $id_list = '('.substr($id_list, 1).')';
368         }
369
370         SugarVCR::store($this->seed->module_dir,  $main_query);
371                 if($count != 0) {
372                         //NOW HANDLE SECONDARY QUERIES
373                         if(!empty($ret_array['secondary_select'])) {
374                                 $secondary_query = $ret_array['secondary_select'] . $ret_array['secondary_from'] . ' WHERE '.$this->seed->table_name.'.id IN ' .$id_list;
375                 if(isset($ret_array['order_by']))
376                 {
377                     $secondary_query .= ' ' . $ret_array['order_by'];
378                 }
379
380                 $secondary_result = $this->db->query($secondary_query);
381
382                 $ref_id_count = array();
383                                 while($row = $this->db->fetchByAssoc($secondary_result)) {
384
385                     $ref_id_count[$row['ref_id']][] = true;
386                                         foreach($row as $name=>$value) {
387                                                 //add it to every row with the given id
388                                                 foreach($idIndex[$row['ref_id']] as $index){
389                                                     $rows[$index][$name]=$value;
390                                                 }
391                                         }
392                                 }
393
394                 $rows_keys = array_keys($rows);
395                 foreach($rows_keys as $key)
396                 {
397                     $rows[$key]['secondary_select_count'] = count($ref_id_count[$rows[$key]['ref_id']]);
398                 }
399                         }
400
401             // retrieve parent names
402             if(!empty($filter_fields['parent_name']) && !empty($filter_fields['parent_id']) && !empty($filter_fields['parent_type'])) {
403                 foreach($idIndex as $id => $rowIndex) {
404                     if(!isset($post_retrieve[$rows[$rowIndex[0]]['parent_type']])) {
405                         $post_retrieve[$rows[$rowIndex[0]]['parent_type']] = array();
406                     }
407                     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');
408                 }
409                 if(isset($post_retrieve)) {
410                     $parent_fields = $seed->retrieve_parent_fields($post_retrieve);
411                     foreach($parent_fields as $child_id => $parent_data) {
412                         //add it to every row with the given id
413                                                 foreach($idIndex[$child_id] as $index){
414                                                     $rows[$index]['parent_name']= $parent_data['parent_name'];
415                                                 }
416                     }
417                 }
418             }
419
420                         $pageData = array();
421
422                         reset($rows);
423                         while($row = current($rows)){
424
425                 $temp = clone $seed;
426                             $dataIndex = count($data);
427
428                             $temp->setupCustomFields($temp->module_dir);
429                                 $temp->loadFromRow($row);
430                                 if (empty($this->seed->assigned_user_id) && !empty($temp->assigned_user_id)) {
431                                     $this->seed->assigned_user_id = $temp->assigned_user_id;
432                                 }
433                                 if($idIndex[$row[$id_field]][0] == $dataIndex){
434                                     $pageData['tag'][$dataIndex] = $temp->listviewACLHelper();
435                                 }else{
436                                     $pageData['tag'][$dataIndex] = $pageData['tag'][$idIndex[$row[$id_field]][0]];
437                                 }
438                                 $data[$dataIndex] = $temp->get_list_view_data($filter_fields);
439                             $pageData['rowAccess'][$dataIndex] = array('view' => $temp->ACLAccess('DetailView'), 'edit' => $temp->ACLAccess('EditView'));
440                             $additionalDetailsAllow = $this->additionalDetails && $temp->ACLAccess('DetailView') && (file_exists('modules/' . $temp->module_dir . '/metadata/additionalDetails.php') || file_exists('custom/modules/' . $temp->module_dir . '/metadata/additionalDetails.php'));
441                             //if($additionalDetailsAllow) $pageData['additionalDetails'] = array();
442                             $additionalDetailsEdit = $temp->ACLAccess('EditView');
443                                 if($additionalDetailsAllow) {
444                     if($this->additionalDetailsAjax) {
445                                            $ar = $this->getAdditionalDetailsAjax($data[$dataIndex]['ID']);
446                     }
447                     else {
448                         $additionalDetailsFile = 'modules/' . $this->seed->module_dir . '/metadata/additionalDetails.php';
449                         if(file_exists('custom/modules/' . $this->seed->module_dir . '/metadata/additionalDetails.php')){
450                                 $additionalDetailsFile = 'custom/modules/' . $this->seed->module_dir . '/metadata/additionalDetails.php';
451                         }
452                         require_once($additionalDetailsFile);
453                         $ar = $this->getAdditionalDetails($data[$dataIndex],
454                                     (empty($this->additionalDetailsFunction) ? 'additionalDetails' : $this->additionalDetailsFunction) . $this->seed->object_name,
455                                     $additionalDetailsEdit);
456                     }
457                     $pageData['additionalDetails'][$dataIndex] = $ar['string'];
458                     $pageData['additionalDetails']['fieldToAddTo'] = $ar['fieldToAddTo'];
459                                 }
460                                 next($rows);
461                         }
462                 }
463                 $nextOffset = -1;
464                 $prevOffset = -1;
465                 $endOffset = -1;
466                 if($count > $limit) {
467                         $nextOffset = $offset + $limit;
468                 }
469
470                 if($offset > 0) {
471                         $prevOffset = $offset - $limit;
472                         if($prevOffset < 0)$prevOffset = 0;
473                 }
474                 $totalCount = $count + $offset;
475
476                 if( $count >= $limit && $totalCounted){
477                         $totalCount  = $this->getTotalCount($main_query);
478                 }
479                 SugarVCR::recordIDs($this->seed->module_dir, array_keys($idIndex), $offset, $totalCount);
480         $module_names = array(
481             'Prospects' => 'Targets'
482         );
483                 $endOffset = (floor(($totalCount - 1) / $limit)) * $limit;
484                 $pageData['ordering'] = $order;
485                 $pageData['ordering']['sortOrder'] = $this->getReverseSortOrder($pageData['ordering']['sortOrder']);
486                 $pageData['urls'] = $this->generateURLS($pageData['ordering']['sortOrder'], $offset, $prevOffset, $nextOffset,  $endOffset, $totalCounted);
487                 $pageData['offsets'] = array( 'current'=>$offset, 'next'=>$nextOffset, 'prev'=>$prevOffset, 'end'=>$endOffset, 'total'=>$totalCount, 'totalCounted'=>$totalCounted);
488                 $pageData['bean'] = array('objectName' => $seed->object_name, 'moduleDir' => $seed->module_dir, 'moduleName' => strtr($seed->module_dir, $module_names));
489         $pageData['stamp'] = $this->stamp;
490         $pageData['access'] = array('view' => $this->seed->ACLAccess('DetailView'), 'edit' => $this->seed->ACLAccess('EditView'));
491                 $pageData['idIndex'] = $idIndex;
492         if(!$this->seed->ACLAccess('ListView')) {
493             $pageData['error'] = 'ACL restricted access';
494         }
495
496         $queryString = '';
497
498         if( isset($_REQUEST["searchFormTab"]) && $_REQUEST["searchFormTab"] == "advanced_search" ||
499                 isset($_REQUEST["type_basic"]) && (count($_REQUEST["type_basic"] > 1) || $_REQUEST["type_basic"][0] != "") ||
500                 isset($_REQUEST["module"]) && $_REQUEST["module"] == "MergeRecords")
501         {
502             $queryString = "-advanced_search";
503         }
504         else if (isset($_REQUEST["searchFormTab"]) && $_REQUEST["searchFormTab"] == "basic_search")
505         {
506             if($seed->module_dir == "Reports") $searchMetaData = SearchFormReports::retrieveReportsSearchDefs();
507             else $searchMetaData = SearchForm::retrieveSearchDefs($seed->module_dir);
508
509             $basicSearchFields = array();
510
511             if( isset($searchMetaData['searchdefs']) && isset($searchMetaData['searchdefs'][$seed->module_dir]['layout']['basic_search']) )
512                 $basicSearchFields = $searchMetaData['searchdefs'][$seed->module_dir]['layout']['basic_search'];
513
514             foreach( $basicSearchFields as $basicSearchField)
515             {
516                 $field_name = (is_array($basicSearchField) && isset($basicSearchField['name'])) ? $basicSearchField['name'] : $basicSearchField;
517                 $field_name .= "_basic";
518                 if( isset($_REQUEST[$field_name])  && ( !is_array($basicSearchField) || !isset($basicSearchField['type']) || $basicSearchField['type'] == 'text' || $basicSearchField['type'] == 'name') )
519                 {
520                     $queryString = htmlentities($_REQUEST[$field_name]);
521                     break;
522                 }
523             }
524         }
525
526
527                 return array('data'=>$data , 'pageData'=>$pageData, 'query' => $queryString);
528         }
529
530
531         /**
532          * generates urls for use by the display  layer
533          *
534          * @param int $sortOrder
535          * @param int $offset
536          * @param int $prevOffset
537          * @param int $nextOffset
538          * @param int $endOffset
539          * @param int $totalCounted
540          * @return array of urls orderBy and baseURL are always returned the others are only returned  according to values passed in.
541          */
542         function generateURLS($sortOrder, $offset, $prevOffset, $nextOffset, $endOffset, $totalCounted) {
543                 $urls = array();
544                 $urls['baseURL'] = $this->getBaseURL(). 'lvso=' . $sortOrder. '&';
545                 $urls['orderBy'] = $urls['baseURL'] .$this->var_order_by.'=';
546
547                 $dynamicUrl = '';
548                 if($nextOffset > -1) {
549                         $urls['nextPage'] = $urls['baseURL'] . $this->var_offset . '=' . $nextOffset . $dynamicUrl;
550                 }
551                 if($offset > 0) {
552                         $urls['startPage'] = $urls['baseURL'] . $this->var_offset . '=0' . $dynamicUrl;
553                 }
554                 if($prevOffset > -1) {
555                         $urls['prevPage'] = $urls['baseURL'] . $this->var_offset . '=' . $prevOffset . $dynamicUrl;
556                 }
557                 if($totalCounted) {
558                         $urls['endPage'] = $urls['baseURL'] . $this->var_offset . '=' . $endOffset . $dynamicUrl;
559                 }else{
560                         $urls['endPage'] = $urls['baseURL'] . $this->var_offset . '=end' . $dynamicUrl;
561                 }
562
563                 return $urls;
564         }
565
566         /**
567          * generates the additional details span to be retrieved via ajax
568          *
569          * @param GUID id id of the record
570          * @return array string to attach to field
571          */
572         function getAdditionalDetailsAjax($id)
573     {
574         global $app_strings;
575
576         $jscalendarImage = SugarThemeRegistry::current()->getImageURL('info_inline.gif');
577
578         $extra = "<span id='adspan_" . $id . "' "
579                 . "onclick=\"lvg_dtails('$id')\" "
580                                 . " style='position: relative;'><!--not_in_theme!--><img vertical-align='middle' class='info' border='0' alt='".$app_strings['LBL_ADDITIONAL_DETAILS']."' src='$jscalendarImage'></span>";
581
582         return array('fieldToAddTo' => $this->additionalDetailsFieldToAdd, 'string' => $extra);
583         }
584
585     /**
586      * generates the additional details values
587      *
588      * @param unknown_type $fields
589      * @param unknown_type $adFunction
590      * @param unknown_type $editAccess
591      * @return array string to attach to field
592      */
593     function getAdditionalDetails($fields, $adFunction, $editAccess)
594     {
595         global $app_strings;
596         global $mod_strings;
597
598         $results = $adFunction($fields);
599
600         $results['string'] = str_replace(array("&#039", "'"), '\&#039', $results['string']); // no xss!
601
602         if(trim($results['string']) == '')
603         {
604             $results['string'] = $app_strings['LBL_NONE'];
605         }
606                 $close = false;
607             $extra = "<img alt='{$app_strings['LBL_INFOINLINE']}' style='padding: 0px 5px 0px 2px' border='0' onclick=\"SUGAR.util.getStaticAdditionalDetails(this,'";
608
609             $extra .= str_replace(array("\rn", "\r", "\n"), array('','','<br />'), $results['string']) ;
610             $extra .= "','<div style=\'float:left\'>{$app_strings['LBL_ADDITIONAL_DETAILS']}</div><div style=\'float: right\'>";
611
612                 if($editAccess && !empty($results['editLink']))
613                 {
614                     $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>";
615                     $close = true;
616                 }
617                 $close = (!empty($results['viewLink'])) ? true : $close;
618                 $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>" : '');
619
620             if($close == true) {
621                 $closeVal = "true";
622                 $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>";
623             } else {
624                 $closeVal = "false";
625             }
626             $extra .= "',".$closeVal.")\" src='".SugarThemeRegistry::current()->getImageURL('info_inline.png')."' class='info'>";
627
628         return array('fieldToAddTo' => $results['fieldToAddTo'], 'string' => $extra);
629     }
630
631 }