]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/SugarFeed/Dashlets/SugarFeedDashlet/SugarFeedDashlet.php
Release 6.4.0
[Github/sugarcrm.git] / modules / SugarFeed / Dashlets / SugarFeedDashlet / SugarFeedDashlet.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
39 require_once('include/Dashlets/DashletGeneric.php');
40 require_once('include/externalAPI/ExternalAPIFactory.php');
41
42 class SugarFeedDashlet extends DashletGeneric {
43 var $displayRows = 15;
44
45 var $categories;
46
47 var $userfeed_created;
48
49 var $selectedCategories = array();
50
51
52     function SugarFeedDashlet($id, $def = null) {
53                 global $current_user, $app_strings, $app_list_strings;
54
55                 require('modules/SugarFeed/metadata/dashletviewdefs.php');
56                 $this->myItemsOnly = false;
57         parent::DashletGeneric($id, $def);
58                 $this->myItemsOnly = false;
59                 $this->isConfigurable = true;
60                 $this->hasScript = true;
61                 $pattern = array();
62                 $pattern[] = "/-/";
63                 $pattern[] = "/[0-9]/";
64                 $replacements = array();
65                 $replacements[] = '';
66                 $replacements[] = '';
67                 $this->idjs = preg_replace($pattern,$replacements,$this->id);
68         // Add in some default categories.
69         $this->categories['ALL'] = translate('LBL_ALL','SugarFeed');
70         // Need to get the rest of the active SugarFeed modules
71         $module_list = SugarFeed::getActiveFeedModules();
72         
73         // Translate the category names
74         if ( ! is_array($module_list) ) { $module_list = array(); }
75         foreach ( $module_list as $module ) {
76             if ( $module == 'UserFeed' ) {
77                 // Fake module, need to translate specially
78                 $this->categories[$module] = translate('LBL_USER_FEED','SugarFeed');
79             } else {
80                 $this->categories[$module] = $app_list_strings['moduleList'][$module];
81             }
82         }
83
84         // Need to add the external api's here
85         $this->externalAPIList = ExternalAPIFactory::getModuleDropDown('SugarFeed',true);
86         if ( !is_array($this->externalAPIList) ) { $this->externalAPIList = array(); }
87         foreach ( $this->externalAPIList as $apiObj => $apiName ) {
88             $this->categories[$apiObj] = $apiName;
89         }
90
91
92         if(empty($def['title'])) $this->title = translate('LBL_HOMEPAGE_TITLE', 'SugarFeed');
93                 if(!empty($def['rows']))$this->displayRows = $def['rows'];
94                 if(!empty($def['categories']))$this->selectedCategories = $def['categories'];
95                 if(!empty($def['userfeed_created'])) $this->userfeed_created = $def['userfeed_created'];
96         $this->searchFields = $dashletData['SugarFeedDashlet']['searchFields'];
97         $this->columns = $dashletData['SugarFeedDashlet']['columns'];
98                 $catCount = count($this->categories);
99                 ACLController::filterModuleList($this->categories, false);
100                 if(count($this->categories) < $catCount){
101                         if(!empty($this->selectedCategories)){
102                                 ACLController::filterModuleList($this->selectedCategories, true);
103                         }else{
104                                 $this->selectedCategories = array_keys($this->categories);
105                                 unset($this->selectedCategories[0]);
106                         }
107                 }
108
109         $this->seedBean = new SugarFeed();
110     }
111
112         function process($lvsParams = array()) {
113         global $current_user;
114
115         $currentSearchFields = array();
116         $configureView = true; // configure view or regular view
117         $query = false;
118         $whereArray = array();
119         $lvsParams['massupdate'] = false;
120
121         // apply filters
122         if(isset($this->filters) || $this->myItemsOnly) {
123             $whereArray = $this->buildWhere();
124         }
125
126         $this->lvs->export = false;
127         $this->lvs->multiSelect = false;
128                 $this->lvs->quickViewLinks = false;
129         // columns
130     foreach($this->columns as $name => $val) {
131                 if(!empty($val['default']) && $val['default']) {
132                     $displayColumns[strtoupper($name)] = $val;
133                     $displayColumns[strtoupper($name)]['label'] = trim($displayColumns[strtoupper($name)]['label'], ':');
134                 }
135             }
136
137         $this->lvs->displayColumns = $displayColumns;
138
139         $this->lvs->lvd->setVariableName($this->seedBean->object_name, array());
140
141         $lvsParams['overrideOrder'] = true;
142         $lvsParams['orderBy'] = 'date_entered';
143         $lvsParams['sortOrder'] = 'DESC';
144         $lvsParams['custom_from'] = '';
145
146
147         // Get the real module list
148         if (empty($this->selectedCategories)){
149             $mod_list = $this->categories;
150         } else {
151             $mod_list = array_flip($this->selectedCategories);//27949, here the key of $this->selectedCategories is not module name, the value is module name, so array_flip it.
152         }
153
154         $external_modules = array();
155         $admin_modules = array();
156         $owner_modules = array();
157         $regular_modules = array();
158         foreach($mod_list as $module => $ignore) {
159                         // Handle the UserFeed differently
160                         if ( $module == 'UserFeed') {
161                                 $regular_modules[] = 'UserFeed';
162                                 continue;
163                         }
164             if ( in_array($module,$this->externalAPIList) ) {
165                 $external_modules[] = $module;
166             }
167                         if (ACLAction::getUserAccessLevel($current_user->id,$module,'view') <= ACL_ALLOW_NONE ) {
168                                 // Not enough access to view any records, don't add it to any lists
169                                 continue;
170                         }
171                         if ( ACLAction::getUserAccessLevel($current_user->id,$module,'view') == ACL_ALLOW_OWNER ) {
172                                 $owner_modules[] = $module;
173             } else {
174                 $regular_modules[] = $module;
175             }
176         }
177
178         if(!empty($this->displayTpl))
179         {
180                 //MFH BUG #14296
181             $where = '';
182             if(!empty($whereArray)){
183                 $where = '(' . implode(') AND (', $whereArray) . ')';
184
185             }
186
187             $additional_where = '';
188
189
190                         $module_limiter = " sugarfeed.related_module in ('" . implode("','", $regular_modules) . "')";
191
192                         if( is_admin($GLOBALS['current_user'] ) )
193             {
194                 $all_modules = array_merge($regular_modules, $owner_modules, $admin_modules);
195                 $module_limiter = " sugarfeed.related_module in ('" . implode("','", $all_modules) . "')";
196             }
197             else if ( count($owner_modules) > 0
198                                 ) {
199                 $module_limiter = " ((sugarfeed.related_module IN ('".implode("','", $regular_modules)."') "
200                                         .") ";
201                                 if ( count($owner_modules) > 0 ) {
202                                         $module_limiter .= "OR (sugarfeed.related_module IN('".implode("','", $owner_modules)."') AND sugarfeed.assigned_user_id = '".$current_user->id."' "
203                                                 .") ";
204                                 }
205                                 $module_limiter .= ")";
206             }
207                         if(!empty($where)) { $where .= ' AND '; }
208
209
210                         $where .= $module_limiter;
211
212             $this->lvs->setup($this->seedBean, $this->displayTpl, $where , $lvsParams, 0, $this->displayRows,
213                               array('name',
214                                     'description',
215                                     'date_entered',
216                                     'created_by',
217                                     'related_module',
218                                     'link_url',
219                                     'link_type'));
220
221             foreach($this->lvs->data['data'] as $row => $data) {
222
223                 $this->lvs->data['data'][$row]['NAME'] = str_replace("{this.CREATED_BY}",get_assigned_user_name($this->lvs->data['data'][$row]['CREATED_BY']),$data['NAME']);
224
225                 //Translate the SugarFeeds labels if necessary.
226                 preg_match('/\{([^\^ }]+)\.([^\}]+)\}/', $this->lvs->data['data'][$row]['NAME'] ,$modStringMatches );
227                 if(count($modStringMatches) == 3 && $modStringMatches[1] == 'SugarFeed' && !empty($data['RELATED_MODULE']) )
228                 {
229                     $modKey = $modStringMatches[2];
230                     $modString = translate($modKey, $modStringMatches[1]);
231                     if( strpos($modString, '{0}') === FALSE || !isset($GLOBALS['app_list_strings']['moduleListSingular'][$data['RELATED_MODULE']]) )
232                         continue;
233                     
234                     $modStringSingular = $GLOBALS['app_list_strings']['moduleListSingular'][$data['RELATED_MODULE']];
235                     $modString = string_format($modString, array($modStringSingular) );
236                     $this->lvs->data['data'][$row]['NAME'] = preg_replace('/' . $modStringMatches[0] . '/', strtolower($modString), $this->lvs->data['data'][$row]['NAME']);
237                 }
238             }
239
240             // assign a baseURL w/ the action set as DisplayDashlet
241             foreach($this->lvs->data['pageData']['urls'] as $type => $url) {
242                 // awu Replacing action=DisplayDashlet with action=DynamicAction&DynamicAction=DisplayDashlet
243                 if($type == 'orderBy')
244                     $this->lvs->data['pageData']['urls'][$type] = preg_replace('/(action=.*&)/Ui', 'action=DynamicAction&DynamicAction=displayDashlet&', $url);
245                 else
246                     $this->lvs->data['pageData']['urls'][$type] = preg_replace('/(action=.*&)/Ui', 'action=DynamicAction&DynamicAction=displayDashlet&', $url) . '&sugar_body_only=1&id=' . $this->id;
247             }
248
249             $this->lvs->ss->assign('dashletId', $this->id);
250
251
252         }
253
254         $td = $GLOBALS['timedate'];
255         $needResort = false;
256         $resortQueue = array();
257         $feedErrors = array();
258
259         $fetchRecordCount = $this->displayRows + $this->lvs->data['pageData']['offsets']['current'];
260
261         foreach ( $external_modules as $apiName ) {
262             $api = ExternalAPIFactory::loadAPI($apiName);
263             if ( $api !== FALSE ) {
264                 // FIXME: Actually calculate the oldest sugar feed we can see, once we get an API that supports this sort of filter.
265                 $reply = $api->getLatestUpdates(0,$fetchRecordCount);
266                 if ( $reply['success'] && count($reply['messages']) > 0 ) {
267                     array_splice($resortQueue, count($resortQueue), 0, $reply['messages']);
268                 } else if ( !$reply['success'] ) {
269                     $feedErrors[] = $reply['errorMessage'];
270                 }
271             }
272         }
273
274         if ( count($feedErrors) > 0 ) {
275             $this->lvs->ss->assign('feedErrors',$feedErrors);
276         }
277
278         // If we need to resort, get to work!
279         foreach ( $this->lvs->data['data'] as $normalMessage ) {
280             list($user_date,$user_time) = explode(' ',$normalMessage['DATE_ENTERED']);
281             list($db_date,$db_time) = $td->to_db_date_time($user_date,$user_time);
282
283             $unix_timestamp = strtotime($db_date.' '.$db_time);
284
285             $normalMessage['sort_key'] = $unix_timestamp;
286             $normalMessage['NAME'] = '</b>'.$normalMessage['NAME'];
287
288             $resortQueue[] = $normalMessage;
289         }
290
291         usort($resortQueue,create_function('$a,$b','return $a["sort_key"]<$b["sort_key"];'));
292
293         // Trim it down to the necessary number of records
294         $numRecords = count($resortQueue);
295         $numRecords = $numRecords - $this->lvs->data['pageData']['offsets']['current'];
296         $numRecords = min($this->displayRows,$numRecords);
297
298         $this->lvs->data['data'] = $resortQueue;
299     }
300
301           function deleteUserFeed() {
302         if(!empty($_REQUEST['record'])) {
303                         $feed = new SugarFeed();
304                         $feed->retrieve($_REQUEST['record']);
305                         if(is_admin($GLOBALS['current_user']) || $feed->created_by == $GLOBALS['current_user']->id){
306                 $feed->mark_deleted($_REQUEST['record']);
307
308                         }
309         }
310     }
311          function pushUserFeed() {
312         if(!empty($_REQUEST['text']) || (!empty($_REQUEST['link_url']) && !empty($_REQUEST['link_type']))) {
313                         $text = htmlspecialchars($_REQUEST['text']);
314                         //allow for bold and italic user tags
315                         $text = preg_replace('/&amp;lt;(\/*[bi])&amp;gt;/i','<$1>', $text);
316             SugarFeed::pushFeed($text, 'UserFeed', $GLOBALS['current_user']->id,
317                                                                 $GLOBALS['current_user']->id,
318                                 $_REQUEST['link_type'], $_REQUEST['link_url']
319                                 );
320         }
321
322     }
323
324          function pushUserFeedReply( ) {
325          if(!empty($_REQUEST['text'])&&!empty($_REQUEST['parentFeed'])) {
326                         $text = htmlspecialchars($_REQUEST['text']);
327                         //allow for bold and italic user tags
328                         $text = preg_replace('/&amp;lt;(\/*[bi])&amp;gt;/i','<$1>', $text);
329             SugarFeed::pushFeed($text, 'SugarFeed', $_REQUEST['parentFeed'],
330                                                                 $GLOBALS['current_user']->id,
331                                 '', ''
332                                 );
333         }
334
335     }
336
337           function displayOptions() {
338         global $app_strings;
339         global $app_list_strings;
340         $ss = new Sugar_Smarty();
341         $ss->assign('titleLBL', translate('LBL_TITLE', 'SugarFeed'));
342                 $ss->assign('categoriesLBL', translate('LBL_CATEGORIES', 'SugarFeed'));
343                 $ss->assign('autenticationPendingLBL', translate('LBL_AUTHENTICATION_PENDING', 'SugarFeed'));
344         $ss->assign('rowsLBL', translate('LBL_ROWS', 'SugarFeed'));
345         $ss->assign('saveLBL', $app_strings['LBL_SAVE_BUTTON_LABEL']);
346         $ss->assign('clearLBL', $app_strings['LBL_CLEAR_BUTTON_LABEL']);
347         $ss->assign('title', $this->title);
348                 $ss->assign('categories', $this->categories);
349         if ( empty($this->selectedCategories) ) {
350             $this->selectedCategories['ALL'] = 'ALL';
351         }
352                 $ss->assign('selectedCategories', $this->selectedCategories);
353         $ss->assign('rows', $this->displayRows);
354         $externalApis = array();
355         foreach ( $this->externalAPIList as $apiObj => $apiName ) {
356             //only show external APis that the user has not created
357             if ( ! EAPM::getLoginInfo($apiName) ) {
358                 $externalApis[] = $apiObj;
359             }
360         }
361         $ss->assign('externalApiList', JSON::encode($externalApis));
362         $ss->assign('authenticateLBL', translate('LBL_AUTHENTICATE', 'SugarFeed'));
363         $ss->assign('id', $this->id);
364         if($this->isAutoRefreshable()) {
365                 $ss->assign('isRefreshable', true);
366                         $ss->assign('autoRefresh', $GLOBALS['app_strings']['LBL_DASHLET_CONFIGURE_AUTOREFRESH']);
367                         $ss->assign('autoRefreshOptions', $this->getAutoRefreshOptions());
368                         $ss->assign('autoRefreshSelect', $this->autoRefresh);
369                 }
370
371         return  $ss->fetch('modules/SugarFeed/Dashlets/SugarFeedDashlet/Options.tpl');
372     }
373
374         /**
375          * creats the values
376          * @return
377          * @param $req Object
378          */
379           function saveOptions($req) {
380         global $sugar_config, $timedate, $current_user, $theme;
381         $options = array();
382         $options['title'] = $req['title'];
383                 $rows = intval($_REQUEST['rows']);
384         if($rows <= 0) {
385             $rows = 15;
386         }
387                 if($rows > 100){
388                         $rows = 100;
389                 }
390         if ( isset($req['autoRefresh']) )
391             $options['autoRefresh'] = $req['autoRefresh'];
392         $options['rows'] = $rows;
393                 $options['categories'] = $req['categories'];
394                 foreach($options['categories'] as $cat){
395                         if($cat == 'ALL'){
396                                 unset($options['categories']);
397                         }
398                 }
399
400
401         return $options;
402     }
403
404
405       function sugarFeedDisplayScript() {
406           // Forces the quicksearch to reload anytime the dashlet gets refreshed
407           return '<script type="text/javascript">
408 enableQS(false);
409 </script>';
410       }
411         /**
412          *
413          * @return javascript including QuickSearch for SugarFeeds
414          */
415          function displayScript() {
416                 require_once('include/QuickSearchDefaults.php');
417         $ss = new Sugar_Smarty();
418         $ss->assign('saving', translate('LBL_SAVING', 'SugarFeed'));
419         $ss->assign('saved', translate('LBL_SAVED', 'SugarFeed'));
420         $ss->assign('id', $this->id);
421         $ss->assign('idjs', $this->idjs);
422
423         $str = $ss->fetch('modules/SugarFeed/Dashlets/SugarFeedDashlet/SugarFeedScript.tpl');
424         return $str; // return parent::display for title and such
425     }
426
427         /**
428          *
429          * @return the fully rendered dashlet
430          */
431         function display(){
432
433                 $listview = parent::display();
434                 $GLOBALS['current_sugarfeed'] = $this;
435                 $listview = preg_replace_callback('/\{([^\^ }]+)\.([^\}]+)\}/', create_function(
436             '$matches',
437             'if($matches[1] == "this"){$var = $matches[2]; return $GLOBALS[\'current_sugarfeed\']->$var;}else{return translate($matches[2], $matches[1]);}'
438         ),$listview);
439
440         //grab each token and store the module for later processing
441         preg_match_all('/\[(\w+)\:/', $listview, $alt_modules);
442
443         //now process each token to create the proper url and image tags in feed, leaving a string for the alt to be replaced in next step
444                 $listview = preg_replace('/\[(\w+)\:([\w\-\d]*)\:([^\]]*)\]/', '<a href="index.php?module=$1&action=DetailView&record=$2"><img src="themes/default/images/$1.gif" border=0 REPLACE_ALT>$3</a>', $listview); /*SKIP_IMAGE_TAG*/
445
446         //process each module for the singular version so we can populate the alt tag on the image
447         $altStrings = array();
448         foreach($alt_modules[1] as $alt){
449             //create the alt string and replace the alt token
450             $altString = 'alt="'.translate('LBL_VIEW','SugarFeed').' '.$GLOBALS['app_list_strings']['moduleListSingular'][$alt].'"';
451             $listview = preg_replace('/REPLACE_ALT/', $altString, $listview,1);
452         }
453
454                 return $listview.'</div></div>';
455         }
456
457
458         /**
459          *
460          * @return the title and the user post form
461          * @param $text Object
462          */
463         function getHeader($text='') {
464                 return parent::getHeader($text) . $this->getPostForm().$this->getDisabledWarning().$this->sugarFeedDisplayScript().'<div class="sugarFeedDashlet"><div id="contentScroller'.$this->idjs.'">';
465         }
466
467
468         /**
469          *
470          * @return a warning message if the sugar feed system is not enabled currently
471          */
472         function getDisabledWarning(){
473         /* Check to see if the sugar feed system is enabled */
474         if ( ! $this->shouldDisplay() ) {
475             // The Sugar Feeds are disabled, populate the warning message
476             return translate('LBL_DASHLET_DISABLED','SugarFeed');
477         } else {
478             return '';
479         }
480     }
481
482         /**
483          *
484          * @return the form for users posting custom messages to the feed stream
485          */
486         function getPostForm(){
487         global $current_user;
488
489         if ( (!empty($this->selectedCategories) && !in_array('UserFeed',$this->selectedCategories))
490                         ) {
491             // The user feed system isn't enabled, don't let them post notes
492             return '';
493         }
494                 $user_name = ucfirst($GLOBALS['current_user']->user_name);
495                 $moreimg = SugarThemeRegistry::current()->getImage('advanced_search' , 'onclick="toggleDisplay(\'more_' . $this->id . '\'); toggleDisplay(\'more_img_'.$this->id.'\'); toggleDisplay(\'less_img_'.$this->id.'\');"',null,null,'.gif',translate('LBL_SHOW_MORE_OPTIONS','SugarFeed'));
496                 $lessimg = SugarThemeRegistry::current()->getImage('basic_search' , 'onclick="toggleDisplay(\'more_' . $this->id . '\'); toggleDisplay(\'more_img_'.$this->id.'\'); toggleDisplay(\'less_img_'.$this->id.'\');"',null,null,'.gif',translate('LBL_HIDE_OPTIONS','SugarFeed'));
497                 $ss = new Sugar_Smarty();
498                 $ss->assign('LBL_TO', translate('LBL_TO', 'SugarFeed'));
499                 $ss->assign('LBL_POST', translate('LBL_POST', 'SugarFeed'));
500                 $ss->assign('LBL_SELECT', translate('LBL_SELECT', 'SugarFeed'));
501                 $ss->assign('LBL_IS', translate('LBL_IS', 'SugarFeed'));
502                 $ss->assign('id', $this->id);
503                 $ss->assign('more_img', $moreimg);
504                 $ss->assign('less_img', $lessimg);
505         if($current_user->getPreference('use_real_names') == 'on'){
506             $ss->assign('user_name', $current_user->full_name);
507         }
508         else {
509             $ss->assign('user_name', $user_name);
510         }
511         $linkTypesIn = SugarFeed::getLinkTypes();
512         $linkTypes = array();
513         foreach ( $linkTypesIn as $key => $value ) {
514             $linkTypes[$key] = translate('LBL_LINK_TYPE_'.$value,'SugarFeed');
515         }
516                 $ss->assign('link_types', $linkTypes);
517                 return $ss->fetch('modules/SugarFeed/Dashlets/SugarFeedDashlet/UserPostForm.tpl');
518
519         }
520
521     // This is called from the include/MySugar/DashletsDialog/DashletsDialog.php and determines if we should display the SugarFeed dashlet as an option or not
522     static function shouldDisplay() {
523
524         $admin = new Administration();
525         $admin->retrieveSettings();
526
527         if ( !isset($admin->settings['sugarfeed_enabled']) || $admin->settings['sugarfeed_enabled'] != '1' ) {
528             return false;
529         } else {
530             return true;
531         }
532     }
533 }