|
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
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* TemplateHandler builds templates using SugarFields and a generic view. |
|
44
|
|
|
* Currently it handles EditViews and DetailViews. It creates a smarty template cached in |
|
45
|
|
|
* cache/modules/moduleName/view |
|
46
|
|
|
* @api |
|
47
|
|
|
*/ |
|
48
|
|
|
class TemplateHandler { |
|
49
|
|
|
var $cacheDir; |
|
50
|
|
|
var $templateDir = 'modules/'; |
|
51
|
|
|
var $ss; |
|
52
|
|
|
|
|
53
|
|
|
public function __construct() { |
|
54
|
|
|
$this->cacheDir = sugar_cached(''); |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* @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 |
|
59
|
|
|
*/ |
|
60
|
|
|
public function TemplateHandler(){ |
|
61
|
|
|
$deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; |
|
62
|
|
|
if(isset($GLOBALS['log'])) { |
|
63
|
|
|
$GLOBALS['log']->deprecated($deprecatedMessage); |
|
64
|
|
|
} |
|
65
|
|
|
else { |
|
66
|
|
|
trigger_error($deprecatedMessage, E_USER_DEPRECATED); |
|
67
|
|
|
} |
|
68
|
|
|
self::__construct(); |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
|
|
72
|
|
|
function loadSmarty(){ |
|
73
|
|
|
if(empty($this->ss)){ |
|
74
|
|
|
$this->ss = new Sugar_Smarty(); |
|
75
|
|
|
} |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
|
|
79
|
|
|
/** |
|
80
|
|
|
* clearAll |
|
81
|
|
|
* Helper function to remove all .tpl files in the cache directory |
|
82
|
|
|
* |
|
83
|
|
|
*/ |
|
84
|
|
|
static function clearAll() { |
|
85
|
|
|
global $beanList; |
|
86
|
|
|
foreach($beanList as $module_dir =>$object_name){ |
|
87
|
|
|
TemplateHandler::clearCache($module_dir); |
|
88
|
|
|
} |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* clearCache |
|
94
|
|
|
* Helper function to remove cached .tpl files for a particular module |
|
95
|
|
|
* |
|
96
|
|
|
* @param String $module The module directory to clear |
|
97
|
|
|
* @param String $view Optional view value (DetailView, EditView, etc.) |
|
98
|
|
|
*/ |
|
99
|
|
|
static function clearCache($module, $view=''){ |
|
100
|
|
|
$cacheDir = create_cache_directory('modules/'. $module . '/'); |
|
101
|
|
|
$d = dir($cacheDir); |
|
102
|
|
|
while($e = $d->read()){ |
|
103
|
|
|
if(!empty($view) && $e != $view )continue; |
|
104
|
|
|
$end =strlen($e) - 4; |
|
105
|
|
|
if(is_file($cacheDir . $e) && $end > 1 && substr($e, $end) == '.tpl'){ |
|
106
|
|
|
unlink($cacheDir . $e); |
|
107
|
|
|
} |
|
108
|
|
|
} |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* Builds a template |
|
113
|
|
|
* This is a private function that should be called only from checkTemplate method |
|
114
|
|
|
* |
|
115
|
|
|
* @param module string module name |
|
116
|
|
|
* @param view string view need (eg DetailView, EditView, etc) |
|
117
|
|
|
* @param tpl string generic tpl to use |
|
118
|
|
|
* @param ajaxSave boolean parameter indicating whether or not this is coming from an Ajax call |
|
119
|
|
|
* @param metaDataDefs metadata definition as Array |
|
120
|
|
|
**/ |
|
121
|
|
|
function buildTemplate($module, $view, $tpl, $ajaxSave, $metaDataDefs) { |
|
122
|
|
|
$this->loadSmarty(); |
|
123
|
|
|
|
|
124
|
|
|
$cacheDir = create_cache_directory($this->templateDir. $module . '/'); |
|
125
|
|
|
$file = $cacheDir . $view . '.tpl'; |
|
126
|
|
|
$string = '{* Create Date: ' . date('Y-m-d H:i:s') . "*}\n"; |
|
127
|
|
|
$this->ss->left_delimiter = '{{'; |
|
128
|
|
|
$this->ss->right_delimiter = '}}'; |
|
129
|
|
|
$this->ss->assign('module', $module); |
|
130
|
|
|
$this->ss->assign('built_in_buttons', array('CANCEL', 'DELETE', 'DUPLICATE', 'EDIT', 'FIND_DUPLICATES', 'SAVE', 'CONNECTOR')); |
|
131
|
|
|
$contents = $this->ss->fetch($tpl); |
|
132
|
|
|
//Insert validation and quicksearch stuff here |
|
133
|
|
|
if($view == 'EditView' || strpos($view,'QuickCreate') || $ajaxSave || $view == "ConvertLead") { |
|
134
|
|
|
|
|
135
|
|
|
global $dictionary, $beanList, $app_strings, $mod_strings; |
|
136
|
|
|
$mod = $beanList[$module]; |
|
137
|
|
|
|
|
138
|
|
|
if($mod == 'aCase') { |
|
139
|
|
|
$mod = 'Case'; |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
$defs = $dictionary[$mod]['fields']; |
|
143
|
|
|
$defs2 = array(); |
|
144
|
|
|
//Retrieve all panel field definitions with displayParams Array field set |
|
145
|
|
|
$panelFields = array(); |
|
146
|
|
|
|
|
147
|
|
|
foreach($metaDataDefs['panels'] as $panel) { |
|
148
|
|
|
foreach($panel as $row) { |
|
149
|
|
|
foreach($row as $entry) { |
|
150
|
|
|
if(empty($entry)) { |
|
151
|
|
|
continue; |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
if(is_array($entry) && |
|
155
|
|
|
isset($entry['name']) && |
|
156
|
|
|
isset($entry['displayParams']) && |
|
157
|
|
|
isset($entry['displayParams']['required']) && |
|
158
|
|
|
$entry['displayParams']['required']) { |
|
159
|
|
|
$panelFields[$entry['name']] = $entry; |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
if(is_array($entry)) { |
|
163
|
|
|
$defs2[$entry['name']] = $entry; |
|
164
|
|
|
} else { |
|
165
|
|
|
$defs2[$entry] = array('name' => $entry); |
|
166
|
|
|
} |
|
167
|
|
|
} //foreach |
|
168
|
|
|
} //foreach |
|
169
|
|
|
} //foreach |
|
170
|
|
|
|
|
171
|
|
|
foreach($panelFields as $field=>$value) { |
|
172
|
|
|
$nameList = array(); |
|
173
|
|
|
if(!is_array($value['displayParams']['required'])) { |
|
174
|
|
|
$nameList[] = $field; |
|
175
|
|
|
} else { |
|
176
|
|
|
foreach($value['displayParams']['required'] as $groupedField) { |
|
177
|
|
|
$nameList[] = $groupedField; |
|
178
|
|
|
} |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
foreach($nameList as $x) { |
|
182
|
|
|
if(isset($defs[$x]) && |
|
183
|
|
|
isset($defs[$x]['type']) && |
|
184
|
|
|
!isset($defs[$x]['required'])) { |
|
185
|
|
|
$defs[$x]['required'] = true; |
|
186
|
|
|
} |
|
187
|
|
|
} |
|
188
|
|
|
} //foreach |
|
189
|
|
|
|
|
190
|
|
|
//Create a base class with field_name_map property |
|
191
|
|
|
$sugarbean = new stdClass; |
|
192
|
|
|
$sugarbean->field_name_map = $defs; |
|
193
|
|
|
$sugarbean->module_dir = $module; |
|
194
|
|
|
|
|
195
|
|
|
$javascript = new javascript(); |
|
196
|
|
|
$view = $view == 'QuickCreate' ? "QuickCreate_{$module}" : $view; |
|
197
|
|
|
$javascript->setFormName($view); |
|
198
|
|
|
|
|
199
|
|
|
$javascript->setSugarBean($sugarbean); |
|
200
|
|
|
if ($view != "ConvertLead") |
|
201
|
|
|
$javascript->addAllFields('', null,true); |
|
202
|
|
|
|
|
203
|
|
|
$validatedFields = array(); |
|
204
|
|
|
$javascript->addToValidateBinaryDependency('assigned_user_name', 'alpha', $javascript->buildStringToTranslateInSmarty('ERR_SQS_NO_MATCH_FIELD').': '.$javascript->buildStringToTranslateInSmarty('LBL_ASSIGNED_TO'), 'false', '', 'assigned_user_id'); |
|
205
|
|
|
$validatedFields[] = 'assigned_user_name'; |
|
206
|
|
|
//Add remaining validation dependency for related fields |
|
207
|
|
|
//1) a relate type as defined in vardefs |
|
208
|
|
|
//2) set in metadata layout |
|
209
|
|
|
//3) not have validateDepedency set to false in metadata |
|
210
|
|
|
//4) have id_name in vardef entry |
|
211
|
|
|
//5) not already been added to Array |
|
212
|
|
|
foreach($sugarbean->field_name_map as $name=>$def) { |
|
213
|
|
|
|
|
214
|
|
|
if($def['type']=='relate' && |
|
215
|
|
|
isset($defs2[$name]) && |
|
216
|
|
|
(!isset($defs2[$name]['validateDependency']) || $defs2[$name]['validateDependency'] === true) && |
|
217
|
|
|
isset($def['id_name']) && |
|
218
|
|
|
!in_array($name, $validatedFields)) { |
|
219
|
|
|
|
|
220
|
|
|
if(isset($mod_strings[$def['vname']]) |
|
221
|
|
|
|| isset($app_strings[$def['vname']]) |
|
222
|
|
|
|| translate($def['vname'],$sugarbean->module_dir) != $def['vname']) { |
|
223
|
|
|
$vname = $def['vname']; |
|
224
|
|
|
} |
|
225
|
|
|
else{ |
|
226
|
|
|
$vname = "undefined"; |
|
227
|
|
|
} |
|
228
|
|
|
$javascript->addToValidateBinaryDependency($name, 'alpha', $javascript->buildStringToTranslateInSmarty('ERR_SQS_NO_MATCH_FIELD').': '.$javascript->buildStringToTranslateInSmarty($vname), (!empty($def['required']) ? 'true' : 'false'), '', $def['id_name']); |
|
229
|
|
|
$validatedFields[] = $name; |
|
230
|
|
|
} |
|
231
|
|
|
} //foreach |
|
232
|
|
|
|
|
233
|
|
|
$contents .= "{literal}\n"; |
|
234
|
|
|
$contents .= $javascript->getScript(); |
|
235
|
|
|
$contents .= $this->createQuickSearchCode($defs, $defs2, $view, $module); |
|
236
|
|
|
$contents .= "{/literal}\n"; |
|
237
|
|
|
}else if(preg_match('/^SearchForm_.+/', $view)){ |
|
238
|
|
|
global $dictionary, $beanList, $app_strings, $mod_strings; |
|
239
|
|
|
$mod = $beanList[$module]; |
|
240
|
|
|
|
|
241
|
|
|
if($mod == 'aCase') { |
|
242
|
|
|
$mod = 'Case'; |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
$defs = $dictionary[$mod]['fields']; |
|
246
|
|
|
$contents .= '{literal}'; |
|
247
|
|
|
$contents .= $this->createQuickSearchCode($defs, array(), $view); |
|
248
|
|
|
$contents .= '{/literal}'; |
|
249
|
|
|
}//if |
|
250
|
|
|
|
|
251
|
|
|
//Remove all the copyright comments |
|
252
|
|
|
$contents = preg_replace('/\{\*[^\}]*?\*\}/', '', $contents); |
|
253
|
|
|
|
|
254
|
|
|
if($fh = @sugar_fopen($file, 'w')) { |
|
255
|
|
|
fputs($fh, $contents); |
|
256
|
|
|
fclose($fh); |
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
|
|
260
|
|
|
$this->ss->left_delimiter = '{'; |
|
261
|
|
|
$this->ss->right_delimiter = '}'; |
|
262
|
|
|
} |
|
263
|
|
|
|
|
264
|
|
|
/** |
|
265
|
|
|
* Checks if a template exists |
|
266
|
|
|
* |
|
267
|
|
|
* @param module string module name |
|
268
|
|
|
* @param view string view need (eg DetailView, EditView, etc) |
|
269
|
|
|
*/ |
|
270
|
|
|
function checkTemplate($module, $view, $checkFormName = false, $formName='') { |
|
271
|
|
|
if(inDeveloperMode() || !empty($_SESSION['developerMode'])){ |
|
272
|
|
|
return false; |
|
273
|
|
|
} |
|
274
|
|
|
$view = $checkFormName ? $formName : $view; |
|
275
|
|
|
return file_exists($this->cacheDir . $this->templateDir . $module . '/' .$view . '.tpl'); |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
/** |
|
279
|
|
|
* Retreives and displays a template |
|
280
|
|
|
* |
|
281
|
|
|
* @param module string module name |
|
282
|
|
|
* @param view string view need (eg DetailView, EditView, etc) |
|
283
|
|
|
* @param tpl string generic tpl to use |
|
284
|
|
|
* @param ajaxSave boolean parameter indicating whether or not this is from an Ajax operation |
|
285
|
|
|
* @param metaData Optional metadata definition Array |
|
286
|
|
|
*/ |
|
287
|
|
|
function displayTemplate($module, $view, $tpl, $ajaxSave = false, $metaDataDefs = null) { |
|
288
|
|
|
$this->loadSmarty(); |
|
289
|
|
|
if(!$this->checkTemplate($module, $view)) { |
|
290
|
|
|
$this->buildTemplate($module, $view, $tpl, $ajaxSave, $metaDataDefs); |
|
291
|
|
|
} |
|
292
|
|
|
$file = $this->cacheDir . $this->templateDir . $module . '/' . $view . '.tpl'; |
|
293
|
|
|
if(file_exists($file)) { |
|
294
|
|
|
return $this->ss->fetch($file); |
|
295
|
|
|
} else { |
|
296
|
|
|
global $app_strings; |
|
297
|
|
|
$GLOBALS['log']->fatal($app_strings['ERR_NO_SUCH_FILE'] .": $file"); |
|
298
|
|
|
return $app_strings['ERR_NO_SUCH_FILE'] .": $file"; |
|
299
|
|
|
} |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
/** |
|
303
|
|
|
* Deletes an existing template |
|
304
|
|
|
* |
|
305
|
|
|
* @param module string module name |
|
306
|
|
|
* @param view string view need (eg DetailView, EditView, etc) |
|
307
|
|
|
*/ |
|
308
|
|
|
function deleteTemplate($module, $view) { |
|
309
|
|
|
if(is_file($this->cacheDir . $this->templateDir . $module . '/' .$view . '.tpl')) { |
|
310
|
|
|
// Bug #54634 : RTC 18144 : Cannot add more than 1 user to role but popup is multi-selectable |
|
311
|
|
|
if ( !isset($this->ss) ) |
|
312
|
|
|
{ |
|
313
|
|
|
$this->loadSmarty(); |
|
314
|
|
|
} |
|
315
|
|
|
$cache_file_name = $this->ss->_get_compile_path($this->cacheDir . $this->templateDir . $module . '/' .$view . '.tpl'); |
|
316
|
|
|
SugarCache::cleanFile($cache_file_name); |
|
317
|
|
|
|
|
318
|
|
|
return unlink($this->cacheDir . $this->templateDir . $module . '/' .$view . '.tpl'); |
|
319
|
|
|
} |
|
320
|
|
|
return false; |
|
321
|
|
|
} |
|
322
|
|
|
|
|
323
|
|
|
|
|
324
|
|
|
/** |
|
325
|
|
|
* createQuickSearchCode |
|
326
|
|
|
* This function creates the $sqs_objects array that will be used by the quicksearch Javascript |
|
327
|
|
|
* code. The $sqs_objects array is wrapped in a $json->encode call. |
|
328
|
|
|
* |
|
329
|
|
|
* @param array $def The vardefs.php definitions |
|
|
|
|
|
|
330
|
|
|
* @param array $defs2 The Meta-Data file definitions |
|
331
|
|
|
* @param string $view |
|
332
|
|
|
* @param strign $module |
|
333
|
|
|
* @return string |
|
334
|
|
|
*/ |
|
335
|
|
|
public function createQuickSearchCode($defs, $defs2, $view = '', $module='') |
|
336
|
|
|
{ |
|
337
|
|
|
$sqs_objects = array(); |
|
338
|
|
|
require_once('include/QuickSearchDefaults.php'); |
|
339
|
|
|
if(isset($this) && $this instanceof TemplateHandler) //If someone calls createQuickSearchCode as a static method (@see ImportViewStep3) $this becomes anoter object, not TemplateHandler |
|
340
|
|
|
{ |
|
341
|
|
|
$qsd = QuickSearchDefaults::getQuickSearchDefaults($this->getQSDLookup()); |
|
342
|
|
|
}else |
|
343
|
|
|
{ |
|
344
|
|
|
$qsd = QuickSearchDefaults::getQuickSearchDefaults(array()); |
|
345
|
|
|
} |
|
346
|
|
|
$qsd->setFormName($view); |
|
347
|
|
|
if(preg_match('/^SearchForm_.+/', $view)){ |
|
348
|
|
|
if(strpos($view, 'popup_query_form')){ |
|
349
|
|
|
$qsd->setFormName('popup_query_form'); |
|
350
|
|
|
$parsedView = 'advanced'; |
|
351
|
|
|
}else{ |
|
352
|
|
|
$qsd->setFormName('search_form'); |
|
353
|
|
|
$parsedView = preg_replace("/^SearchForm_/", "", $view); |
|
354
|
|
|
} |
|
355
|
|
|
//Loop through the Meta-Data fields to see which ones need quick search support |
|
356
|
|
|
foreach($defs as $f) { |
|
357
|
|
|
$field = $f; |
|
358
|
|
|
$name = $qsd->form_name . '_' . $field['name']; |
|
359
|
|
|
|
|
360
|
|
|
if($field['type'] == 'relate' && isset($field['module']) && preg_match('/_name$|_c$/si',$name) || !empty($field['quicksearch']) ) { |
|
361
|
|
|
if(preg_match('/^(Campaigns|Teams|Users|Contacts|Accounts)$/si', $field['module'], $matches)) { |
|
362
|
|
|
|
|
363
|
|
|
if($matches[0] == 'Campaigns') { |
|
364
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->loadQSObject('Campaigns', 'Campaign', $field['name'], $field['id_name'], $field['id_name']); |
|
365
|
|
|
} else if($matches[0] == 'Users'){ |
|
366
|
|
|
|
|
367
|
|
|
if(!empty($f['name']) && !empty($f['id_name'])) { |
|
368
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->getQSUser($f['name'],$f['id_name']); |
|
369
|
|
|
} |
|
370
|
|
|
else { |
|
371
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->getQSUser(); |
|
372
|
|
|
} |
|
373
|
|
|
} else if($matches[0] == 'Campaigns') { |
|
374
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->loadQSObject('Campaigns', 'Campaign', $field['name'], $field['id_name'], $field['id_name']); |
|
375
|
|
|
} else if($matches[0] == 'Accounts') { |
|
376
|
|
|
$nameKey = $name; |
|
377
|
|
|
$idKey = isset($field['id_name']) ? $field['id_name'] : 'account_id'; |
|
378
|
|
|
|
|
379
|
|
|
//There are billingKey, shippingKey and additionalFields entries you can define in editviewdefs.php |
|
380
|
|
|
//entry to allow quick search to autocomplete fields with a suffix value of the |
|
381
|
|
|
//billing/shippingKey value (i.e. 'billingKey' => 'primary' in Contacts will populate |
|
382
|
|
|
//primary_XXX fields with the Account's billing address values). |
|
383
|
|
|
//addtionalFields are key/value pair of fields to fill from Accounts(key) to Contacts(value) |
|
384
|
|
|
$billingKey = isset($f['displayParams']['billingKey']) ? $f['displayParams']['billingKey'] : null; |
|
385
|
|
|
$shippingKey = isset($f['displayParams']['shippingKey']) ? $f['displayParams']['shippingKey'] : null; |
|
386
|
|
|
$additionalFields = isset($f['displayParams']['additionalFields']) ? $f['displayParams']['additionalFields'] : null; |
|
387
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->getQSAccount($nameKey, $idKey, $billingKey, $shippingKey, $additionalFields); |
|
388
|
|
|
} else if($matches[0] == 'Contacts'){ |
|
389
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->getQSContact($field['name'], $field['id_name']); |
|
390
|
|
|
} |
|
391
|
|
|
} else { |
|
392
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->getQSParent($field['module']); |
|
393
|
|
|
if(!isset($field['field_list']) && !isset($field['populate_list'])) { |
|
394
|
|
|
$sqs_objects[$name.'_'.$parsedView]['populate_list'] = array($field['name'], $field['id_name']); |
|
395
|
|
|
$sqs_objects[$name.'_'.$parsedView]['field_list'] = array('name', 'id'); |
|
396
|
|
|
} else { |
|
397
|
|
|
$sqs_objects[$name.'_'.$parsedView]['populate_list'] = $field['field_list']; |
|
398
|
|
|
$sqs_objects[$name.'_'.$parsedView]['field_list'] = $field['populate_list']; |
|
399
|
|
|
} |
|
400
|
|
|
} |
|
401
|
|
|
} else if($field['type'] == 'parent') { |
|
402
|
|
|
$sqs_objects[$name.'_'.$parsedView] = $qsd->getQSParent(); |
|
403
|
|
|
} //if-else |
|
404
|
|
|
} //foreach |
|
405
|
|
|
|
|
406
|
|
|
foreach ( $sqs_objects as $name => $field ) |
|
407
|
|
|
foreach ( $field['populate_list'] as $key => $fieldname ) |
|
408
|
|
|
$sqs_objects[$name]['populate_list'][$key] = $sqs_objects[$name]['populate_list'][$key] . '_'.$parsedView; |
|
409
|
|
|
}else{ |
|
410
|
|
|
//Loop through the Meta-Data fields to see which ones need quick search support |
|
411
|
|
|
foreach($defs2 as $f) { |
|
412
|
|
|
if(!isset($defs[$f['name']])) continue; |
|
413
|
|
|
|
|
414
|
|
|
$field = $defs[$f['name']]; |
|
415
|
|
|
if ($view == "ConvertLead") |
|
416
|
|
|
{ |
|
417
|
|
|
$field['name'] = $module . $field['name']; |
|
418
|
|
|
if (isset($field['module']) && isset($field['id_name']) && substr($field['id_name'], -4) == "_ida") { |
|
419
|
|
|
$lc_module = strtolower($field['module']); |
|
420
|
|
|
$ida_suffix = "_".$lc_module.$lc_module."_ida"; |
|
421
|
|
|
if (preg_match('/'.$ida_suffix.'$/', $field['id_name']) > 0) { |
|
422
|
|
|
$field['id_name'] = $module . $field['id_name']; |
|
423
|
|
|
} |
|
424
|
|
|
else |
|
425
|
|
|
$field['id_name'] = $field['name'] . "_" . $field['id_name']; |
|
426
|
|
|
} |
|
427
|
|
|
else { |
|
428
|
|
|
if (!empty($field['id_name'])) |
|
429
|
|
|
$field['id_name'] = $module.$field['id_name']; |
|
430
|
|
|
} |
|
431
|
|
|
} |
|
432
|
|
|
$name = $qsd->form_name . '_' . $field['name']; |
|
433
|
|
|
|
|
434
|
|
|
|
|
435
|
|
|
if($field['type'] == 'relate' && isset($field['module']) && (preg_match('/_name$|_c$/si',$name) || !empty($field['quicksearch']))) { |
|
436
|
|
|
if (!preg_match('/_c$/si',$name) |
|
437
|
|
|
&& (!isset($field['id_name']) || !preg_match('/_c$/si',$field['id_name'])) |
|
438
|
|
|
&& preg_match('/^(Campaigns|Teams|Users|Contacts|Accounts)$/si', $field['module'], $matches) |
|
439
|
|
|
) { |
|
440
|
|
|
|
|
441
|
|
|
if($matches[0] == 'Campaigns') { |
|
442
|
|
|
$sqs_objects[$name] = $qsd->loadQSObject('Campaigns', 'Campaign', $field['name'], $field['id_name'], $field['id_name']); |
|
443
|
|
|
} else if($matches[0] == 'Users'){ |
|
444
|
|
|
if($field['name'] == 'reports_to_name'){ |
|
445
|
|
|
$sqs_objects[$name] = $qsd->getQSUser('reports_to_name','reports_to_id'); |
|
446
|
|
|
// Bug #52994 : QuickSearch for a 1-M User relationship changes assigned to user |
|
447
|
|
|
}elseif($field['name'] == 'assigned_user_name'){ |
|
448
|
|
|
$sqs_objects[$name] = $qsd->getQSUser('assigned_user_name','assigned_user_id'); |
|
449
|
|
|
} |
|
450
|
|
|
else |
|
451
|
|
|
{ |
|
452
|
|
|
$sqs_objects[$name] = $qsd->getQSUser($field['name'], $field['id_name']); |
|
453
|
|
|
|
|
454
|
|
|
} |
|
455
|
|
|
} else if($matches[0] == 'Campaigns') { |
|
456
|
|
|
$sqs_objects[$name] = $qsd->loadQSObject('Campaigns', 'Campaign', $field['name'], $field['id_name'], $field['id_name']); |
|
457
|
|
|
} else if($matches[0] == 'Accounts') { |
|
458
|
|
|
$nameKey = $name; |
|
459
|
|
|
$idKey = isset($field['id_name']) ? $field['id_name'] : 'account_id'; |
|
460
|
|
|
|
|
461
|
|
|
//There are billingKey, shippingKey and additionalFields entries you can define in editviewdefs.php |
|
462
|
|
|
//entry to allow quick search to autocomplete fields with a suffix value of the |
|
463
|
|
|
//billing/shippingKey value (i.e. 'billingKey' => 'primary' in Contacts will populate |
|
464
|
|
|
//primary_XXX fields with the Account's billing address values). |
|
465
|
|
|
//addtionalFields are key/value pair of fields to fill from Accounts(key) to Contacts(value) |
|
466
|
|
|
$billingKey = SugarArray::staticGet($f, 'displayParams.billingKey'); |
|
467
|
|
|
$shippingKey = SugarArray::staticGet($f, 'displayParams.shippingKey'); |
|
468
|
|
|
$additionalFields = SugarArray::staticGet($f, 'displayParams.additionalFields'); |
|
469
|
|
|
$sqs_objects[$name] = $qsd->getQSAccount($nameKey, $idKey, $billingKey, $shippingKey, $additionalFields); |
|
470
|
|
|
} else if($matches[0] == 'Contacts'){ |
|
471
|
|
|
$sqs_objects[$name] = $qsd->getQSContact($field['name'], $field['id_name']); |
|
472
|
|
|
if(preg_match('/_c$/si',$name) || !empty($field['quicksearch'])){ |
|
473
|
|
|
$sqs_objects[$name]['field_list'] = array('salutation', 'first_name', 'last_name', 'id'); |
|
474
|
|
|
} |
|
475
|
|
|
} |
|
476
|
|
|
} else { |
|
477
|
|
|
$sqs_objects[$name] = $qsd->getQSParent($field['module']); |
|
478
|
|
|
if(!isset($field['field_list']) && !isset($field['populate_list'])) { |
|
479
|
|
|
$sqs_objects[$name]['populate_list'] = array($field['name'], $field['id_name']); |
|
480
|
|
|
// now handle quicksearches where the column to match is not 'name' but rather specified in 'rname' |
|
481
|
|
|
if (!isset($field['rname'])) |
|
482
|
|
|
$sqs_objects[$name]['field_list'] = array('name', 'id'); |
|
483
|
|
|
else |
|
484
|
|
|
{ |
|
485
|
|
|
$sqs_objects[$name]['field_list'] = array($field['rname'], 'id'); |
|
486
|
|
|
$sqs_objects[$name]['order'] = $field['rname']; |
|
487
|
|
|
$sqs_objects[$name]['conditions'] = array(array('name'=>$field['rname'],'op'=>'like_custom','end'=>'%','value'=>'')); |
|
488
|
|
|
} |
|
489
|
|
|
} else { |
|
490
|
|
|
$sqs_objects[$name]['populate_list'] = $field['field_list']; |
|
491
|
|
|
$sqs_objects[$name]['field_list'] = $field['populate_list']; |
|
492
|
|
|
} |
|
493
|
|
|
} |
|
494
|
|
|
} else if($field['type'] == 'parent') { |
|
495
|
|
|
$sqs_objects[$name] = $qsd->getQSParent(); |
|
496
|
|
|
} //if-else |
|
497
|
|
|
|
|
498
|
|
|
// Bug 53949 - Captivea (sve) - Partial fix : Append metadata fields that are not already included in $sqs_objects array |
|
499
|
|
|
// (for example with hardcoded modules before, metadata arrays are not taken into account in 6.4.x 6.5.x) |
|
500
|
|
|
// As QuickSearchDefault methods are called at other places, this will not fix the SQS problem for everywhere, but it fixes it on Editview |
|
501
|
|
|
|
|
502
|
|
|
//merge populate_list && field_list with vardef |
|
503
|
|
|
if (!empty($field['field_list']) && !empty($field['populate_list'])) { |
|
504
|
|
|
for ($j=0; $j<count($field['field_list']); $j++) { |
|
|
|
|
|
|
505
|
|
|
//search for the same couple (field_list_item,populate_field_item) |
|
506
|
|
|
$field_list_item = $field['field_list'][$j]; |
|
507
|
|
|
$field_list_item_alternate = $qsd->form_name . '_' . $field['field_list'][$j]; |
|
508
|
|
|
$populate_list_item = $field['populate_list'][$j]; |
|
509
|
|
|
$found = false; |
|
510
|
|
|
for ($k=0; $k<count($sqs_objects[$name]['field_list']); $k++) { |
|
|
|
|
|
|
511
|
|
|
if (($field_list_item == $sqs_objects[$name]['populate_list'][$k] || $field_list_item_alternate == $sqs_objects[$name]['populate_list'][$k]) && //il faut inverser field_list et populate_list (cf lignes 465,466 ci-dessus) |
|
512
|
|
|
$populate_list_item == $sqs_objects[$name]['field_list'][$k]) { |
|
513
|
|
|
$found = true; |
|
514
|
|
|
break; |
|
515
|
|
|
} |
|
516
|
|
|
} |
|
517
|
|
|
if (!$found) { |
|
518
|
|
|
$sqs_objects[$name]['field_list'][] = $field['populate_list'][$j]; // as in lines 462 and 463 |
|
519
|
|
|
$sqs_objects[$name]['populate_list'][] = $field['field_list'][$j]; |
|
520
|
|
|
} |
|
521
|
|
|
} |
|
522
|
|
|
} |
|
523
|
|
|
|
|
524
|
|
|
} //foreach |
|
525
|
|
|
} |
|
526
|
|
|
|
|
527
|
|
|
//Implement QuickSearch for the field |
|
528
|
|
|
if(!empty($sqs_objects) && count($sqs_objects) > 0) { |
|
529
|
|
|
$quicksearch_js = '<script language="javascript">'; |
|
530
|
|
|
$quicksearch_js.= 'if(typeof sqs_objects == \'undefined\'){var sqs_objects = new Array;}'; |
|
531
|
|
|
$json = getJSONobj(); |
|
532
|
|
|
foreach($sqs_objects as $sqsfield=>$sqsfieldArray){ |
|
533
|
|
|
$quicksearch_js .= "sqs_objects['$sqsfield']={$json->encode($sqsfieldArray)};"; |
|
534
|
|
|
} |
|
535
|
|
|
return $quicksearch_js . '</script>'; |
|
536
|
|
|
} |
|
537
|
|
|
return ''; |
|
538
|
|
|
} |
|
539
|
|
|
|
|
540
|
|
|
|
|
541
|
|
|
/** |
|
542
|
|
|
* Get lookup array for QuickSearchDefaults custom class |
|
543
|
|
|
* @return array |
|
544
|
|
|
* @see QuickSearchDefaults::getQuickSearchDefaults() |
|
545
|
|
|
*/ |
|
546
|
|
|
protected function getQSDLookup() |
|
547
|
|
|
{ |
|
548
|
|
|
return array(); |
|
549
|
|
|
} |
|
550
|
|
|
} |
|
551
|
|
|
?> |
|
552
|
|
|
|
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.