1
|
|
|
<?php |
2
|
|
|
/********************************************************************************* |
3
|
|
|
* SugarCRM Community Edition is a customer relationship management program developed by |
4
|
|
|
* SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
5
|
|
|
|
6
|
|
|
* SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd. |
7
|
|
|
* Copyright (C) 2011 - 2014 Salesagility Ltd. |
8
|
|
|
* |
9
|
|
|
* This program is free software; you can redistribute it and/or modify it under |
10
|
|
|
* the terms of the GNU Affero General Public License version 3 as published by the |
11
|
|
|
* Free Software Foundation with the addition of the following permission added |
12
|
|
|
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
13
|
|
|
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
14
|
|
|
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
15
|
|
|
* |
16
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT |
17
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
18
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
19
|
|
|
* details. |
20
|
|
|
* |
21
|
|
|
* You should have received a copy of the GNU Affero General Public License along with |
22
|
|
|
* this program; if not, see http://www.gnu.org/licenses or write to the Free |
23
|
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
24
|
|
|
* 02110-1301 USA. |
25
|
|
|
* |
26
|
|
|
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
27
|
|
|
* SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
28
|
|
|
* |
29
|
|
|
* The interactive user interfaces in modified source and object code versions |
30
|
|
|
* of this program must display Appropriate Legal Notices, as required under |
31
|
|
|
* Section 5 of the GNU Affero General Public License version 3. |
32
|
|
|
* |
33
|
|
|
* In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
34
|
|
|
* these Appropriate Legal Notices must retain the display of the "Powered by |
35
|
|
|
* SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
36
|
|
|
* reasonably feasible for technical reasons, the Appropriate Legal Notices must |
37
|
|
|
* display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
38
|
|
|
********************************************************************************/ |
39
|
|
|
|
40
|
|
|
|
41
|
|
|
require_once('include/tabs.php'); |
42
|
|
|
/** |
43
|
|
|
* Old search form |
44
|
|
|
* @api |
45
|
|
|
*/ |
46
|
|
|
class SearchForm { |
47
|
|
|
/** |
48
|
|
|
* SearchForm Template to use (xtpl) |
49
|
|
|
* @var string |
50
|
|
|
*/ |
51
|
|
|
var $tpl; |
52
|
|
|
/** |
53
|
|
|
* SearchField meta data array to use. Populated from moduleDir/metadata/SearchFields |
54
|
|
|
* @var array |
55
|
|
|
*/ |
56
|
|
|
var $searchFields; |
57
|
|
|
/** |
58
|
|
|
* Seed bean to use |
59
|
|
|
* @var bean |
60
|
|
|
*/ |
61
|
|
|
var $bean; |
62
|
|
|
/** |
63
|
|
|
* Module the search from is for |
64
|
|
|
* @var string |
65
|
|
|
*/ |
66
|
|
|
var $module; |
67
|
|
|
/** |
68
|
|
|
* meta data for the tabs to display |
69
|
|
|
* @var array |
70
|
|
|
*/ |
71
|
|
|
var $tabs; |
72
|
|
|
/** |
73
|
|
|
* XTPL object |
74
|
|
|
* @var object |
75
|
|
|
*/ |
76
|
|
|
var $xtpl; |
77
|
|
|
/** |
78
|
|
|
* Use to determine whether or not to show the saved search options |
79
|
|
|
* @var boolean |
80
|
|
|
*/ |
81
|
|
|
var $showSavedSearchOptions = true; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* loads SearchFields MetaData, sets member variables |
85
|
|
|
* |
86
|
|
|
* @param string $module moduleDir |
87
|
|
|
* @param bean $seedBean seed bean to use |
88
|
|
|
* @param string $tpl template to use, defaults to moduleDir/SearchForm.html |
89
|
|
|
* |
90
|
|
|
*/ |
91
|
|
|
function __construct($module, &$seedBean, $tpl = null) { |
92
|
|
|
global $app_strings; |
93
|
|
|
|
94
|
|
|
$this->module = $module; |
95
|
|
|
require_once('modules/' . $module . '/metadata/SearchFields.php'); |
96
|
|
|
if(file_exists('custom/modules/' . $module . '/metadata/SearchFields.php')){ |
97
|
|
|
require_once('custom/modules/' . $module . '/metadata/SearchFields.php'); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
|
101
|
|
|
//require_once('modules/' . $module . '/metadata/SearchFields.php'); |
102
|
|
|
$this->searchFields = $searchFields[$module]; |
103
|
|
|
if(empty($tpl)) { |
104
|
|
|
if(!empty($GLOBALS['layout_edit_mode'])){ |
105
|
|
|
$this->tpl = sugar_cached('studio/custom/working/modules/' . $module . '/SearchForm.html'); |
106
|
|
|
} |
107
|
|
|
else { |
108
|
|
|
$this->tpl = get_custom_file_if_exists('modules/' . $module . '/SearchForm.html'); |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
else { |
112
|
|
|
$this->tpl = $tpl; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
$this->bean = $seedBean; |
116
|
|
|
$this->tabs = array(array('title' => $app_strings['LNK_BASIC_SEARCH'], |
117
|
|
|
'link' => $module . '|basic_search', |
118
|
|
|
'key' => $module . '|basic_search'), |
119
|
|
|
array('title' => $app_strings['LNK_ADVANCED_SEARCH'], |
120
|
|
|
'link' => $module . '|advanced_search', |
121
|
|
|
'key' => $module . '|advanced_search')); |
122
|
|
|
|
123
|
|
|
if(file_exists('modules/'.$this->module.'/index.php')){ |
124
|
|
|
$this->tabs[] = array('title' => $app_strings['LNK_SAVED_VIEWS'], |
125
|
|
|
'link' => $module . '|saved_views', |
126
|
|
|
'key' => $module . '|saved_views'); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead |
133
|
|
|
*/ |
134
|
|
|
function SearchForm($module, &$seedBean, $tpl = null){ |
135
|
|
|
$deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; |
136
|
|
|
if(isset($GLOBALS['log'])) { |
137
|
|
|
$GLOBALS['log']->deprecated($deprecatedMessage); |
138
|
|
|
} |
139
|
|
|
else { |
140
|
|
|
trigger_error($deprecatedMessage, E_USER_DEPRECATED); |
141
|
|
|
} |
142
|
|
|
self::__construct($module, $seedBean, $tpl); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Populate the searchFields from an array |
147
|
|
|
* |
148
|
|
|
* @param array $array array to search through |
149
|
|
|
* @param string $switchVar variable to use in switch statement |
150
|
|
|
* @param bool $addAllBeanFields true to process at all bean fields |
151
|
|
|
*/ |
152
|
|
|
function populateFromArray(&$array, $switchVar = null, $addAllBeanFields = true) { |
153
|
|
|
|
154
|
|
|
//CL Bug:33176 |
155
|
|
|
if(empty($array['searchFormTab']) && empty($switchVar)) { |
156
|
|
|
$array['searchFormTab'] = 'advanced_search'; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
if(!empty($array['searchFormTab']) || !empty($switchVar)) { |
160
|
|
|
$arrayKeys = array_keys($array); |
161
|
|
|
$searchFieldsKeys = array_keys($this->searchFields); |
162
|
|
|
if(empty($switchVar)) $switchVar = $array['searchFormTab']; |
163
|
|
|
switch($switchVar) { |
164
|
|
|
case 'basic_search': |
165
|
|
|
foreach($this->searchFields as $name => $params) { |
166
|
|
|
if(isset($array[$name . '_basic'])) { |
167
|
|
|
$this->searchFields[$name]['value'] = |
168
|
|
|
is_string($array[$name . '_basic'])?trim($array[$name . '_basic']):$array[$name . '_basic']; |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
if($addAllBeanFields) { |
172
|
|
|
foreach($this->bean->field_name_map as $key => $params) { |
173
|
|
|
if(in_array($key . '_basic' , $arrayKeys) && !in_array($key, $searchFieldsKeys)) { |
174
|
|
|
|
175
|
|
|
$this->searchFields[$key] = array('query_type' => 'default', |
176
|
|
|
'value' => $array[$key . '_basic']); |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
break; |
181
|
|
|
case 'advanced_search': |
182
|
|
|
foreach($this->searchFields as $name => $params) { |
183
|
|
|
if(isset($array[$name])) { |
184
|
|
|
$this->searchFields[$name]['value'] = is_string($array[$name])?trim($array[$name]):$array[$name]; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
if((empty($array['massupdate']) || $array['massupdate'] == 'false') && $addAllBeanFields) { |
188
|
|
|
foreach($this->bean->field_name_map as $key => $params) { |
189
|
|
|
if(in_array($key, $arrayKeys) && !in_array($key, $searchFieldsKeys)) { |
190
|
|
|
$this->searchFields[$key] = array('query_type' => 'default', |
191
|
|
|
'value' => $array[$key]); |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
} |
195
|
|
|
break; |
196
|
|
|
case 'saved_views': |
197
|
|
|
foreach($this->searchFields as $name => $params) { |
198
|
|
|
if(isset($array[$name . '_basic'])) { // save basic first |
199
|
|
|
$this->searchFields[$name]['value'] = $array[$name . '_basic']; |
200
|
|
|
} |
201
|
|
|
if(isset($array[$name])) { // overwrite by advanced if available |
202
|
|
|
$this->searchFields[$name]['value'] = $array[$name]; |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
if($addAllBeanFields) { |
206
|
|
|
foreach($this->bean->field_name_map as $key => $params) { |
207
|
|
|
if(!in_array($key, $searchFieldsKeys)) { |
208
|
|
|
if(in_array($key . '_basic', $arrayKeys) ) { |
209
|
|
|
$this->searchFields[$key] = array('query_type' => 'default', |
210
|
|
|
'value' => $array[$key . '_basic']); |
211
|
|
|
} |
212
|
|
|
if(in_array($key, $arrayKeys)) { |
213
|
|
|
$this->searchFields[$key] = array('query_type' => 'default', |
214
|
|
|
'value' => $array[$key]); |
215
|
|
|
} |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Populate the searchFields from $_REQUEST |
225
|
|
|
* |
226
|
|
|
* @param string $switchVar variable to use in switch statement |
227
|
|
|
* @param bool $addAllBeanFields true to process at all bean fields |
228
|
|
|
*/ |
229
|
|
|
function populateFromRequest($switchVar = null, $addAllBeanFields = true) { |
230
|
|
|
$this->populateFromArray($_REQUEST, $switchVar, $addAllBeanFields); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* The fuction will returns an array of filter conditions. |
236
|
|
|
* |
237
|
|
|
*/ |
238
|
|
|
function generateSearchWhere($add_custom_fields = false, $module='') { |
239
|
|
|
global $timedate; |
240
|
|
|
$values = $this->searchFields; |
241
|
|
|
|
242
|
|
|
$where_clauses = array(); |
243
|
|
|
//$like_char = '%'; |
244
|
|
|
$table_name = $this->bean->object_name; |
245
|
|
|
|
246
|
|
|
foreach($this->searchFields as $field=>$parms) { |
247
|
|
|
$customField = false; |
248
|
|
|
// Jenny - Bug 7462: We need a type check here to avoid database errors |
249
|
|
|
// when searching for numeric fields. This is a temporary fix until we have |
250
|
|
|
// a generic search form validation mechanism. |
251
|
|
|
$type = (!empty($this->bean->field_name_map[$field]['type']))?$this->bean->field_name_map[$field]['type']:''; |
252
|
|
|
if(!empty($this->bean->field_name_map[$field]['source']) && $this->bean->field_name_map[$field]['source'] == 'custom_fields'){ |
253
|
|
|
$customField = true; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
if ($type == 'int') { |
257
|
|
|
if (!empty($parms['value'])) { |
258
|
|
|
$tempVal = explode(',', $parms['value']); |
259
|
|
|
$newVal = ''; |
260
|
|
|
foreach($tempVal as $key => $val) { |
261
|
|
|
if (!empty($newVal)) |
262
|
|
|
$newVal .= ','; |
263
|
|
|
if(!empty($val) && !(is_numeric($val))) |
264
|
|
|
$newVal .= -1; |
265
|
|
|
else |
266
|
|
|
$newVal .= $val; |
267
|
|
|
} |
268
|
|
|
$parms['value'] = $newVal; |
269
|
|
|
} |
270
|
|
|
} |
271
|
|
|
// do not include where clause for custom fields with checkboxes that are unchecked |
272
|
|
|
elseif($type == 'bool' && empty($parms['value']) && $customField) { |
273
|
|
|
continue; |
274
|
|
|
} |
275
|
|
|
elseif($type == 'bool' && !empty($parms['value'])){ |
276
|
|
|
if ($parms['value'] == 'on'){ |
277
|
|
|
$parms['value'] = 1; |
278
|
|
|
} |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
if(isset($parms['value']) && $parms['value'] != "") { |
282
|
|
|
$operator = 'like'; |
283
|
|
|
if(!empty($parms['operator'])) { |
284
|
|
|
$operator = strtolower($parms['operator']); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
if(is_array($parms['value'])) { |
288
|
|
|
$field_value = ''; |
289
|
|
|
|
290
|
|
|
// If it is a custom field of multiselect we have to do some special processing |
291
|
|
|
if($customField && !empty($this->bean->field_name_map[$field]['isMultiSelect']) && $this->bean->field_name_map[$field]['isMultiSelect']) { |
292
|
|
|
$operator = 'custom_enum'; |
293
|
|
|
$db_field = $this->bean->table_name . "_cstm." . $field; |
294
|
|
|
foreach($parms['value'] as $key => $val) { |
295
|
|
|
if($val != ' ' and $val != '') { |
296
|
|
|
$qVal = $GLOBALS['db']->quote($val); |
297
|
|
|
if (!empty($field_value)) { |
298
|
|
|
$field_value .= ' or '; |
299
|
|
|
} |
300
|
|
|
$field_value .= "$db_field like '$qVal' or $db_field like '%$qVal^%' or $db_field like '%^$qVal%' or $db_field like '%^$qVal^%'"; |
301
|
|
|
} |
302
|
|
|
} |
303
|
|
|
} else { |
304
|
|
|
$operator = $operator != 'subquery' ? 'in' : $operator; |
305
|
|
|
foreach($parms['value'] as $key => $val) { |
306
|
|
|
if($val != ' ' and $val != '') { |
307
|
|
|
if (!empty($field_value)) { |
308
|
|
|
$field_value .= ','; |
309
|
|
|
} |
310
|
|
|
$field_value .= "'" . $GLOBALS['db']->quote($val) . "'"; |
311
|
|
|
} |
312
|
|
|
} |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
else { |
316
|
|
|
$field_value = $GLOBALS['db']->quote($parms['value']); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
//set db_fields array. |
320
|
|
|
if(!isset($parms['db_field'])) { |
321
|
|
|
$parms['db_field'] = array($field); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
if(isset($parms['my_items']) and $parms['my_items'] == true) { |
325
|
|
|
global $current_user; |
326
|
|
|
$field_value = $GLOBALS['db']->quote($current_user->id); |
327
|
|
|
$operator = '='; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
$where = ''; |
331
|
|
|
$itr = 0; |
332
|
|
|
if($field_value != '') { |
333
|
|
|
foreach ($parms['db_field'] as $db_field) { |
334
|
|
|
|
335
|
|
|
if (strstr($db_field, '.') === false) { |
336
|
|
|
if(!$customField){ |
337
|
|
|
$db_field = $this->bean->table_name . "." . $db_field; |
338
|
|
|
}else{ |
339
|
|
|
$db_field = $this->bean->table_name . "_cstm." . $db_field; |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
if($type == 'date') { |
345
|
|
|
// The regular expression check is to circumvent special case YYYY-MM |
346
|
|
|
$operator = '='; |
347
|
|
|
if(preg_match('/^\d{4}.\d{1,2}$/', $field_value) == 0) { |
348
|
|
|
$db_field = $this->bean->db->convert($db_field, "date_format", "%Y-%m"); |
349
|
|
|
} else { |
350
|
|
|
$field_value = $timedate->to_db_date($field_value, false); |
351
|
|
|
$db_field = $this->bean->db->convert($db_field, "date_format", "%Y-%m-%d"); |
352
|
|
|
} |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
if($type == 'datetime'|| $type == 'datetimecombo') { |
356
|
|
|
$dates = $timedate->getDayStartEndGMT($field_value); |
357
|
|
|
$field_value = array($this->bean->db->convert($dates["start"], "datetime"), |
358
|
|
|
$this->bean->db->convert($dates["end"], "datetime")); |
359
|
|
|
$operator = 'between'; |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
if($this->bean->db->supports('case_sensitive') && isset($parms['query_type']) && $parms['query_type'] == 'case_insensitive') { |
363
|
|
|
$db_field = 'upper(' . $db_field . ")"; |
364
|
|
|
$field_value = strtoupper($field_value); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
$itr++; |
368
|
|
|
if(!empty($where)) { |
369
|
|
|
$where .= " OR "; |
370
|
|
|
} |
371
|
|
|
switch($operator) { |
372
|
|
|
case 'subquery': |
373
|
|
|
$in = 'IN'; |
374
|
|
|
if ( isset($parms['subquery_in_clause']) ) { |
375
|
|
|
if ( !is_array($parms['subquery_in_clause']) ) { |
376
|
|
|
$in = $parms['subquery_in_clause']; |
377
|
|
|
} |
378
|
|
|
elseif ( isset($parms['subquery_in_clause'][$field_value]) ) { |
379
|
|
|
$in = $parms['subquery_in_clause'][$field_value]; |
380
|
|
|
} |
381
|
|
|
} |
382
|
|
|
$sq = $parms['subquery']; |
383
|
|
|
if(is_array($sq)){ |
384
|
|
|
$and_or = ' AND '; |
385
|
|
|
if (isset($sq['OR'])){ |
386
|
|
|
$and_or = ' OR '; |
387
|
|
|
} |
388
|
|
|
$first = true; |
389
|
|
|
foreach($sq as $q){ |
390
|
|
|
if(empty($q) || strlen($q)<2) continue; |
391
|
|
|
if(!$first){ |
392
|
|
|
$where .= $and_or; |
393
|
|
|
} |
394
|
|
|
$where .= " {$db_field} $in ({$q} '{$field_value}%') "; |
395
|
|
|
$first = false; |
396
|
|
|
} |
397
|
|
|
}elseif(!empty($parms['query_type']) && $parms['query_type'] == 'format'){ |
398
|
|
|
$stringFormatParams = array(0 => $field_value, 1 => $GLOBALS['current_user']->id); |
399
|
|
|
$where .= "{$db_field} $in (".string_format($parms['subquery'], $stringFormatParams).")"; |
400
|
|
|
}else{ |
401
|
|
|
$where .= "{$db_field} $in ({$parms['subquery']} '{$field_value}%')"; |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
break; |
405
|
|
|
case 'like': |
406
|
|
|
$where .= $db_field . " like ".$this->bean->db->quoted($field_value.'%'); |
407
|
|
|
break; |
408
|
|
|
case 'in': |
409
|
|
|
$where .= $db_field . " in (".$field_value.')'; |
410
|
|
|
break; |
411
|
|
|
case '=': |
412
|
|
|
$where .= $db_field . " = ".$this->bean->db->quoted($field_value); |
413
|
|
|
break; |
414
|
|
|
case 'between': |
415
|
|
|
if(!is_array($field_value)) { |
416
|
|
|
$field_value = explode('<>', $field_value); |
417
|
|
|
} |
418
|
|
|
$where .= "(". $db_field . " >= ".$this->bean->db->quoted($field_value[0]) . |
419
|
|
|
" AND " .$db_field . " <= ".$this->bean->db->quoted($field_value[1]).")"; |
420
|
|
|
break; |
421
|
|
|
} |
422
|
|
|
} |
423
|
|
|
} |
424
|
|
|
if(!empty($where)) { |
425
|
|
|
if($itr > 1) { |
426
|
|
|
array_push($where_clauses, '( '.$where.' )'); |
427
|
|
|
} |
428
|
|
|
else { |
429
|
|
|
array_push($where_clauses, $where); |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
} |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
return $where_clauses; |
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
/** |
439
|
|
|
* displays the tabs (top of the search form) |
440
|
|
|
* |
441
|
|
|
* @param string $currentKey key in $this->tabs to show as the current tab |
442
|
|
|
* |
443
|
|
|
* @return string html |
444
|
|
|
*/ |
445
|
|
|
function displayTabs($currentKey) { |
446
|
|
|
$GLOBALS['log']->debug('SearchForm.php->displayTabs(): tabs='.print_r($this->tabs,true)); |
447
|
|
|
|
448
|
|
|
$tabPanel = new SugarWidgetTabs($this->tabs, $currentKey, 'SUGAR.searchForm.searchFormSelect'); |
449
|
|
|
|
450
|
|
|
if(isset($_REQUEST['saved_search_select']) && $_REQUEST['saved_search_select']!='_none') { |
451
|
|
|
$saved_search=loadBean('SavedSearch'); |
|
|
|
|
452
|
|
|
$saved_search->retrieveSavedSearch($_REQUEST['saved_search_select']); |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
$str = $tabPanel->display(); |
456
|
|
|
$str .= '<script>'; |
457
|
|
|
if(!empty($_REQUEST['displayColumns'])) |
458
|
|
|
$str .= 'SUGAR.savedViews.displayColumns = "' . $_REQUEST['displayColumns'] . '";'; |
459
|
|
|
elseif(isset($saved_search->contents['displayColumns']) && !empty($saved_search->contents['displayColumns'])) |
460
|
|
|
$str .= 'SUGAR.savedViews.displayColumns = "' . $saved_search->contents['displayColumns'] . '";'; |
461
|
|
|
if(!empty($_REQUEST['hideTabs'])) |
462
|
|
|
$str .= 'SUGAR.savedViews.hideTabs = "' . $_REQUEST['hideTabs'] . '";'; |
463
|
|
|
elseif(isset($saved_search->contents['hideTabs']) && !empty($saved_search->contents['hideTabs'])) |
464
|
|
|
$str .= 'SUGAR.savedViews.hideTabs = "' . $saved_search->contents['hideTabs'] . '";'; |
465
|
|
|
if(!empty($_REQUEST['orderBy'])) |
466
|
|
|
$str .= 'SUGAR.savedViews.selectedOrderBy = "' . $_REQUEST['orderBy'] . '";'; |
467
|
|
|
elseif(isset($saved_search->contents['orderBy']) && !empty($saved_search->contents['orderBy'])) |
468
|
|
|
$str .= 'SUGAR.savedViews.selectedOrderBy = "' . $saved_search->contents['orderBy'] . '";'; |
469
|
|
|
if(!empty($_REQUEST['sortOrder'])) |
470
|
|
|
$str .= 'SUGAR.savedViews.selectedSortOrder = "' . $_REQUEST['sortOrder'] . '";'; |
471
|
|
|
elseif(isset($saved_search->contents['sortOrder']) && !empty($saved_search->contents['sortOrder'])) |
472
|
|
|
$str .= 'SUGAR.savedViews.selectedSortOrder = "' . $saved_search->contents['sortOrder'] . '";'; |
473
|
|
|
|
474
|
|
|
$str .= '</script>'; |
475
|
|
|
|
476
|
|
|
return $str; |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
/** |
480
|
|
|
* sets up the search forms, populates the preset values |
481
|
|
|
* |
482
|
|
|
*/ |
483
|
|
|
function setup() { |
484
|
|
|
global $mod_strings, $app_strings, $app_list_strings, $theme, $timedate; |
485
|
|
|
$GLOBALS['log']->debug('SearchForm.php->setup()'); |
486
|
|
|
$this->xtpl = new XTemplate($this->tpl); |
487
|
|
|
$this->xtpl->assign("MOD", $mod_strings); |
488
|
|
|
$this->xtpl->assign("APP", $app_strings); |
489
|
|
|
$this->xtpl->assign("THEME", $theme); |
490
|
|
|
$this->xtpl->assign("CALENDAR_DATEFORMAT", $timedate->get_cal_date_format()); |
491
|
|
|
$this->xtpl->assign("USER_DATEFORMAT", '('. $timedate->get_user_date_format().')'); |
492
|
|
|
|
493
|
|
|
foreach($this->searchFields as $name => $params) { |
494
|
|
|
if(isset($params['template_var'])) $templateVar = $params['template_var']; |
495
|
|
|
else $templateVar = strtoupper($name); |
496
|
|
|
if(isset($params['value'])) { // populate w/ preselected values |
497
|
|
|
if(isset($params['options'])) { |
498
|
|
|
$options = $app_list_strings[$params['options']]; |
499
|
|
|
if(isset($params['options_add_blank']) && $params['options_add_blank']) array_unshift($options, ''); |
500
|
|
|
$this->xtpl->assign($templateVar, get_select_options_with_id($options, $params['value'])); |
501
|
|
|
} |
502
|
|
|
else { |
503
|
|
|
if(isset($params['input_type'])) { |
504
|
|
|
switch($params['input_type']) { |
505
|
|
|
case 'checkbox': // checkbox input |
506
|
|
|
if($params['value'] == 'on' || $params['value']) |
507
|
|
|
$this->xtpl->assign($templateVar, 'checked'); |
508
|
|
|
break; |
509
|
|
|
} |
510
|
|
|
} |
511
|
|
|
else {// regular text input |
512
|
|
|
$this->xtpl->assign($templateVar, to_html($params['value'])); |
513
|
|
|
} |
514
|
|
|
} |
515
|
|
|
} |
516
|
|
|
else { // populate w/o preselected values |
517
|
|
|
if(isset($params['options'])) { |
518
|
|
|
$options = $app_list_strings[$params['options']]; |
519
|
|
|
if(isset($params['options_add_blank']) && $params['options_add_blank']) array_unshift($options, ''); |
520
|
|
|
$this->xtpl->assign($templateVar, get_select_options_with_id($options, '')); |
521
|
|
|
} |
522
|
|
|
} |
523
|
|
|
} |
524
|
|
|
if (!empty($_REQUEST['assigned_user_id'])) $this->xtpl->assign("USER_FILTER", get_select_options_with_id(get_user_array(FALSE), $_REQUEST['assigned_user_id'])); |
525
|
|
|
else $this->xtpl->assign("USER_FILTER", get_select_options_with_id(get_user_array(FALSE), '')); |
526
|
|
|
|
527
|
|
|
// handle my items only |
528
|
|
|
if(isset($this->searchFields['current_user_only']) && isset($this->searchFields['current_user_only']['value'])) |
529
|
|
|
$this->xtpl->assign("CURRENT_USER_ONLY", "checked"); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* displays the search form header |
534
|
|
|
* |
535
|
|
|
* @param string $view which view is currently being displayed |
536
|
|
|
* |
537
|
|
|
*/ |
538
|
|
|
function displayHeader($view) { |
539
|
|
|
global $current_user; |
540
|
|
|
$GLOBALS['log']->debug('SearchForm.php->displayHeader()'); |
541
|
|
|
$header_text = ''; |
542
|
|
|
if(is_admin($current_user) && $_REQUEST['module'] != 'DynamicLayout' && !empty($_SESSION['editinplace'])){ |
543
|
|
|
$header_text = "<a href='index.php?action=index&module=DynamicLayout&from_action=SearchForm&from_module=".$_REQUEST['module'] ."'>".SugarThemeRegistry::current()->getImage("EditLayout","border='0' align='bottom'",null,null,'.gif','Edit Layout')."</a>"; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
echo $header_text . $this->displayTabs($this->module . '|' . $view); |
547
|
|
|
echo "<form name='search_form' class='search_form'>" . |
548
|
|
|
"<input type='hidden' name='searchFormTab' value='{$view}'/>" . |
549
|
|
|
"<input type='hidden' name='module' value='{$_REQUEST['module']}'/>" . |
550
|
|
|
"<input type='hidden' name='action' value='{$_REQUEST['action']}'/>" . |
551
|
|
|
"<input type='hidden' name='query' value='true'/>"; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
/** |
555
|
|
|
* displays the search form body, for example if basic_search is being displayed, then the function call would be |
556
|
|
|
* displayWithHeaders('basic_search', $htmlForBasicSearchBody) { |
557
|
|
|
* |
558
|
|
|
* @param string $view which view is currently being displayed |
559
|
|
|
* @param string $basic_search_text body of the basic search tab |
560
|
|
|
* @param string $advanced_search_text body of the advanced search tab |
561
|
|
|
* @param string $saved_views_text body of the saved views tab |
562
|
|
|
* |
563
|
|
|
*/ |
564
|
|
|
function displayWithHeaders($view, $basic_search_text = '', $advanced_search_text = '', $saved_views_text = '') { |
565
|
|
|
$GLOBALS['log']->debug('SearchForm.php->displayWithHeaders()'); |
566
|
|
|
$this->displayHeader($view); |
567
|
|
|
echo "<div id='{$this->module}basic_searchSearchForm' " . (($view == 'basic_search') ? '' : "style='display: none'") . ">" . $basic_search_text . "</div>"; |
568
|
|
|
echo "<div id='{$this->module}advanced_searchSearchForm' " . (($view == 'advanced_search') ? '' : "style='display: none'") . ">" . $advanced_search_text . "</div>"; |
569
|
|
|
echo "<div id='{$this->module}saved_viewsSearchForm' " . (($view == 'saved_views') ? '' : "style='display: none'") . ">" . $saved_views_text . "</div>"; |
570
|
|
|
echo $this->getButtons(); |
571
|
|
|
echo '</form>'; |
572
|
|
|
// echo '<script type="text/javascript">Calendar.setup ({inputField : "search_jscal_field", ifFormat : "'.$timedate->get_cal_date_format().'", showsTime : false, button : "search_jscal_trigger", singleClick : true, step : 1});</script>'; |
573
|
|
|
} |
574
|
|
|
|
575
|
|
|
/** |
576
|
|
|
* displays the basic search form body |
577
|
|
|
* |
578
|
|
|
* @param bool $header display this with headers |
579
|
|
|
* @param bool $return echo or return the html |
580
|
|
|
* |
581
|
|
|
* @return string html of contents |
582
|
|
|
*/ |
583
|
|
|
function displayBasic($header = true, $return = false) { |
584
|
|
|
global $current_user; |
585
|
|
|
|
586
|
|
|
$this->bean->custom_fields->populateAllXTPL($this->xtpl, 'search' ); |
587
|
|
|
$this->xtpl->parse("main"); |
588
|
|
|
if(!empty($GLOBALS['layout_edit_mode'])){ |
589
|
|
|
$this->xtpl->parse("advanced"); |
590
|
|
|
} |
591
|
|
|
$text = $this->xtpl->text("main"); |
592
|
|
|
if(!empty($GLOBALS['layout_edit_mode'])){ |
593
|
|
|
$text .= $this->xtpl->text("advanced"); |
594
|
|
|
} |
595
|
|
|
if($header && empty($GLOBALS['layout_edit_mode'])) { |
596
|
|
|
$this->displayWithHeaders('basic_search', $text); |
597
|
|
|
} |
598
|
|
|
else { |
599
|
|
|
if($return) return $text; |
600
|
|
|
else echo $text; |
601
|
|
|
} |
602
|
|
|
} |
603
|
|
|
|
604
|
|
|
/** |
605
|
|
|
* displays the advanced search form body |
606
|
|
|
* |
607
|
|
|
* @param bool $header display this with headers |
608
|
|
|
* @param bool $return echo or return the html |
609
|
|
|
* |
610
|
|
|
* @return string html of contents |
611
|
|
|
*/ |
612
|
|
|
function displayAdvanced($header = true, $return = false, $listViewDefs='', $lv='') { |
613
|
|
|
global $current_user, $current_language; |
614
|
|
|
$GLOBALS['log']->debug('SearchForm.php->displayAdvanced()'); |
615
|
|
|
$this->bean->custom_fields->populateAllXTPL($this->xtpl, 'search' ); |
616
|
|
|
if(!empty($listViewDefs) && !empty($lv)){ |
617
|
|
|
$GLOBALS['log']->debug('SearchForm.php->displayAdvanced(): showing saved search'); |
618
|
|
|
$savedSearch = new SavedSearch($listViewDefs[$this->module], $lv->data['pageData']['ordering']['orderBy'], $lv->data['pageData']['ordering']['sortOrder']); |
619
|
|
|
$this->xtpl->assign('SAVED_SEARCH', $savedSearch->getForm($this->module, false)); |
620
|
|
|
$this->xtpl->assign('MOD_SAVEDSEARCH', return_module_language($current_language, 'SavedSearch')); |
621
|
|
|
$this->xtpl->assign('ADVANCED_SEARCH_IMG', SugarThemeRegistry::current()->getImageURL('advanced_search.gif')); |
622
|
|
|
//this determines whether the saved search subform should be rendered open or not |
623
|
|
|
if(isset($_REQUEST['showSSDIV']) && $_REQUEST['showSSDIV']=='yes'){ |
624
|
|
|
$this->xtpl->assign('SHOWSSDIV', 'yes'); |
625
|
|
|
$this->xtpl->assign('DISPLAYSS', ''); |
626
|
|
|
}else{ |
627
|
|
|
$this->xtpl->assign('SHOWSSDIV', 'no'); |
628
|
|
|
$this->xtpl->assign('DISPLAYSS', 'display:none'); |
629
|
|
|
} |
630
|
|
|
} |
631
|
|
|
$this->xtpl->parse("advanced"); |
632
|
|
|
$text = $this->xtpl->text("advanced"); |
633
|
|
|
|
634
|
|
|
if($header) { |
635
|
|
|
$this->displayWithHeaders('advanced_search', '', $text); |
636
|
|
|
} |
637
|
|
|
else { |
638
|
|
|
if($return) return $text; |
639
|
|
|
else echo $text; |
640
|
|
|
} |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** |
644
|
|
|
* displays the saved views form body |
645
|
|
|
* |
646
|
|
|
* @param bool $header display this with headers |
647
|
|
|
* @param bool $return echo or return the html |
648
|
|
|
* |
649
|
|
|
* @return string html of contents |
650
|
|
|
*/ |
651
|
|
|
function displaySavedViews($listViewDefs, $lv, $header = true, $return = false) { |
652
|
|
|
global $current_user; |
653
|
|
|
|
654
|
|
|
$savedSearch = new SavedSearch($listViewDefs[$this->module], $lv->data['pageData']['ordering']['orderBy'], $lv->data['pageData']['ordering']['sortOrder']); |
655
|
|
|
|
656
|
|
|
if($header) { |
657
|
|
|
$this->displayWithHeaders('saved_views', $this->displayBasic(false, true), $this->displayAdvanced(false, true), $savedSearch->getForm($this->module)); |
658
|
|
|
echo '<script>SUGAR.savedViews.handleForm();</script>'; |
659
|
|
|
} |
660
|
|
|
else { |
661
|
|
|
echo $savedSearch->getForm($this->module, false); |
662
|
|
|
} |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
/** |
666
|
|
|
* get the search buttons |
667
|
|
|
* |
668
|
|
|
* @return string html of contents |
669
|
|
|
*/ |
670
|
|
|
function getButtons() { |
671
|
|
|
global $app_strings; |
672
|
|
|
|
673
|
|
|
$SAVED_SEARCHES_OPTIONS = ''; |
674
|
|
|
$savedSearch = new SavedSearch(); |
675
|
|
|
$SAVED_SEARCHES_OPTIONS = $savedSearch->getSelect($this->module); |
676
|
|
|
$str = "<input tabindex='2' title='{$app_strings['LBL_SEARCH_BUTTON_TITLE']}' onclick='SUGAR.savedViews.setChooser()' class='button' type='submit' name='button' value='{$app_strings['LBL_SEARCH_BUTTON_LABEL']}' id='search_form_submit'/> "; |
677
|
|
|
$str .= "<input tabindex='2' title='{$app_strings['LBL_CLEAR_BUTTON_TITLE']}' onclick='SUGAR.searchForm.clear_form(this.form); return false;' class='button' type='button' name='clear' value=' {$app_strings['LBL_CLEAR_BUTTON_LABEL']} ' id='search_form_clear'/>"; |
678
|
|
|
|
679
|
|
|
if(!empty($SAVED_SEARCHES_OPTIONS) && $this->showSavedSearchOptions){ |
680
|
|
|
$str .= " <span class='white-space'> |
681
|
|
|
| <b>{$app_strings['LBL_SAVED_SEARCH_SHORTCUT']}</b> |
682
|
|
|
{$SAVED_SEARCHES_OPTIONS} |
683
|
|
|
<span id='go_btn_span' style='display:none'><input tabindex='2' title='go_select' id='go_select' onclick='SUGAR.searchForm.clear_form(this.form);' class='button' type='button' name='go_select' value=' {$app_strings['LBL_GO_BUTTON_LABEL']} '/></span> |
684
|
|
|
</span> |
685
|
|
|
</form>"; |
686
|
|
|
} |
687
|
|
|
$str .= " |
688
|
|
|
<script> |
689
|
|
|
function toggleInlineSearch(){ |
690
|
|
|
if (document.getElementById('inlineSavedSearch').style.display == 'none'){ |
691
|
|
|
document.getElementById('showSSDIV').value = 'yes' |
692
|
|
|
document.getElementById('inlineSavedSearch').style.display = ''; |
693
|
|
|
|
694
|
|
|
document.getElementById('up_down_img').src='".SugarThemeRegistry::current()->getImageURL('basic_search.gif')."'; |
695
|
|
|
document.getElementById('up_down_img').setAttribute('alt','".$GLOBALS['app_strings']['LBL_ALT_HIDE_OPTIONS']."'); |
696
|
|
|
|
697
|
|
|
}else{ |
698
|
|
|
|
699
|
|
|
document.getElementById('up_down_img').src='".SugarThemeRegistry::current()->getImageURL('advanced_search.gif')."'; |
700
|
|
|
document.getElementById('up_down_img').setAttribute('alt','".$GLOBALS['app_strings']['LBL_ALT_SHOW_OPTIONS']."'); |
701
|
|
|
document.getElementById('showSSDIV').value = 'no'; |
702
|
|
|
document.getElementById('inlineSavedSearch').style.display = 'none'; |
703
|
|
|
} |
704
|
|
|
} |
705
|
|
|
|
706
|
|
|
|
707
|
|
|
</script> |
708
|
|
|
"; |
709
|
|
|
return $str; |
710
|
|
|
} |
711
|
|
|
} |
712
|
|
|
|
713
|
|
|
?> |
714
|
|
|
|
This function has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.