]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/ListView/ListViewDisplay.php
Release 6.5.16
[Github/sugarcrm.git] / include / ListView / ListViewDisplay.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
40
41 require_once('include/ListView/ListViewData.php');
42 require_once('include/MassUpdate.php');
43
44 class ListViewDisplay {
45     static $listViewCounter = 0;
46
47         var $show_mass_update_form = false;
48         var $show_action_dropdown = true;
49         var $rowCount;
50         var $mass = null;
51         var $seed;
52         var $multi_select_popup;
53         var $lvd;
54         var $moduleString;
55         var $export = true;
56         var $multiSelect = true;
57         var $mailMerge = true;
58         var $should_process = true;
59         var $show_plus = false;
60         /*
61          * Used in view.popup.php. Sometimes there are fields on the search form that are not referenced in the listviewdefs. If this
62          * is the case, then the filterFields will be set and the related fields will not be referenced when calling create_new_list_query.
63          */
64         var $mergeDisplayColumns = false;
65     public $actionsMenuExtraItems = array();
66
67         /**
68          * Constructor
69          * @return null
70          */
71         function ListViewDisplay() {
72                 $this->lvd = new ListViewData();
73                 $this->searchColumns = array () ;
74         }
75         function shouldProcess($moduleDir){
76                 $searching = false;
77                 $sessionSearchQuery = "{$moduleDir}2_QUERY_QUERY";
78                 if (!empty($_SESSION[$sessionSearchQuery])) {
79                         $searching = true;
80                 }
81                 if(!empty($GLOBALS['sugar_config']['save_query']) && $GLOBALS['sugar_config']['save_query'] == 'populate_only'){
82                     if(empty($GLOBALS['displayListView']) 
83                             && (!empty($_REQUEST['clear_query']) 
84                                 || $_REQUEST['module'] == $moduleDir 
85                                     && ((empty($_REQUEST['query']) || $_REQUEST['query'] == 'MSI' )
86                                         && (!$searching)))) {
87                                 $_SESSION['last_search_mod'] = $_REQUEST['module'] ;
88                                 $this->should_process = false;
89                                 return false;
90                         }
91                 }
92                 $this->should_process = true;
93                 return true;
94         }
95
96         /**
97          * Setup the class
98          * @param seed SugarBean Seed SugarBean to use
99          * @param file File Template file to use
100          * @param string $where
101          * @param offset:0 int offset to start at
102          * @param int:-1 $limit
103          * @param string[]:array() $filter_fields
104          * @param array:array() $params
105          *      Potential $params are
106                 $params['distinct'] = use distinct key word
107                 $params['include_custom_fields'] = (on by default)
108                 $params['massupdate'] = true by default;
109         $params['handleMassupdate'] = true by default, have massupdate.php handle massupdates?
110          * @param string:'id' $id_field
111          */
112         function setup($seed, $file, $where, $params = array(), $offset = 0, $limit = -1,  $filter_fields = array(), $id_field = 'id') {
113         $this->should_process = true;
114         if(isset($seed->module_dir) && !$this->shouldProcess($seed->module_dir)){
115                         return false;
116         }
117         if(isset($params['export'])) {
118           $this->export = $params['export'];
119         }
120         if(!empty($params['multiSelectPopup'])) {
121                   $this->multi_select_popup = $params['multiSelectPopup'];
122         }
123                 if(!empty($params['massupdate']) && $params['massupdate'] != false) {
124                         $this->show_mass_update_form = true;
125                         $this->mass = $this->getMassUpdate();
126                         $this->mass->setSugarBean($seed);
127                         if(!empty($params['handleMassupdate']) || !isset($params['handleMassupdate'])) {
128                 $this->mass->handleMassUpdate();
129             }
130                 }
131                 $this->seed = $seed;
132
133         $filter_fields = $this->setupFilterFields($filter_fields);
134
135         $data = $this->lvd->getListViewData($seed, $where, $offset, $limit, $filter_fields, $params, $id_field);
136
137         $this->fillDisplayColumnsWithVardefs();
138
139                 $this->process($file, $data, $seed->object_name);
140                 return true;
141         }
142
143         function setupFilterFields($filter_fields = array())
144         {
145                 // create filter fields based off of display columns
146         if(empty($filter_fields) || $this->mergeDisplayColumns) {
147             foreach($this->displayColumns as $columnName => $def) {
148
149                $filter_fields[strtolower($columnName)] = true;
150
151             if(isset($this->seed->field_defs[strtolower($columnName)]['type']) &&
152                strtolower($this->seed->field_defs[strtolower($columnName)]['type']) == 'currency' &&
153                isset($this->seed->field_defs['currency_id'])) {
154                     $filter_fields['currency_id'] = true;
155             }
156
157                if(!empty($def['related_fields'])) {
158                     foreach($def['related_fields'] as $field) {
159                         //id column is added by query construction function. This addition creates duplicates
160                         //and causes issues in oracle. #10165
161                         if ($field != 'id') {
162                             $filter_fields[$field] = true;
163                         }
164                     }
165                 }
166                 if (!empty($this->seed->field_defs[strtolower($columnName)]['db_concat_fields'])) {
167                     foreach($this->seed->field_defs[strtolower($columnName)]['db_concat_fields'] as $index=>$field){
168                         if(!isset($filter_fields[strtolower($field)]) || !$filter_fields[strtolower($field)])
169                         {
170                             $filter_fields[strtolower($field)] = true;
171                         }
172                     }
173                 }
174             }
175             foreach ($this->searchColumns as $columnName => $def )
176             {
177                 $filter_fields[strtolower($columnName)] = true;
178             }
179         }
180
181
182         return $filter_fields;
183         }
184
185
186         /**
187          * Any additional processing
188          * @param file File template file to use
189          * @param data array row data
190          * @param html_var string html string to be passed back and forth
191          */
192         function process($file, $data, $htmlVar) {
193                 $this->rowCount = count($data['data']);
194                 $this->moduleString = $data['pageData']['bean']['moduleDir'] . '2_' . strtoupper($htmlVar) . '_offset';
195         }
196
197         /**
198          * Display the listview
199          * @return string ListView contents
200          */
201         public function display() 
202         {
203                 if (!$this->should_process) {
204                     return '';
205                 }
206                 
207                 $str = '';
208                 if ($this->show_mass_update_form) {
209                         $str = $this->mass->getDisplayMassUpdateForm(true, $this->multi_select_popup).$this->mass->getMassUpdateFormHeader($this->multi_select_popup);
210                 }
211         
212                 return $str;
213         }
214         /**
215          * Display the select link
216      * @return string select link html
217          * @param echo Bool set true if you want it echo'd, set false to have contents returned
218          */
219         function buildSelectLink($id = 'select_link', $total=0, $pageTotal=0, $location="top") {
220                 global $app_strings;
221                 if ($pageTotal < 0)
222                         $pageTotal = $total;
223
224
225         $total_label = "";
226         if (!empty($GLOBALS['sugar_config']['disable_count_query']) && $GLOBALS['sugar_config']['disable_count_query'] === true && $total > $pageTotal) {
227             $this->show_plus = true;
228             $total_label =  $pageTotal.'+';
229             $total = $pageTotal;
230         } else {
231             $total_label = $total;
232         }
233
234                 $close_inline_img = SugarThemeRegistry::current()->getImage('close_inline', 'border=0', null, null, ".gif", $app_strings['LBL_CLOSEINLINE']);
235                 $menuItems = array(
236             "<input title=\"".$app_strings['LBL_SELECT_ALL_TITLE']."\" type='checkbox' class='checkbox massall' name='massall' id='massall_".$location."' value='' onclick='sListView.check_all(document.MassUpdate, \"mass[]\", this.checked);' /><a id='$id'  href='javascript: void(0);'></a>",
237             "<a  name='thispage' id='button_select_this_page_".$location."' class='menuItem' onmouseover='hiliteItem(this,\"yes\");' onmouseout='unhiliteItem(this);' onclick='if (document.MassUpdate.select_entire_list.value==1){document.MassUpdate.select_entire_list.value=0;sListView.check_all(document.MassUpdate, \"mass[]\", true, $pageTotal)}else {sListView.check_all(document.MassUpdate, \"mass[]\", true)};' href='#'>{$app_strings['LBL_LISTVIEW_OPTION_CURRENT']}&nbsp;&#x28;{$pageTotal}&#x29;&#x200E;</a>",
238             "<a  name='selectall' id='button_select_all_".$location."' class='menuItem' onmouseover='hiliteItem(this,\"yes\");' onmouseout='unhiliteItem(this);' onclick='sListView.check_entire_list(document.MassUpdate, \"mass[]\",true,{$total});' href='#'>{$app_strings['LBL_LISTVIEW_OPTION_ENTIRE']}&nbsp;&#x28;{$total_label}&#x29;&#x200E;</a>",
239             "<a name='deselect' id='button_deselect_".$location."' class='menuItem' onmouseover='hiliteItem(this,\"yes\");' onmouseout='unhiliteItem(this);' onclick='sListView.clear_all(document.MassUpdate, \"mass[]\", false);' href='#'>{$app_strings['LBL_LISTVIEW_NONE']}</a>",
240         );
241
242         $link = array(
243             'class' => 'clickMenu selectmenu',
244             'id' => 'selectLink',
245             'buttons' => $menuItems,
246             'flat' => false,
247         );
248         return $link;
249         }
250
251         /**
252          * Display the actions link
253          *
254          * @param  string $id link id attribute, defaults to 'actions_link'
255          * @return string HTML source
256          */
257         protected function buildActionsLink($id = 'actions_link', $location = 'top')
258         {
259             global $app_strings;
260                 $closeText = SugarThemeRegistry::current()->getImage('close_inline', 'border=0', null, null, ".gif", $app_strings['LBL_CLOSEINLINE']);
261                 $moreDetailImage = SugarThemeRegistry::current()->getImageURL('MoreDetail.png');
262                 $menuItems = array();
263
264                 // delete
265                 if ( ACLController::checkAccess($this->seed->module_dir,'delete',true) && $this->delete )
266                         $menuItems[] = $this->buildDeleteLink($location);
267                 // compose email
268         if ( $this->email )
269                         $menuItems[] = $this->buildComposeEmailLink($this->data['pageData']['offsets']['total'], $location);
270                 // mass update
271                 $mass = $this->getMassUpdate();
272                 $mass->setSugarBean($this->seed);
273                 if ( ( ACLController::checkAccess($this->seed->module_dir,'edit',true) && ACLController::checkAccess($this->seed->module_dir,'massupdate',true) ) && $this->showMassupdateFields && $mass->doMassUpdateFieldsExistForFocus() )
274             $menuItems[] = $this->buildMassUpdateLink($location);
275                 // merge
276                 if ( $this->mailMerge )
277                     $menuItems[] = $this->buildMergeLink(null, $location);
278                 if ( $this->mergeduplicates )
279                     $menuItems[] = $this->buildMergeDuplicatesLink($location);
280                 // add to target list
281                 if ( $this->targetList && ACLController::checkAccess('ProspectLists','edit',true) )
282                     $menuItems[] = $this->buildTargetList($location);
283                 // export
284                 if ( ACLController::checkAccess($this->seed->module_dir,'export',true) && $this->export )
285                         $menuItems[] = $this->buildExportLink($location);
286
287                 foreach ( $this->actionsMenuExtraItems as $item )
288                     $menuItems[] = $item;
289
290         $link = array(
291             'class' => 'clickMenu selectActions fancymenu',
292             'id' => 'selectActions',
293             'name' => 'selectActions',
294             'buttons' => $menuItems,
295             'flat' => false,
296         );
297         return $link;
298
299 }
300         /**
301          * Builds the export link
302          *
303          * @return string HTML
304          */
305         protected function buildExportLink($loc = 'top')
306         {
307                 global $app_strings;
308                 return "<a href='javascript:void(0)' id=\"export_listview_". $loc ." \" onclick=\"return sListView.send_form(true, '{$this->seed->module_dir}', 'index.php?entryPoint=export','{$app_strings['LBL_LISTVIEW_NO_SELECTED']}')\">{$app_strings['LBL_EXPORT']}</a>";
309     }
310
311         /**
312          * Builds the massupdate link
313          *
314          * @return string HTML
315          */
316         protected function buildMassUpdateLink($loc = 'top')
317         {
318                 global $app_strings;
319
320         $onClick = "document.getElementById('massupdate_form').style.display = ''; var yLoc = YAHOO.util.Dom.getY('massupdate_form'); scroll(0,yLoc);";
321                 return "<a href='javascript:void(0)' id=\"massupdate_listview_". $loc ."\" onclick=\"$onClick\">{$app_strings['LBL_MASS_UPDATE']}</a>";
322
323         }
324
325         /**
326          * Builds the compose email link
327          *
328          * @return string HTML
329          */
330         protected function buildComposeEmailLink($totalCount, $loc = 'top')
331         {
332                 global $app_strings,$dictionary;
333
334         if (!is_array($this->seed->field_defs)) {
335             return '';
336         }
337         $foundEmailField = false;
338         // Search for fields that look like an email address
339         foreach ($this->seed->field_defs as $field) {
340             if(isset($field['type'])&&$field['type']=='link'
341                &&isset($field['relationship'])&&isset($dictionary[$this->seed->object_name]['relationships'][$field['relationship']])
342                &&$dictionary[$this->seed->object_name]['relationships'][$field['relationship']]['rhs_module']=='EmailAddresses') {
343                 $foundEmailField = true;
344                 break;
345             }
346         }
347         if (!$foundEmailField) {
348             return '';
349         }
350
351
352                 $userPref = $GLOBALS['current_user']->getPreference('email_link_type');
353                 $defaultPref = $GLOBALS['sugar_config']['email_default_client'];
354                 if($userPref != '')
355                         $client = $userPref;
356                 else
357                         $client = $defaultPref;
358
359                 if($client == 'sugar')
360                         $script = "<a href='javascript:void(0)' " .
361                     "id=\"composeemail_listview_". $loc ."\"".
362                                         'onclick="return sListView.send_form_for_emails(true, \''."Emails".'\', \'index.php?module=Emails&action=Compose&ListView=true\',\''.$app_strings['LBL_LISTVIEW_NO_SELECTED'].'\', \''.$this->seed->module_dir.'\', \''.$totalCount.'\', \''.$app_strings['LBL_LISTVIEW_LESS_THAN_TEN_SELECT'].'\')">' .
363                                         $app_strings['LBL_EMAIL_COMPOSE'] . '</a>';
364                 else
365                         $script = "<a href='javascript:void(0)' " .
366                     "id=\"composeemail_listview_". $loc ."\"".
367                                         "onclick=\"return sListView.use_external_mail_client('{$app_strings['LBL_LISTVIEW_NO_SELECTED']}', '{$_REQUEST['module']}');\">" .
368                                         $app_strings['LBL_EMAIL_COMPOSE'] . '</a>';
369
370         return $script;
371         } // fn
372         /**
373          * Builds the delete link
374          *
375          * @return string HTML
376          */
377         protected function buildDeleteLink($loc = 'top')
378         {
379                 global $app_strings;
380         return "<a href='javascript:void(0)' id=\"delete_listview_". $loc ."\" onclick=\"return sListView.send_mass_update('selected', '{$app_strings['LBL_LISTVIEW_NO_SELECTED']}', 1)\">{$app_strings['LBL_DELETE_BUTTON_LABEL']}</a>";
381         }
382         /**
383          * Display the selected object span object
384          *
385      * @return string select object span
386          */
387         function buildSelectedObjectsSpan($echo = true, $total=0) {
388                 global $app_strings;
389
390         $displayStyle = $total > 0 ? "" : "display: none;";
391                 $selectedObjectSpan = "<span style='$displayStyle' id='selectedRecordsTop'>{$app_strings['LBL_LISTVIEW_SELECTED_OBJECTS']}<input  style='border: 0px; background: transparent; font-size: inherit; color: inherit' type='text' id='selectCountTop' readonly name='selectCount[]' value='{$total}' /></span>";
392
393         return $selectedObjectSpan;
394         }
395     /**
396          * Builds the mail merge link
397          * The link can be disabled by setting module level duplicate_merge property to false
398          * in the moudle's vardef file.
399          *
400          * @return string HTML
401          */
402         protected function buildMergeDuplicatesLink($loc = 'top')
403         {
404         global $app_strings, $dictionary;
405
406         $return_string='';
407         $return_string.= isset($_REQUEST['module']) ? "&return_module={$_REQUEST['module']}" : "";
408         $return_string.= isset($_REQUEST['action']) ? "&return_action={$_REQUEST['action']}" : "";
409         $return_string.= isset($_REQUEST['record']) ? "&return_id={$_REQUEST['record']}" : "";
410         //need delete and edit access.
411                 if (!(ACLController::checkAccess($this->seed->module_dir, 'edit', true)) or !(ACLController::checkAccess($this->seed->module_dir, 'delete', true))) {
412                         return "";
413                 }
414
415         if (isset($dictionary[$this->seed->object_name]['duplicate_merge']) && $dictionary[$this->seed->object_name]['duplicate_merge']==true ) {
416             return "<a href='javascript:void(0)' ".
417                             "id='mergeduplicates_listview_". $loc ."'".
418                             "onclick='if (sugarListView.get_checks_count()> 1) {sListView.send_form(true, \"MergeRecords\", \"index.php\", \"{$app_strings['LBL_LISTVIEW_NO_SELECTED']}\", \"{$this->seed->module_dir}\",\"$return_string\");} else {alert(\"{$app_strings['LBL_LISTVIEW_TWO_REQUIRED']}\");return false;}'>".
419                             $app_strings['LBL_MERGE_DUPLICATES'].'</a>';
420         }
421
422         return "";
423      }
424     /**
425          * Builds the mail merge link
426          *
427          * @return string HTML
428          */
429         protected function buildMergeLink(array $modules_array = null, $loc = 'top')
430         {
431         if ( empty($modules_array) ) {
432             require('modules/MailMerge/modules_array.php');
433         }
434         global $current_user, $app_strings;
435
436         $admin = new Administration();
437         $admin->retrieveSettings('system');
438         $user_merge = $current_user->getPreference('mailmerge_on');
439         $module_dir = (!empty($this->seed->module_dir) ? $this->seed->module_dir : '');
440         $str = '';
441         
442         if ($user_merge == 'on' && isset($admin->settings['system_mailmerge_on']) && $admin->settings['system_mailmerge_on'] && !empty($modules_array[$module_dir])) {
443             return "<a href='javascript:void(0)'  " .
444                     "id='merge_listview_". $loc ."'"  .
445                                         'onclick="if (document.MassUpdate.select_entire_list.value==1){document.location.href=\'index.php?action=index&module=MailMerge&entire=true\'} else {return sListView.send_form(true, \'MailMerge\',\'index.php\',\''.$app_strings['LBL_LISTVIEW_NO_SELECTED'].'\');}">' .
446                                         $app_strings['LBL_MAILMERGE'].'</a>';
447         }
448         return $str;
449         }
450
451         /**
452          * Builds the add to target list link
453          *
454      * @return string HTML
455          */
456         protected function buildTargetList($loc = 'top')
457         {
458         global $app_strings;
459                 unset($_REQUEST[session_name()]);
460                 unset($_REQUEST['PHPSESSID']);
461         $current_query_by_page = base64_encode(serialize($_REQUEST));
462
463                 $js = <<<EOF
464             if(sugarListView.get_checks_count() < 1) {
465                 alert('{$app_strings['LBL_LISTVIEW_NO_SELECTED']}');
466                 return false;
467             }
468                         if ( document.forms['targetlist_form'] ) {
469                                 var form = document.forms['targetlist_form'];
470                                 form.reset;
471                         } else
472                                 var form = document.createElement ( 'form' ) ;
473                         form.setAttribute ( 'name' , 'targetlist_form' );
474                         form.setAttribute ( 'method' , 'post' ) ;
475                         form.setAttribute ( 'action' , 'index.php' );
476                         document.body.appendChild ( form ) ;
477                         if ( !form.module ) {
478                             var input = document.createElement('input');
479                             input.setAttribute ( 'name' , 'module' );
480                             input.setAttribute ( 'value' , '{$this->seed->module_dir}' );
481                             input.setAttribute ( 'type' , 'hidden' );
482                             form.appendChild ( input ) ;
483                             var input = document.createElement('input');
484                             input.setAttribute ( 'name' , 'action' );
485                             input.setAttribute ( 'value' , 'TargetListUpdate' );
486                             input.setAttribute ( 'type' , 'hidden' );
487                             form.appendChild ( input ) ;
488                         }
489                         if ( !form.uids ) {
490                             var input = document.createElement('input');
491                             input.setAttribute ( 'name' , 'uids' );
492                             input.setAttribute ( 'type' , 'hidden' );
493                             form.appendChild ( input ) ;
494                         }
495                         if ( !form.prospect_list ) {
496                             var input = document.createElement('input');
497                             input.setAttribute ( 'name' , 'prospect_list' );
498                             input.setAttribute ( 'type' , 'hidden' );
499                             form.appendChild ( input ) ;
500                         }
501                         if ( !form.return_module ) {
502                             var input = document.createElement('input');
503                             input.setAttribute ( 'name' , 'return_module' );
504                             input.setAttribute ( 'type' , 'hidden' );
505                             form.appendChild ( input ) ;
506                         }
507                         if ( !form.return_action ) {
508                             var input = document.createElement('input');
509                             input.setAttribute ( 'name' , 'return_action' );
510                             input.setAttribute ( 'type' , 'hidden' );
511                             form.appendChild ( input ) ;
512                         }
513                         if ( !form.select_entire_list ) {
514                             var input = document.createElement('input');
515                             input.setAttribute ( 'name' , 'select_entire_list' );
516                             input.setAttribute ( 'value', document.MassUpdate.select_entire_list.value);
517                             input.setAttribute ( 'type' , 'hidden' );
518                             form.appendChild ( input ) ;
519                         }
520                         if ( !form.current_query_by_page ) {
521                             var input = document.createElement('input');
522                             input.setAttribute ( 'name' , 'current_query_by_page' );
523                             input.setAttribute ( 'value', '{$current_query_by_page}' );
524                             input.setAttribute ( 'type' , 'hidden' );
525                             form.appendChild ( input ) ;
526                         }
527                         open_popup('ProspectLists','600','400','',true,false,{ 'call_back_function':'set_return_and_save_targetlist','form_name':'targetlist_form','field_to_name_array':{'id':'prospect_list'} } );
528 EOF;
529         $js = str_replace(array("\r","\n"),'',$js);
530         return "<a href='javascript:void(0)' id=\"targetlist_listview_". $loc ." \" onclick=\"$js\">{$app_strings['LBL_ADD_TO_PROSPECT_LIST_BUTTON_LABEL']}</a>";
531         }
532         /**
533          * Display the bottom of the ListView (ie MassUpdate
534          * @return string contents
535          */
536         public function displayEnd() 
537         {
538                 $str = '';
539                 if($this->show_mass_update_form) {
540                         $str .= $this->mass->getMassUpdateForm(true);
541                         $str .= $this->mass->endMassUpdateForm();
542                 }
543
544                 return $str;
545         }
546
547     /**
548      * Display the multi select data box etc.
549      * @return string contents
550      */
551         public function getMultiSelectData() 
552         {
553                 $str = "<script>YAHOO.util.Event.addListener(window, \"load\", sListView.check_boxes);</script>\n";
554
555                 $massUpdateRun = isset($_REQUEST['massupdate']) && $_REQUEST['massupdate'] == 'true';
556                 $uids = empty($_REQUEST['uid']) || $massUpdateRun ? '' : $_REQUEST['uid'];
557         $select_entire_list = ($massUpdateRun) ? 0 : (isset($_POST['select_entire_list']) ? $_POST['select_entire_list'] : (isset($_REQUEST['select_entire_list']) ? $_REQUEST['select_entire_list'] : 0));
558
559                 $str .= "<textarea style='display: none' name='uid'>{$uids}</textarea>\n" .
560                                 "<input type='hidden' name='select_entire_list' value='{$select_entire_list}'>\n".
561                                 "<input type='hidden' name='{$this->moduleString}' value='0'>\n".
562                         "<input type='hidden' name='show_plus' value='{$this->show_plus}'>\n";
563                 return $str;
564         }
565
566      /**
567      * @return MassUpdate instance
568      */
569     protected function getMassUpdate()
570     {
571         return new MassUpdate();
572     }
573
574     /**
575      * Fill displayColumns with additional field values from vardefs of the current bean seed.
576      * We need vardefs to be in displayColumns for a further processing (e.g. in SugarField)
577      * Similar vardef field values do not override field values from displayColumns, only necessary and missing ones are added
578      */
579     protected function fillDisplayColumnsWithVardefs()
580     {
581         foreach ($this->displayColumns as $columnName => $def) {
582             $seedName =  strtolower($columnName);
583             if (!empty($this->lvd->seed->field_defs[$seedName])) {
584                 $seedDef = $this->lvd->seed->field_defs[$seedName];
585             }
586
587             if (empty($this->displayColumns[$columnName]['type'])) {
588                 if (!empty($seedDef['type'])) {
589                     $this->displayColumns[$columnName]['type'] = (!empty($seedDef['custom_type']))?$seedDef['custom_type']:$seedDef['type'];
590                 } else {
591                     $this->displayColumns[$columnName]['type'] = '';
592                 }
593             }//fi empty(...)
594
595             if (!empty($seedDef['options'])) {
596                 $this->displayColumns[$columnName]['options'] = $seedDef['options'];
597             }
598
599             //C.L. Fix for 11177
600             if ($this->displayColumns[$columnName]['type'] == 'html') {
601                 $cField = $this->seed->custom_fields;
602                 if (isset($cField) && isset($cField->bean->$seedName)) {
603                     $seedName2 = strtoupper($columnName);
604                     $htmlDisplay = html_entity_decode($cField->bean->$seedName);
605                     $count = 0;
606                     while ($count < count($data['data'])) {
607                         $data['data'][$count][$seedName2] = &$htmlDisplay;
608                         $count++;
609                     }
610                 }
611             }//fi == 'html'
612
613             //Bug 40511, make sure relate fields have the correct module defined
614             if ($this->displayColumns[$columnName]['type'] == "relate" && !empty($seedDef['link']) && empty( $this->displayColumns[$columnName]['module'])) {
615                 $link = $seedDef['link'];
616                 if (!empty($this->lvd->seed->field_defs[$link]) && !empty($this->lvd->seed->field_defs[$seedDef['link']]['module'])) {
617                     $this->displayColumns[$columnName]['module'] = $this->lvd->seed->field_defs[$seedDef['link']]['module'];
618                 }
619             }
620
621             if (!empty($seedDef['sort_on'])) {
622                 $this->displayColumns[$columnName]['orderBy'] = $seedDef['sort_on'];
623             }
624
625             if (isset($seedDef)) {
626                 // Merge the two arrays together, making sure the seedDef doesn't override anything explicitly set in the displayColumns array.
627                 $this->displayColumns[$columnName] = $this->displayColumns[$columnName] + $seedDef;
628             }
629
630             //C.L. Bug 38388 - ensure that ['id'] is set for related fields
631             if (!isset($this->displayColumns[$columnName]['id']) && isset($this->displayColumns[$columnName]['id_name'])) {
632                 $this->displayColumns[$columnName]['id'] = strtoupper($this->displayColumns[$columnName]['id_name']);
633             }
634         }
635     }
636 }