]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/Dashlets/DashletGenericChart.php
Release 6.3.0
[Github/sugarcrm.git] / include / Dashlets / DashletGenericChart.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38 require_once('include/Dashlets/Dashlet.php');
39 require_once('include/generic/LayoutManager.php');
40
41 abstract class DashletGenericChart extends Dashlet 
42 {       
43     /**
44      * The title of the dashlet
45      * @var string
46      */
47     public $title;
48     
49     /**
50      * @see Dashlet::$isConfigurable
51      */
52     public $isConfigurable = true;
53     
54     /**
55      * @see Dashlet::$isRefreshable
56      */
57     public $isRefreshable  = true;
58     
59     /**
60      * location of smarty template file for configuring
61      * @var string
62      */
63     protected $_configureTpl = 'include/Dashlets/DashletGenericChartConfigure.tpl';
64     
65     /**
66      * Bean file used in this Dashlet
67      * @var object
68      */
69     private $_seedBean;
70     
71     /**
72      * Module used in this Dashlet
73      * @var string
74      */
75     protected $_seedName;
76     
77     /**
78      * Array of fields and thier defintions that we are searching on
79      * @var array
80      */
81     protected $_searchFields;
82     
83     /**
84      * smarty object for the generic configuration template
85      * @var object
86      */
87     private $_configureSS;
88     
89     
90     /**
91      * Constructor
92      *
93      * @param int   $id
94      * @param array $options
95      */
96     public function __construct(
97         $id, 
98         array $options = null
99         ) 
100     {
101         parent::Dashlet($id);
102         
103         if ( isset($options) ) {
104             foreach ( $options as $key => $value ) {
105                 $this->$key = $value;
106             }
107         }
108         
109         // load searchfields
110         $classname = get_class($this);
111         if ( is_file("modules/Charts/Dashlets/$classname/$classname.data.php") ) {
112             require("modules/Charts/Dashlets/$classname/$classname.data.php");
113             $this->_searchFields = $dashletData[$classname]['searchFields'];
114         }
115         
116         // load language files
117         $this->loadLanguage($classname, 'modules/Charts/Dashlets/');
118         
119         if ( empty($options['title']) ) 
120             $this->title = $this->dashletStrings['LBL_TITLE'];
121         if ( isset($options['autoRefresh']) ) 
122             $this->autoRefresh = $options['autoRefresh'];
123         
124         $this->layoutManager = new LayoutManager();
125         $this->layoutManager->setAttribute('context', 'Report');
126         // fake a reporter object here just to pass along the db type used in many widgets.
127         // this should be taken out when sugarwidgets change
128         $temp = (object) array('db' => &$GLOBALS['db'], 'report_def_str' => '');
129         $this->layoutManager->setAttributePtr('reporter', $temp);
130     }
131
132     /**
133      * @see Dashlet::setRefreshIcon()
134      */
135     public function setRefreshIcon()
136     {
137         $additionalTitle = '';
138         if($this->isRefreshable)
139             $additionalTitle .= '<a href="#" onclick="SUGAR.mySugar.retrieveDashlet(\'' 
140                                 . $this->id . '\',\'predefined_chart\'); return false;"><img border="0" align="absmiddle" title="' . translate('LBL_DASHLET_REFRESH', 'Home') . '" alt="' . translate('LBL_DASHLET_REFRESH', 'Home') . '" src="' 
141                                 . SugarThemeRegistry::current()->getImageURL('dashlet-header-refresh.png').'"/></a>';           
142         return $additionalTitle;
143     }
144     
145     /**
146      * Displays the javascript for the dashlet
147      * 
148      * @return string javascript to use with this dashlet
149      */
150     public function displayScript() 
151     {
152
153                 require_once('include/SugarCharts/SugarChartFactory.php');
154                 $sugarChart = SugarChartFactory::getInstance();
155                 return $sugarChart->getDashletScript($this->id);
156
157     }
158     
159     /**
160      * Gets the smarty object for the config window. Designed to allow lazy loading the object
161      * when it's needed.
162      */
163     protected function getConfigureSmartyInstance()
164     {
165         if ( !($this->_configureSS instanceof Sugar_Smarty) ) {
166             
167             $this->_configureSS = new Sugar_Smarty();
168         }
169         
170         return $this->_configureSS;
171     }
172     
173     /**
174      * Saves the chart config options
175      * Filter the $_REQUEST and only save only the needed options
176      *
177      * @param  array $req
178      * @return array
179      */
180     public function saveOptions(
181         $req
182         ) 
183     {
184         global $timedate;
185         
186         $options = array();
187
188         foreach($req as $name => $value)
189             if(!is_array($value)) $req[$name] = trim($value);
190         
191         foreach($this->_searchFields as $name => $params) {
192             $widgetDef = $params;
193             if ( isset($this->getSeedBean()->field_defs[$name]) )
194                 $widgetDef = $this->getSeedBean()->field_defs[$name];
195             if ( $widgetDef['type'] == 'date')           // special case date types
196                 $options[$widgetDef['name']] = $timedate->swap_formats($req['type_'.$widgetDef['name']], $timedate->get_date_format(), $timedate->dbDayFormat);
197             elseif ( $widgetDef['type'] == 'time')       // special case time types
198                 $options[$widgetDef['name']] = $timedate->swap_formats($req['type_'.$widgetDef['name']], $timedate->get_time_format(), $timedate->dbTimeFormat);
199             elseif ( $widgetDef['type'] == 'datepicker') // special case datepicker types
200                 $options[$widgetDef['name']] = $timedate->swap_formats($req[$widgetDef['name']], $timedate->get_date_format(), $timedate->dbDayFormat);
201             elseif (!empty($req[$widgetDef['name']])) 
202                 $options[$widgetDef['name']] = $req[$widgetDef['name']];
203         }
204         
205         if (!empty($req['dashletTitle']))
206             $options['title'] = $req['dashletTitle'];
207         
208         $options['autoRefresh'] = empty($req['autoRefresh']) ? '0' : $req['autoRefresh'];
209         
210         return $options;
211     }
212     
213     /**
214      * Handles displaying the chart dashlet configuration popup window
215      *
216      * @return string HTML to return to the browser
217      */
218     public function displayOptions()
219     {
220         $currentSearchFields = array();
221         
222         if ( is_array($this->_searchFields) ) {
223             foreach($this->_searchFields as $name=>$params) {
224                 if(!empty($name)) {
225                     $name = strtolower($name);
226                     $currentSearchFields[$name] = array();
227     
228                     $widgetDef = $params;
229                     if ( isset($this->getSeedBean()->field_defs[$name]) )
230                         $widgetDef = $this->getSeedBean()->field_defs[$name];
231                     
232                     if($widgetDef['type'] == 'enum' || $widgetDef['type'] == 'singleenum') $widgetDef['remove_blank'] = true; // remove the blank option for the dropdown
233     
234                     if ( empty($widgetDef['input_name0']) )
235                         $widgetDef['input_name0'] = empty($this->$name) ? '' : $this->$name;
236                     $currentSearchFields[$name]['label'] = translate($widgetDef['vname'], $this->getSeedBean()->module_dir);
237                     if ( $currentSearchFields[$name]['label'] == $widgetDef['vname'] )
238                         $currentSearchFields[$name]['label'] = translate($widgetDef['vname'], 'Charts');
239                     $currentSearchFields[$name]['input'] = $this->layoutManager->widgetDisplayInput($widgetDef, true, (empty($this->$name) ? '' : $this->$name));
240                 }
241                 else { // ability to create spacers in input fields
242                     $currentSearchFields['blank' + $count]['label'] = '';
243                     $currentSearchFields['blank' + $count]['input'] = '';
244                     $count++;
245                 }
246             }
247         }
248         $this->currentSearchFields = $currentSearchFields;
249         $this->getConfigureSmartyInstance()->assign('title',translate('LBL_TITLE','Charts'));
250         $this->getConfigureSmartyInstance()->assign('save',$GLOBALS['app_strings']['LBL_SAVE_BUTTON_LABEL']);
251         $this->getConfigureSmartyInstance()->assign('clear',$GLOBALS['app_strings']['LBL_CLEAR_BUTTON_LABEL']);
252         $this->getConfigureSmartyInstance()->assign('id', $this->id);
253         $this->getConfigureSmartyInstance()->assign('searchFields', $this->currentSearchFields);
254         $this->getConfigureSmartyInstance()->assign('dashletTitle', $this->title);
255         $this->getConfigureSmartyInstance()->assign('dashletType', 'predefined_chart');
256         $this->getConfigureSmartyInstance()->assign('module', $_REQUEST['module']);
257         $this->getConfigureSmartyInstance()->assign('showClearButton', $this->isConfigPanelClearShown);
258         
259         if($this->isAutoRefreshable()) {
260                 $this->getConfigureSmartyInstance()->assign('isRefreshable', true);
261                         $this->getConfigureSmartyInstance()->assign('autoRefresh', $GLOBALS['app_strings']['LBL_DASHLET_CONFIGURE_AUTOREFRESH']);
262                         $this->getConfigureSmartyInstance()->assign('autoRefreshOptions', $this->getAutoRefreshOptions());
263                         $this->getConfigureSmartyInstance()->assign('autoRefreshSelect', $this->autoRefresh);
264                 }
265         
266         return parent::displayOptions() . $this->getConfigureSmartyInstance()->fetch($this->_configureTpl);
267     }
268     
269     /**
270      * Returns the DashletGenericChart::_seedBean object. Designed to allow lazy loading the object
271      * when it's needed.
272      *
273      * @return object
274      */
275     protected function getSeedBean()
276     {
277         if ( !($this->_seedBean instanceof SugarBean) )
278             $this->_seedBean = SugarModule::get($this->_seedName)->loadBean();
279         
280         return $this->_seedBean;
281     }
282     
283     /**
284      * Returns the built query read to feed into SugarChart::getData()
285      *
286      * @return string SQL query
287      */
288     protected function constructQuery()
289     {
290         return '';
291     }
292     
293     /**
294      * Returns the array of group by parameters for SugarChart::$group_by
295      *
296      * @return string SQL query
297      */
298     protected function constructGroupBy()
299     {
300         return array();
301     }
302     
303     /**
304      * Displays the Dashlet, must call process() prior to calling this
305      *
306      * @return string HTML that displays Dashlet
307      */
308     public function display() 
309     {
310         return parent::display() . $this->processAutoRefresh();
311     }
312     
313     /**
314      * Processes and displays the auto refresh code for the dashlet
315      *
316      * @param int $dashletOffset
317      * @return string HTML code
318      */
319     protected function processAutoRefresh($dashletOffset = 0) 
320     {
321         global $sugar_config;
322         
323         if ( empty($dashletOffset) ) {
324             $dashletOffset = 0;
325             $module = $_REQUEST['module'];
326             if(isset($_REQUEST[$module.'2_'.strtoupper($this->getSeedBean()->object_name).'_offset'])) {
327                 $dashletOffset = $_REQUEST[$module.'2_'.strtoupper($this->getSeedBean()->object_name).'_offset'];
328             }
329         }
330         
331         if ( !$this->isRefreshable ) {
332             return '';
333         }
334         if ( !empty($sugar_config['dashlet_auto_refresh_min']) && $sugar_config['dashlet_auto_refresh_min'] == -1 ) {
335             return '';
336         }
337         $autoRefreshSS = new Sugar_Smarty();    
338         $autoRefreshSS->assign('dashletOffset', $dashletOffset);
339         $autoRefreshSS->assign('dashletId', $this->id);
340         $autoRefreshSS->assign('strippedDashletId', str_replace("-","",$this->id)); //javascript doesn't like "-" in function names
341         if ( empty($this->autoRefresh) ) {
342             $this->autoRefresh = 0;
343         }
344         elseif ( !empty($sugar_config['dashlet_auto_refresh_min']) ) {
345             $this->autoRefresh = min($sugar_config['dashlet_auto_refresh_min'],$this->autoRefresh);
346         }
347         $autoRefreshSS->assign('dashletRefreshInterval', $this->autoRefresh * 1000);
348         $autoRefreshSS->assign('url', "predefined_chart");
349         $tpl = 'include/Dashlets/DashletGenericAutoRefresh.tpl';
350         if ( $_REQUEST['action'] == "DynamicAction" ) {
351             $tpl = 'include/Dashlets/DashletGenericAutoRefreshDynamic.tpl';
352         }
353         
354         return $autoRefreshSS->fetch($tpl);
355     }
356 }