]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Calendar/Calendar.php
Release 6.5.11
[Github/sugarcrm.git] / modules / Calendar / Calendar.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-2013 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
40
41
42 require_once('include/utils/activity_utils.php');
43 require_once('modules/Calendar/CalendarUtils.php');
44 require_once('modules/Calendar/CalendarActivity.php');
45
46
47 class Calendar {
48         
49         public $view = 'week'; // current view
50         public $style; // calendar style (basic or advanced)
51         public $dashlet = false; // if is displayed in dashlet  
52         public $date_time; // current date
53         
54         public $show_tasks = true;
55         public $show_calls = true;
56         public $show_completed = true;
57         public $enable_repeat = true;   
58
59         public $time_step = 60; // time step of each slot in minutes
60                 
61         public $acts_arr = array(); // Array of activities objects      
62         public $items = array(); // Array of activities data to be displayed    
63         public $shared_ids = array(); // ids of users for shared view
64         
65         
66         public $cells_per_day; // entire 24h day count of slots         
67         public $grid_start_ts; // start timestamp of calendar grid
68         
69         public $day_start_time; // working day start time in format '11:00'
70         public $day_end_time; // working day end time in format '11:00'
71         public $scroll_slot; // first slot of working day
72         public $celcount; // count of slots in a working day    
73
74     /**
75      * @var bool $print Whether is print mode.
76      */
77     private $print = false;
78                 
79         /**
80          * constructor
81          * @param string $view 
82          * @param array $time_arr 
83          */     
84         function __construct($view = "day", $time_arr = array()){
85                 global $current_user, $timedate;        
86                 
87                 $this->view = $view;            
88
89                 if(!in_array($this->view,array('day','week','month','year','shared')))
90                         $this->view = 'week';
91                 
92                 $date_arr = array();
93                 if(!empty($_REQUEST['day']))
94                         $_REQUEST['day'] = intval($_REQUEST['day']);
95                 if(!empty($_REQUEST['month']))
96                         $_REQUEST['month'] = intval($_REQUEST['month']);
97
98                 if (!empty($_REQUEST['day']))
99                         $date_arr['day'] = $_REQUEST['day'];
100                 if (!empty($_REQUEST['month']))
101                         $date_arr['month'] = $_REQUEST['month'];
102                 if (!empty($_REQUEST['week']))
103                         $date_arr['week'] = $_REQUEST['week'];
104
105                 if (!empty($_REQUEST['year'])){
106                         if ($_REQUEST['year'] > 2037 || $_REQUEST['year'] < 1970){
107                                 print("Sorry, calendar cannot handle the year you requested");
108                                 print("<br>Year must be between 1970 and 2037");
109                                 exit;
110                         }
111                         $date_arr['year'] = $_REQUEST['year'];
112                 }
113
114                 if(empty($_REQUEST['day']))
115                         $_REQUEST['day'] = "";
116                 if(empty($_REQUEST['week']))
117                         $_REQUEST['week'] = "";
118                 if(empty($_REQUEST['month']))
119                         $_REQUEST['month'] = "";
120                 if(empty($_REQUEST['year']))
121                         $_REQUEST['year'] = "";
122
123                 // if date is not set in request use current date
124                 if(empty($date_arr) || !isset($date_arr['year']) || !isset($date_arr['month']) || !isset($date_arr['day']) ){   
125                         $today = $timedate->getNow(true);
126                         $date_arr = array(
127                               'year' => $today->year,
128                               'month' => $today->month,
129                               'day' => $today->day,
130                         );
131                 }
132                 
133                 $current_date_db = $date_arr['year']."-".str_pad($date_arr['month'],2,"0",STR_PAD_LEFT)."-".str_pad($date_arr['day'],2,"0",STR_PAD_LEFT);
134                 $this->date_time = $GLOBALS['timedate']->fromString($current_date_db);  
135         
136                 $this->show_tasks = $current_user->getPreference('show_tasks');
137                 if(is_null($this->show_tasks))
138                         $this->show_tasks = SugarConfig::getInstance()->get('calendar.show_tasks_by_default',true);
139         
140                 $this->show_calls = $current_user->getPreference('show_calls');
141                 if(is_null($this->show_calls))
142                         $this->show_calls = SugarConfig::getInstance()->get('calendar.show_calls_by_default',true);
143         
144                 // Show completed Meetings, Calls, Tasks
145         $this->show_completed = $current_user->getPreference('show_completed');
146         if(is_null($this->show_completed))
147         {
148             $this->show_completed = SugarConfig::getInstance()->get('calendar.show_completed_by_default', true);
149         }
150         
151                 $this->enable_repeat = SugarConfig::getInstance()->get('calendar.enable_repeat',true);  
152
153                 if(in_array($this->view,array('month','year'))){
154                         $this->style = "basic"; 
155                 }else{
156                         $displayTimeslots = $GLOBALS['current_user']->getPreference('calendar_display_timeslots');
157                         if (is_null($displayTimeslots)) {
158                                 $displayTimeslots = SugarConfig::getInstance()->get('calendar.display_timeslots', true);
159                         }
160                         if ($displayTimeslots) {
161                                 $this->style = "advanced";
162                         } else {
163                                 $this->style = "basic";
164                         }
165                 }
166                 
167                 $this->day_start_time = $current_user->getPreference('day_start_time');
168                 if(is_null($this->day_start_time))
169                         $this->day_start_time = SugarConfig::getInstance()->get('calendar.default_day_start',"08:00");
170                 $this->day_end_time = $current_user->getPreference('day_end_time');
171                 if(is_null($this->day_end_time))
172                         $this->day_end_time = SugarConfig::getInstance()->get('calendar.default_day_end',"19:00");
173                         
174                 if($this->view == "day"){
175                         $this->time_step = SugarConfig::getInstance()->get('calendar.day_timestep',15);
176                 }else if($this->view == "week" || $this->view == "shared"){
177                         $this->time_step = SugarConfig::getInstance()->get('calendar.week_timestep',30);
178                 }else if($this->view == "month"){
179                         $this->time_step = SugarConfig::getInstance()->get('calendar.month_timestep',60);
180                 }else{
181                         $this->time_step = 60;
182                 }
183                 $this->cells_per_day = 24 * (60 / $this->time_step);            
184                 $this->calculate_grid_start_ts();
185                 $this->calculate_day_range();           
186         }
187         
188         /**
189          * Load activities data to array
190          */             
191         public function load_activities(){
192                 $field_list = CalendarUtils::get_fields();
193                 
194                 foreach($this->acts_arr as $user_id => $acts){  
195                         foreach($acts as $act){
196                                                                                         
197                                         $item = array();
198                                         $item['user_id'] = $user_id;
199                                         $item['module_name'] = $act->sugar_bean->module_dir;
200                                         $item['type'] = strtolower($act->sugar_bean->object_name);
201                                         $item['assigned_user_id'] = $act->sugar_bean->assigned_user_id;
202                                         $item['record'] = $act->sugar_bean->id;         
203                                         $item['name'] = $act->sugar_bean->name;
204                                         
205                                         if(isset($act->sugar_bean->duration_hours)){
206                                                 $item['duration_hours'] = $act->sugar_bean->duration_hours;
207                                                 $item['duration_minutes'] = $act->sugar_bean->duration_minutes;
208                                         }                               
209                                                                 
210                                         $item['detail'] = 0;
211                                         $item['edit'] = 0;
212                                         
213                                         if($act->sugar_bean->ACLAccess('DetailView'))
214                                                 $item['detail'] = 1;                                            
215                                         if($act->sugar_bean->ACLAccess('Save'))
216                                                 $item['edit'] = 1;                                      
217                                                 
218                                         if(empty($act->sugar_bean->id)){
219                                                 $item['detail'] = 0;
220                                                 $item['edit'] = 0;
221                                         }
222                                         
223                                         if(!empty($act->sugar_bean->repeat_parent_id))
224                                                 $item['repeat_parent_id'] = $act->sugar_bean->repeat_parent_id;                                 
225                                         
226                                         if($item['detail'] == 1){
227                                                 if(isset($field_list[$item['module_name']])){
228                                                         foreach($field_list[$item['module_name']] as $field){
229                                                                 if(!isset($item[$field]) && isset($act->sugar_bean->$field)){
230                                                                         $item[$field] = $act->sugar_bean->$field;
231                                                                         if(empty($item[$field]))
232                                                                                 $item[$field] = "";
233                                                                 }
234                                                         }                                       
235                                                 }                               
236                                         }
237
238                     if (!empty($act->sugar_bean->parent_type) && !empty($act->sugar_bean->parent_id)) {
239                         $focus = BeanFactory::getBean($act->sugar_bean->parent_type, $act->sugar_bean->parent_id);
240                         // If the bean wasn't loaded, e.g. insufficient permissions
241                         if (!empty($focus))
242                         {
243                             $item['related_to'] = $focus->name;
244                         }
245                     }
246
247                                         if(!isset($item['duration_hours']) || empty($item['duration_hours']))
248                                                 $item['duration_hours'] = 0;
249                                         if(!isset($item['duration_minutes']) || empty($item['duration_minutes']))
250                                                 $item['duration_minutes'] = 0;  
251                                                 
252                                         $item = array_merge($item,CalendarUtils::get_time_data($act->sugar_bean));                      
253                         
254                                         $this->items[] = $item;
255                         }
256                 }
257         }       
258         
259         /**
260          * initialize ids of shared users
261          */     
262         public function init_shared(){
263                 global $current_user;
264                 
265                 
266                 $user_ids = $current_user->getPreference('shared_ids');
267                 if(!empty($user_ids) && count($user_ids) != 0 && !isset($_REQUEST['shared_ids'])) {
268                         $this->shared_ids = $user_ids;
269                 }else if(isset($_REQUEST['shared_ids']) && count($_REQUEST['shared_ids']) > 0){
270                         $this->shared_ids = $_REQUEST['shared_ids'];
271                         $current_user->setPreference('shared_ids', $_REQUEST['shared_ids']);
272                 }else{
273                         $this->shared_ids = array($current_user->id);                           
274                 }
275         }
276         
277         /**
278          * Calculate timestamp the calendar grid should be started from 
279          */
280         protected function calculate_grid_start_ts(){
281         
282                 if($this->view == "week" || $this->view == "shared"){
283                         $week_start = CalendarUtils::get_first_day_of_week($this->date_time);
284                         $this->grid_start_ts = $week_start->format('U') + $week_start->getOffset(); 
285                 }else if($this->view == "month"){
286                         $month_start = $this->date_time->get_day_by_index_this_month(0);
287                         $week_start = CalendarUtils::get_first_day_of_week($month_start);
288                         $this->grid_start_ts = $week_start->format('U') + $week_start->getOffset(); // convert to timestamp, ignore tz
289                 }else if($this->view == "day"){
290                         $this->grid_start_ts = $this->date_time->format('U') + $this->date_time->getOffset();
291                 }       
292         }
293         
294         /**
295          * calculate count of timeslots per visible day, calculates day start and day end in minutes 
296          */     
297         function calculate_day_range(){ 
298                 
299                 list($hour_start,$minute_start) =  explode(":",$this->day_start_time);          
300                 list($hour_end,$minute_end) =  explode(":",$this->day_end_time);
301                 $this->scroll_slot = intval($hour_start * (60 / $this->time_step) + ($minute_start / $this->time_step));
302                 $this->celcount = (($hour_end * 60 + $minute_end) - ($hour_start * 60 + $minute_start)) / $this->time_step;
303         }       
304         
305         /**
306          * loads array of objects
307          * @param User $user user object
308          * @param string $type
309          */     
310         public function add_activities($user,$type='sugar'){
311                 global $timedate;
312                 $start_date_time = $this->date_time;
313                 if($this->view == 'week' || $this->view == 'shared'){           
314                         $start_date_time = CalendarUtils::get_first_day_of_week($this->date_time);
315                         $end_date_time = $start_date_time->get("+7 days");
316                 }else if($this->view == 'month'){
317                         $start_date_time = $this->date_time->get_day_by_index_this_month(0);    
318                         $end_date_time = $start_date_time->get("+".$start_date_time->format('t')." days");
319                         $start_date_time = CalendarUtils::get_first_day_of_week($start_date_time);
320                         $end_date_time = CalendarUtils::get_first_day_of_week($end_date_time)->get("+7 days");
321                 }else{
322                         $end_date_time = $this->date_time->get("+1 day");
323                 }
324                 
325                 $start_date_time = $start_date_time->get("-5 days"); // 5 days step back to fetch multi-day activities that
326
327                 $acts_arr = array();
328                 if($type == 'vfb')
329                 {
330                                 $acts_arr = CalendarActivity::get_freebusy_activities($user, $start_date_time, $end_date_time);
331                 }
332                 else
333                 {
334                                 $acts_arr = CalendarActivity::get_activities($user->id, $this->show_tasks, $start_date_time, $end_date_time, $this->view, $this->show_calls, $this->show_completed);
335                 }
336                 
337                 $this->acts_arr[$user->id] = $acts_arr;  
338         }
339
340         /**
341          * Get date string of next or previous calendar grid
342          * @param string $direction next or previous
343          * @return string
344          */
345         public function get_neighbor_date_str($direction){
346                 if($direction == "previous")
347                         $sign = "-";
348                 else 
349                         $sign = "+";
350                         
351                 if($this->view == 'month'){
352             $day = $this->date_time->get_day_by_index_this_month(0)->get($sign."1 month")->get_day_begin(1);
353                 }else if($this->view == 'week' || $this->view == 'shared'){
354                         $day = CalendarUtils::get_first_day_of_week($this->date_time);
355                         $day = $day->get($sign."7 days");
356                 }else if($this->view == 'day'){
357                         $day = $this->date_time->get($sign."1 day")->get_day_begin();
358                 }else if($this->view == 'year'){
359                         $day = $this->date_time->get($sign."1 year")->get_day_begin();
360                 }else{
361                         return "get_neighbor_date_str: notdefined for this view";
362                 }
363                 return $day->get_date_str();
364         }
365
366     public function setPrint($print)
367     {
368         $this->print = $print;
369     }
370     
371     public function isPrint()
372     {
373         return $this->print;
374     }
375
376 }
377
378 ?>