Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/Dashlets/DashletGeneric.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2 1
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
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41 1
require_once('include/Dashlets/Dashlet.php');
42 1
require_once('include/ListView/ListViewSmarty.php');
43 1
require_once('include/generic/LayoutManager.php');
44
45
/**
46
 * Generic Dashlet class
47
 * @api
48
 */
49
class DashletGeneric extends Dashlet {
50
   /**
51
     * Fields that are searchable
52
     * @var array
53
     */
54
    var $searchFields;
55
    /**
56
     * Displayable columns (ones available to display)
57
     * @var array
58
     */
59
    var $columns;
60
    /**
61
     * Bean file used in this Dashlet
62
     * @var bean
63
     */
64
    var $seedBean;
65
    /**
66
     * collection of filters to apply
67
     * @var array
68
     */
69
    var $filters = null;
70
    /**
71
     * Number of Rows to display
72
     * @var int
73
     */
74
    var $displayRows = '5';
75
    /**
76
     * Actual columns to display, will be a subset of $columns
77
     * @var array
78
     */
79
    var $displayColumns = null;
80
    /**
81
     * Flag to display only the current users's items.
82
     * @var bool
83
     */
84
    var $myItemsOnly = true;
85
    /**
86
     * Flag to display "myItemsOnly" checkbox in the DashletGenericConfigure.
87
     * @var bool
88
     */
89
    var $showMyItemsOnly = true;
90
    /**
91
     * location of Smarty template file for display
92
     * @var string
93
     */
94
    var $displayTpl = 'include/Dashlets/DashletGenericDisplay.tpl';
95
    /**
96
     * location of smarty template file for configuring
97
     * @var string
98
     */
99
    var $configureTpl = 'include/Dashlets/DashletGenericConfigure.tpl';
100
    /**
101
     * smarty object for the generic configuration template
102
     * @var string
103
     */
104
    var $configureSS;
105
    /** search inputs to be populated in configure template.
106
     *  modify this after processDisplayOptions, but before displayOptions to modify search inputs
107
     *  @var array
108
     */
109
    var $currentSearchFields;
110
    /**
111
     * ListView Smarty Class
112
     * @var Smarty
113
     */
114
    var $lvs;
115
    var $layoutManager;
116
117 1
    function __construct($id, $options = null) {
118 1
        parent::__construct($id);
119 1
        $this->isConfigurable = true;
120 1
        if(isset($options)) {
121 1
            if(!empty($options['filters'])) $this->filters = $options['filters'];
122 1
            if(!empty($options['title'])) $this->title = $options['title'];
123 1
            if(!empty($options['displayRows'])) $this->displayRows = $options['displayRows'];
124 1
            if(!empty($options['displayColumns'])) $this->displayColumns = $options['displayColumns'];
125 1
            if(isset($options['myItemsOnly'])) $this->myItemsOnly = $options['myItemsOnly'];
126 1
            if(isset($options['autoRefresh'])) $this->autoRefresh = $options['autoRefresh'];
127
        }
128
129 1
        $this->layoutManager = new LayoutManager();
130 1
        $this->layoutManager->setAttribute('context', 'Report');
131
        // fake a reporter object here just to pass along the db type used in many widgets.
132
        // this should be taken out when sugarwidgets change
133 1
        $temp = (object) array('db' => &$GLOBALS['db'], 'report_def_str' => '');
134 1
        $this->layoutManager->setAttributePtr('reporter', $temp);
135 1
        $this->lvs = new ListViewSmarty();
136 1
    }
137
138
    /**
139
     * @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
140
     */
141
    function DashletGeneric($id, $options = null){
142
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
143
        if(isset($GLOBALS['log'])) {
144
            $GLOBALS['log']->deprecated($deprecatedMessage);
145
        }
146
        else {
147
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
148
        }
149
        self::__construct($id, $options);
150
    }
151
152
    /**
153
     * Sets up the display options template
154
     *
155
     * @return string HTML that shows options
156
     */
157
    function processDisplayOptions() {
158
    	 require_once('include/templates/TemplateGroupChooser.php');
159
160
        $this->configureSS = new Sugar_Smarty();
161
        // column chooser
162
        $chooser = new TemplateGroupChooser();
163
164
        $chooser->args['id'] = 'edit_tabs';
165
        $chooser->args['left_size'] = 5;
166
        $chooser->args['right_size'] = 5;
167
        $chooser->args['values_array'][0] = array();
168
        $chooser->args['values_array'][1] = array();
169
170
        $this->loadCustomMetadata();
171
        // Bug 39517 - Don't add custom fields automatically to the available fields to display in the listview
172
        //$this->addCustomFields();
173
        if($this->displayColumns) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->displayColumns of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
174
             // columns to display
175
             foreach($this->displayColumns as $num => $name) {
176
                    // defensive code for array being returned
177
                    $translated = translate($this->columns[$name]['label'], $this->seedBean->module_dir);
178
                    if(is_array($translated)) $translated = $this->columns[$name]['label'];
179
                    $chooser->args['values_array'][0][$name] = trim($translated, ':');
180
             }
181
             // columns not displayed
182
             foreach(array_diff(array_keys($this->columns), array_values($this->displayColumns)) as $num => $name) {
183
                    // defensive code for array being returned
184
                    $translated = translate($this->columns[$name]['label'], $this->seedBean->module_dir);
185
                    if(is_array($translated)) $translated = $this->columns[$name]['label'];
186
                    $chooser->args['values_array'][1][$name] = trim($translated, ':');
187
             }
188
        }
189
        else {
190
             foreach($this->columns as $name => $val) {
191
                // defensive code for array being returned
192
                $translated = translate($this->columns[$name]['label'], $this->seedBean->module_dir);
193
                if(is_array($translated)) $translated = $this->columns[$name]['label'];
194
                if(!empty($val['default']) && $val['default'])
195
                    $chooser->args['values_array'][0][$name] = trim($translated, ':');
196
                else
197
                    $chooser->args['values_array'][1][$name] = trim($translated, ':');
198
            }
199
        }
200
201
        $chooser->args['left_name'] = 'display_tabs';
202
        $chooser->args['right_name'] = 'hide_tabs';
203
        $chooser->args['max_left'] = '6';
204
205
        $chooser->args['left_label'] =  $GLOBALS['app_strings']['LBL_DISPLAY_COLUMNS'];
206
        $chooser->args['right_label'] =  $GLOBALS['app_strings']['LBL_HIDE_COLUMNS'];
207
        $chooser->args['title'] =  '';
208
        $this->configureSS->assign('columnChooser', $chooser->display());
209
210
        $query = false;
211
        $count = 0;
212
213
        if(!is_array($this->filters)) {
214
            // use default search params
215
            $this->filters = array();
216
            foreach($this->searchFields as $name => $params) {
217
                if(!empty($params['default']))
218
                    $this->filters[$name] = $params['default'];
219
            }
220
        }
221
        $currentSearchFields = array();
222
        foreach($this->searchFields as $name=>$params) {
223
            if(!empty($name)) {
224
                $name = strtolower($name);
225
                $currentSearchFields[$name] = array();
226
                $widgetDef = $this->seedBean->field_defs[$name];
227
                if($widgetDef['name'] == 'assigned_user_name') $widgetDef['name'] = 'assigned_user_id';
228
                //bug 39170 - begin
229
                if($widgetDef['name'] == 'created_by_name') $name = $widgetDef['name'] = 'created_by';
230
                if($widgetDef['name'] == 'modified_by_name') $name = $widgetDef['name'] = 'modified_user_id';
231
                //bug 39170 - end
232
                if($widgetDef['type']=='enum'){
233
                   $filterNotSelected = array(); // we need to have some value otherwise '' or null values make -none- to be selected by default
234
                }else{
235
                   $filterNotSelected = '';
236
                }
237
                $widgetDef['input_name0'] = empty($this->filters[$name]) ? $filterNotSelected : $this->filters[$name];
238
239
                $currentSearchFields[$name]['label'] = !empty($params['label']) ? translate($params['label'], $this->seedBean->module_dir) : translate($widgetDef['vname'], $this->seedBean->module_dir);
240
                $currentSearchFields[$name]['input'] = $this->layoutManager->widgetDisplayInput($widgetDef, true, (empty($this->filters[$name]) ? '' : $this->filters[$name]));
0 ignored issues
show
The call to LayoutManager::widgetDisplayInput() has too many arguments starting with empty($this->filters[$na...: $this->filters[$name].

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
241
            }
242
            else { // ability to create spacers in input fields
243
                $currentSearchFields['blank' + $count]['label'] = '';
244
                $currentSearchFields['blank' + $count]['input'] = '';
245
                $count++;
246
            }
247
        }
248
        $this->currentSearchFields = $currentSearchFields;
249
250
        $this->configureSS->assign('strings', array('general' => $GLOBALS['mod_strings']['LBL_DASHLET_CONFIGURE_GENERAL'],
251
                                     'filters' => $GLOBALS['mod_strings']['LBL_DASHLET_CONFIGURE_FILTERS'],
252
                                     'myItems' => $GLOBALS['mod_strings']['LBL_DASHLET_CONFIGURE_MY_ITEMS_ONLY'],
253
                                     'displayRows' => $GLOBALS['mod_strings']['LBL_DASHLET_CONFIGURE_DISPLAY_ROWS'],
254
                                     'title' => $GLOBALS['mod_strings']['LBL_DASHLET_CONFIGURE_TITLE'],
255
                                     'save' => $GLOBALS['app_strings']['LBL_SAVE_BUTTON_LABEL'],
256
                                     'clear' => $GLOBALS['app_strings']['LBL_CLEAR_BUTTON_LABEL'],
257
                                     'autoRefresh' => $GLOBALS['app_strings']['LBL_DASHLET_CONFIGURE_AUTOREFRESH'],
258
                                     ));
259
        $this->configureSS->assign('id', $this->id);
260
        $this->configureSS->assign('showMyItemsOnly', $this->showMyItemsOnly);
261
        $this->configureSS->assign('myItemsOnly', $this->myItemsOnly);
262
        $this->configureSS->assign('searchFields', $this->currentSearchFields);
263
        $this->configureSS->assign('showClearButton', $this->isConfigPanelClearShown);
264
        // title
265
        $this->configureSS->assign('dashletTitle', $this->title);
266
267
        // display rows
268
        $displayRowOptions = $GLOBALS['sugar_config']['dashlet_display_row_options'];
269
        $this->configureSS->assign('displayRowOptions', $displayRowOptions);
270
        $this->configureSS->assign('displayRowSelect', $this->displayRows);
271
272
        if($this->isAutoRefreshable()) {
273
       		$this->configureSS->assign('isRefreshable', true);
274
			$this->configureSS->assign('autoRefreshOptions', $this->getAutoRefreshOptions());
275
			$this->configureSS->assign('autoRefreshSelect', $this->autoRefresh);
276
		}
277
    }
278
    /**
279
     * Displays the options for this Dashlet
280
     *
281
     * @return string HTML that shows options
282
     */
283
    function displayOptions() {
284
        $this->processDisplayOptions();
285
        return parent::displayOptions() . $this->configureSS->fetch($this->configureTpl);
0 ignored issues
show
The method fetch cannot be called on $this->configureSS (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
286
    }
287
288 1
    function buildWhere() {
289 1
        global $current_user;
290
291 1
        $returnArray = array();
292
293 1
        if(!is_array($this->filters)) {
294
            // use defaults
295
            $this->filters = array();
296
            foreach($this->searchFields as $name => $params) {
297
                if(!empty($params['default']))
298
                    $this->filters[$name] = $params['default'];
299
            }
300
        }
301 1
        foreach($this->filters as $name=>$params) {
302 1
            if(!empty($params)) {
303 1
                if($name == 'assigned_user_id' && $this->myItemsOnly) continue; // don't handle assigned user filter if filtering my items only
304 1
                $widgetDef = $this->seedBean->field_defs[$name];
305
306 1
                $widgetClass = $this->layoutManager->getClassFromWidgetDef($widgetDef, true);
307 1
                $widgetDef['table'] = $this->seedBean->table_name;
308 1
                $widgetDef['table_alias'] = $this->seedBean->table_name;
309 1
                if(!empty($widgetDef['source']) && $widgetDef['source'] == 'custom_fields') {
310
                    $widgetDef['table'] = $this->seedBean->table_name."_cstm";
311
                    $widgetDef['table_alias'] = $widgetDef['table'];
312
                }
313 1
                switch($widgetDef['type']) {// handle different types
314 1
                    case 'date':
315 1
                    case 'datetime':
316 1
                    case 'datetimecombo':
317
                        if(is_array($params) && !empty($params)) {
318
                            if(!empty($params['date']))
319
                                $widgetDef['input_name0'] = $params['date'];
320
                            $filter = 'queryFilter' . $params['type'];
321
                        }
322
                        else {
323
                            $filter = 'queryFilter' . $params;
324
                        }
325
                        array_push($returnArray, $widgetClass->$filter($widgetDef, true));
326
                        break;
327 1
                    case 'assigned_user_name':
328
                        // This type runs through the SugarWidgetFieldname class, and needs a little extra help to make it through
329
                        if ( ! isset($widgetDef['column_key']) ) {
330
                            $widgetDef['column_key'] = $name;
331
                        }
332
                        // No break here, we want to run through the default handler
333 1
                    case 'relate':
334
                        if (isset($widgetDef['link']) && $this->seedBean->load_relationship($widgetDef['link'])) {
335
                            $widgetLink = $widgetDef['link'];
336
                            $widgetDef['module'] = $this->seedBean->$widgetLink->focus->module_name;
337
                            $widgetDef['link'] = $this->seedBean->$widgetLink->getRelationshipObject()->name;
338
                        }
339
                        // No break - run through the default handler
340
                    default:
341 1
                        $widgetDef['input_name0'] = $params;
342 1
                        if(is_array($params) && !empty($params)) { // handle array query
343 1
                            array_push($returnArray, $widgetClass->queryFilterone_of($widgetDef, false));
344
                        }
345
                        else {
346
                            array_push($returnArray, $widgetClass->queryFilterStarts_With($widgetDef, true));
347
                        }
348 1
                        $widgetDef['input_name0'] = $params;
349 1
                    break;
350
                }
351
            }
352
        }
353
354 1
        if($this->myItemsOnly) array_push($returnArray, $this->seedBean->table_name . '.' . "assigned_user_id = '" . $current_user->id . "'");
355
356 1
        return $returnArray;
357
    }
358
359 1
	protected function loadCustomMetadata()
360
	{
361 1
    	$customMetadate = 'custom/modules/'.$this->seedBean->module_dir.'/metadata/dashletviewdefs.php';
362 1
    	if ( file_exists ( $customMetadate )){
363
    		require($customMetadate);
364
			$this->searchFields = $dashletData[$this->seedBean->module_dir.'Dashlet']['searchFields'];
365
			foreach($this->searchFields  as $key =>$def){
366
				if($key == 'assigned_user_name'){
367
					$this->searchFields['assigned_user_id'] = $def;
368
					unset($this->searchFields['assigned_user_name'] );
369
					break;
370
				}
371
			}
372
373
	        $this->columns = $dashletData[$this->seedBean->module_dir.'Dashlet']['columns'];
374
    	}
375 1
	}
376
377
    /**
378
     * Does all dashlet processing, here's your chance to modify the rows being displayed!
379
     */
380 1
    function process($lvsParams = array()) {
381 1
        $currentSearchFields = array();
382 1
        $configureView = true; // configure view or regular view
383 1
        $query = false;
384 1
        $whereArray = array();
385 1
        $lvsParams['massupdate'] = false;
386
387 1
		$this->loadCustomMetadata();
388 1
        $this->addCustomFields();
389
        // apply filters
390 1
        if(isset($this->filters) || $this->myItemsOnly) {
391 1
            $whereArray = $this->buildWhere();
392
        }
393
394 1
        $this->lvs->export = false;
395 1
        $this->lvs->multiSelect = false;
396
        // columns
397 1
        $displayColumns = array();
398 1
        if(!empty($this->displayColumns)) { // use user specified columns
399
        	foreach($this->displayColumns as $name => $val) {
400
                $displayColumns[strtoupper($val)] = $this->columns[$val];
401
                $displayColumns[strtoupper($val)]['label'] = trim($displayColumns[strtoupper($val)]['label'], ':');// strip : at the end of headers
402
            }
403
        }
404 1
        else if (isset($this->columns)){
405
           // use the default
406 1
            foreach($this->columns as $name => $val) {
407 1
                if(!empty($val['default']) && $val['default']) {
408 1
                    $displayColumns[strtoupper($name)] = $val;
409 1
                    $displayColumns[strtoupper($name)]['label'] = trim($displayColumns[strtoupper($name)]['label'], ':');
410
                }
411
            }
412
        }
413 1
        $this->lvs->displayColumns = $displayColumns;
414
415
416 1
        $this->lvs->lvd->setVariableName($this->seedBean->object_name, array());
417 1
        $lvdOrderBy = $this->lvs->lvd->getOrderBy(); // has this list been ordered, if not use default
418
419 1
        $nameRelatedFields = array();
420
421
        //bug: 44592 - dashlet sort order was not being preserved between logins
422 1
        if(!empty($lvsParams['orderBy']) && !empty($lvsParams['sortOrder']))
423
        {
424
            $lvsParams['overrideOrder'] = true;
425
        }
426
        else
427
        {
428 1
            if(empty($lvdOrderBy['orderBy'])) {
429
                foreach($displayColumns as $colName => $colParams) {
430
                    if(!empty($colParams['defaultOrderColumn'])) {
431
                        $lvsParams['overrideOrder'] = true;
432
                        $lvsParams['orderBy'] = $colName;
433
                        $lvsParams['sortOrder'] = $colParams['defaultOrderColumn']['sortOrder'];
434
                    }
435
                }
436
            }
437
        }
438
		// Check for 'last_name' column sorting with related fields (last_name, first_name)
439
		// See ListViewData.php for actual sorting change.
440 1
		if ($lvdOrderBy['orderBy'] == 'last_name' && !empty($displayColumns['NAME']) && !empty($displayColumns['NAME']['related_fields']) &&
441 1
			in_array('last_name', $displayColumns['NAME']['related_fields']) &&
442 1
			in_array('first_name', $displayColumns['NAME']['related_fields'])) {
443
				$lvsParams['overrideLastNameOrder'] = true;
444
		}
445
446 1
        if(!empty($this->displayTpl))
447
        {
448
        	//MFH BUG #14296
449 1
            $where = '';
450 1
            if(!empty($whereArray)){
451 1
                $where = '(' . implode(') AND (', $whereArray) . ')';
452
            }
453 1
            $this->lvs->setup($this->seedBean, $this->displayTpl, $where , $lvsParams, 0, $this->displayRows/*, $filterFields*/);
0 ignored issues
show
The method setup() does not seem to exist on object<Smarty>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
454 1
            if(in_array('CREATED_BY', array_keys($displayColumns))) { // handle the created by field
455
                foreach($this->lvs->data['data'] as $row => $data) {
456
                    $this->lvs->data['data'][$row]['CREATED_BY'] = get_assigned_user_name($data['CREATED_BY']);
457
                }
458
            }
459
            // assign a baseURL w/ the action set as DisplayDashlet
460 1
            foreach($this->lvs->data['pageData']['urls'] as $type => $url) {
461
            	// awu Replacing action=DisplayDashlet with action=DynamicAction&DynamicAction=DisplayDashlet
462 1
                if($type == 'orderBy')
463 1
                    $this->lvs->data['pageData']['urls'][$type] = preg_replace('/(action=.*&)/Ui', 'action=DynamicAction&DynamicAction=displayDashlet&', $url);
464
                else
465 1
                    $this->lvs->data['pageData']['urls'][$type] = preg_replace('/(action=.*&)/Ui', 'action=DynamicAction&DynamicAction=displayDashlet&', $url) . '&sugar_body_only=1&id=' . $this->id;
466
            }
467
468 1
            $this->lvs->ss->assign('dashletId', $this->id);
469
        }
470 1
    }
471
472
   /**
473
     * Displays the Dashlet, must call process() prior to calling this
474
     *
475
     * @return string HTML that displays Dashlet
476
     */
477 1
    function display() {
478 1
        return parent::display() . $this->lvs->display(false) . $this->processAutoRefresh();
479
    }
480
481
    /**
482
     * Filter the $_REQUEST and only save only the needed options
483
     * @param array $req the array to pull options from
484
     *
485
     * @return array options array
486
     */
487
    function saveOptions($req) {
488
        $options = array();
489
490
		$this->loadCustomMetadata();
491
        foreach($req as $name => $value) {
492
            if(!is_array($value)) $req[$name] = trim($value);
493
        }
494
        $options['filters'] = array();
495
        foreach($this->searchFields as $name=>$params) {
496
            $widgetDef = $this->seedBean->field_defs[$name];
497
            //bug39170 - begin
498
            if($widgetDef['name']=='created_by_name' && $req['created_by']) $widgetDef['name'] = 'created_by';
499
            if($widgetDef['name']=='modified_by_name' && $req['modified_user_id']) $widgetDef['name'] = 'modified_user_id';
500
            //bug39170 - end
501
            if($widgetDef['type'] == 'datetimecombo' || $widgetDef['type'] == 'datetime' || $widgetDef['type'] == 'date') { // special case datetime types
502
                $options['filters'][$widgetDef['name']] = array();
503
                if(!empty($req['type_' . $widgetDef['name']])) { // save the type of date filter
504
                    $options['filters'][$widgetDef['name']]['type'] = $req['type_' . $widgetDef['name']];
505
                }
506
                if(!empty($req['date_' . $widgetDef['name']])) { // save the date
507
                    $options['filters'][$widgetDef['name']]['date'] = $req['date_' . $widgetDef['name']];
508
                }
509
            }
510
            elseif(!empty($req[$widgetDef['name']])) {
511
                $options['filters'][$widgetDef['name']] = $req[$widgetDef['name']];
512
            }
513
        }
514
        if(!empty($req['dashletTitle'])) {
515
            $options['title'] = $req['dashletTitle'];
516
        }
517
518
        // Don't save the options for myItemsOnly if we're not even showing the options.
519
        if($this->showMyItemsOnly){
520
            if(!empty($req['myItemsOnly'])) {
521
                 $options['myItemsOnly'] = $req['myItemsOnly'];
522
            }
523
            else {
524
                $options['myItemsOnly'] = false;
525
            }
526
        }
527
        $options['displayRows'] = empty($req['displayRows']) ? '5' : $req['displayRows'];
528
        // displayColumns
529
        if(!empty($req['displayColumnsDef'])) {
530
            $options['displayColumns'] = explode('|', $req['displayColumnsDef']);
531
        }
532
        $options['autoRefresh'] = empty($req['autoRefresh']) ? '0' : $req['autoRefresh'];
533
        return $options;
534
    }
535
536
    /**
537
     * Internal function to add custom fields
538
     *
539
     */
540 1
    function addCustomFields() {
541 1
        foreach($this->seedBean->field_defs as $fieldName => $def) {
542 1
            if(!empty($def['type']) && $def['type'] == 'html')
543
                continue;
544 1
            if(isset($def['vname'])) {
545 1
                $translated = translate($def['vname'], $this->seedBean->module_dir);
546 1
                if(is_array($translated)) $translated = $def['vname'];
547 1
                if(!empty($def['source']) && $def['source'] == 'custom_fields') {
548
                	if(isset($this->columns[$fieldName]['default']) && $this->columns[$fieldName]['default']){
549
                		$this->columns[$fieldName] = array('width' => '10',
550
                                                       'label' => $translated,
551
                                                       'default' => 1);
552
                	}else{
553
                    $this->columns[$fieldName] = array('width' => '10',
554 1
                                                       'label' => $translated);
555
                	}
556
557
                }
558
            }
559
        }
560 1
    }
561
}
562
?>
563