]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/ListView/ListView.php
Release 6.1.4
[Github/sugarcrm.git] / include / ListView / ListView.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM 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 require_once('include/EditView/SugarVCR.php');
39 class ListView
40 {
41         var $local_theme= null;
42         var $local_app_strings= null;
43         var $local_image_path = null;
44         var $local_current_module = null;
45         var $local_mod_strings = null;
46         var $records_per_page = 20;
47         var $xTemplate = null;
48         var $xTemplatePath = null;
49         var $seed_data = null;
50         var $query_where = null;
51         var $query_limit = -1;
52         var $query_orderby = null;
53         var $header_title = '';
54         var $header_text = '';
55         var $initialized = false;
56         var $show_export_button = true;
57         var $show_delete_button = true;
58         var $show_select_menu = true;
59         var $show_paging = true;
60         var $show_mass_update = true;
61         var $show_mass_update_form = true;
62         var $query_where_has_changed = false;
63         var $display_header_and_footer = true;
64         var $baseURL = '';
65         var $is_dynamic = false;
66         var $inline = false;
67         var $start_link_wrapper = '';
68         var $end_link_wrapper = '';
69         var $list_field_defs = array();
70
71         var $shouldProcess = false;
72         var $data_array;
73         var $related_field_name = '';
74         var $child_focus = '';
75         var $layout_manager = null;
76         var $process_for_popups = false;
77         var $multi_select_popup=false;
78         var $_additionalDetails = false;
79         var $additionalDetailsFunction = null;
80         var $sort_order = '';
81         var $force_mass_update=false;
82         var $keep_mass_update_form_open=false;
83         var $ignorePopulateOnly = false;
84
85 function setDataArray($value) {
86         $this->data_array = $value;
87 }
88
89 function processListViewMulti($seed, $xTemplateSection, $html_varName) {
90
91         $this->shouldProcess = true;
92
93         echo "<form name='MassUpdate' method='post' action='index.php'>";
94         $this->processListViewTwo($seed, $xTemplateSection, $html_varName);
95
96         echo "<a href='javascript:" . ((!$this->multi_select_popup) ? 'sListView.' : ''). "check_all(document.MassUpdate, \"mass[]\", true)'>".translate('LBL_CHECKALL')."</a> - <a href='javascript:sListView.check_all(document.MassUpdate, \"mass[]\", false);'>".translate('LBL_CLEARALL')."</a>";
97         echo '<br><br>';
98 }
99
100
101 function processListView($seed, $xTemplateSection, $html_varName)
102 {
103         global $sugar_config;
104
105         $populateOnly = $this->ignorePopulateOnly ? FALSE : (!empty($sugar_config['save_query']) && $sugar_config['save_query'] == 'populate_only');
106         if(isset($seed->module_dir) && $populateOnly) {
107             if(empty($GLOBALS['displayListView']) && strcmp(strtolower($_REQUEST['action']), 'popup') != 0 && (!empty($_REQUEST['clear_query']) || $_REQUEST['module'] == $seed->module_dir && ((empty($_REQUEST['query']) || $_REQUEST['query'] == 'MSI')&& (empty($_SESSION['last_search_mod']) || $_SESSION['last_search_mod'] != $seed->module_dir)))) {
108                         $_SESSION['last_search_mod'] = $_REQUEST['module'] ;
109                         return;
110                 }
111         }
112         if(strcmp(strtolower($_REQUEST['action']), 'popup') != 0){
113             $_SESSION['last_search_mod'] = $_REQUEST['module'] ;
114         }
115     //following session variable will track the detail view nvigation history.
116     //needs to the reset after each search.
117         $this->setLocalSessionVariable($html_varName,"DETAIL_NAV_HISTORY",false);
118
119         require_once('include/MassUpdate.php');
120         $mass = new MassUpdate();
121         $add_acl_javascript = false;
122         if(!isset($_REQUEST['action'])) {
123                 $this->shouldProcess=false;
124         } else {
125         $this->shouldProcess = is_subclass_of($seed, "SugarBean")
126                 && (($_REQUEST['action'] == 'index') || ('ListView' == substr($_REQUEST['action'],0,8)) /* cn: to include all ListViewXXX.php type views */)
127                 && ($_REQUEST['module'] == $seed->module_dir);
128         }
129
130         //when processing a multi-select popup.
131         if($this->process_for_popups && $this->multi_select_popup)  $this->shouldProcess =true;
132         //mass update turned off?
133         if(!$this->show_mass_update) $this->shouldProcess = false;
134         if(is_subclass_of($seed, "SugarBean")) {
135                 if($seed->bean_implements('ACL')) {
136                         if(!ACLController::checkAccess($seed->module_dir,'list',true)) {
137                                 if($_REQUEST['module'] != 'Home') {
138                                         ACLController::displayNoAccess();
139                                 }
140                                 return;
141                         }
142                         if(!ACLController::checkAccess($seed->module_dir,'export',true)) {
143                                 $sugar_config['disable_export']= true;
144                         }
145
146                 }
147         }
148
149         //force mass update form if requested.
150         if($this->force_mass_update) {
151                 $this->shouldProcess = true;
152         }
153
154         if($this->shouldProcess) {
155                 echo $mass->getDisplayMassUpdateForm(true, $this->multi_select_popup);
156                 echo $mass->getMassUpdateFormHeader($this->multi_select_popup);
157                 $mass->setSugarBean($seed);
158
159                 //C.L. Fix for 10048, do not process handleMassUpdate for multi select popups
160                 if(!$this->multi_select_popup) {
161                         $mass->handleMassUpdate();
162                 }
163         }
164
165         $this->processListViewTwo($seed,$xTemplateSection, $html_varName);
166
167         if($this->shouldProcess && empty($this->process_for_popups)) {
168                 //echo "<a href='javascript:sListView.clear_all(document.MassUpdate, \"mass[]\");'>".translate('LBL_CLEARALL')."</a>";
169                 // cn: preserves current functionality, exception is InboundEmail
170                 if($this->show_mass_update_form) {
171                         echo $mass->getMassUpdateForm();
172                 }
173                 if(!$this->keep_mass_update_form_open) {
174                         echo $mass->endMassUpdateForm();
175                 }
176         }
177 }
178
179
180 function process_dynamic_listview($source_module, $sugarbean,$subpanel_def)
181 {
182                 $this->source_module = $source_module;
183                 $this->subpanel_module = $subpanel_def->name;
184                 if(!isset($this->xTemplate))
185                         $this->createXTemplate();
186
187                 $html_var = $this->subpanel_module . "_CELL";
188                 
189                 $list_data = $this->processUnionBeans($sugarbean,$subpanel_def, $html_var);
190                 
191                 $list = $list_data['list'];
192                 $parent_data = $list_data['parent_data'];
193
194                 if($subpanel_def->isCollection()) {
195                         $thepanel=$subpanel_def->get_header_panel_def();
196                 } else {
197                         $thepanel=$subpanel_def;
198                 }
199                 
200                 
201
202                 $this->process_dynamic_listview_header($thepanel->get_module_name(), $thepanel, $html_var);
203                 $this->process_dynamic_listview_rows($list,$parent_data, 'dyn_list_view', $html_var,$subpanel_def);
204
205                 if($this->display_header_and_footer)
206                 {
207                         $this->getAdditionalHeader();
208                         if(!empty($this->header_title))
209                         {
210                                 echo get_form_header($this->header_title, $this->header_text, false);
211                         }
212                 }
213
214                 $this->xTemplate->out('dyn_list_view');
215
216                 if(isset($_SESSION['validation']))
217                 {
218                         print base64_decode('PGEgaHJlZj0naHR0cDovL3d3dy5zdWdhcmNybS5jb20nPlBPV0VSRUQmbmJzcDtCWSZuYnNwO1NVR0FSQ1JNPC9hPg==');
219                 }
220                 if(isset($list_data['query'])) {
221                         return ($list_data['query']);
222                 }
223         }
224
225 /**
226  * @return void
227  * @param unknown $data
228  * @param unknown $xTemplateSection
229  * @param unknown $html_varName
230  * @desc INTERNAL FUNCTION handles the rows
231  */
232  function process_dynamic_listview_rows($data,$parent_data, $xtemplateSection, $html_varName, $subpanel_def)
233  {
234          global $odd_bg;
235          global $even_bg;
236          global $hilite_bg;
237          global $click_bg;
238
239         $this->xTemplate->assign("BG_HILITE", $hilite_bg);
240         $this->xTemplate->assign('CHECKALL', "<img src='".SugarThemeRegistry::current()->getImageURL('blank.gif')."' width=\"1\" height=\"1\" alt=\"\" />");
241         //$this->xTemplate->assign("BG_CLICK", $click_bg);
242         $oddRow = true;
243         $count = 0;
244         reset($data);
245
246         //GETTING OFFSET
247         $offset = $this->getOffset($html_varName);
248         //$totaltime = 0;
249         $processed_ids = array();
250
251         $fill_additional_fields = array();
252         //Either retrieve the is_fill_in_additional_fields property from the lone
253         //subpanel or visit each subpanel's subpanels to retreive the is_fill_in_addition_fields
254         //property
255         $subpanel_list=array();
256         if($subpanel_def->isCollection()) {
257                 $subpanel_list=$subpanel_def->sub_subpanels;
258         } else {
259                 $subpanel_list[]= $subpanel_def;
260         }
261
262         foreach($subpanel_list as $this_subpanel)
263         {
264                 if($this_subpanel->is_fill_in_additional_fields())
265                 {
266                         $fill_additional_fields[] = $this_subpanel->bean_name;
267                         $fill_additional_fields[$this_subpanel->bean_name] = true;
268                 }
269         }
270
271         if ( empty($data) ) {
272             $this->xTemplate->assign("ROW_COLOR", 'oddListRow');
273             $thepanel=$subpanel_def;
274             if($subpanel_def->isCollection())
275             $thepanel=$subpanel_def->get_header_panel_def();
276             $this->xTemplate->assign("COL_COUNT", count($thepanel->get_list_fields()));
277             $this->xTemplate->parse($xtemplateSection.".nodata");
278         }
279
280         while(list($aVal, $aItem) = each($data))
281         {
282                 $aItem->check_date_relationships_load();
283                 // TODO: expensive and needs to be removed and done better elsewhere
284
285                 if(!empty($fill_additional_fields[$aItem->object_name])
286                    || ($aItem->object_name == 'Case' && !empty($fill_additional_fields['aCase']))
287                    )
288                 {
289                         $aItem->fill_in_additional_list_fields();
290                         //$aItem->fill_in_additional_detail_fields();
291                 }
292                 //rrs bug: 25343
293                 $aItem->call_custom_logic("process_record");
294
295                 if(isset($parent_data[$aItem->id])) {
296
297                         $aItem->parent_name = $parent_data[$aItem->id]['parent_name'];
298                         if(!empty($parent_data[$aItem->id]['parent_name_owner'])) {
299                         $aItem->parent_name_owner =  $parent_data[$aItem->id]['parent_name_owner'];
300                         $aItem->parent_name_mod =  $parent_data[$aItem->id]['parent_name_mod'];
301                 }}
302
303                 $fields = $aItem->get_list_view_data();
304                 if(isset($processed_ids[$aItem->id])) {
305                         continue;
306
307                 } else {
308                         $processed_ids[$aItem->id] = 1;
309                 }
310
311
312                 //ADD OFFSET TO ARRAY
313                 $fields['OFFSET'] = ($offset + $count + 1);
314
315                 if($this->shouldProcess) {
316                         if($aItem->ACLAccess('EditView')) {
317                         $this->xTemplate->assign('PREROW', "<input type='checkbox' class='checkbox' name='mass[]' value='". $fields['ID']. "' />");
318                         } else {
319                                 $this->xTemplate->assign('PREROW', '');
320
321                         }
322                         if($aItem->ACLAccess('DetailView')) {
323                                 $this->xTemplate->assign('TAG_NAME','a');
324                         } else {
325                                 $this->xTemplate->assign('TAG_NAME','span');
326                         }
327                         $this->xTemplate->assign('CHECKALL', "<input type='checkbox' class='checkbox' name='massall' id='massall' value='' onclick='sListView.check_all(document.MassUpdate, \"mass[]\", this.checked);' />");
328                 }
329
330                 if($oddRow)
331                 {
332                         $ROW_COLOR = 'oddListRow';
333                         $BG_COLOR =  $odd_bg;
334                 }
335                 else
336                 {
337                         $ROW_COLOR = 'evenListRow';
338                         $BG_COLOR =  $even_bg;
339                 }
340                 $oddRow = !$oddRow;
341
342                 $this->xTemplate->assign("ROW_COLOR", $ROW_COLOR);
343                 $this->xTemplate->assign("BG_COLOR", $BG_COLOR);
344                 $layout_manager = $this->getLayoutManager();
345                 $layout_manager->setAttribute('context','List');
346                 $layout_manager->setAttribute('image_path',$this->local_image_path);
347                 $layout_manager->setAttribute('module_name', $subpanel_def->_instance_properties['module']);
348                 if(!empty($this->child_focus))
349                         $layout_manager->setAttribute('related_module_name',$this->child_focus->module_dir);
350
351                 //AG$subpanel_data = $this->list_field_defs;
352                 //$bla = array_pop($subpanel_data);
353                 //select which sub-panel to display here, the decision will be made based on the type of
354                 //the sub-panel and panel in the bean being processed.
355                 if($subpanel_def->isCollection()) {
356                         $thepanel=$subpanel_def->sub_subpanels[$aItem->panel_name];
357                 } else {
358                         $thepanel=$subpanel_def;
359                 }
360                 //get data source name
361                 $linked_field=$thepanel->get_data_source_name();
362                 $linked_field_set=$thepanel->get_data_source_name(true);
363                 foreach($thepanel->get_list_fields() as $field_name=>$list_field)
364                 {
365                         //add linked field attribute to the array.
366                         $list_field['linked_field']=$linked_field;
367                         $list_field['linked_field_set']=$linked_field_set;
368
369                         $usage = empty($list_field['usage']) ? '' : $list_field['usage'];
370                         if($usage != 'query_only')
371                         {
372                                 $list_field['name']=$field_name;
373
374                                 $module_field = $field_name.'_mod';
375                                 $owner_field = $field_name.'_owner';
376                                 if(!empty($aItem->$module_field)) {
377
378                                         $list_field['owner_id'] = $aItem->$owner_field;
379                                         $list_field['owner_module'] = $aItem->$module_field;
380
381                                 } else {
382                                         $list_field['owner_id'] = false;
383                                         $list_field['owner_module'] = false;
384                                 }
385                                 if(isset($list_field['alias'])) $list_field['name'] = $list_field['alias'];
386                                 else $list_field['name']=$field_name;
387                                 $list_field['fields'] = $fields;
388                                 $list_field['module'] = $aItem->module_dir;
389                                 $list_field['start_link_wrapper'] = $this->start_link_wrapper;
390                                 $list_field['end_link_wrapper'] = $this->end_link_wrapper;
391                                 $list_field['subpanel_id'] = $this->subpanel_id;
392                                 $list_field['DetailView'] = $aItem->ACLAccess('DetailView');
393                                 $list_field['ListView'] = $aItem->ACLAccess('ListView');
394                                 $list_field['EditView'] = $aItem->ACLAccess('EditView');
395                                 $list_field['Delete'] = $aItem->ACLAccess('Delete');
396                 if ( isset($aItem->field_defs[strtolower($list_field['name'])])) {
397                         require_once('include/SugarFields/SugarFieldHandler.php');
398                     // We need to see if a sugar field exists for this field type first,
399                     // if it doesn't, toss it at the old sugarWidgets. This is for
400                     // backwards compatibilty and will be removed in a future release
401                     $vardef = $aItem->field_defs[strtolower($list_field['name'])];
402                     if ( isset($vardef['type']) ) {
403                         $fieldType = isset($vardef['custom_type'])?$vardef['custom_type']:$vardef['type'];
404                         $tmpField = SugarFieldHandler::getSugarField($fieldType,true);
405                     } else {
406                         $tmpField = NULL;
407                     }
408
409                     if ( $tmpField != NULL ) {
410                         $widget_contents = SugarFieldHandler::displaySmarty($list_field['fields'],$vardef,'ListView',$list_field);
411                     } else {
412                         // No SugarField for this particular type
413                         // Use the old, icky, SugarWidget for now
414                         $widget_contents = $layout_manager->widgetDisplay($list_field);
415                     }
416
417                     if ( isset($list_field['widget_class']) && $list_field['widget_class'] == 'SubPanelDetailViewLink' ) {
418                         // We need to call into the old SugarWidgets for the time being, so it can generate a proper link with all the various corner-cases handled
419                         // So we'll populate the field data with the pre-rendered display for the field
420                         $list_field['fields'][$field_name] = $widget_contents;
421                         if('full_name' == $field_name){//bug #32465
422                            $list_field['fields'][strtoupper($field_name)] = $widget_contents;
423                         }
424                         $widget_contents = $layout_manager->widgetDisplay($list_field);
425                     } else if(isset($list_field['widget_class']) && $list_field['widget_class'] == 'SubPanelEmailLink' ) {
426                         $widget_contents = $layout_manager->widgetDisplay($list_field);
427                     }
428                 } else {
429                     // This handles the edit and remove buttons
430                                 $widget_contents = $layout_manager->widgetDisplay($list_field);
431                 }
432                                 static $count;
433                                 if(!isset($count))$count = 0; else $count++;
434                 $this->xTemplate->assign('CELL_COUNT', $count);
435                 if ( empty($widget_contents) ) $widget_contents = '&nbsp;';
436                                 $this->xTemplate->assign('CELL', $widget_contents);
437                                 $this->xTemplate->parse($xtemplateSection.".row.cell");
438                         }
439                 }
440
441                 $aItem->setupCustomFields($aItem->module_dir);
442                 $aItem->custom_fields->populateAllXTPL($this->xTemplate, 'detail', $html_varName, $fields);
443
444                 $count++;
445
446                 $this->xTemplate->parse($xtemplateSection.".row");
447         }
448
449         $this->xTemplate->parse($xtemplateSection);
450 }
451
452 /**sets whether or not to display the xtemplate header and footer
453  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
454  * All Rights Reserved.
455  * Contributor(s): ______________________________________.
456 */
457 function setDisplayHeaderAndFooter($bool) {
458                 $this->display_header_and_footer = $bool;
459 }
460
461 /**initializes ListView
462  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
463  * All Rights Reserved.
464  * Contributor(s): ______________________________________.
465 */
466  function ListView() {
467
468
469         if(!$this->initialized) {
470                 global $sugar_config;
471                 $this->records_per_page = $sugar_config['list_max_entries_per_page'] + 0;
472                 $this->initialized = true;
473                 global $app_strings, $currentModule;
474                 $this->local_theme = SugarThemeRegistry::current()->__toString();
475                 $this->local_app_strings =$app_strings;
476                 $this->local_image_path = SugarThemeRegistry::current()->getImagePath();
477                 $this->local_current_module = $currentModule;
478         }
479 }
480 /**sets how many records should be displayed per page in the list view
481  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
482  * All Rights Reserved.
483  * Contributor(s): ______________________________________.
484 */
485  function setRecordsPerPage($count) {
486         $this->records_per_page = $count;
487 }
488 /**sets the header title */
489  function setHeaderTitle($value) {
490         $this->header_title = $value;
491 }
492 /**sets the header text this is text thats appended to the header table and is usually used for the creation of buttons
493  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
494  * All Rights Reserved.
495  * Contributor(s): ______________________________________.
496 */
497  function setHeaderText($value) {
498         $this->header_text = $value;
499 }
500 /**sets the path for the XTemplate HTML file to be used this is only needed to be set if you are allowing ListView to create the XTemplate
501  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
502  * All Rights Reserved.
503  * Contributor(s): ______________________________________.
504 */
505  function setXTemplatePath($value) {
506         $this->xTemplatePath= $value;
507 }
508
509 /**this is a helper function for allowing ListView to create a new XTemplate it groups parameters that should be set into a single function
510  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
511  * All Rights Reserved.
512  * Contributor(s): ______________________________________.
513 */
514  function initNewXTemplate($XTemplatePath, $modString, $imagePath = null) {
515         $this->setXTemplatePath($XTemplatePath);
516         if(isset($modString))
517                 $this->setModStrings($modString);
518         if(isset($imagePath))
519                 $this->setImagePath($imagePath);
520 }
521
522
523 function getOrderBy($varName,$defaultOrderBy='', $force_sortorder='') {
524         $sortBy = $this->getSessionVariable($varName, "ORDER_BY") ;
525
526         if(empty($sortBy)) {
527                 $this->setUserVariable($varName, "ORDER_BY", $defaultOrderBy);
528                 $sortBy = $defaultOrderBy;
529         } else {
530                 $this->setUserVariable($varName, "ORDER_BY", $sortBy);
531         }
532         if($sortBy == 'amount') {
533                 $sortBy = 'amount*1';
534         }
535         if($sortBy == 'amount_usdollar') {
536                 $sortBy = 'amount_usdollar*1';
537         }
538
539         $desc = $this->getSessionVariable($varName, $sortBy."S");
540
541         if(empty($desc))
542                 $desc = false;
543         if(isset($_REQUEST[$this->getSessionVariableName($varName,  "ORDER_BY")]))
544                 $last = $this->getSessionVariable($varName, "OBL");
545                 if(!empty($last) && $last == $sortBy) {
546                         $desc = !$desc;
547                 }else {
548                         $this->setSessionVariable($varName, "OBL", $sortBy);
549                 }
550         $this->setSessionVariable($varName, $sortBy."S", $desc);
551         if(!empty($sortBy)) {
552                 if(empty($force_sortorder)) {
553                         if(substr_count(strtolower($sortBy), ' desc') == 0 && substr_count(strtolower($sortBy), ' asc') == 0) {
554                                 if($desc) {
555                                         $this->query_orderby = $sortBy.' desc';
556                                 } else {
557                                         $this->query_orderby = $sortBy.' asc';
558                                 }
559                         }
560
561                 } else {
562                         $this->query_orderby = $sortBy . ' ' . $force_sortorder;
563                 }
564         }else {
565                 $this->query_orderby = "";
566         }
567         $this->sortby = $sortBy;
568         return $this->query_orderby;
569
570 }
571
572
573 /**sets the parameters dealing with the db
574  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
575  * All Rights Reserved.
576  * Contributor(s): ______________________________________.
577 */
578  function setQuery($where, $limit, $orderBy, $varName, $allowOrderByOveride=true) {
579         $this->query_where = $where;
580         if($this->getSessionVariable("query", "where") != $where) {
581                 $this->query_where_has_changed = true;
582                 $this->setSessionVariable("query", "where", $where);
583         }
584
585         $this->query_limit = $limit;
586         if(!$allowOrderByOveride) {
587                 $this->query_orderby = $orderBy;
588                 return;
589         }
590         $this->getOrderBy($varName, $orderBy);
591
592     $this->setLocalSessionVariable($varName, "QUERY_WHERE", $where);
593
594         //SETTING ORDER_BY FOR USE IN DETAILVIEW
595     $this->setLocalSessionVariable($varName, "ORDER_BY_DETAIL", $this->query_orderby);
596 }
597
598 function displayArrow() {
599
600 }
601
602 /**sets the theme used only use if it is different from the global
603  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
604  * All Rights Reserved.
605  * Contributor(s): ______________________________________.
606 */
607  function setTheme($theme) {
608         $this->local_theme = $theme;
609         if(isset($this->xTemplate))$this->xTemplate->assign("THEME", $this->local_theme);
610 }
611
612 /**sets the AppStrings used only use if it is different from the global
613  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
614  * All Rights Reserved.
615  * Contributor(s): ______________________________________.
616 */
617  function setAppStrings($app_strings) {
618         unset($this->local_app_strings);
619         $this->local_app_strings = $app_strings;
620         if(isset($this->xTemplate))$this->xTemplate->assign("APP", $this->local_app_strings);
621 }
622
623 /**sets the ModStrings used
624  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
625  * All Rights Reserved.
626  * Contributor(s): ______________________________________.
627 */
628  function setModStrings($mod_strings) {
629         unset($this->local_module_strings);
630         $this->local_mod_strings = $mod_strings;
631         if(isset($this->xTemplate))$this->xTemplate->assign("MOD", $this->local_mod_strings);
632 }
633
634 /**sets the ImagePath used
635  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
636  * All Rights Reserved.
637  * Contributor(s): ______________________________________.
638 */
639  function setImagePath($image_path) {
640         $this->local_image_path = $image_path;
641         if(empty($this->local_image_path)) {
642                 $this->local_image_path = SugarThemeRegistry::get($this->local_theme)->getImagePath();
643         }
644         if(isset($this->xTemplate))$this->xTemplate->assign("IMAGE_PATH", $this->local_image_path);
645 }
646
647 /**sets the currentModule only use if this is different from the global
648  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
649  * All Rights Reserved.
650  * Contributor(s): ______________________________________.
651 */
652  function setCurrentModule($currentModule) {
653         unset($this->local_current_module);
654         $this->local_current_module = $currentModule;
655         if(isset($this->xTemplate))$this->xTemplate->assign("MODULE_NAME", $this->local_current_module);
656 }
657
658 /**INTERNAL FUNCTION creates an XTemplate DO NOT CALL THIS THIS IS AN INTERNAL FUNCTION
659  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
660  * All Rights Reserved.
661  * Contributor(s): ______________________________________.
662 */
663  function createXTemplate() {
664         if(!isset($this->xTemplate)) {
665                 if(isset($this->xTemplatePath)) {
666
667                         $this->xTemplate = new XTemplate($this->xTemplatePath);
668                         $this->xTemplate->assign("APP", $this->local_app_strings);
669                         if(isset($this->local_mod_strings))$this->xTemplate->assign("MOD", $this->local_mod_strings);
670                         $this->xTemplate->assign("THEME", $this->local_theme);
671                         $this->xTemplate->assign("IMAGE_PATH", $this->local_image_path);
672                         $this->xTemplate->assign("MODULE_NAME", $this->local_current_module);
673                 } else {
674                         $GLOBALS['log']->error("NO XTEMPLATEPATH DEFINED CANNOT CREATE XTEMPLATE");
675                 }
676         }
677 }
678
679 /**sets the XTemplate telling ListView to use newXTemplate as its current XTemplate
680  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
681  * All Rights Reserved.
682  * Contributor(s): ______________________________________.
683 */
684  function setXTemplate($newXTemplate) {
685         $this->xTemplate = $newXTemplate;
686 }
687
688 /**returns the XTemplate
689  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
690  * All Rights Reserved.
691  * Contributor(s): ______________________________________.
692 */
693  function getXTemplate() {
694         return $this->xTemplate;
695 }
696
697 /**assigns a name value pair to the XTemplate
698  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
699  * All Rights Reserved.
700  * Contributor(s): ______________________________________.
701 */
702  function xTemplateAssign($name, $value) {
703
704                 if(!isset($this->xTemplate)) {
705                         $this->createXTemplate();
706                 }
707                 $this->xTemplate->assign($name, $value);
708
709 }
710
711 /**INTERNAL FUNCTION returns the offset first checking the querey then checking the session if the where clause has changed from the last time it returns 0
712  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
713  * All Rights Reserved.
714  * Contributor(s): ______________________________________.
715 */
716  function getOffset($localVarName) {
717         if($this->query_where_has_changed || isset($GLOBALS['record_has_changed'])) {
718                 $this->setSessionVariable($localVarName,"offset", 0);
719         }
720         $offset = $this->getSessionVariable($localVarName,"offset");
721         if(isset($offset)) {
722                 return $offset;
723         }
724         return 0;
725 }
726
727 /**INTERNAL FUNCTION sets the offset in the session
728  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
729  * All Rights Reserved.
730  * Contributor(s): ______________________________________.
731 */
732  function setOffset($localVarName, $value) {
733                 $this->setSessionVariable($localVarName, "offset", $value);
734 }
735
736 /**INTERNAL FUNCTION sets a session variable
737  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
738  * All Rights Reserved.
739  * Contributor(s): ______________________________________.
740 */
741  function setSessionVariable($localVarName,$varName, $value) {
742         $_SESSION[$this->local_current_module."_".$localVarName."_".$varName] = $value;         
743 }
744
745 function setUserVariable($localVarName,$varName, $value) {
746                 if($this->is_dynamic ||  $localVarName == 'CELL')return;
747                 global $current_user;
748                 $current_user->setPreference($this->local_current_module."_".$localVarName."_".$varName, $value);
749 }
750
751 /**INTERNAL FUNCTION returns a session variable first checking the querey for it then checking the session
752  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
753  * All Rights Reserved.
754  * Contributor(s): ______________________________________.
755 */
756  function getSessionVariable($localVarName,$varName) {
757         //Set any variables pass in through request first
758         if(isset($_REQUEST[$this->getSessionVariableName($localVarName, $varName)])) {
759                 $this->setSessionVariable($localVarName,$varName,$_REQUEST[$this->getSessionVariableName($localVarName, $varName)]);
760         }
761                 
762         if(isset($_SESSION[$this->getSessionVariableName($localVarName, $varName)])) {
763                 return $_SESSION[$this->getSessionVariableName($localVarName, $varName)];
764          }
765          return "";
766 }
767
768 function getUserVariable($localVarName, $varName) {
769         global $current_user;
770         if($this->is_dynamic ||  $localVarName == 'CELL')return;
771         if(isset($_REQUEST[$this->getSessionVariableName($localVarName, $varName)])) {
772
773                         $this->setUserVariable($localVarName,$varName,$_REQUEST[$this->getSessionVariableName($localVarName, $varName)]);
774         }
775         return $current_user->getPreference($this->getSessionVariableName($localVarName, $varName));
776 }
777
778
779
780
781
782         /**
783
784          * @return void
785          * @param unknown $localVarName
786          * @param unknown $varName
787          * @desc INTERNAL FUNCTION returns the session/query variable name
788          * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
789          * All Rights Reserved.
790          * Contributor(s): ______________________________________..
791          */
792         function getSessionVariableName($localVarName,$varName) {
793             return $this->local_current_module."_".$localVarName."_".$varName;
794         }
795
796         /**
797
798          * @return void
799          * @param unknown $seed
800          * @param unknown $xTemplateSection
801          * @param unknown $html_varName
802          * @desc INTERNAL FUNCTION Handles List Views using seeds that extend SugarBean
803                 $XTemplateSection is the section in the XTemplate file that should be parsed usually main
804                 $html_VarName is the variable name used in the XTemplateFile e.g. TASK
805                 $seed is a seed that extends SugarBean
806                  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
807                  * All Rights Reserved..
808                  * Contributor(s): ______________________________________..
809          */
810         function processSugarBean($xtemplateSection, $html_varName, $seed) {
811                 global $list_view_row_count;
812
813                 $current_offset = $this->getOffset($html_varName);
814                 $response = array();
815
816                 //ADDING VCR CONTROL
817                 SugarVCR::erase($seed->module_dir);
818                 $params = array();
819                 //$filter = array('id', 'full_name');
820                 $filter=array();
821                 $ret_array = $seed->create_new_list_query($this->query_orderby, $this->query_where, $filter, $params, 0, '', true, $seed, true);
822         if(!is_array($params)) $params = array();
823         if(!isset($params['custom_select'])) $params['custom_select'] = '';
824         if(!isset($params['custom_from'])) $params['custom_from'] = '';
825         if(!isset($params['custom_where'])) $params['custom_where'] = '';
826         if(!isset($params['custom_order_by'])) $params['custom_order_by'] = '';
827                 $main_query = $ret_array['select'] . $params['custom_select'] . $ret_array['from'] . $params['custom_from'] . $ret_array['where'] . $params['custom_where'] . $ret_array['order_by'] . $params['custom_order_by'];
828                  SugarVCR::store($seed->module_dir,  $main_query);
829                 //ADDING VCR CONTROL
830
831                 if(empty($this->related_field_name)) {
832                         $response = $seed->get_list($this->query_orderby, $this->query_where, $current_offset, $this->query_limit);
833                 } else {
834                         $related_field_name = $this->related_field_name;
835                         $response = $seed->get_related_list($this->child_focus,$related_field_name, $this->query_orderby,
836                         $this->query_where, $current_offset, $this->query_limit);
837                 }
838
839                 $list = $response['list'];
840                 $row_count = $response['row_count'];
841                 $next_offset = $response['next_offset'];
842                 $previous_offset = $response['previous_offset'];
843
844                 if(!empty($response['current_offset'])) {
845                         $current_offset = $response['current_offset'];
846                 }
847
848                 $list_view_row_count = $row_count;
849                 $this->processListNavigation($xtemplateSection,$html_varName, $current_offset, $next_offset, $previous_offset, $row_count, null, null, empty($seed->list_fields) ? null : count($seed->list_fields));
850
851                 return $list;
852         }
853
854         function processUnionBeans($sugarbean, $subpanel_def, $html_var = 'CELL') {
855
856                 $last_detailview_record = $this->getSessionVariable("detailview", "record");
857                 if(!empty($last_detailview_record) && $last_detailview_record != $sugarbean->id){
858                         $GLOBALS['record_has_changed'] = true;
859                 }
860                 $this->setSessionVariable("detailview", "record", $sugarbean->id);
861                 
862                 $current_offset = $this->getOffset($html_var);
863                 $module = isset($_REQUEST['module']) ? $_REQUEST['module'] : '';
864                 $response = array();
865
866                 $this->sort_order = 'asc';
867                 if(isset($_REQUEST['sort_order'])) {
868                         $this->sort_order = $_REQUEST['sort_order'];
869                 } else {
870                         if(isset($subpanel_def->_instance_properties['sort_order'])) {
871                             $sort_order = $subpanel_def->_instance_properties['sort_order'];
872                         }
873                         
874                         if(isset($_SESSION['last_sub' .$this->subpanel_module. '_order'])) {
875                                 // We swap the order when the request contains an offset (indicating a column sort issued);
876                                 // otherwise we do not sort.  If we don't make this check, then the subpanel listview will
877                                 // swap ordering each time a new record is entered via quick create forms
878                                 
879                                 if(isset($_REQUEST[$module. '_' . $html_var . '_offset'])) {
880                                         $this->sort_order = $_SESSION['last_sub' .$this->subpanel_module. '_order'] == 'asc' ? 'desc' : 'asc';
881                                 } else {
882                                   $this->sort_order = $_SESSION['last_sub' .$this->subpanel_module. '_order'];
883                                 }
884                         }
885                         elseif(isset($sort_order)) {
886                                 $this->sort_order = $sort_order;
887                         }
888                 }
889
890
891                 if(isset($subpanel_def->_instance_properties['sort_by'])) 
892                         $this->query_orderby = $subpanel_def->_instance_properties['sort_by'];
893         else 
894                 $this->query_orderby = 'id';
895                 
896         $this->getOrderBy($html_var,$this->query_orderby, $this->sort_order);
897
898                 $_SESSION['last_sub' .$this->subpanel_module. '_order'] = $this->sort_order;
899                 $_SESSION['last_sub' .$this->subpanel_module. '_url'] = $this->getBaseURL($html_var);
900
901                 
902                 if(!empty($this->response)){
903                         $response =& $this->response;
904                         echo 'cached';
905                 }else{
906                         $response = SugarBean::get_union_related_list($sugarbean,$this->sortby, $this->sort_order, $this->query_where, $current_offset, -1,-1,$this->query_limit,$subpanel_def);
907                         $this->response =& $response;
908                 }
909                 $list = $response['list'];
910                 $row_count = $response['row_count'];
911                 $next_offset = $response['next_offset'];
912                 $previous_offset = $response['previous_offset'];
913                 if(!empty($response['current_offset']))$current_offset = $response['current_offset'];
914                 global $list_view_row_count;
915                 $list_view_row_count = $row_count;
916                 $this->processListNavigation('dyn_list_view', $html_var, $current_offset, $next_offset, $previous_offset, $row_count, $sugarbean,$subpanel_def);
917
918                 return array('list'=>$list, 'parent_data'=>$response['parent_data'], 'query'=>$response['query']);
919         }
920
921         function getBaseURL($html_varName) {
922                 static $cache = array();
923
924                 if(!empty($cache[$html_varName]))return $cache[$html_varName];
925                 $blockVariables = array('mass', 'uid', 'massupdate', 'delete', 'merge', 'selectCount','current_query_by_page');
926                 if(!empty($this->base_URL)) {
927                         return $this->base_URL;
928                 }
929
930                         $baseurl = $_SERVER['PHP_SELF'];
931                         if(empty($baseurl)) {
932                                 $baseurl = 'index.php';
933                         }
934
935                         /*fixes an issue with deletes when doing a search*/
936                         foreach(array_merge($_GET, $_POST) as $name=>$value) {
937                                 //echo ("$name = $value <br/>");
938                                 if(!empty($value) && $name != 'sort_order' //&& $name != ListView::getSessionVariableName($html_varName,"ORDER_BY") 
939                                                 && $name != ListView::getSessionVariableName($html_varName,"offset") 
940                                                 /*&& substr_count($name, "ORDER_BY")==0*/ && !in_array($name, $blockVariables)) 
941                                 {
942                                         if(is_array($value)) {
943                                                 foreach($value as $valuename=>$valuevalue) {
944                                                         if(substr_count($baseurl, '?') > 0)
945                                                                 $baseurl        .= "&{$name}[]=".$valuevalue;
946                                                         else
947                                                                 $baseurl        .= "?{$name}[]=".$valuevalue;
948                                                 }
949                                         } else {
950                                                 $value = urlencode($value);
951                                                 if(substr_count($baseurl, '?') > 0) {
952                                                         $baseurl        .= "&$name=$value";
953                                                 } else {
954                                                         $baseurl        .= "?$name=$value";
955                                                 }
956                                         }
957                                 }
958                         }
959
960
961                         if($_SERVER['REQUEST_METHOD'] == 'POST') {
962                                 // at this point it is possible that the above foreach already executed resulting in double ?'s in the url
963                                 if(substr_count($baseurl, '?') == 0) {
964                                         $baseurl .= '?';
965                                 }
966                                 if(isset($_REQUEST['action'])) $baseurl.= '&action='.$_REQUEST['action'];
967                                 if(isset($_REQUEST['record'])) $baseurl .= '&record='.$_REQUEST['record'];
968                                 if(isset($_REQUEST['module'])) $baseurl .= '&module='.$_REQUEST['module'];
969                         }
970
971                         $baseurl .= "&".ListView::getSessionVariableName($html_varName,"offset")."=";
972                         $cache[$html_varName] = $baseurl;
973                         return $baseurl;
974         }
975         /**
976          * @return void
977          * @param unknown $data
978          * @param unknown $xTemplateSection
979          * @param unknown $html_varName
980          * @desc INTERNAL FUNCTION process the List Navigation
981          * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
982          * All Rights Reserved.
983          * Contributor(s): ______________________________________..
984          */
985          function processListNavigation($xtemplateSection, $html_varName, $current_offset, $next_offset, $previous_offset, $row_count, $sugarbean=null, $subpanel_def=null, $col_count = 20) {
986
987                 global $export_module;
988                 global $sugar_config;
989                 global $current_user;
990                 global $currentModule;
991
992                 $start_record = $current_offset + 1;
993
994         if(!is_numeric($col_count))
995             $col_count = 20;
996
997                 if($row_count == 0)
998                         $start_record = 0;
999
1000                 $end_record = $start_record + $this->records_per_page;
1001                 // back up the the last page.
1002                 if($end_record > $row_count+1) {
1003                         $end_record = $row_count+1;
1004                 }
1005                 // Deterime the start location of the last page
1006                 if($row_count == 0)
1007                         $number_pages = 0;
1008                 else
1009                         $number_pages = floor(($row_count - 1) / $this->records_per_page);
1010
1011                 $last_offset = $number_pages * $this->records_per_page;
1012
1013                 if(empty($this->query_limit)  || $this->query_limit > $this->records_per_page) {
1014                         $this->base_URL = $this->getBaseURL($html_varName);
1015                         $dynamic_url = '';
1016
1017                         if($this->is_dynamic) {
1018                                 $dynamic_url .='&'. $this->getSessionVariableName($html_varName,'ORDER_BY') . '='. $this->getSessionVariable($html_varName,'ORDER_BY').'&sort_order='.$this->sort_order.'&to_pdf=true&action=SubPanelViewer&subpanel=' . $this->subpanel_module;
1019                         }
1020
1021                         $current_URL = $this->base_URL.$current_offset.$dynamic_url;
1022                         $start_URL = $this->base_URL."0".$dynamic_url;
1023                         $previous_URL  = $this->base_URL.$previous_offset.$dynamic_url;
1024                         $next_URL  = $this->base_URL.$next_offset.$dynamic_url;
1025                         $end_URL  = $this->base_URL.'end'.$dynamic_url;
1026
1027                         if(!empty($this->start_link_wrapper)) {
1028                                 $current_URL = $this->start_link_wrapper.$current_URL.$this->end_link_wrapper;
1029                                 $start_URL = $this->start_link_wrapper.$start_URL.$this->end_link_wrapper;
1030                                 $previous_URL = $this->start_link_wrapper.$previous_URL.$this->end_link_wrapper;
1031                                 $next_URL = $this->start_link_wrapper.$next_URL.$this->end_link_wrapper;
1032                                 $end_URL = $this->start_link_wrapper.$end_URL.$this->end_link_wrapper;
1033                         }
1034
1035                         $moduleString = "{$currentModule}_{$html_varName}_offset";
1036                         $moduleStringOrder = "{$currentModule}_{$html_varName}_ORDER_BY";
1037                         if($this->shouldProcess && !$this->multi_select_popup) {
1038                                 // check the checkboxes onload
1039                                 echo "<script>YAHOO.util.Event.addListener(window, \"load\", sListView.check_boxes);</script>\n";
1040
1041                                 $massUpdateRun = isset($_REQUEST['massupdate']) && $_REQUEST['massupdate'] == 'true';
1042                                 $uids = empty($_REQUEST['uid']) || $massUpdateRun ? '' : $_REQUEST['uid'];
1043                                 $select_entire_list = isset($_REQUEST['select_entire_list']) && !$massUpdateRun ? $_REQUEST['select_entire_list'] : 0;
1044
1045                                 echo "<textarea style='display: none' name='uid'>{$uids}</textarea>\n" .
1046                                          "<input type='hidden' name='select_entire_list' value='{$select_entire_list}'>\n".
1047                                          "<input type='hidden' name='{$moduleString}' value='0'>\n".
1048                                          "<input type='hidden' name='{$moduleStringOrder}' value='0'>\n";
1049
1050                         }
1051
1052
1053                         $GLOBALS['log']->debug("Offsets: (start, previous, next, last)(0, $previous_offset, $next_offset, $last_offset)");
1054
1055                         if(0 == $current_offset) {
1056                                 $start_link = "<button type='button' name='listViewStartButton' title='{$this->local_app_strings['LNK_LIST_START']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("start_off","alt='".$this->local_app_strings['LNK_LIST_START']."'  border='0' align='absmiddle'")."</button>";
1057                                 $previous_link = "<button type='button' name='listViewPrevButton' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("previous_off","alt='".$this->local_app_strings['LNK_LIST_PREVIOUS']."'  border='0' align='absmiddle'")."</button>";
1058                         } else {
1059                                 if($this->multi_select_popup) {// nav links for multiselect popup, submit form to save checks.
1060                                         $start_link = "<button type='button' class='button' name='listViewStartButton' title='{$this->local_app_strings['LNK_LIST_START']}' onClick='javascript:save_checks(0, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("start","alt='".$this->local_app_strings['LNK_LIST_START']."'  border='0' align='absmiddle'")."</button>";
1061                                         $previous_link = "<button type='button' class='button' name='listViewPrevButton' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' onClick='javascript:save_checks($previous_offset, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("previous","alt='".$this->local_app_strings['LNK_LIST_PREVIOUS']."'  border='0' align='absmiddle'")."</button>";
1062                                 } elseif($this->shouldProcess) {
1063                                         $start_link = "<button type='button' class='button' name='listViewStartButton' title='{$this->local_app_strings['LNK_LIST_START']}' onClick='location.href=\"$start_URL\"; sListView.save_checks(0, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("start","alt='".$this->local_app_strings['LNK_LIST_START']."'  border='0' align='absmiddle'")."</button>";
1064                                         $previous_link = "<button type='button' class='button' name='listViewPrevButton' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' onClick='location.href=\"$previous_URL\"; sListView.save_checks($previous_offset, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("previous","alt='".$this->local_app_strings['LNK_LIST_PREVIOUS']."'  border='0' align='absmiddle'")."</button>";
1065                                 } else {
1066                                         $onClick = '';
1067                                         if(0 != preg_match('/javascript.*/', $start_URL)){
1068                                                 $onClick = "\"$start_URL;\"";
1069                                         }else{
1070                                                 $onClick ="'location.href=\"$start_URL\";'";
1071                                         }
1072                                         $start_link = "<button type='button' class='button' name='listViewStartButton' title='{$this->local_app_strings['LNK_LIST_START']}' onClick=".$onClick.">".SugarThemeRegistry::current()->getImage("start","alt='".$this->local_app_strings['LNK_LIST_START']."'  border='0' align='absmiddle'")."</button>";
1073
1074                                         $onClick = '';
1075                                         if(0 != preg_match('/javascript.*/', $previous_URL)){
1076                                                 $onClick = "\"$previous_URL;\"";
1077                                         }else{
1078                                                 $onClick = "'location.href=\"$previous_URL\";'";
1079                                         }
1080                                         $previous_link = "<button type='button' class='button' name='listViewPrevButton' title='{$this->local_app_strings['LNK_LIST_PREVIOUS']}' onClick=".$onClick.">".SugarThemeRegistry::current()->getImage("previous","alt='".$this->local_app_strings['LNK_LIST_PREVIOUS']."'  border='0' align='absmiddle'")."</button>";
1081                                 }
1082                         }
1083
1084                         if($last_offset <= $current_offset) {
1085                                 $end_link = "<button type='button' name='listViewEndButton' title='{$this->local_app_strings['LNK_LIST_END']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("end_off","alt='".$this->local_app_strings['LNK_LIST_END']."'  border='0' align='absmiddle'")."</button>";
1086                                 $next_link = "<button type='button' name='listViewNextButton' title='{$this->local_app_strings['LNK_LIST_NEXT']}' class='button' disabled>".SugarThemeRegistry::current()->getImage("next_off","alt='".$this->local_app_strings['LNK_LIST_NEXT']."'  border='0' align='absmiddle'")."</button>";
1087                         } else {
1088                                 if($this->multi_select_popup) { // nav links for multiselect popup, submit form to save checks.
1089                                         $end_link = "<button type='button' name='listViewEndButton' class='button' title='{$this->local_app_strings['LNK_LIST_END']}' onClick='javascript:save_checks($last_offset, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("end","alt='".$this->local_app_strings['LNK_LIST_END']."'  border='0' align='absmiddle'")."</button>";
1090                                         if(!empty($sugar_config['disable_count_query'])) {
1091                                                 $end_link = '';
1092                                         }
1093                                         $next_link = "<button type='button' name='listViewNextButton' title='{$this->local_app_strings['LNK_LIST_NEXT']}' class='button' onClick='javascript:save_checks($next_offset, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("next","alt='".$this->local_app_strings['LNK_LIST_NEXT']."'  border='0' align='absmiddle'")."</button>";
1094                                 } elseif($this->shouldProcess) {
1095                                         $end_link = "<button type='button' name='listViewEndButton' class='button' title='{$this->local_app_strings['LNK_LIST_END']}' onClick='location.href=\"$end_URL\"; sListView.save_checks(\"end\", \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("end","alt='".$this->local_app_strings['LNK_LIST_END']."'  border='0' align='absmiddle'")."</button>";
1096                                         $next_link = "<button type='button' name='listViewNextButton' class='button' title='{$this->local_app_strings['LNK_LIST_NEXT']}' onClick='location.href=\"$next_URL\"; sListView.save_checks($next_offset, \"{$moduleString}\");'>".SugarThemeRegistry::current()->getImage("next","alt='".$this->local_app_strings['LNK_LIST_NEXT']."'  border='0' align='absmiddle'")."</button>";
1097                                 } else {
1098                                         $onClick = '';
1099                                         if(0 != preg_match('/javascript.*/', $next_URL)){
1100                                                 $onClick = "\"$next_URL;\"";
1101                                         }else{
1102                                                 $onClick ="'location.href=\"$next_URL\";'";
1103                                         }
1104                                         $next_link = "<button type='button' name='listViewNextButton' class='button' title='{$this->local_app_strings['LNK_LIST_NEXT']}' onClick=".$onClick.">".SugarThemeRegistry::current()->getImage("next","alt='".$this->local_app_strings['LNK_LIST_NEXT']."'  border='0' align='absmiddle'")."</button>";
1105
1106                                         $onClick = '';
1107                                         if(0 != preg_match('/javascript.*/', $end_URL)){
1108                                                 $onClick = "\"$end_URL;\"";
1109                                         }else{
1110                                                 $onClick = "'location.href=\"$end_URL\";'";
1111                                         }
1112                                         $end_link = "<button type='button' name='listViewEndButton' class='button' title='{$this->local_app_strings['LNK_LIST_END']}' onClick=".$onClick.">".SugarThemeRegistry::current()->getImage("end","alt='".$this->local_app_strings['LNK_LIST_END']."'  border='0' align='absmiddle'")."</button>";
1113
1114                                 }
1115                         }
1116
1117                         $GLOBALS['log']->info("Offset (next, current, prev)($next_offset, $current_offset, $previous_offset)");
1118                         $GLOBALS['log']->info("Start/end records ($start_record, $end_record)");
1119
1120                         $end_record = $end_record-1;
1121
1122                         echo "<script>
1123                                 function select_overlib() {
1124                                         return overlib('<a style=\'width: 150px\' 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, $this->records_per_page)}else {sListView.check_all(document.MassUpdate, \"mass[]\", true)};\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_CURRENT']}&nbsp;({$this->records_per_page})</a>"
1125                                 . "<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'sListView.check_entire_list(document.MassUpdate, \"mass[]\",true,{$row_count});\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_ENTIRE']}&nbsp;({$row_count})</a>"
1126                                 . "<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'sListView.clear_all(document.MassUpdate, \"mass[]\", false);\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_NONE']}</a>"
1127                                 . "', CENTER, '"
1128                                 . "', STICKY, MOUSEOFF, 3000, CLOSETEXT, '<img border=0 src=" . SugarThemeRegistry::current()->getImageURL('close_inline.gif')
1129                                 . ">', WIDTH, 150, CLOSETITLE, '" . $this->local_app_strings['LBL_ADDITIONAL_DETAILS_CLOSE_TITLE'] . "', CLOSECLICK, FGCLASS, 'olOptionsFgClass', "
1130                                 . "CGCLASS, 'olOptionsCgClass', BGCLASS, 'olBgClass', TEXTFONTCLASS, 'olFontClass', CAPTIONFONTCLASS, 'olOptionsCapFontClass', CLOSEFONTCLASS, 'olOptionsCloseFontClass');
1131                                 }
1132                                 </script>";
1133
1134                         if($this->show_select_menu) {
1135                                 $select_link = "<a id='select_link' onclick='return select_overlib();' href=\"#\">".$this->local_app_strings['LBL_LINK_SELECT']."&nbsp;<img src='".SugarThemeRegistry::current()->getImageURL('MoreDetail.png')."' width='11' height='7' border='0''>"."</a>";
1136                         } else {
1137                                 $select_link = "&nbsp;";
1138                         }
1139
1140                         // put overlib strings into functions to avoid backslash plague!
1141                         /*echo "<script>
1142                                 function export_overlib() {
1143                                         return overlib('<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'return sListView.send_form(true, \"{$_REQUEST['module']}\", \"export.php\", \"{$this->local_app_strings['LBL_LISTVIEW_NO_SELECTED']}\")\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_SELECTED']}</a>"
1144                                 . "<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'return sListView.send_form(false, \"{$_REQUEST['module']}\", \"export.php\", \"{$this->local_app_strings['LBL_LISTVIEW_NO_SELECTED']}\")\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_CURRENT']}</a>"
1145                                 . "<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' href=\'export.php?module={$_REQUEST['module']}\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_ENTIRE']}</a>"
1146                                 . "', CAPTION, '" . $this->local_app_strings['LBL_EXPORT']
1147                                 . "', STICKY, MOUSEOFF, 3000, CLOSETEXT, '<img border=0 style=\'margin-left:2px; margin-right: 2px;\' src=" . $this->local_image_path
1148                                 . "close.gif>', WIDTH, 150, CLOSETITLE, '" . $this->local_app_strings['LBL_ADDITIONAL_DETAILS_CLOSE_TITLE'] . "', CLOSECLICK, FGCLASS, 'olOptionsFgClass', "
1149                                 . "CGCLASS, 'olOptionsCgClass', BGCLASS, 'olBgClass', TEXTFONTCLASS, 'olFontClass', CAPTIONFONTCLASS, 'olOptionsCapFontClass', CLOSEFONTCLASS, 'olOptionsCloseFontClass');
1150                                 }
1151                                 </script>";
1152         */
1153                         //$export_link = "<a id='export_link' onclick='return export_overlib();' href=\"#\">".SugarThemeRegistry::current()->getImage("export","alt='".$this->local_app_strings['LBL_EXPORT']."'  border='0' align='absmiddle'")."&nbsp;".$this->local_app_strings['LBL_EXPORT']."</a>";
1154                         $export_link = '<input class="button" type="button" value="'.$this->local_app_strings['LBL_EXPORT'].'" ' .
1155                                         'onclick="return sListView.send_form(true, \''.$_REQUEST['module'].'\', \'index.php?entryPoint=export\',\''.$this->local_app_strings['LBL_LISTVIEW_NO_SELECTED'].'\')">';
1156
1157                     if($this->show_delete_button) {
1158                                 $delete_link = '<input class="button" type="button" name="Delete" value="'.$this->local_app_strings['LBL_DELETE_BUTTON_LABEL'].'" onclick="return sListView.send_mass_update(\'selected\',\''.$this->local_app_strings['LBL_LISTVIEW_NO_SELECTED'].'\', 1)">';
1159                     } else {
1160                         $delete_link = '&nbsp;';
1161                     }
1162
1163                     $admin = new Administration();
1164                         $admin->retrieveSettings('system');
1165
1166                         $user_merge = $current_user->getPreference('mailmerge_on');
1167                         if($user_merge == 'on' && isset($admin->settings['system_mailmerge_on']) && $admin->settings['system_mailmerge_on']) {
1168                                 echo "<script>
1169                                 function mailmerge_overlib() {
1170                                         return overlib('<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' onclick=\'return sListView.send_form(true, \"MailMerge\", \"index.php\", \"{$this->local_app_strings['LBL_LISTVIEW_NO_SELECTED']}\")\' href=\'#\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_SELECTED']}</a>"
1171                                                 . "<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' href=\'index.php?action=index&module=MailMerge\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_CURRENT']}</a>"
1172                                                 . "<a style=\'width: 150px\' class=\'menuItem\' onmouseover=\'hiliteItem(this,\"yes\");\' onmouseout=\'unhiliteItem(this);\' href=\'index.php?action=index&module=MailMerge&entire=true\'>{$this->local_app_strings['LBL_LISTVIEW_OPTION_ENTIRE']}</a>"
1173                                                 . "', CAPTION, '" . $this->local_app_strings['LBL_MAILMERGE']
1174                                                 . "', STICKY, MOUSEOFF, 3000, CLOSETEXT, '<img border=0 style=\'margin-left:2px; margin-right: 2px;\' src=" . $this->local_image_path
1175                                                 . "close.gif>', WIDTH, 150, CLOSETITLE, '" . $this->local_app_strings['LBL_ADDITIONAL_DETAILS_CLOSE_TITLE'] . "', CLOSECLICK, FGCLASS, 'olOptionsFgClass', "
1176                                                 . "CGCLASS, 'olOptionsCgClass', BGCLASS, 'olBgClass', TEXTFONTCLASS, 'olFontClass', CAPTIONFONTCLASS, 'olOptionsCapFontClass', CLOSEFONTCLASS, 'olCloseFontClass');
1177                                 }
1178                         </script>";
1179                                 $merge_link = "&nbsp;|&nbsp;<a id='mailmerge_link' onclick='return mailmerge_overlib()'; href=\"#\">".$this->local_app_strings['LBL_MAILMERGE']."</a>";
1180                         } else {
1181                                 $merge_link = "&nbsp;";
1182                         }
1183                         
1184                         $selected_objects_span = "&nbsp;|&nbsp;{$this->local_app_strings['LBL_LISTVIEW_SELECTED_OBJECTS']}<input  style='border: 0px; background: transparent; font-size: inherit; color: inherit' type='text' readonly name='selectCount[]' value='" . (!empty($select_entire_list) ? $row_count : 0) . "' />";
1185
1186                         if($_REQUEST['module'] == 'Home' || $this->local_current_module == 'Import'
1187                                 || $this->show_export_button == false
1188                                 || (!empty($sugar_config['disable_export']))
1189                                 || (!empty($sugar_config['admin_export_only'])
1190                                 && !(
1191                                          is_admin($current_user)
1192                                          || (ACLController::moduleSupportsACL($_REQUEST['module'])
1193                                              && ACLAction::getUserAccessLevel($current_user->id,$_REQUEST['module'], 'access') == ACL_ALLOW_ENABLED
1194                                              && (ACLAction::getUserAccessLevel($current_user->id, $_REQUEST['module'], 'admin') == ACL_ALLOW_ADMIN ||
1195                                                 ACLAction::getUserAccessLevel($current_user->id, $_REQUEST['module'], 'admin') == ACL_ALLOW_ADMIN_DEV)))))
1196                         {
1197                                 if ($_REQUEST['module'] != 'InboundEmail' && $_REQUEST['module'] != 'EmailMan' && $_REQUEST['module'] != 'iFrames') {
1198                                         $selected_objects_span = '';
1199                                 }
1200                                 $export_link = "&nbsp;";
1201                                 $merge_link = "&nbsp;";
1202                         } elseif($_REQUEST['module'] != "Accounts" && $_REQUEST['module'] != "Cases" && $_REQUEST['module'] != "Contacts" && $_REQUEST['module'] != "Leads" && $_REQUEST['module'] != "Opportunities") {
1203                                 $merge_link = "&nbsp;";
1204                         }
1205
1206                         if($this->show_paging == true) {
1207                                 if(!empty($sugar_config['disable_count_query'])) {
1208                                         if($row_count > $end_record) {
1209                                                 $row_count .= '+';
1210                                         }
1211                                 }
1212
1213                                 $html_text = '';
1214                                 $html_text .= "<tr class='pagination'>\n";
1215                                 $html_text .= "<td COLSPAN=\"$col_count\" align=\"right\">\n";
1216                                 //$html_text .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td align=\"left\"  >$export_link$merge_link$selected_objects_span</td>\n";
1217                                 //$html_text .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td align=\"left\"  >";
1218                                 if ($subpanel_def != null) {
1219                         include_once('include/SubPanel/SubPanelTiles.php');
1220                         $subpanelTiles = new SubPanelTiles($sugarbean);
1221                                         $html_text .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td align=\"left\"  >";
1222
1223                     //attempt to get the query to recreate this subpanel
1224                     if(!empty($this->response)){
1225                         $response =& $this->response;
1226                                         }else{
1227                                                 $response = SugarBean::get_union_related_list($sugarbean,$this->sortby, $this->sort_order, $this->query_where, $current_offset, -1,-1,$this->query_limit,$subpanel_def);
1228                                                 $this->response = $response;
1229                                         }
1230                     //if query is present, then pass it in as parameter
1231                     if (isset($response['query']) && !empty($response['query'])){
1232                         $html_text .= $subpanelTiles->get_buttons($subpanel_def, $response['query']);
1233                     }else{
1234                         $html_text .= $subpanelTiles->get_buttons($subpanel_def);
1235                     }
1236                                 }
1237                                 else {
1238                                         $html_text .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\"><tr><td align=\"left\"  nowrap>$select_link&nbsp;$export_link&nbsp;$delete_link&nbsp;$selected_objects_span";
1239                                 }
1240                                 $html_text .= "</td>\n<td nowrap align=\"right\">".$start_link."&nbsp;&nbsp;".$previous_link."&nbsp;&nbsp;<span class='pageNumbers'>(".$start_record." - ".$end_record." ".$this->local_app_strings['LBL_LIST_OF']." ".$row_count.")</span>&nbsp;&nbsp;".$next_link."&nbsp;&nbsp;".$end_link."</td></tr></table>\n";
1241                                 $html_text .= "</td>\n";
1242                                 $html_text .= "</tr>\n";
1243                                 $this->xTemplate->assign("PAGINATION",$html_text);
1244                         }
1245
1246                         //C.L. - Fix for 23461
1247                         if(empty($_REQUEST['action']) || $_REQUEST['action'] != 'Popup') {
1248                    $_SESSION['export_where'] = $this->query_where;
1249                         }
1250                         $this->xTemplate->parse($xtemplateSection.".list_nav_row");
1251                 }
1252         } // end processListNavigation
1253
1254         function processOrderBy($html_varName) {
1255
1256                 if(!isset($this->base_URL)) {
1257                         $this->base_URL = $_SERVER['PHP_SELF'];
1258
1259                         if(isset($_SERVER['QUERY_STRING'])) {
1260                                 $this->base_URL = preg_replace("/\&".$this->getSessionVariableName($html_varName,"ORDER_BY")."=[0-9a-zA-Z\_\.]*/","",$this->base_URL .'?'.$_SERVER['QUERY_STRING']);
1261                                 $this->base_URL = preg_replace("/\&".$this->getSessionVariableName($html_varName,"offset")."=[0-9]*/","",$this->base_URL);
1262                         }
1263                         if($_SERVER['REQUEST_METHOD'] == 'POST') {
1264                                 $this->base_URL .= '?';
1265                                 if(isset($_REQUEST['action'])) $this->base_URL .= '&action='.$_REQUEST['action'];
1266                                 if(isset($_REQUEST['record'])) $this->base_URL .= '&record='.$_REQUEST['record'];
1267                                 if(isset($_REQUEST['module'])) $this->base_URL .= '&module='.$_REQUEST['module'];
1268                         }
1269                         $this->base_URL .= "&".$this->getSessionVariableName($html_varName,"offset")."=";
1270                 }
1271
1272                 if($this->is_dynamic) {
1273                         $this->base_URL.='&to_pdf=true&action=SubPanelViewer&subpanel=' . $this->source_module;
1274                 }
1275
1276                 $sort_URL_base = $this->base_URL. "&".$this->getSessionVariableName($html_varName,"ORDER_BY")."=";
1277
1278                 if($sort_URL_base !== "")
1279                 {
1280                         $this->xTemplate->assign("ORDER_BY", $sort_URL_base);
1281                         return $sort_URL_base;
1282                 } else {
1283                         return '';
1284                 }
1285         }
1286
1287
1288         function getAdditionalHeader() {
1289
1290         }
1291
1292
1293         /**
1294          * @return void
1295          * @param unknown $data
1296          * @param unknown $xTemplateSection
1297          * @param unknown $html_varName
1298          * @desc INTERNAL FUNCTION handles the rows
1299          * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1300          * All Rights Reserved.
1301          * Contributor(s): ______________________________________..
1302          */
1303         function processListRows($data, $xtemplateSection, $html_varName)
1304         {
1305                 global $odd_bg;
1306                 global $even_bg;
1307                 global $hilite_bg;
1308                 global $app_strings, $sugar_version, $sugar_config;
1309                 global $currentModule;
1310
1311                 static $overlib_included;
1312                 if(!$overlib_included) {
1313                         echo '<script type="text/javascript" src="include/javascript/sugar_grp_overlib.js"></script>
1314                                 <div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>';
1315                         $overlib_included = true;
1316                 }
1317
1318
1319                 $this->xTemplate->assign('BG_HILITE', $hilite_bg);
1320                 $this->xTemplate->assign('CHECKALL', "<img src='".SugarThemeRegistry::current()->getImageURL('blank.gif')."' width=\"1\" height=\"1\" alt=\"\" />");
1321         //$this->xTemplate->assign("BG_CLICK", $click_bg);
1322                 $oddRow = true;
1323                 $count = 0;
1324                 reset($data);
1325
1326                 //GETTING OFFSET
1327                 $offset = $this->getOffset($html_varName);
1328             $timeStamp = $this->unique_id();
1329             $_SESSION[$html_varName."_FROM_LIST_VIEW"] = $timeStamp;
1330
1331             $associated_row_data = array();
1332
1333             //mail merge list
1334             $mergeList = array();
1335             $module = '';
1336                 //todo what is this?  It is using an array as a boolean
1337                 while(list($aVal, $aItem) = each($data))
1338                 {
1339                         if(isset($this->data_array)) {
1340                                 $fields = $this->data_array;
1341                         } else {
1342                                 $aItem->check_date_relationships_load();
1343                                 $fields = $aItem->get_list_view_data();
1344                         }
1345
1346                         if(is_object($aItem)) { // cn: bug 5349
1347                                 //add item id to merge list, if the button is clicked
1348                                 $mergeList[] = $aItem->id;
1349                                 if(empty($module)) {
1350                                         $module = $aItem->module_dir;
1351                                 }
1352                         }
1353                         //ADD OFFSET TO ARRAY
1354
1355                                 $fields['OFFSET'] = ($offset + $count + 1);
1356
1357                 $fields['STAMP'] = $timeStamp;
1358                         if($this->shouldProcess) {
1359
1360                         $prerow = '';
1361                         if(!isset($this->data_array)) {
1362                                 $prerow .= "<input onclick='sListView.check_item(this, document.MassUpdate)' type='checkbox' class='checkbox' name='mass[]' value='". $fields['ID']. "'>";
1363                         }
1364                         $this->xTemplate->assign('PREROW', $prerow);
1365
1366                         $this->xTemplate->assign('CHECKALL', "<input type='checkbox' class='checkbox' name='massall' id='massall' value='' onclick='sListView.check_all(document.MassUpdate, \"mass[]\", this.checked)'>");
1367                         }
1368                         if(!isset($this->data_array)) {
1369                                 $tag = $aItem->listviewACLHelper();
1370                                 $this->xTemplate->assign('TAG',$tag) ;
1371                         }
1372
1373                         if($oddRow)
1374                         {
1375                                 $ROW_COLOR = 'oddListRow';
1376                                 $BG_COLOR =  $odd_bg;
1377                         }
1378                         else
1379                         {
1380                                 $ROW_COLOR = 'evenListRow';
1381                                 $BG_COLOR =  $even_bg;
1382                         }
1383                         $oddRow = !$oddRow;
1384
1385                         $this->xTemplate->assign('ROW_COLOR', $ROW_COLOR);
1386                         $this->xTemplate->assign('BG_COLOR', $BG_COLOR);
1387
1388                         if(isset($this->data_array))
1389                         {
1390                                 $this->xTemplate->assign('KEY', $aVal);
1391                                 $this->xTemplate->assign('VALUE', $aItem);
1392                                 $this->xTemplate->assign('INDEX', $count);
1393
1394                         }
1395                         else
1396                         {
1397         //AED -- some modules do not have their additionalDetails.php established. Add a check to ensure require_once does not fail
1398         // Bug #2786
1399                                 if($this->_additionalDetails && $aItem->ACLAccess('DetailView') && (file_exists('modules/' . $aItem->module_dir . '/metadata/additionalDetails.php') || file_exists('custom/modules/' . $aItem->module_dir . '/metadata/additionalDetails.php'))) {
1400
1401                                         $additionalDetailsFile = 'modules/' . $aItem->module_dir . '/metadata/additionalDetails.php';
1402                                         if(file_exists('custom/modules/' . $aItem->module_dir . '/metadata/additionalDetails.php')){
1403                                                 $additionalDetailsFile = 'custom/modules/' . $aItem->module_dir . '/metadata/additionalDetails.php';
1404                                         }
1405
1406                                         require_once($additionalDetailsFile);
1407                                         $ad_function = (empty($this->additionalDetailsFunction) ? 'additionalDetails' : $this->additionalDetailsFunction) . $aItem->object_name;
1408                                         $results = $ad_function($fields);
1409                                         $results['string'] = str_replace(array("&#039", "'"), '\&#039', $results['string']); // no xss!
1410
1411                                         if(trim($results['string']) == '') $results['string'] = $app_strings['LBL_NONE'];
1412                                         $fields[$results['fieldToAddTo']] = $fields[$results['fieldToAddTo']].'</a>';
1413                                 }
1414                                 //fixes bug for IE where empty list view rows causes IE to not display bottom border
1415                                 if(isset($fields['DESCRIPTION']) && empty($fields['DESCRIPTION']))
1416                                 $fields['DESCRIPTION'] = "&nbsp;";
1417                                 if(isset($fields['LIST_ORDER']) && empty($fields['LIST_ORDER']))
1418                                 $fields['LIST_ORDER'] = "&nbsp;";
1419
1420                                 $this->xTemplate->assign($html_varName, $fields);
1421                                 $aItem->setupCustomFields($aItem->module_dir);
1422                                 $aItem->custom_fields->populateAllXTPL($this->xTemplate, 'detail', $html_varName, $fields);
1423                         }
1424                         if(!isset($this->data_array) && $aItem->ACLAccess('DetailView')) {
1425                                 $count++;
1426                         }
1427                         if(isset($this->data_array)) {
1428                                 $count++;
1429                         }
1430                         if(!isset($this->data_array)) {
1431                                 $aItem->list_view_parse_additional_sections($this->xTemplate, $xtemplateSection);
1432
1433                                 if($this->xTemplate->exists($xtemplateSection.'.row.pro')) {
1434                                         $this->xTemplate->parse($xtemplateSection.'.row.pro');
1435                                 }
1436                         }
1437                         $this->xTemplate->parse($xtemplateSection . '.row');
1438
1439                         if(isset($fields['ID'])) {
1440                                 $associated_row_data[$fields['ID']] = $fields;
1441                         }
1442                 }
1443
1444                 $_SESSION['MAILMERGE_RECORDS'] = $mergeList;
1445                 $_SESSION['MAILMERGE_MODULE_FROM_LISTVIEW'] = $module;
1446             if(empty($_REQUEST['action']) || $_REQUEST['action'] != 'Popup') {
1447                 $_SESSION['MAILMERGE_MODULE'] = $module;
1448             }
1449
1450                 if($this->process_for_popups)
1451                 {
1452                         $json = getJSONobj();
1453             $is_show_fullname = showFullName() ? 1 : 0;
1454                         $associated_javascript_data = '<script type="text/javascript">' . "\n"
1455                                 //. '<!-- // associated javascript data generated by ListView' . "\n"
1456                                 . 'var associated_javascript_data = '
1457                                 . $json->encode($associated_row_data) . ";\n"
1458                                 //. '-->' . "\n"
1459                 . 'var is_show_fullname = '
1460                 . $is_show_fullname . ";\n"
1461                                 . '</script>';
1462                         $this->xTemplate->assign('ASSOCIATED_JAVASCRIPT_DATA', $associated_javascript_data);
1463                 }
1464
1465                 $this->xTemplate->parse($xtemplateSection);
1466         }
1467
1468
1469         function getLayoutManager()
1470         {
1471                 require_once('include/generic/LayoutManager.php');
1472                 if($this->layout_manager == null)
1473                 {
1474                         $this->layout_manager = new LayoutManager();
1475                 }
1476                 return $this->layout_manager;
1477         }
1478
1479
1480         function process_dynamic_listview_header($source_module, $subpanel_def, $html_var = 'CELL')
1481         {
1482
1483
1484                 $layout_manager = $this->getLayoutManager();
1485                 $layout_manager->setAttribute('order_by_link',$this->processOrderBy($html_var));
1486                 $layout_manager->setAttribute('context','HeaderCell');
1487                 $layout_manager->setAttribute('image_path',$this->local_image_path);
1488                 $layout_manager->setAttribute('html_varName',$html_var);
1489                 $layout_manager->setAttribute('module_name', $source_module);
1490                 list($orderBy,$desc) = $this->getOrderByInfo($html_var);
1491
1492                 if($orderBy == 'amount*1')
1493                 {
1494                         $orderBy=  'amount';
1495                 }
1496
1497                 foreach($subpanel_def->get_list_fields() as $column_name=>$widget_args)
1498                 {
1499                         $usage = empty($widget_args['usage']) ? '' : $widget_args['usage'];
1500                         if($usage != 'query_only')
1501                         {
1502                                 $imgArrow = '';
1503
1504                                 if($orderBy == $column_name || (isset($widget_args['sort_by']) && str_replace('.','_',$widget_args['sort_by']) == $orderBy))
1505                                 {
1506                                         $imgArrow = "_down";
1507                                         if($this->sort_order == 'desc') {
1508                                                 $imgArrow = "_up";
1509                                         }
1510                                 }
1511                                 $widget_args['name']=$column_name;
1512                                 $widget_args['sort'] = $imgArrow;
1513                                 $widget_args['start_link_wrapper'] = $this->start_link_wrapper;
1514                                 $widget_args['end_link_wrapper'] = $this->end_link_wrapper;
1515                                 $widget_args['subpanel_module'] = $this->subpanel_module;
1516
1517                                 $widget_contents = $layout_manager->widgetDisplay($widget_args);
1518                                 $cell_width = empty($widget_args['width']) ? '' : $widget_args['width'];
1519                                 $this->xTemplate->assign('HEADER_CELL', $widget_contents);
1520                                 static $count;
1521                           if(!isset($count))$count = 0; else $count++;
1522                                 $this->xTemplate->assign('CELL_COUNT', $count);
1523                                 $this->xTemplate->assign('CELL_WIDTH', $cell_width);
1524                                 $this->xTemplate->parse('dyn_list_view.header_cell');
1525                         }
1526                 }
1527
1528         }
1529
1530
1531         /**
1532          * @return void
1533          * @param unknown $seed
1534          * @param unknown $xTemplateSection
1535          * @param unknown $html_varName
1536          * @desc PUBLIC FUNCTION Handles List Views using seeds that extend SugarBean
1537                 $XTemplateSection is the section in the XTemplate file that should be parsed usually main
1538                 $html_VarName is the variable name used in the XTemplateFile e.g. TASK
1539                 $seed is a seed there are two types of seeds one is a subclass of SugarBean, the other is a list usually created from a sugar bean using get_list
1540                 if no XTemplate is set it will create  a new XTemplate
1541                  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc..
1542                  * All Rights Reserved..
1543                  * Contributor(s): ______________________________________..
1544          */
1545
1546         function processListViewTwo($seed, $xTemplateSection, $html_varName) {
1547             global $current_user;
1548                 if(!isset($this->xTemplate)) {
1549                         $this->createXTemplate();
1550                 }
1551
1552                 $isSugarBean = is_subclass_of($seed, "SugarBean");
1553                 $list = null;
1554
1555                 if($isSugarBean) {
1556                         $list = $this->processSugarBean($xTemplateSection, $html_varName, $seed);
1557                 } else {
1558                         $list = $seed;
1559                 }
1560
1561                 if (is_object($seed) && isset($seed->object_name) && $seed->object_name == 'WorkFlow') {
1562                     $tab=array();
1563                 $access = get_workflow_admin_modules_for_user($current_user);
1564                 for ($i = 0; $i < count($list); $i++) {
1565                     if(!empty($access[$list[$i]->base_module])){
1566                     $tab[]=$list[$i];
1567                 }
1568                 }
1569             $list = $tab;
1570                 }
1571
1572                 if($this->is_dynamic) {
1573                         $this->processHeaderDynamic($xTemplateSection,$html_varName);
1574                         $this->processListRows($list,$xTemplateSection, $html_varName);
1575                 } else {
1576                         $this->processSortArrows($html_varName);
1577
1578                         if($isSugarBean) {
1579                                 $seed->parse_additional_headers($this->xTemplate, $xTemplateSection);
1580                         }
1581                         $this->xTemplateAssign('CHECKALL', "<img src='".SugarThemeRegistry::current()->getImageURL('blank.gif')."' width=\"1\" height=\"1\" al=\"\">");
1582
1583                         // Process the  order by before processing the pro_nav.  The pro_nav requires the order by values to be set
1584                         $this->processOrderBy($html_varName);
1585
1586
1587                         $this->processListRows($list,$xTemplateSection, $html_varName);
1588                 }
1589
1590                 if($this->display_header_and_footer) {
1591                         $this->getAdditionalHeader();
1592                         if(!empty($this->header_title)) {
1593                                 echo get_form_header($this->header_title, $this->header_text, false);
1594                         }
1595                 }
1596
1597                 $this->xTemplate->out($xTemplateSection);
1598
1599                 if(isset($_SESSION['validation'])) {
1600                         print base64_decode('PGEgaHJlZj0naHR0cDovL3d3dy5zdWdhcmNybS5jb20nPlBPV0VSRUQmbmJzcDtCWSZuYnNwO1NVR0FSQ1JNPC9hPg==');
1601                 }
1602         }
1603
1604         function getArrowStart() {
1605         $imgFileParts = pathinfo(SugarThemeRegistry::current()->getImageURL("arrow.gif"));
1606
1607                 return "&nbsp;<img border='0' src='".$imgFileParts['dirname']."/".$imgFileParts['filename']."";
1608         }
1609
1610         function getArrowUpDownStart($upDown) {
1611         $ext = ( SugarThemeRegistry::current()->pngSupport ? "png" : "gif" );
1612
1613         if (!isset($upDown) || empty($upDown)) {
1614                 $upDown = "";
1615         }
1616                 return "&nbsp;<img border='0' src='".SugarThemeRegistry::current()->getImageURL("arrow{$upDown}.{$ext}")."' ";
1617         }
1618
1619         function getArrowEnd() {
1620                 $imgFileParts = pathinfo(SugarThemeRegistry::current()->getImageURL("arrow.gif"));
1621
1622         list($width,$height) = ListView::getArrowImageSize();
1623                 return '.'.$imgFileParts['extension']."' width='$width' height='$height' align='absmiddle' alt=".translate('LBL_SORT').">";
1624         }
1625
1626         function getArrowImageSize() {
1627             // just get the non-sort image's size.. the up and down have be the same.
1628                 $image = SugarThemeRegistry::current()->getImageURL("arrow.gif",false);
1629
1630                 $cache_key = 'arrow_size.'.$image;
1631
1632                 // Check the cache
1633                 $result = sugar_cache_retrieve($cache_key);
1634                 if(!empty($result))
1635                    return $result;
1636
1637                 // No cache hit.  Calculate the value and return.
1638                 $result = getimagesize($image);
1639                 sugar_cache_put($cache_key, $result);
1640                 return $result;
1641         }
1642
1643         function getOrderByInfo($html_varName)
1644         {
1645                 $orderBy = $this->getSessionVariable($html_varName, "OBL");
1646                 $desc = $this->getSessionVariable($html_varName, $orderBy.'S');
1647                 $orderBy = str_replace('.', '_', $orderBy);
1648                 return array($orderBy,$desc);
1649         }
1650
1651         function processSortArrows($html_varName)
1652         {
1653
1654                 $this->xTemplateAssign("arrow_start", $this->getArrowStart());
1655
1656                 list($orderBy,$desc) = $this->getOrderByInfo($html_varName);
1657
1658                 $imgArrow = "_down";
1659                 if($desc) {
1660                         $imgArrow = "_up";
1661                 }
1662
1663                 if($orderBy == 'amount*1')
1664                 {
1665                         $this->xTemplateAssign('amount_arrow', $imgArrow);
1666                 }
1667                 else if($orderBy == 'amount_usdollar*1')
1668                 {
1669                         $this->xTemplateAssign('amount_usdollar_arrow', $imgArrow);
1670                 }
1671                 else
1672                 {
1673                         $this->xTemplateAssign($orderBy.'_arrow', $imgArrow);
1674                 }
1675
1676                 $this->xTemplateAssign('arrow_end', $this->getArrowEnd());
1677         }
1678
1679         // this is where translation happens for dynamic list views
1680         function loadListFieldDefs(&$subpanel_fields,&$child_focus)
1681         {
1682                 $this->list_field_defs = $subpanel_fields;
1683
1684                 for($i=0;$i < count($this->list_field_defs);$i++)
1685                 {
1686                         $list_field = $this->list_field_defs[$i];
1687                         $field_def = null;
1688                         $key = '';
1689                         if(!empty($list_field['vname']))
1690                         {
1691                                 $key = $list_field['vname'];
1692                         } else if(isset($list_field['name']) &&  isset($child_focus->field_defs[$list_field['name']]))
1693                         {
1694                                         $field_def = $child_focus->field_defs[$list_field['name']];
1695                                         $key = $field_def['vname'];
1696                         }
1697                         if(!empty($key))
1698                         {
1699                                 $list_field['label'] = translate($key,$child_focus->module_dir);
1700                                 $this->list_field_defs[$i]['label'] = preg_replace('/:$/','',$list_field['label']);
1701                         }
1702                         else
1703                         {
1704                                 $this->list_field_defs[$i]['label'] ='&nbsp;';
1705                         }
1706                 }
1707         }
1708
1709     function unique_id() {
1710         return sugar_microtime();
1711     }
1712
1713      /**INTERNAL FUNCTION sets a session variable keeping it local to the listview
1714      not the current_module
1715      * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1716      * All Rights Reserved.
1717      * Contributor(s): ______________________________________.
1718      */
1719      function setLocalSessionVariable($localVarName,$varName, $value) {
1720         $_SESSION[$localVarName."_".$varName] = $value;
1721      }
1722
1723      /**INTERNAL FUNCTION returns a session variable that is local to the listview,
1724      not the current_module
1725      * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
1726      * All Rights Reserved.
1727      * Contributor(s): ______________________________________.
1728      */
1729  function getLocalSessionVariable($localVarName,$varName) {
1730     if(isset($_SESSION[$localVarName."_".$varName])) {
1731                 return $_SESSION[$localVarName."_".$varName];
1732         }
1733     else{
1734         return "";
1735     }
1736  }
1737
1738  /* Set to true if you want Additional Details to appear in the listview
1739   */
1740  function setAdditionalDetails($value = true, $function = '') {
1741         if(!empty($function)) $this->additionalDetailsFunction = $function;
1742         $this->_additionalDetails = $value;
1743  }
1744
1745 }
1746 ?>