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