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-2012 SugarCRM Inc.
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.
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
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
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.
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.
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 ********************************************************************************/
39 require_once('include/utils/activity_utils.php');
40 require_once('modules/Calendar/CalendarUtils.php');
41 require_once('modules/Calendar/CalendarActivity.php');
45 public $view = 'week'; // current view
46 public $dashlet = false; // if is displayed in dashlet
47 public $date_time; // current date
49 public $show_tasks = true;
50 public $show_calls = true;
52 public $time_step = 60; // time step of each slot in minutes
54 public $acts_arr = array(); // Array of activities objects
55 public $items = array(); // Array of activities data to be displayed
56 public $shared_ids = array(); // ids of users for shared view
59 public $cells_per_day; // entire 24h day count of slots
60 public $grid_start_ts; // start timestamp of calendar grid
62 public $day_start_time; // working day start time in format '11:00'
63 public $day_end_time; // working day end time in format '11:00'
64 public $scroll_slot; // first slot of working day
65 public $celcount; // count of slots in a working day
70 * @param array $time_arr
72 function __construct($view = "day", $time_arr = array()){
73 global $current_user, $timedate;
77 if(!in_array($this->view,array('day','week','month','year','shared')))
81 if(!empty($_REQUEST['day']))
82 $_REQUEST['day'] = intval($_REQUEST['day']);
83 if(!empty($_REQUEST['month']))
84 $_REQUEST['month'] = intval($_REQUEST['month']);
86 if (!empty($_REQUEST['day']))
87 $date_arr['day'] = $_REQUEST['day'];
88 if (!empty($_REQUEST['month']))
89 $date_arr['month'] = $_REQUEST['month'];
90 if (!empty($_REQUEST['week']))
91 $date_arr['week'] = $_REQUEST['week'];
93 if (!empty($_REQUEST['year'])){
94 if ($_REQUEST['year'] > 2037 || $_REQUEST['year'] < 1970){
95 print("Sorry, calendar cannot handle the year you requested");
96 print("<br>Year must be between 1970 and 2037");
99 $date_arr['year'] = $_REQUEST['year'];
102 if(empty($_REQUEST['day']))
103 $_REQUEST['day'] = "";
104 if(empty($_REQUEST['week']))
105 $_REQUEST['week'] = "";
106 if(empty($_REQUEST['month']))
107 $_REQUEST['month'] = "";
108 if(empty($_REQUEST['year']))
109 $_REQUEST['year'] = "";
111 // if date is not set in request use current date
112 if(empty($date_arr) || !isset($date_arr['year']) || !isset($date_arr['month']) || !isset($date_arr['day']) ){
113 $today = $timedate->getNow(true);
115 'year' => $today->year,
116 'month' => $today->month,
117 'day' => $today->day,
121 $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);
122 $this->date_time = $GLOBALS['timedate']->fromString($current_date_db);
124 $this->show_tasks = $current_user->getPreference('show_tasks');
125 if(is_null($this->show_tasks))
126 $this->show_tasks = SugarConfig::getInstance()->get('calendar.show_tasks_by_default',true);
127 $this->show_calls = $current_user->getPreference('show_calls');
128 if(is_null($this->show_calls))
129 $this->show_calls = SugarConfig::getInstance()->get('calendar.show_calls_by_default',true);
131 $this->day_start_time = $current_user->getPreference('day_start_time');
132 if(is_null($this->day_start_time))
133 $this->day_start_time = SugarConfig::getInstance()->get('calendar.default_day_start',"08:00");
134 $this->day_end_time = $current_user->getPreference('day_end_time');
135 if(is_null($this->day_end_time))
136 $this->day_end_time = SugarConfig::getInstance()->get('calendar.default_day_end',"19:00");
138 if($this->view == "day"){
139 $this->time_step = SugarConfig::getInstance()->get('calendar.day_timestep',15);
140 }else if($this->view == "week" || $this->view == "shared"){
141 $this->time_step = SugarConfig::getInstance()->get('calendar.week_timestep',30);
142 }else if($this->view == "month"){
143 $this->time_step = SugarConfig::getInstance()->get('calendar.month_timestep',60);
145 $this->time_step = 60;
147 $this->cells_per_day = 24 * (60 / $this->time_step);
148 $this->calculate_grid_start_ts();
150 $this->calculate_day_range();
154 * Load activities data to array
156 public function load_activities(){
157 $field_list = CalendarUtils::get_fields();
159 foreach($this->acts_arr as $user_id => $acts){
160 foreach($acts as $act){
162 $item['user_id'] = $user_id;
163 $item['module_name'] = $act->sugar_bean->module_dir;
164 $item['type'] = strtolower($act->sugar_bean->object_name);
165 $item['assigned_user_id'] = $act->sugar_bean->assigned_user_id;
166 $item['id'] = $act->sugar_bean->id;
167 $item['name'] = $act->sugar_bean->name;
168 $item['status'] = $act->sugar_bean->status;
170 if(isset($act->sugar_bean->duration_hours)){
171 $item['duration_hours'] = $act->sugar_bean->duration_hours;
172 $item['duration_minutes'] = $act->sugar_bean->duration_minutes;
178 if($act->sugar_bean->ACLAccess('DetailView'))
180 if($act->sugar_bean->ACLAccess('Save'))
183 if(empty($act->sugar_bean->id)){
188 if($item['detail'] == 1){
189 if(isset($field_list[$item['module_name']])){
190 foreach($field_list[$item['module_name']] as $field){
191 if(!isset($item[$field])){
192 $item[$field] = $act->sugar_bean->$field;
193 if($act->sugar_bean->field_defs[$field]['type'] == 'text'){
195 if(strlen($t) > 300){
196 $t = substr($t, 0, 300);
199 $t = str_replace("\r\n","<br>",$t);
200 $t = str_replace("\r","<br>",$t);
201 $t = str_replace("\n","<br>",$t);
209 if(!isset($item['duration_hours']) || empty($item['duration_hours']))
210 $item['duration_hours'] = 0;
211 if(!isset($item['duration_minutes']) || empty($item['duration_minutes']))
212 $item['duration_minutes'] = 0;
214 $item = array_merge($item,CalendarUtils::get_time_data($act->sugar_bean));
216 $this->items[] = $item;
222 * Get javascript objects of activities to be displayed on calendar
225 public function get_activities_js(){
226 $field_list = CalendarUtils::get_fields();
229 foreach($this->items as $act){
234 "type" : "'.$act["type"].'",
235 "module_name" : "'.$act["module_name"].'",
236 "record" : "'.$act["id"].'",
237 "user_id" : "'.$act["user_id"].'",
238 "timestamp" : "'.$act["timestamp"].'",
239 "time_start" : "'.$act["time_start"].'",
240 "record_name": "'.$act["name"].'",'.
242 foreach($field_list[$act['module_name']] as $field){
243 if(!isset($act[$field]))
245 $a_str .= ' "'. $field . '" : "'.$act[$field].'",
249 "detail" : "'.$act["detail"].'",
250 "edit" : "'.$act["edit"].'"
259 * initialize ids of shared users
261 public function init_shared(){
262 global $current_user;
265 $user_ids = $current_user->getPreference('shared_ids');
266 if(!empty($user_ids) && count($user_ids) != 0 && !isset($_REQUEST['shared_ids'])) {
267 $this->shared_ids = $user_ids;
268 }else if(isset($_REQUEST['shared_ids']) && count($_REQUEST['shared_ids']) > 0){
269 $this->shared_ids = $_REQUEST['shared_ids'];
270 $current_user->setPreference('shared_ids', $_REQUEST['shared_ids']);
272 $this->shared_ids = array($current_user->id);
277 * Calculate timestamp the calendar grid should be started from
279 protected function calculate_grid_start_ts(){
281 if($this->view == "week" || $this->view == "shared"){
282 $week_start = CalendarUtils::get_first_day_of_week($this->date_time);
283 $this->grid_start_ts = $week_start->format('U') + $week_start->getOffset();
284 }else if($this->view == "month"){
285 $month_start = $this->date_time->get_day_by_index_this_month(0);
286 $week_start = CalendarUtils::get_first_day_of_week($month_start);
287 $this->grid_start_ts = $week_start->format('U') + $week_start->getOffset(); // convert to timestamp, ignore tz
288 }else if($this->view == "day"){
289 $this->grid_start_ts = $this->date_time->format('U') + $this->date_time->getOffset();
291 $this->grid_start_ts = 0;
295 * calculate count of timeslots per visible day, calculates day start and day end in minutes
297 function calculate_day_range(){
299 list($hour_start,$minute_start) = explode(":",$this->day_start_time);
300 list($hour_end,$minute_end) = explode(":",$this->day_end_time);
302 $this->d_start_minutes = $hour_start * 60 + $minute_start;
303 $this->d_end_minutes = $hour_end * 60 + $minute_end;
305 $this->scroll_slot = intval($hour_start * (60 / $this->time_step) + ($minute_start / $this->time_step));
306 $this->celcount = (($hour_end * 60 + $minute_end) - ($hour_start * 60 + $minute_start)) / $this->time_step;
310 * loads array of objects
311 * @param User $user user object
312 * @param string $type
314 public function add_activities($user,$type='sugar'){
316 $start_date_time = $this->date_time;
317 if($this->view == 'week' || $this->view == 'shared'){
318 $start_date_time = CalendarUtils::get_first_day_of_week($this->date_time);
319 $end_date_time = $start_date_time->get("+7 days");
320 }else if($this->view == 'month'){
321 $start_date_time = $this->date_time->get_day_by_index_this_month(0);
322 $end_date_time = $start_date_time->get("+".$start_date_time->format('t')." days");
323 $start_date_time = CalendarUtils::get_first_day_of_week($start_date_time);
324 $end_date_time = CalendarUtils::get_first_day_of_week($end_date_time)->get("+7 days");
326 $end_date_time = $this->date_time->get("+1 day");
331 $acts_arr = CalendarActivity::get_freebusy_activities($user, $start_date_time, $end_date_time);
333 $acts_arr = CalendarActivity::get_activities($user->id, $this->show_tasks, $start_date_time, $end_date_time, $this->view,$this->show_calls);
336 $this->acts_arr[$user->id] = $acts_arr;
340 * Get date string of next or previous calendar grid
341 * @param string $direction next or previous
344 public function get_neighbor_date_str($direction){
345 if($direction == "previous")
350 if($this->view == 'month'){
351 $day = $this->date_time->get_day_by_index_this_month(0)->get($sign."1 month")->get_day_begin(1);
352 }else if($this->view == 'week' || $this->view == 'shared'){
353 $day = CalendarUtils::get_first_day_of_week($this->date_time);
354 $day = $day->get($sign."7 days");
355 }else if($this->view == 'day'){
356 $day = $this->date_time->get($sign."1 day")->get_day_begin();
357 }else if($this->view == 'year'){
358 $day = $this->date_time->get($sign."1 year")->get_day_begin();
360 return "get_neighbor_date_str: notdefined for this view";
362 return $day->get_date_str();