]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/MassUpdate.php
Release 6.5.16
[Github/sugarcrm.git] / include / MassUpdate.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 require_once('include/EditView/EditView2.php');
40
41 /**
42  * MassUpdate class for updating multiple records at once
43  * @api
44  */
45 class MassUpdate
46 {
47         /*
48          * internal sugarbean reference
49          */
50         var $sugarbean = null;
51
52         /**
53          * where clauses used to filter rows that have to be updated
54          */
55         var $where_clauses = '';
56
57         /**
58           * set the sugar bean to its internal member
59           * @param sugar bean reference
60           */
61         function setSugarBean($sugar)
62         {
63                 $this->sugarbean = $sugar;
64         }
65
66         /**
67          * get the massupdate form
68          * @param bool boolean need to execute the massupdate form or not
69          * @param multi_select_popup booleanif it is a multi-select value
70          */
71         function getDisplayMassUpdateForm($bool, $multi_select_popup = false)
72         {
73
74                 require_once('include/formbase.php');
75
76                 if(!$multi_select_popup)
77                 $form = '<form action="index.php" method="post" name="displayMassUpdate" id="displayMassUpdate">' . "\n";
78                 else
79                 $form = '<form action="index.php" method="post" name="MassUpdate" id="MassUpdate">' . "\n";
80
81                 if($bool)
82                 {
83                         $form .= '<input type="hidden" name="mu" value="false" />' . "\n";
84                 }
85                 else
86                 {
87                         $form .= '<input type="hidden" name="mu" value="true" />' . "\n";
88                 }
89
90                 $form .= getAnyToForm('mu', true);
91                 if(!$multi_select_popup) $form .= "</form>\n";
92
93                 return $form;
94         }
95         /**
96          * returns the mass update's html form header
97          * @param multi_select_popup boolean if it is a mult-select or not
98          */
99         function getMassUpdateFormHeader($multi_select_popup = false)
100         {
101                 global $sugar_version;
102                 global $sugar_config;
103                 global $current_user;
104
105                 unset($_REQUEST['current_query_by_page']);
106                 unset($_REQUEST[session_name()]);
107                 unset($_REQUEST['PHPSESSID']);
108                 $query = base64_encode(serialize($_REQUEST));
109
110         $bean = loadBean($_REQUEST['module']);
111        $order_by_name = $bean->module_dir.'2_'.strtoupper($bean->object_name).'_ORDER_BY' ;
112        $lvso = isset($_REQUEST['lvso'])?$_REQUEST['lvso']:"";
113        $request_order_by_name = isset($_REQUEST[$order_by_name])?$_REQUEST[$order_by_name]:"";
114        $action = isset($_REQUEST['action'])?$_REQUEST['action']:"";
115        $module = isset($_REQUEST['module'])?$_REQUEST['module']:"";
116                 if($multi_select_popup)
117                 $tempString = '';
118                 else
119                 $tempString = "<form action='index.php' method='post' name='MassUpdate'  id='MassUpdate' onsubmit=\"return check_form('MassUpdate');\">\n"
120                 . "<input type='hidden' name='return_action' value='{$action}' />\n"
121         . "<input type='hidden' name='return_module' value='{$module}' />\n"
122                 . "<input type='hidden' name='massupdate' value='true' />\n"
123                 . "<input type='hidden' name='delete' value='false' />\n"
124                 . "<input type='hidden' name='merge' value='false' />\n"
125         . "<input type='hidden' name='current_query_by_page' value='{$query}' />\n"
126         . "<input type='hidden' name='module' value='{$module}' />\n"
127         . "<input type='hidden' name='action' value='MassUpdate' />\n"
128         . "<input type='hidden' name='lvso' value='{$lvso}' />\n"
129         . "<input type='hidden' name='{$order_by_name}' value='{$request_order_by_name}' />\n";
130
131                 // cn: bug 9103 - MU navigation in emails is broken
132                 if($_REQUEST['module'] == 'Emails') {
133                         $type = "";
134                         // determine "type" - inbound, archive, etc.
135                         if (isset($_REQUEST['type'])) {
136                                 $type = $_REQUEST['type'];
137                         }
138                         // determine owner
139                         $tempString .=<<<eoq
140                                 <input type='hidden' name='type' value="{$type}" />
141                                 <input type='hidden' name='ie_assigned_user_id' value="{$current_user->id}" />
142 eoq;
143                 }
144
145                 return $tempString;
146         }
147
148         /**
149           * Executes the massupdate form
150           * @param displayname Name to display in the popup window
151       * @param varname name of the variable
152           */
153         function handleMassUpdate(){
154
155                 require_once('include/formbase.php');
156                 global $current_user, $db, $disable_date_format, $timedate;
157
158                 foreach($_POST as $post=>$value){
159                         if(is_array($value)){
160                                 if(empty($value)){
161                                         unset($_POST[$post]);
162                                 }
163                         }elseif(strlen($value) == 0){
164                                 if( isset($this->sugarbean->field_defs[$post]) && $this->sugarbean->field_defs[$post]['type'] == 'radioenum' && isset($_POST[$post]) ){
165                                   $_POST[$post] = '';
166                                 }else{
167                                   unset($_POST[$post]);
168                             }
169             }
170
171                         if(is_string($value) && isset($this->sugarbean->field_defs[$post])) {
172                         if(($this->sugarbean->field_defs[$post]['type'] == 'bool'
173                                         || (!empty($this->sugarbean->field_defs[$post]['custom_type']) && $this->sugarbean->field_defs[$post]['custom_type'] == 'bool'
174                                         ))){
175                                                 if(strcmp($value, '2') == 0)$_POST[$post] = 0;
176                                                 if(!empty($this->sugarbean->field_defs[$post]['dbType']) && strcmp($this->sugarbean->field_defs[$post]['dbType'], 'varchar') == 0 ){
177                                                         if(strcmp($value, '1') == 0 )$_POST[$post] = 'on';
178                                                         if(strcmp($value, '2') == 0)$_POST[$post] = 'off';
179                                                 }
180                         }
181
182                             if( ($this->sugarbean->field_defs[$post]['type'] == 'radioenum' && isset($_POST[$post]) && strlen($value) == 0)
183                             || ($this->sugarbean->field_defs[$post]['type'] == 'enum' && $value == '__SugarMassUpdateClearField__') // Set to '' if it's an explicit clear
184                             ){
185                                     $_POST[$post] = '';
186                             }
187                 if ($this->sugarbean->field_defs[$post]['type'] == 'bool') {
188                     $this->checkClearField($post, $value);
189                 }
190                             if($this->sugarbean->field_defs[$post]['type'] == 'date' && !empty($_POST[$post])){
191                                 $_POST[$post] = $timedate->to_db_date($_POST[$post], false);
192                             }
193                 if($this->sugarbean->field_defs[$post]['type'] == 'datetime' && !empty($_POST[$post])){
194                                 $_POST[$post] = $timedate->to_db($this->date_to_dateTime($post, $value));
195                             }
196                             if($this->sugarbean->field_defs[$post]['type'] == 'datetimecombo' && !empty($_POST[$post])){
197                                 $_POST[$post] = $timedate->to_db($_POST[$post]);
198                             }
199             }
200          }
201
202                 //We need to disable_date_format so that date values for the beans remain in database format
203                 //notice we make this call after the above section since the calls to TimeDate class there could wind up
204                 //making it's way to the UserPreferences objects in which case we want to enable the global date formatting
205                 //to correctly retrieve the user's date format preferences
206                 $old_value = $disable_date_format;
207                 $disable_date_format = true;
208
209                 if(!empty($_REQUEST['uid'])) $_POST['mass'] = explode(',', $_REQUEST['uid']); // coming from listview
210                 elseif(isset($_REQUEST['entire']) && empty($_POST['mass'])) {
211                         if(empty($order_by))$order_by = '';
212
213             // TODO: define filter array here to optimize the query
214             // by not joining the unneeded tables
215             $query = $this->sugarbean->create_new_list_query($order_by, $this->where_clauses, array(), array(), 0, '', false, $this, true, true);
216                         $result = $db->query($query,true);
217                         $new_arr = array();
218                         while($val = $db->fetchByAssoc($result,false))
219                         {
220                                 array_push($new_arr, $val['id']);
221                         }
222                         $_POST['mass'] = $new_arr;
223                 }
224
225                 if(isset($_POST['mass']) && is_array($_POST['mass'])  && $_REQUEST['massupdate'] == 'true'){
226                         $count = 0;
227
228
229                         foreach($_POST['mass'] as $id){
230                 if(empty($id)) {
231                     continue;
232                 }
233                                 if(isset($_POST['Delete'])){
234                                         $this->sugarbean->retrieve($id);
235                                         if($this->sugarbean->ACLAccess('Delete')){
236                                                 $this->sugarbean->mark_deleted($id);
237                                         }
238                                 }
239                                 else {
240                                         if($this->sugarbean->object_name == 'Contact' && isset($_POST['Sync'])){ // special for contacts module
241                                                 if($_POST['Sync'] == 'true') {
242                                                         $this->sugarbean->retrieve($id);
243                                                         if($this->sugarbean->ACLAccess('Save')){
244                                                                 if($this->sugarbean->object_name == 'Contact'){
245
246                                                                         $this->sugarbean->contacts_users_id = $current_user->id;
247                                                                         $this->sugarbean->save(false);
248                                                                 }
249                                                         }
250                                                 }
251                                                 elseif($_POST['Sync'] == 'false') {
252                                                         $this->sugarbean->retrieve($id);
253                                                         if($this->sugarbean->ACLAccess('Save')){
254                                                                 if($this->sugarbean->object_name == 'Contact'){
255                                                                         if (!isset($this->sugarbean->users))
256                                                                         {
257                                                                                 $this->sugarbean->load_relationship('user_sync');
258                                                                         }
259                                                                         $this->sugarbean->contacts_users_id = null;
260                                                                         $this->sugarbean->user_sync->delete($this->sugarbean->id, $current_user->id);
261                                                                 }
262                                                         }
263                                                 }
264                                         } //end if for special Contact handling
265
266                                         if($count++ != 0) {
267                                            //Create a new instance to clear values and handle additional updates to bean's 2,3,4...
268                        $className = get_class($this->sugarbean);
269                        $this->sugarbean = new $className();
270                                         }
271
272                                         $this->sugarbean->retrieve($id);
273
274
275                                         if($this->sugarbean->ACLAccess('Save')){
276                                                 $_POST['record'] = $id;
277                                                 $_GET['record'] = $id;
278                                                 $_REQUEST['record'] = $id;
279                                                 $newbean=$this->sugarbean;
280
281                                                 $old_reports_to_id = null;
282                                                 if(!empty($_POST['reports_to_id']) && $newbean->reports_to_id != $_POST['reports_to_id']) {
283                                                    $old_reports_to_id = empty($newbean->reports_to_id) ? 'null' : $newbean->reports_to_id;
284                                                 }
285
286                                                 $check_notify = FALSE;
287
288                                                 if (isset( $this->sugarbean->assigned_user_id)) {
289                                                         $old_assigned_user_id = $this->sugarbean->assigned_user_id;
290                                                         if (!empty($_POST['assigned_user_id'])
291                                                         && ($old_assigned_user_id != $_POST['assigned_user_id'])
292                                                         && ($_POST['assigned_user_id'] != $current_user->id)) {
293                                                                 $check_notify = TRUE;
294                                                         }
295                                                 }
296
297                                                 //Call include/formbase.php, but do not call retrieve again
298                         populateFromPost('', $newbean, true, true);
299                                                 $newbean->save_from_post = false;
300
301                                                 if (!isset($_POST['parent_id'])) {
302                                                         $newbean->parent_type = null;
303                                                 }
304
305                                                 $email_address_id = '';
306                             if (!empty($_POST['optout_primary'])) {
307                                 $optout_flag_value = 0;
308                                 if ($_POST['optout_primary'] == 'true') {
309                                         $optout_flag_value = 1;
310                                 } // if
311                                 if (isset($this->sugarbean->emailAddress)) {
312                                         if (!empty($this->sugarbean->emailAddress->addresses)) {
313                                                 foreach($this->sugarbean->emailAddress->addresses as $key =>$emailAddressRow) {
314                                                         if ($emailAddressRow['primary_address'] == '1') {
315                                                                 $email_address_id = $emailAddressRow['email_address_id'];
316                                                                 break;
317                                                                                 } // if
318                                                                         } // foreach
319                                                                 } // if
320
321                                                         } // if
322                             } // if
323
324
325                                                 $newbean->save($check_notify);
326                                                 if (!empty($email_address_id)) {
327                                                 $query = "UPDATE email_addresses SET opt_out = {$optout_flag_value} where id = '{$emailAddressRow['email_address_id']}'";
328                                                 $GLOBALS['db']->query($query);
329
330                                                 } // if
331
332                                                 if(!empty($old_reports_to_id) && method_exists($newbean, 'update_team_memberships')) {
333                                                    $old_id = $old_reports_to_id == 'null' ? '' : $old_reports_to_id;
334                                                 }
335                                         }
336                                 }
337                         }
338
339                 }
340                 $disable_date_format = $old_value;
341         }
342         /**
343           * Displays the massupdate form
344           */
345         function getMassUpdateForm(
346             $hideDeleteIfNoFieldsAvailable = false
347             )
348         {
349                 global $app_strings;
350                 global $current_user;
351
352                 if($this->sugarbean->bean_implements('ACL') && ( !ACLController::checkAccess($this->sugarbean->module_dir, 'edit', true) || !ACLController::checkAccess($this->sugarbean->module_dir, 'massupdate', true) ) ){
353                         return '';
354                 }
355
356                 $lang_delete = translate('LBL_DELETE');
357                 $lang_update = translate('LBL_UPDATE');
358                 $lang_confirm= translate('NTC_DELETE_CONFIRMATION_MULTIPLE');
359                 $lang_sync = translate('LBL_SYNC_CONTACT');
360                 $lang_oc_status = translate('LBL_OC_STATUS');
361                 $lang_unsync = translate('LBL_UNSYNC');
362                 $lang_archive = translate('LBL_ARCHIVE');
363                 $lang_optout_primaryemail = $app_strings['LBL_OPT_OUT_FLAG_PRIMARY'];
364
365                 $field_count = 0;
366
367                 $html = "<div id='massupdate_form' style='display:none;'><table width='100%' cellpadding='0' cellspacing='0' border='0' class='formHeader h3Row'><tr><td nowrap><h3><span>" . $app_strings['LBL_MASS_UPDATE']."</h3></td></tr></table>";
368                 $html .= "<div id='mass_update_div'><table cellpadding='0' cellspacing='1' border='0' width='100%' class='edit view' id='mass_update_table'>";
369
370                 $even = true;
371
372                 if($this->sugarbean->object_name == 'Contact')
373                 {
374                         $html .= "<tr><td width='15%' scope='row'>$lang_sync</td><td width='35%' class='dataField'><select name='Sync'><option value=''>{$GLOBALS['app_strings']['LBL_NONE']}</option><option value='false'>{$GLOBALS['app_list_strings']['checkbox_dom']['2']}</option><option value='true'>{$GLOBALS['app_list_strings']['checkbox_dom']['1']}</option></select></td>";
375                         $even = false;
376                 } else if($this->sugarbean->object_name == 'Employee') {
377                         $this->sugarbean->field_defs['employee_status']['type'] = 'enum';
378                         $this->sugarbean->field_defs['employee_status']['massupdate'] = true;
379                         $this->sugarbean->field_defs['employee_status']['options'] = 'employee_status_dom';
380                 } else if($this->sugarbean->object_name == 'InboundEmail'){
381                         $this->sugarbean->field_defs['status']['type'] = 'enum';
382                         $this->sugarbean->field_defs['status']['options'] = 'user_status_dom';
383                 }
384
385                 //These fields should never appear on mass update form
386                 static $banned = array('date_modified'=>1, 'date_entered'=>1, 'created_by'=>1, 'modified_user_id'=>1, 'deleted'=>1,'modified_by_name'=>1,);
387
388                 foreach($this->sugarbean->field_defs as $field)
389                 {
390                          if(!isset($banned[$field['name']]) && (!isset($field['massupdate']) || !empty($field['massupdate'])))
391                          {
392                                 $newhtml = '';
393
394                                 if($even)
395                                 {
396                                         $newhtml .= "<tr>";
397                                 }
398
399                                 if(isset($field['vname']))
400                                 {
401                                         $displayname = translate($field['vname']);
402                                 }else{
403                                         $displayname = '';
404                                 }
405
406                                 if(isset($field['type']) && $field['type'] == 'relate' && isset($field['id_name']) && $field['id_name'] == 'assigned_user_id')
407                                 {
408                                         $field['type'] = 'assigned_user_name';
409                                 }
410
411                                 if(isset($field['custom_type']))
412                                 {
413                                         $field['type'] = $field['custom_type'];
414                                 }
415
416                                 if(isset($field['type']))
417                                 {
418                                         switch($field["type"])
419                                         {
420                                                 case "relate":
421                                                     // bug 14691: avoid laying out an empty cell in the <table>
422                                                         $handleRelationship = $this->handleRelationship($displayname, $field);
423                                                         if ($handleRelationship != '')
424                                                         {
425                                                                 $even = !$even;
426                                                                 $newhtml .= $handleRelationship;
427                                                         }
428                                                         break;
429                                                 case "parent":$even = !$even; $newhtml .=$this->addParent($displayname, $field); break;
430                                                 case "int":
431                                                         if(!empty($field['massupdate']) && empty($field['auto_increment']))
432                                                         {
433                                                                 $even = !$even; $newhtml .=$this->addInputType($displayname, $field);
434                                                         }
435                                                          break;
436                                                 case "contact_id":$even = !$even; $newhtml .=$this->addContactID($displayname, $field["name"]); break;
437                                                 case "assigned_user_name":$even = !$even; $newhtml .= $this->addAssignedUserID($displayname,  $field["name"]); break;
438                                                 case "account_id":$even = !$even; $newhtml .= $this->addAccountID($displayname,  $field["name"]); break;
439                                                 case "account_name":$even = !$even; $newhtml .= $this->addAccountID($displayname,  $field["id_name"]); break;
440                                                 case "bool": $even = !$even; $newhtml .= $this->addBool($displayname,  $field["name"]); break;
441                                                 case "enum":
442                                                 case "multienum":
443                                                         if(!empty($field['isMultiSelect']))
444                                                         {
445                                                                 $even = !$even; $newhtml .= $this->addStatusMulti($displayname,  $field["name"], translate($field["options"])); break;
446                                                         }else if(!empty($field['options'])) {
447                                                                 $even = !$even; $newhtml .= $this->addStatus($displayname,  $field["name"], translate($field["options"])); break;
448                                                         }else if(!empty($field['function'])){
449                                                                 $functionValue = $this->getFunctionValue($this->sugarbean, $field);
450                                                                 $even = !$even; $newhtml .= $this->addStatus($displayname,  $field["name"], $functionValue); break;
451                                                         }
452                                                         break;
453                                                 case "radioenum":
454                                                 $even = !$even; $newhtml .= $this->addRadioenum($displayname,  $field["name"] , translate($field["options"])); break;
455                                                 case "datetimecombo":
456                                                 $even = !$even; $newhtml .= $this->addDatetime($displayname,  $field["name"]); break;
457                                                 case "datetime":
458                                                 case "date":$even = !$even; $newhtml .= $this->addDate($displayname,  $field["name"]); break;
459                         default:
460                             $newhtml .= $this->addDefault($displayname,  $field, $even); break;
461                             break;
462                                         }
463                                 }
464
465                                 if($even)
466                                 {
467                                         $newhtml .="</tr>";
468                                 }
469
470                                 $field_count++;
471
472                                 if(!in_array($newhtml, array('<tr>', '</tr>', '<tr></tr>', '<tr><td></td></tr>'))){
473                                         $html.=$newhtml;
474                                 }
475                         }
476                 }
477
478
479                 if ($this->sugarbean->object_name == 'Contact' ||
480                         $this->sugarbean->object_name == 'Account' ||
481                         $this->sugarbean->object_name == 'Lead' ||
482                         $this->sugarbean->object_name == 'Prospect') {
483
484                         $html .= "<tr><td width='15%'  scope='row' class='dataLabel'>$lang_optout_primaryemail</td><td width='35%' class='dataField'><select name='optout_primary'><option value=''>{$GLOBALS['app_strings']['LBL_NONE']}</option><option value='false'>{$GLOBALS['app_list_strings']['checkbox_dom']['2']}</option><option value='true'>{$GLOBALS['app_list_strings']['checkbox_dom']['1']}</option></select></td></tr>";
485
486                         }
487                 $html .="</table>";
488
489                  $html .= "<table cellpadding='0' cellspacing='0' border='0' width='100%'><tr><td class='buttons'><input onclick='return sListView.send_mass_update(\"selected\", \"{$app_strings['LBL_LISTVIEW_NO_SELECTED']}\")' type='submit' id='update_button' name='Update' value='{$lang_update}' class='button'>&nbsp;<input onclick='javascript:toggleMassUpdateForm();' type='button' id='cancel_button' name='Cancel' value='{$GLOBALS['app_strings']['LBL_CANCEL_BUTTON_LABEL']}' class='button'>";
490                 // TODO: allow ACL access for Delete to be set false always for users
491 //              if($this->sugarbean->ACLAccess('Delete', true) && $this->sugarbean->object_name != 'User') {
492 //                      global $app_list_strings;
493 //                      $html .=" <input id='delete_button' type='submit' name='Delete' value='{$lang_delete}' onclick='return confirm(\"{$lang_confirm}\") && sListView.send_mass_update(\"selected\", \"{$app_strings['LBL_LISTVIEW_NO_SELECTED']}\", 1)' class='button'>";
494 //              }
495
496                 // only for My Inbox views - to allow CSRs to have an "Archive" emails feature to get the email "out" of their inbox.
497                 if($this->sugarbean->object_name == 'Email'
498                 && (isset($_REQUEST['assigned_user_id']) && !empty($_REQUEST['assigned_user_id']))
499                 && (isset($_REQUEST['type']) && !empty($_REQUEST['type']) && $_REQUEST['type'] == 'inbound')) {
500                         $html .=<<<eoq
501                         <input type='button' name='archive' value="{$lang_archive}" class='button' onClick='setArchived();'>
502                         <input type='hidden' name='ie_assigned_user_id' value="{$current_user->id}">
503                         <input type='hidden' name='ie_type' value="inbound">
504 eoq;
505                 }
506
507                 $html .= "</td></tr></table></div></div>";
508
509                 $html .= <<<EOJS
510 <script>
511 function toggleMassUpdateForm(){
512     document.getElementById('massupdate_form').style.display = 'none';
513 }
514 </script>
515 EOJS;
516
517                 if($field_count > 0)
518                 {
519                         return $html;
520                 }else{
521                         //If no fields are found, render either a form that still permits Mass Update deletes or just display a message that no fields are available
522                         $html = "<div id='massupdate_form' style='display:none;'><table width='100%' cellpadding='0' cellspacing='0' border='0' class='formHeader h3Row'><tr><td nowrap><h3><span>" . $app_strings['LBL_MASS_UPDATE']."</h3></td></tr></table>";
523                         if($this->sugarbean->ACLAccess('Delete', true) && !$hideDeleteIfNoFieldsAvailable){
524                                 $html .= "<table cellpadding='0' cellspacing='0' border='0' width='100%'><tr><td><input type='submit' name='Delete' value='$lang_delete' onclick=\"return confirm('{$lang_confirm}')\" class='button'></td></tr></table></div>";
525                         }else{
526                                 $html .= $app_strings['LBL_NO_MASS_UPDATE_FIELDS_AVAILABLE'] . "</div>";
527                         }
528                         return $html;
529                 }
530         }
531
532         function getFunctionValue($focus, $vardef){
533                 $function = $vardef['function'];
534             if(is_array($function) && isset($function['name'])){
535                 $function = $vardef['function']['name'];
536             }else{
537                 $function = $vardef['function'];
538             }
539                 if(!empty($vardef['function']['returns']) && $vardef['function']['returns'] == 'html'){
540                         if(!empty($vardef['function']['include'])){
541                                 require_once($vardef['function']['include']);
542                         }
543                         return call_user_func($function, $focus, $vardef['name'], '', 'MassUpdate');
544                 }else{
545                         return call_user_func($function, $focus, $vardef['name'], '', 'MassUpdate');
546                 }
547         }
548
549         /**
550           * Returns end of the massupdate form
551           */
552         function endMassUpdateForm(){
553                 return '</form>';
554         }
555
556         /**
557           * Decides which popup HTML code is needed for mass updating
558           * @param displayname Name to display in the popup window
559           * @param field name of the field to update
560           */
561         function handleRelationship($displayname, $field)
562         {
563                 $ret_val = '';
564                 if(isset($field['module']))
565                 {
566                         if ($field['name'] == 'reports_to_name' && ($field['module'] == 'Users' || $field['module'] == 'Employee') )
567                             return $this->addUserName($displayname, $field['name'], $field['id_name'], $field['module']);
568
569                     switch($field['module'])
570                         {
571                                 case 'Accounts':
572                                         $ret_val = $this->addAccountID($displayname, $field['name'], $field['id_name']);
573                                         break;
574                                 case 'Contacts':
575                                         $ret_val = $this->addGenericModuleID($displayname, $field['name'], $field['id_name'], "Contacts");
576                                         break;
577                                 case 'Users':
578                                         $ret_val = $this->addGenericModuleID($displayname, $field['name'], $field['id_name'], "Users");
579                                         break;
580                                 case 'Employee':
581                                         $ret_val = $this->addGenericModuleID($displayname, $field['name'], $field['id_name'], "Employee");
582                                         break;
583                                 case 'Releases':
584                                         $ret_val = $this->addGenericModuleID($displayname, $field['name'], $field['id_name'], "Releases");
585                                         break;
586                                 default:
587                                         if(!empty($field['massupdate'])){
588                                                 $ret_val = $this->addGenericModuleID($displayname, $field['name'], $field['id_name'], $field['module']);
589                                         }
590                                         break;
591                         }
592                 }
593
594                 return $ret_val;
595         }
596         /**
597           * Add a parent selection popup window
598           * @param displayname Name to display in the popup window
599           * @param field_name name of the field
600           */
601         function addParent($displayname, $field){
602                 global $app_strings, $app_list_strings;
603
604                 ///////////////////////////////////////
605                 ///
606                 /// SETUP POPUP
607
608                 $popup_request_data = array(
609                 'call_back_function' => 'set_return',
610                 'form_name' => 'MassUpdate',
611                 'field_to_name_array' => array(
612                         'id' => "parent_id",
613                         'name' => "parent_name",
614                         ),
615                         );
616
617                         $json = getJSONobj();
618                         $encoded_popup_request_data = $json->encode($popup_request_data);
619
620             $qsName = array(
621                                     'form' => 'MassUpdate',
622                                                 'method' => 'query',
623                         'modules' => array("Accounts"),
624                         'group' => 'or',
625                                                 'field_list' => array('name', 'id'),
626                                                 'populate_list' => array("mass_parent_name", "mass_parent_id"),
627                                                 'conditions' => array(array('name'=>'name','op'=>'like_custom','end'=>'%','value'=>'')),
628                                                 'limit' => '30','no_match_text' => $app_strings['ERR_SQS_NO_MATCH']);
629                 $qsName = $json->encode($qsName);
630
631                         //
632                         ///////////////////////////////////////
633
634                         $change_parent_button = "<span class='id-ff'><button title='".$app_strings['LBL_SELECT_BUTTON_TITLE']."'  type='button' class='button' value='".$app_strings['LBL_SELECT_BUTTON_LABEL']
635                         ."' name='button_parent_name' onclick='open_popup(document.MassUpdate.{$field['type_name']}.value, 600, 400, \"\", true, false, {$encoded_popup_request_data});'>
636                         ".SugarThemeRegistry::current()->getImage("id-ff-select", '', null, null, ".png", $app_strings['LBL_ID_FF_SELECT'])."
637                         </button></span>";
638                         $parent_type = $field['parent_type'];
639             $parent_types = $app_list_strings[$parent_type];
640             $disabled_parent_types = ACLController::disabledModuleList($parent_types,false, 'list');
641             foreach($disabled_parent_types as $disabled_parent_type) {
642                             unset($parent_types[$disabled_parent_type]);
643             }
644                         $types = get_select_options_with_id($parent_types, '');
645                         //BS Fix Bug 17110
646                         $pattern = "/\n<OPTION.*".$app_strings['LBL_NONE']."<\/OPTION>/";
647                         $types = preg_replace($pattern, "", $types);
648                         // End Fix
649
650             $json = getJSONobj();
651             $disabled_parent_types = $json->encode($disabled_parent_types);
652
653                         return <<<EOHTML
654 <td width="15%" scope="row">{$displayname} </td>
655 <td>
656     <table width='100%' border='0' cellspacing='0' cellpadding='0'>
657     <tr>
658         <td valign='top'>
659             <select name='{$field['type_name']}' id='mass_{$field['type_name']}'>
660                 $types
661             </select>
662         </td>
663         <td valign='top'>
664                         <input name='{$field['id_name']}' id='mass_{$field['id_name']}' type='hidden' value=''>
665                         <input name='parent_name' id='mass_parent_name' class='sqsEnabled' autocomplete='off'
666                 type='text' value=''>
667             $change_parent_button
668         </td>
669     </tr>
670     </table>
671 </td>
672 <script type="text/javascript">
673 <!--
674 var disabledModules='{$disabled_parent_types}';
675 if(typeof sqs_objects == 'undefined'){
676     var sqs_objects = new Array;
677 }
678 sqs_objects['MassUpdate_parent_name'] = $qsName;
679 registerSingleSmartInputListener(document.getElementById('mass_parent_name'));
680 addToValidateBinaryDependency('MassUpdate', 'parent_name', 'alpha', false, '{$app_strings['ERR_SQS_NO_MATCH_FIELD']} {$app_strings['LBL_ASSIGNED_TO']}','parent_id');
681
682 document.getElementById('mass_{$field['type_name']}').onchange = function()
683 {
684     document.MassUpdate.parent_name.value="";
685     document.MassUpdate.parent_id.value="";
686
687         new_module = document.forms["MassUpdate"].elements["parent_type"].value;
688
689         if(typeof(disabledModules[new_module]) != 'undefined') {
690                 sqs_objects["MassUpdate_parent_name"]["disable"] = true;
691                 document.forms["MassUpdate"].elements["parent_name"].readOnly = true;
692         } else {
693                 sqs_objects["MassUpdate_parent_name"]["disable"] = false;
694                 document.forms["MassUpdate"].elements["parent_name"].readOnly = false;
695         }
696         sqs_objects["MassUpdate_parent_name"]["modules"] = new Array(new_module);
697     enableQS(false);
698
699     checkParentType(document.MassUpdate.parent_type.value, document.MassUpdate.button_parent_name);
700 }
701 -->
702 </script>
703 EOHTML;
704         }
705
706         /**
707           * Add a generic input type='text' field
708           * @param displayname Name to display in the popup window
709           * @param field_name name of the field
710           */
711         function addInputType($displayname, $varname){
712                 //letrium ltd
713                 $displayname = addslashes($displayname);
714                 $html = <<<EOQ
715         <td scope="row" width="20%">$displayname</td>
716         <td class='dataField' width="30%"><input type="text" name='$varname' size="12" id='{$varname}' maxlength='10' value=""></td>
717         <script> addToValidate('MassUpdate','$varname','int',false,'$displayname');</script>
718 EOQ;
719                 return $html;
720
721         }
722
723     /**
724           * Add a generic widget to lookup Users.
725           * @param displayname Name to display in the popup window
726           * @param varname name of the variable
727           * @param id_name name of the id in vardef
728           * @param mod_type name of the module, either "Contact" or "Releases" currently
729           */
730         function addUserName($displayname, $varname, $id_name='', $mod_type){
731                 global $app_strings;
732
733                 if(empty($id_name))
734                 $id_name = strtolower($mod_type)."_id";
735
736                 ///////////////////////////////////////
737                 ///
738                 /// SETUP POPUP
739         $reportsDisplayName = showFullName() ? 'name' : 'user_name';
740                 $popup_request_data = array(
741                         'call_back_function' => 'set_return',
742                         'form_name' => 'MassUpdate',
743                         'field_to_name_array' => array(
744                                 'id' => "{$id_name}",
745                                 "$reportsDisplayName" => "{$varname}",
746                                 ),
747                                 );
748
749                                 $json = getJSONobj();
750                                 $encoded_popup_request_data = $json->encode($popup_request_data);
751
752                 $qsName = array(
753                                     'form' => 'MassUpdate',
754                                                 'method' => 'get_user_array',
755                         'modules' => array("{$mod_type}"),
756                         'group' => 'or',
757                                                 'field_list' => array('user_name', 'id'),
758                                                 'populate_list' => array("mass_{$varname}", "mass_{$id_name}"),
759                                                 'conditions' => array(array('name'=>'name','op'=>'like_custom','end'=>'%','value'=>'')),
760                                                 'limit' => '30','no_match_text' => $app_strings['ERR_SQS_NO_MATCH']);
761                 $qsName = $json->encode($qsName);
762                                 //
763                                 ///////////////////////////////////////
764
765             return <<<EOHTML
766 <td width='15%'  scope='row' class='dataLabel'>$displayname</td>
767 <td width='35%' class='dataField'>
768     <input name='{$varname}' id='mass_{$varname}' class='sqsEnabled' autocomplete='off' type='text' value=''>
769     <input name='{$id_name}' id='mass_{$id_name}' type='hidden' value=''>&nbsp;
770     <input title='{$app_strings['LBL_SELECT_BUTTON_TITLE']}'
771         type='button' class='button' value='{$app_strings['LBL_SELECT_BUTTON_LABEL']}' name='button'
772         onclick='open_popup("$mod_type", 600, 400, "", true, false, {$encoded_popup_request_data});'
773         />
774 </td>
775 <script type="text/javascript">
776 <!--
777 if(typeof sqs_objects == 'undefined'){
778     var sqs_objects = new Array;
779 }
780 sqs_objects['MassUpdate_{$varname}'] = $qsName;
781 registerSingleSmartInputListener(document.getElementById('mass_{$varname}'));
782 addToValidateBinaryDependency('MassUpdate', '{$varname}', 'alpha', false, '{$app_strings['ERR_SQS_NO_MATCH_FIELD']} {$app_strings['LBL_ASSIGNED_TO']}','{$id_name}');
783 -->
784 </script>
785 EOHTML;
786         }
787
788
789         /**
790           * Add a generic module popup selection popup window HTML code.
791           * Currently supports Contact and Releases
792           * @param displayname Name to display in the popup window
793           * @param varname name of the variable
794           * @param id_name name of the id in vardef
795           * @param mod_type name of the module, either "Contact" or "Releases" currently
796           */
797         function addGenericModuleID($displayname, $varname, $id_name='', $mod_type){
798                 global $app_strings;
799
800                 if(empty($id_name))
801                 $id_name = strtolower($mod_type)."_id";
802
803                 ///////////////////////////////////////
804                 ///
805                 /// SETUP POPUP
806
807                 $popup_request_data = array(
808                         'call_back_function' => 'set_return',
809                         'form_name' => 'MassUpdate',
810                         'field_to_name_array' => array(
811                                 'id' => "{$id_name}",
812                                 'name' => "{$varname}",
813                                 ),
814                                 );
815
816                                 $json = getJSONobj();
817                                 $encoded_popup_request_data = $json->encode($popup_request_data);
818
819                 $qsName = array(
820                                     'form' => 'MassUpdate',
821                                                 'method' => 'query',
822                         'modules' => array("{$mod_type}"),
823                         'group' => 'or',
824                                                 'field_list' => array('name', 'id'),
825                                                 'populate_list' => array("mass_{$varname}", "mass_{$id_name}"),
826                                                 'conditions' => array(array('name'=>'name','op'=>'like_custom','end'=>'%','value'=>'')),
827                                                 'limit' => '30','no_match_text' => $app_strings['ERR_SQS_NO_MATCH']);
828                 $qsName = $json->encode($qsName);
829                                 $img = SugarThemeRegistry::current()->getImageURL("id-ff-select.png");
830                                 //
831                                 ///////////////////////////////////////
832
833             return <<<EOHTML
834 <td width='15%'  scope='row' class='dataLabel'>$displayname</td>
835 <td width='35%' class='dataField'>
836     <input name='{$varname}' id='mass_{$varname}' class='sqsEnabled' autocomplete='off' type='text' value=''>
837     <input name='{$id_name}' id='mass_{$id_name}' type='hidden' value=''>
838         <span class="id-ff multiple">
839     <button title='{$app_strings['LBL_SELECT_BUTTON_TITLE']}'
840         type='button' class='button' value='{$app_strings['LBL_SELECT_BUTTON_LABEL']}' name='button'
841         onclick='open_popup("$mod_type", 600, 400, "", true, false, {$encoded_popup_request_data});'
842         /><img alt="$img" src="$img"></button></span>
843 </td>
844 <script type="text/javascript">
845 <!--
846 if(typeof sqs_objects == 'undefined'){
847     var sqs_objects = new Array;
848 }
849 sqs_objects['MassUpdate_{$varname}'] = $qsName;
850 registerSingleSmartInputListener(document.getElementById('mass_{$varname}'));
851 addToValidateBinaryDependency('MassUpdate', '{$varname}', 'alpha', false, '{$app_strings['ERR_SQS_NO_MATCH_FIELD']} {$app_strings['LBL_ASSIGNED_TO']}','{$id_name}');
852 -->
853 </script>
854 EOHTML;
855         }
856         /**
857           * Add Account selection popup window HTML code
858           * @param displayname Name to display in the popup window
859           * @param varname name of the variable
860           * @param id_name name of the id in vardef
861           */
862         function addAccountID($displayname, $varname, $id_name=''){
863                 global $app_strings;
864
865                 $json = getJSONobj();
866
867                 if(empty($id_name))
868                 $id_name = "account_id";
869
870                 ///////////////////////////////////////
871                 ///
872                 /// SETUP POPUP
873
874                 $popup_request_data = array(
875                         'call_back_function' => 'set_return',
876                         'form_name' => 'MassUpdate',
877                         'field_to_name_array' => array(
878                                 'id' => "{$id_name}",
879                                 'name' => "{$varname}",
880                                 ),
881                                 );
882
883                                 $encoded_popup_request_data = $json->encode($popup_request_data);
884
885                                 //
886                                 ///////////////////////////////////////
887
888                                 $qsParent = array(
889                                                         'form' => 'MassUpdate',
890                                                         'method' => 'query',
891                                                         'modules' => array('Accounts'),
892                                                         'group' => 'or',
893                                                         'field_list' => array('name', 'id'),
894                                                         'populate_list' => array('parent_name', 'parent_id'),
895                                                         'conditions' => array(array('name'=>'name','op'=>'like_custom','end'=>'%','value'=>'')),
896                                                         'order' => 'name',
897                                                         'limit' => '30',
898                                                         'no_match_text' => $app_strings['ERR_SQS_NO_MATCH']
899                                                         );
900                                                         $qsParent['populate_list'] = array('mass_'. $varname, 'mass_' . $id_name);
901                                                         $img = SugarThemeRegistry::current()->getImageURL("id-ff-select.png");
902                                                         $html = '<td scope="row">' . $displayname . " </td>\n"
903                                                         . '<td><input class="sqsEnabled" type="text" autocomplete="off" id="mass_' . $varname .'" name="' . $varname . '" value="" /><input id="mass_' . $id_name . '" type="hidden" name="'
904                                                         . $id_name . '" value="" />&nbsp;<span class="id-ff multiple"><button type="button" name="btn1" class="button" title="'
905                                                         . $app_strings['LBL_SELECT_BUTTON_LABEL'] . '"  value="' . $app_strings['LBL_SELECT_BUTTON_LABEL'] . '" onclick='
906                                                         . "'open_popup(\"Accounts\",600,400,\"\",true,false,{$encoded_popup_request_data});' /><img alt=\"$img\" src=\"$img\"></button></span></td>\n";
907                                                         $html .= '<script type="text/javascript" language="javascript">if(typeof sqs_objects == \'undefined\'){var sqs_objects = new Array;}sqs_objects[\'MassUpdate_' . $varname . '\'] = ' .
908                                                         $json->encode($qsParent) . '; registerSingleSmartInputListener(document.getElementById(\'mass_' . $varname . '\'));
909                                         addToValidateBinaryDependency(\'MassUpdate\', \''.$varname.'\', \'alpha\', false, \'' . $app_strings['ERR_SQS_NO_MATCH_FIELD'] . $app_strings['LBL_ACCOUNT'] . '\',\''.$id_name.'\');
910                                         </script>';
911
912                                                         return $html;
913         }
914
915         /**
916           * Add AssignedUser popup window HTML code
917           * @param displayname Name to display in the popup window
918           * @param varname name of the variable
919           */
920         function addAssignedUserID($displayname, $varname){
921                 global $app_strings;
922
923                 $json = getJSONobj();
924
925                 $popup_request_data = array(
926                 'call_back_function' => 'set_return',
927                 'form_name' => 'MassUpdate',
928                 'field_to_name_array' => array(
929                         'id' => 'assigned_user_id',
930                         'user_name' => 'assigned_user_name',
931                         ),
932                         );
933                         $encoded_popup_request_data = $json->encode($popup_request_data);
934                         $qsUser = array(
935                                     'form' => 'MassUpdate',
936                                                 'method' => 'get_user_array', // special method
937                                                 'field_list' => array('user_name', 'id'),
938                                                 'populate_list' => array('assigned_user_name', 'assigned_user_id'),
939                                                 'conditions' => array(array('name'=>'user_name','op'=>'like_custom','end'=>'%','value'=>'')),
940                                                 'limit' => '30','no_match_text' => $app_strings['ERR_SQS_NO_MATCH']);
941
942                                                 $qsUser['populate_list'] = array('mass_assigned_user_name', 'mass_assigned_user_id');
943                                                 $img = SugarThemeRegistry::current()->getImageURL("id-ff-select.png");
944                                                 $html = <<<EOQ
945                 <td width="15%" scope="row">$displayname</td>
946                 <td ><input class="sqsEnabled" autocomplete="off" id="mass_assigned_user_name" name='assigned_user_name' type="text" value=""><input id='mass_assigned_user_id' name='assigned_user_id' type="hidden" value="" />
947                 <span class="id-ff multiple"><button id="mass_assigned_user_name_btn" title="{$app_strings['LBL_SELECT_BUTTON_TITLE']}" type="button" class="button" value='{$app_strings['LBL_SELECT_BUTTON_LABEL']}' name=btn1
948                                 onclick='open_popup("Users", 600, 400, "", true, false, $encoded_popup_request_data);' /><img src="$img"></button></span>
949                 </td>
950 EOQ;
951                                                 $html .= '<script type="text/javascript" language="javascript">if(typeof sqs_objects == \'undefined\'){var sqs_objects = new Array;}sqs_objects[\'MassUpdate_assigned_user_name\'] = ' .
952                                                 $json->encode($qsUser) . '; registerSingleSmartInputListener(document.getElementById(\'mass_assigned_user_name\'));
953                                 addToValidateBinaryDependency(\'MassUpdate\', \'assigned_user_name\', \'alpha\', false, \'' . $app_strings['ERR_SQS_NO_MATCH_FIELD'] . $app_strings['LBL_ASSIGNED_TO'] . '\',\'assigned_user_id\');
954                                 </script>';
955
956                                                 return $html;
957         }
958         /**
959           * Add Status selection popup window HTML code
960           * @param displayname Name to display in the popup window
961           * @param varname name of the variable
962           * @param options array of options for status
963           */
964         function addStatus($displayname, $varname, $options){
965                 global $app_strings, $app_list_strings;
966
967                 // cn: added "mass_" to the id tag to differentiate from the status id in StoreQuery
968                 $html = '<td scope="row" width="15%">'.$displayname.'</td><td>';
969                 if(is_array($options)){
970                         if(!isset($options['']) && !isset($options['0'])){
971                            $new_options = array();
972                            $new_options[''] = '';
973                            foreach($options as $key=>$value) {
974                                    $new_options[$key] = $value;
975                            }
976                            $options = $new_options;
977                         }
978             $options = get_select_options_with_id_separate_key(
979                 $options,
980                 $options,
981                 '__SugarMassUpdateClearField__',
982                 true
983             );
984                         $html .= '<select id="mass_'.$varname.'" name="'.$varname.'">'.$options.'</select>';
985                 }else{
986                         $html .= $options;
987                 }
988                 $html .= '</td>';
989                 return $html;
990         }
991
992 /**
993           * Add Status selection popup window HTML code
994           * @param displayname Name to display in the popup window
995           * @param varname name of the variable
996           * @param options array of options for status
997           */
998         function addBool($displayname, $varname){
999                 global $app_strings, $app_list_strings;
1000                 return $this->addStatus($displayname, $varname, $app_list_strings['checkbox_dom']);
1001         }
1002         function addStatusMulti($displayname, $varname, $options){
1003                 global $app_strings, $app_list_strings;
1004
1005                 if(!isset($options['']) && !isset($options['0'])){
1006                    $new_options = array();
1007                    $new_options[''] = '';
1008                    foreach($options as $key=>$value) {
1009                            $new_options[$key] = $value;
1010                    }
1011                    $options = $new_options;
1012                 }
1013                 $options = get_select_options_with_id_separate_key($options, $options, '', true);;
1014
1015                 // cn: added "mass_" to the id tag to differentiate from the status id in StoreQuery
1016                 $html = '<td scope="row" width="15%">'.$displayname.'</td>
1017                          <td><select id="mass_'.$varname.'" name="'.$varname.'[]" size="5" MULTIPLE>'.$options.'</select></td>';
1018                 return $html;
1019         }
1020         /**
1021           * Add Date selection popup window HTML code
1022           * @param displayname Name to display in the popup window
1023           * @param varname name of the variable
1024           */
1025         function addDate($displayname, $varname){
1026                 global $timedate;
1027                 //letrium ltd
1028                 $displayname = addslashes($displayname);
1029                 $userformat = '('. $timedate->get_user_date_format().')';
1030                 $cal_dateformat = $timedate->get_cal_date_format();
1031                 global $app_strings, $app_list_strings, $theme;
1032
1033                 $javascriptend = <<<EOQ
1034                  <script type="text/javascript">
1035                 Calendar.setup ({
1036                         inputField : "${varname}jscal_field", daFormat : "$cal_dateformat", ifFormat : "$cal_dateformat", showsTime : false, button : "${varname}jscal_trigger", singleClick : true, step : 1, weekNumbers:false
1037                 });
1038                 </script>
1039 EOQ;
1040         $jscalendarImage = SugarThemeRegistry::current()->getImageURL('jscalendar.gif');
1041                 $html = <<<EOQ
1042         <td scope="row" width="20%">$displayname</td>
1043         <td class='dataField' width="30%"><input onblur="parseDate(this, '$cal_dateformat')" type="text" name='$varname' size="12" id='{$varname}jscal_field' maxlength='10' value="">
1044     <img src="$jscalendarImage" id="{$varname}jscal_trigger" align="absmiddle" title="{$app_strings['LBL_MASSUPDATE_DATE']}" alt='{$app_strings['LBL_MASSUPDATE_DATE']}'>&nbsp;<span class="dateFormat">$userformat</span>
1045         $javascriptend</td>
1046         <script> addToValidate('MassUpdate','$varname','date',false,'$displayname');</script>
1047 EOQ;
1048                 return $html;
1049
1050         }
1051
1052         function addRadioenumItem($name, $value, $output) {
1053                 $_output = '';
1054                 $_output .= '<label>';
1055                 $_output .= '<input type="radio" name="'
1056                 . $name . '" value="'
1057                 . $value. '"';
1058
1059             $_output .= ' />' . ($output == '' ? $GLOBALS['app_strings']['LBL_LINK_NONE'] : $output);
1060             $_output .= '</label><br />';
1061             return $_output;
1062         }
1063
1064         function addRadioenum($displayname, $varname, $options){
1065                  foreach ($options as $_key=>$_val){
1066             $_html_result[] = $this->addRadioenumItem($varname, $_key, $_val);
1067         }
1068
1069                 $html = '<td scope="row" width="15%">'.$displayname.'</td>
1070                          <td>'.implode("\n",$_html_result).'</td>';
1071                 return $html;
1072         }
1073         /**
1074           * Add Datetime selection popup window HTML code
1075           * @param displayname Name to display in the popup window
1076           * @param varname name of the variable
1077           */
1078         function addDatetime($displayname, $varname){
1079                 global $timedate;
1080                 $userformat = $timedate->get_user_time_format();
1081                 $cal_dateformat = $timedate->get_cal_date_format();
1082                 global $app_strings, $app_list_strings, $theme;
1083                 $jscalendarImage = SugarThemeRegistry::current()->getImageURL('jscalendar.gif');
1084
1085                 $javascriptend = <<<EOQ
1086                  <script type="text/javascript">
1087                 Calendar.setup ({
1088                         inputField : "{$varname}_date",
1089                         daFormat : "$cal_dateformat",
1090                         ifFormat : "$cal_dateformat",
1091                         showsTime : false,
1092                         button : "{$varname}_trigger",
1093                         singleClick : true,
1094                         step : 1,
1095                         weekNumbers:false
1096                 });
1097                 </script>
1098 EOQ;
1099         $dtscript = getVersionedScript('include/SugarFields/Fields/Datetimecombo/Datetimecombo.js');
1100                 $html = <<<EOQ
1101                 <td scope="row" width="20%">$displayname</td>
1102                 <td class='dataField' width="30%"><input onblur="parseDate(this, '$cal_dateformat')" type="text" name='$varname' size="12" id='{$varname}_date' maxlength='10' value="">
1103                 <img border="0" src="$jscalendarImage" alt='{$app_strings['LBL_MASSUPDATE_DATE']}' id="{$varname}_trigger" title="{$app_strings['LBL_MASSUPDATE_DATE']}"  align="absmiddle">&nbsp;$javascriptend
1104
1105                 <span id="{$varname}_time_section"></span>
1106                 </td>
1107                 <input type="hidden" id="{$varname}" name="{$varname}">
1108                 $dtscript
1109                 <script type="text/javascript">
1110                 var combo_{$varname} = new Datetimecombo(" ", "$varname", "$userformat", '','','',1);
1111                 //Render the remaining widget fields
1112                 text = combo_{$varname}.html('');
1113                 document.getElementById('{$varname}_time_section').innerHTML = text;
1114
1115                 //Call eval on the update function to handle updates to calendar picker object
1116                 eval(combo_{$varname}.jsscript(''));
1117
1118                 function update_{$varname}_available() {
1119                       YAHOO.util.Event.onAvailable("{$varname}_date", this.handleOnAvailable, this);
1120                 }
1121
1122                 update_{$varname}_available.prototype.handleOnAvailable = function(me) {
1123                         Calendar.setup ({
1124                         onClose : update_{$varname},
1125                         inputField : "{$varname}_date",
1126                         daFormat : "$cal_dateformat",
1127                         ifFormat : "$cal_dateformat",
1128                         button : "{$varname}_trigger",
1129                         singleClick : true,
1130                         step : 1,
1131                         weekNumbers:false
1132                         });
1133
1134                         //Call update for first time to round hours and minute values
1135                         combo_{$varname}.update(false);
1136                 }
1137
1138                 var obj_{$varname} = new update_{$varname}_available();
1139                 </script>
1140
1141                 <script> addToValidate('MassUpdate','{$varname}_date','date',false,'$displayname');
1142                 addToValidateBinaryDependency('MassUpdate', '{$varname}_hours', 'alpha', false, "{$app_strings['ERR_MISSING_REQUIRED_FIELDS']}", '{$varname}_date');
1143                 addToValidateBinaryDependency('MassUpdate', '{$varname}_minutes', 'alpha', false, "{$app_strings['ERR_MISSING_REQUIRED_FIELDS']}", '{$varname}_date');
1144                 addToValidateBinaryDependency('MassUpdate', '{$varname}_meridiem', 'alpha', false, "{$app_strings['ERR_MISSING_REQUIRED_FIELDS']}", '{$varname}_date');
1145                 </script>
1146
1147 EOQ;
1148                 return $html;
1149         }
1150
1151         function date_to_dateTime($field, $value) {
1152                 global $timedate;
1153             //Check if none was set
1154         if (isset($this->sugarbean->field_defs[$field]['group'])) {
1155             $group =  $this->sugarbean->field_defs[$field]['group'];
1156             if (isset($this->sugarbean->field_defs[$group."_flag"]) && isset($_POST[$group."_flag"])
1157                 && $_POST[$group."_flag"] == 1) {
1158                 return "";
1159             }
1160         }
1161
1162         $oldDateTime = $this->sugarbean->$field;
1163         $oldTime = explode(" ", $oldDateTime);
1164         if (isset($oldTime[1])) {
1165                 $oldTime = $oldTime[1];
1166         } else {
1167                 $oldTime = $timedate->now();
1168         }
1169         $oldTime = explode(" ", $oldTime);
1170         if (isset($oldTime[1])) {
1171                 $oldTime = $oldTime[1];
1172         } else {
1173                 $oldTime = $oldTime[0];
1174         }
1175         $value = explode(" ", $value);
1176         $value = $value[0];
1177             return $value." ".$oldTime;
1178         }
1179
1180         function checkClearField($field, $value) {
1181             if ($value == 1 && strpos($field, '_flag')) {
1182                 $fName = substr($field, -5);
1183             if (isset($this->sugarbean->field_defs[$field]['group'])) {
1184                 $group =  $this->sugarbean->field_defs[$field]['group'];
1185                 if (isset($this->sugarbean->field_defs[$group])) {
1186                     $_POST[$group] = "";
1187                 }
1188             }
1189             }
1190         }
1191
1192     function generateSearchWhere($module, $query) {//this function is similar with function prepareSearchForm() in view.list.php
1193         $seed = loadBean($module);
1194         $this->use_old_search = true;
1195         if(file_exists('modules/'.$module.'/SearchForm.html')){
1196             if(file_exists('modules/' . $module . '/metadata/SearchFields.php')) {
1197                 require_once('include/SearchForm/SearchForm.php');
1198                 $searchForm = new SearchForm($module, $seed);
1199             }
1200             elseif(!empty($_SESSION['export_where'])) { //bug 26026, sometimes some module doesn't have a metadata/SearchFields.php, the searchfrom is generated in the ListView.php.
1201             //So currently massupdate will not gernerate the where sql. It will use the sql stored in the SESSION. But this will cause bug 24722, and it cannot be avoided now.
1202                 $where = $_SESSION['export_where'];
1203                 $whereArr = explode (" ", trim($where));
1204                 if ($whereArr[0] == trim('where')) {
1205                     $whereClean = array_shift($whereArr);
1206                 }
1207                 $this->where_clauses = implode(" ", $whereArr);
1208                 return;
1209             }
1210             else {
1211                 $this->where_clauses = '';
1212                 return;
1213             }
1214         }
1215         else{
1216             $this->use_old_search = false;
1217             require_once('include/SearchForm/SearchForm2.php');
1218
1219             if(file_exists('custom/modules/'.$module.'/metadata/metafiles.php')){
1220                 require('custom/modules/'.$module.'/metadata/metafiles.php');
1221             }elseif(file_exists('modules/'.$module.'/metadata/metafiles.php')){
1222                 require('modules/'.$module.'/metadata/metafiles.php');
1223             }
1224
1225             $searchFields = $this->getSearchFields($module);
1226             $searchdefs = $this->getSearchDefs($module);
1227
1228             if(empty($searchdefs) || empty($searchFields)) {
1229                $this->where_clauses = ''; //for some modules, such as iframe, it has massupdate, but it doesn't have search function, the where sql should be empty.
1230                return;
1231             }
1232
1233             $searchForm = new SearchForm($seed, $module);
1234             $searchForm->setup($searchdefs, $searchFields, 'SearchFormGeneric.tpl');
1235         }
1236         /* bug 31271: using false to not add all bean fields since some beans - like SavedReports
1237            can have fields named 'module' etc. which may break the query */
1238         $query = unserialize(base64_decode($query));
1239         $searchForm->populateFromArray($query, null, true);
1240         $this->searchFields = $searchForm->searchFields;
1241         $where_clauses = $searchForm->generateSearchWhere(true, $module);
1242         if (count($where_clauses) > 0 ) {
1243             $this->where_clauses = '('. implode(' ) AND ( ', $where_clauses) . ')';
1244             $GLOBALS['log']->info("MassUpdate Where Clause: {$this->where_clauses}");
1245         } else {
1246             $this->where_clauses = '';
1247         }
1248     }
1249
1250     protected function getSearchDefs($module, $metafiles = array())
1251     {
1252         if (file_exists('custom/modules/'.$module.'/metadata/searchdefs.php'))
1253         {
1254             require('custom/modules/'.$module.'/metadata/searchdefs.php');
1255         }
1256         elseif (!empty($metafiles[$module]['searchdefs']))
1257         {
1258             require($metafiles[$module]['searchdefs']);
1259         }
1260         elseif (file_exists('modules/'.$module.'/metadata/searchdefs.php'))
1261         {
1262             require('modules/'.$module.'/metadata/searchdefs.php');
1263         }
1264
1265         return isset($searchdefs) ? $searchdefs : array();
1266     }
1267
1268     protected function getSearchFields($module, $metafiles = array())
1269     {
1270         if (file_exists('custom/modules/' . $module . '/metadata/SearchFields.php'))
1271         {
1272             require('custom/modules/' . $module . '/metadata/SearchFields.php');
1273         }
1274         elseif(!empty($metafiles[$module]['searchfields']))
1275         {
1276             require($metafiles[$module]['searchfields']);
1277         }
1278         elseif(file_exists('modules/'.$module.'/metadata/SearchFields.php'))
1279         {
1280             require('modules/'.$module.'/metadata/SearchFields.php');
1281         }
1282
1283         return isset($searchFields) ? $searchFields : array();
1284     }
1285     /**
1286      * This is kinda a hack how it is implimented, but will tell us whether or not a focus has
1287      * fields for Mass Update
1288      *
1289      * @return bool
1290      */
1291     public function doMassUpdateFieldsExistForFocus()
1292     {
1293         static $banned = array('date_modified'=>1, 'date_entered'=>1, 'created_by'=>1, 'modified_user_id'=>1, 'deleted'=>1,'modified_by_name'=>1,);
1294         foreach($this->sugarbean->field_defs as $field) {
1295             if(!isset($banned[$field['name']]) && (!isset($field['massupdate']) || !empty($field['massupdate']))){
1296                 if(isset($field['type']) && $field['type'] == 'relate' && isset($field['id_name']) && $field['id_name'] == 'assigned_user_id')
1297                     $field['type'] = 'assigned_user_name';
1298                 if(isset($field['custom_type']))$field['type'] = $field['custom_type'];
1299                 if(isset($field['type']))
1300                 {
1301                     switch($field["type"]){
1302                     case "relate":
1303                     case "parent":
1304                     case "int":
1305                     case "contact_id":
1306                     case "assigned_user_name":
1307                     case "account_id":
1308                     case "account_name":
1309                     case "bool":
1310                     case "enum":
1311                     case "multienum":
1312                     case "radioenum":
1313                     case "datetimecombo":
1314                     case "datetime":
1315                     case "date":
1316                         return true;
1317                         break;
1318                     }
1319                 }
1320             }
1321         }
1322
1323         return false;
1324     }
1325
1326      /**
1327      * Have to be overridden in children
1328      * @param string $displayname field label
1329      * @param string $field field name
1330      * @param bool $even even or odd
1331      * @return string html field data
1332      */
1333     protected function addDefault($displayname,  $field, & $even)
1334     {
1335         return '';
1336     }
1337 }
1338
1339 ?>