adamjakab /
SuiteCRM
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 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 | * 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 | |||
| 42 | |||
| 43 | require_once('include/utils.php'); |
||
| 44 | require_once('modules/Calendar/Calendar.php'); |
||
| 45 | require_once('modules/vCals/vCal.php'); |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Class for constructing the iCal response string for the current user. |
||
| 49 | * |
||
| 50 | * @see vCal |
||
| 51 | */ |
||
| 52 | class iCal extends vCal { |
||
| 53 | |||
| 54 | const UTC_FORMAT = 'Ymd\THi00\Z'; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * Constructor for the iCal class. |
||
| 58 | */ |
||
| 59 | 2 | public function __construct() |
|
| 60 | { |
||
| 61 | 2 | parent::__construct(); |
|
| 62 | 2 | } |
|
| 63 | |||
| 64 | /** |
||
| 65 | * Gets a UTC formatted string from the given dateTime |
||
| 66 | * |
||
| 67 | * @param SugarDateTime $dateTime the dateTime to format |
||
| 68 | * @return string the UTC formatted dateTime |
||
| 69 | */ |
||
| 70 | 1 | protected function getUtcDateTime($dateTime) |
|
| 71 | { |
||
| 72 | 1 | return $dateTime->format(self::UTC_FORMAT); |
|
| 73 | } |
||
| 74 | |||
| 75 | /** |
||
| 76 | * Gets the UTC formatted dateTime from the given timestamp. |
||
| 77 | * |
||
| 78 | * Checks the version of Sugar to see if user timezone adjustments are needed. |
||
| 79 | * |
||
| 80 | * @param integer $ts the timestamp to format |
||
| 81 | * @return string the UTC formatted dateTime |
||
| 82 | */ |
||
| 83 | protected function getUtcTime($ts) |
||
| 84 | { |
||
| 85 | global $timedate, $sugar_version; |
||
| 86 | $timestamp = ($ts+(date('Z')-$timedate->adjustmentForUserTimeZone()*60)); |
||
| 87 | return $this->getUtcDateTime(new SugarDateTime("@" . $ts)); |
||
| 88 | } |
||
| 89 | |||
| 90 | /** |
||
| 91 | * Converts the given number of minutes to formatted number of hours and remaining minutes. |
||
| 92 | * |
||
| 93 | * @param integer $minutes the number of minutes to format |
||
| 94 | * @return string the formatted hours and minutes |
||
| 95 | */ |
||
| 96 | protected function convertMinsToHoursAndMins($minutes) |
||
| 97 | { |
||
| 98 | $hrs = floor(abs($minutes) / 60); |
||
| 99 | $remainderMinutes = abs($minutes) - ($hrs * 60); |
||
| 100 | $sign = (($minutes < 0) ? "-" : "+"); |
||
| 101 | return $sign . str_pad($hrs, 2, "0", STR_PAD_LEFT) . str_pad($remainderMinutes, 2, "0", STR_PAD_LEFT); |
||
| 102 | } |
||
| 103 | |||
| 104 | /** |
||
| 105 | * Create a todo entry for the given task. |
||
| 106 | * |
||
| 107 | * @param UserBean $user_bean the current UserBean |
||
| 108 | * @param Task $task the task for the todo entry |
||
| 109 | * @param string $moduleName the name of the task module |
||
| 110 | * @param string $dtstamp the current timestamp |
||
| 111 | * @return string the todo entry for the task |
||
| 112 | */ |
||
| 113 | protected function createSugarIcalTodo($user_bean, $task, $moduleName, $dtstamp) |
||
| 114 | { |
||
| 115 | global $sugar_config; |
||
| 116 | $ical_array = array(); |
||
| 117 | $ical_array[] = array("BEGIN", "VTODO"); |
||
| 118 | $validDueDate = (isset($task->date_due) && $task->date_due != "" && $task->date_due != "0000-00-00"); |
||
| 119 | $validDueTime = (isset($task->time_due) && $task->time_due != ""); |
||
| 120 | $dueYear = 1970; |
||
| 121 | $dueMonth = 1; |
||
| 122 | $dueDay = 1; |
||
| 123 | $dueHour = 0; |
||
| 124 | $dueMin = 0; |
||
| 125 | if ($validDueDate) { |
||
| 126 | $dateDueArr = explode("-", $task->date_due); |
||
| 127 | $dueYear = (int)$dateDueArr[0]; |
||
| 128 | $dueMonth = (int)$dateDueArr[1]; |
||
| 129 | $dueDay = (int)$dateDueArr[2]; |
||
| 130 | |||
| 131 | if ($validDueTime) { |
||
| 132 | $timeDueArr = explode(":", $task->time_due); |
||
| 133 | $dueHour = (int)$timeDueArr[0]; |
||
| 134 | $dueMin = (int)$timeDueArr[1]; |
||
| 135 | } |
||
| 136 | } |
||
| 137 | $date_arr = array( |
||
| 138 | 'day'=>$dueDay, |
||
| 139 | 'month'=>$dueMonth, |
||
| 140 | 'hour'=>$dueHour, |
||
| 141 | 'min'=>$dueMin, |
||
| 142 | 'year'=>$dueYear); |
||
| 143 | $due_date_time = new SugarDateTime(); |
||
| 144 | $due_date_time->setDate($dueYear, $dueMonth, $dueDay); |
||
| 145 | $due_date_time->setTime($dueHour, $dueMin); |
||
| 146 | $ical_array[] = array( |
||
| 147 | "DTSTART;TZID=" . $user_bean->getPreference('timezone'), |
||
| 148 | str_replace("Z", "", $this->getUtcDateTime($due_date_time)) |
||
| 149 | ); |
||
| 150 | $ical_array[] = array("DTSTAMP", $dtstamp); |
||
| 151 | $ical_array[] = array("SUMMARY", $task->name); |
||
| 152 | $ical_array[] = array("UID", $task->id); |
||
| 153 | if ($validDueDate) { |
||
| 154 | $iCalDueDate = str_replace("-", "", $task->date_due); |
||
| 155 | if (strlen($iCalDueDate) > 8) { |
||
| 156 | $iCalDueDate = substr($iCalDueDate, 0, 8); |
||
| 157 | } |
||
| 158 | $ical_array[] = array("DUE;VALUE=DATE", $iCalDueDate); |
||
| 159 | } |
||
| 160 | if ($moduleName == "ProjectTask") { |
||
| 161 | $ical_array[] = array( |
||
| 162 | "DESCRIPTION:Project", |
||
| 163 | $task->project_name . vCal::EOL . vCal::EOL . $task->description |
||
| 164 | ); |
||
| 165 | } else { |
||
| 166 | $ical_array[] = array("DESCRIPTION", $task->description); |
||
| 167 | } |
||
| 168 | $ical_array[] = array( |
||
| 169 | "URL;VALUE=URI", |
||
| 170 | $sugar_config['site_url']."/index.php?module=".$moduleName."&action=DetailView&record=".$task->id |
||
| 171 | ); |
||
| 172 | if ($task->status == 'Completed') { |
||
| 173 | $ical_array[] = array("STATUS", "COMPLETED"); |
||
| 174 | $ical_array[] = array("PERCENT-COMPLETE", "100"); |
||
| 175 | $ical_array[] = array("COMPLETED", $this->getUtcDateTime($due_date_time)); |
||
| 176 | } else if (!empty($task->percent_complete)) { |
||
| 177 | $ical_array[] = array("PERCENT-COMPLETE", $task->percent_complete); |
||
| 178 | } |
||
| 179 | if ($task->priority == "Low") { |
||
| 180 | $ical_array[] = array("PRIORITY", "9"); |
||
| 181 | } else if ($task->priority == "Medium") { |
||
| 182 | $ical_array[] = array("PRIORITY", "5"); |
||
| 183 | } else if ($task->priority == "High") { |
||
| 184 | $ical_array[] = array("PRIORITY", "1"); |
||
| 185 | } |
||
| 186 | $ical_array[] = array("END", "VTODO"); |
||
| 187 | return vCal::create_ical_string_from_array($ical_array,true); |
||
| 188 | } |
||
| 189 | |||
| 190 | /** |
||
| 191 | * Creates the string for the user's events and todos between the given start |
||
| 192 | * and end times |
||
| 193 | * |
||
| 194 | * @param UserBean $user_bean the current UserBean |
||
| 195 | * @param DateTime $start_date_time the start date to search from |
||
| 196 | * @param DateTime $end_date_time the end date to search to |
||
| 197 | * @param string $dtstamp the current timestamp |
||
| 198 | * @return string the entries for events and todos |
||
| 199 | */ |
||
| 200 | 1 | protected function createSugarIcal(&$user_bean,&$start_date_time,&$end_date_time, $dtstamp) |
|
| 201 | { |
||
| 202 | 1 | $ical_array = array(); |
|
| 203 | 1 | global $DO_USER_TIME_OFFSET, $sugar_config, $current_user, $timedate; |
|
| 204 | |||
| 205 | 1 | $hide_calls = false; |
|
| 206 | 1 | if (!empty($_REQUEST['hide_calls']) && $_REQUEST['hide_calls'] == "true") |
|
| 207 | { |
||
| 208 | $hide_calls = true; |
||
| 209 | } |
||
| 210 | |||
| 211 | 1 | $taskAsVTODO = true; |
|
| 212 | 1 | if (!empty($_REQUEST['show_tasks_as_events']) && ($_REQUEST['show_tasks_as_events'] == "1" || $_REQUEST['show_tasks_as_events'] == "true")) |
|
| 213 | { |
||
| 214 | $taskAsVTODO = false; |
||
| 215 | } |
||
| 216 | |||
| 217 | 1 | $acts_arr = CalendarActivity::get_activities($user_bean->id, |
|
| 218 | 1 | !$taskAsVTODO, |
|
| 219 | $start_date_time, |
||
|
0 ignored issues
–
show
|
|||
| 220 | $end_date_time, |
||
|
0 ignored issues
–
show
$end_date_time of type object<DateTime> is not a sub-type of object<SugarDateTime>. It seems like you assume a child class of the class DateTime to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. Loading history...
|
|||
| 221 | 1 | 'month', |
|
| 222 | 1 | !$hide_calls); |
|
| 223 | |||
| 224 | |||
| 225 | // loop thru each activity, get start/end time in UTC, and return iCal strings |
||
| 226 | 1 | foreach($acts_arr as $act) |
|
| 227 | { |
||
| 228 | |||
| 229 | $event = $act->sugar_bean; |
||
| 230 | if (!$hide_calls || ($hide_calls && $event->object_name != "Call")) |
||
| 231 | { |
||
| 232 | $ical_array[] = array("BEGIN", "VEVENT"); |
||
| 233 | $ical_array[] = array("SUMMARY", $event->name); |
||
| 234 | $ical_array[] = array( |
||
| 235 | "DTSTART;TZID=" . $user_bean->getPreference('timezone'), |
||
| 236 | str_replace( |
||
| 237 | "Z", |
||
| 238 | "", |
||
| 239 | $timedate->tzUser($act->start_time, $current_user)->format(self::UTC_FORMAT) |
||
| 240 | ) |
||
| 241 | ); |
||
| 242 | $ical_array[] = array( |
||
| 243 | "DTEND;TZID=" . $user_bean->getPreference('timezone'), |
||
| 244 | str_replace( |
||
| 245 | "Z", |
||
| 246 | "", |
||
| 247 | $timedate->tzUser($act->end_time, $current_user)->format(self::UTC_FORMAT) |
||
| 248 | ) |
||
| 249 | ); |
||
| 250 | $ical_array[] = array("DTSTAMP", $dtstamp); |
||
| 251 | $ical_array[] = array("DESCRIPTION", $event->description); |
||
| 252 | $ical_array[] = array( |
||
| 253 | "URL;VALUE=URI", |
||
| 254 | $sugar_config['site_url']."/index.php?module=". |
||
| 255 | $event->module_dir."&action=DetailView&record=". $event->id |
||
| 256 | ); |
||
| 257 | $ical_array[] = array("UID", $event->id); |
||
| 258 | if ($event->object_name == "Meeting") |
||
| 259 | { |
||
| 260 | $ical_array[] = array("LOCATION", $event->location); |
||
| 261 | $eventUsers = $event->get_meeting_users(); |
||
| 262 | $query = "SELECT contact_id as id from meetings_contacts where meeting_id='$event->id' AND deleted=0"; |
||
| 263 | $eventContacts = $event->build_related_list($query, new Contact()); |
||
| 264 | $eventAttendees = array_merge($eventUsers, $eventContacts); |
||
| 265 | if (is_array($eventAttendees)) |
||
| 266 | { |
||
| 267 | foreach($eventAttendees as $attendee) |
||
| 268 | { |
||
| 269 | if ($attendee->id != $user_bean->id) |
||
| 270 | { |
||
| 271 | // Define the participant status |
||
| 272 | $participant_status = ''; |
||
| 273 | if (!empty($attendee->accept_status)) { |
||
| 274 | switch ($attendee->accept_status) { |
||
| 275 | case 'accept': |
||
| 276 | $participant_status = ';PARTSTAT=ACCEPTED'; |
||
| 277 | break; |
||
| 278 | case 'decline': |
||
| 279 | $participant_status = ';PARTSTAT=DECLINED'; |
||
| 280 | break; |
||
| 281 | case 'tentative': |
||
| 282 | $participant_status = ';PARTSTAT=TENTATIVE'; |
||
| 283 | break; |
||
| 284 | } |
||
| 285 | } |
||
| 286 | $ical_array[] = array( |
||
| 287 | 'ATTENDEE'.$participant_status.';CN="'.$attendee->get_summary_text().'"', |
||
| 288 | 'mailto:'.(!empty($attendee->email1) ? $attendee->email1:'[email protected]') |
||
| 289 | ); |
||
| 290 | } |
||
| 291 | } |
||
| 292 | } |
||
| 293 | } |
||
| 294 | if ($event->object_name == "Call") |
||
| 295 | { |
||
| 296 | $eventUsers = $event->get_call_users(); |
||
| 297 | $eventContacts = $event->get_contacts(); |
||
| 298 | $eventAttendees = array_merge($eventUsers, $eventContacts); |
||
| 299 | if (is_array($eventAttendees)) |
||
| 300 | { |
||
| 301 | foreach($eventAttendees as $attendee) |
||
| 302 | { |
||
| 303 | if ($attendee->id != $user_bean->id) |
||
| 304 | { |
||
| 305 | // Define the participant status |
||
| 306 | $participant_status = ''; |
||
| 307 | if (!empty($attendee->accept_status)) { |
||
| 308 | switch ($attendee->accept_status) { |
||
| 309 | case 'accept': |
||
| 310 | $participant_status = ';PARTSTAT=ACCEPTED'; |
||
| 311 | break; |
||
| 312 | case 'decline': |
||
| 313 | $participant_status = ';PARTSTAT=DECLINED'; |
||
| 314 | break; |
||
| 315 | case 'tentative': |
||
| 316 | $participant_status = ';PARTSTAT=TENTATIVE'; |
||
| 317 | break; |
||
| 318 | } |
||
| 319 | } |
||
| 320 | $ical_array[] = array( |
||
| 321 | 'ATTENDEE'.$participant_status.';CN="'.$attendee->get_summary_text().'"', |
||
| 322 | 'mailto:'.(!empty($attendee->email1) ? $attendee->email1:'[email protected]') |
||
| 323 | ); |
||
| 324 | } |
||
| 325 | } |
||
| 326 | } |
||
| 327 | } |
||
| 328 | if (isset($event->reminder_time) && $event->reminder_time > 0 && $event->status != "Held") |
||
| 329 | { |
||
| 330 | $ical_array[] = array("BEGIN", "VALARM"); |
||
| 331 | $ical_array[] = array("TRIGGER", "-PT"); |
||
| 332 | $ical_array[] = array("ACTION", "DISPLAY"); |
||
| 333 | $ical_array[] = array("DESCRIPTION", $event->name); |
||
| 334 | $ical_array[] = array("END", "VALARM"); |
||
| 335 | } |
||
| 336 | $ical_array[] = array("END", "VEVENT"); |
||
| 337 | } |
||
| 338 | |||
| 339 | } |
||
| 340 | |||
| 341 | 1 | $str = vCal::create_ical_string_from_array($ical_array,true); |
|
| 342 | |||
| 343 | 1 | require_once('include/TimeDate.php'); |
|
| 344 | 1 | $timedate = new TimeDate(); |
|
| 345 | 1 | $today = gmdate("Y-m-d"); |
|
| 346 | 1 | $today = $timedate->handle_offset($today, $timedate->dbDayFormat, false); |
|
|
0 ignored issues
–
show
The method
TimeDate::handle_offset() has been deprecated with message: for public usehandles offset values for Timezones and DST This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. Loading history...
|
|||
| 347 | |||
| 348 | 1 | require_once('modules/ProjectTask/ProjectTask.php'); |
|
| 349 | 1 | $where = "project_task.assigned_user_id='{$user_bean->id}' ". |
|
| 350 | 1 | "AND (project_task.status IS NULL OR (project_task.status!='Deferred')) ". |
|
| 351 | 1 | "AND (project_task.date_start IS NULL OR " . CalendarActivity::get_occurs_within_where_clause('project_task', '', $start_date_time, $end_date_time, 'date_start', 'month') . ")"; |
|
|
0 ignored issues
–
show
$start_date_time of type object<DateTime> is not a sub-type of object<SugarDateTime>. It seems like you assume a child class of the class DateTime to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. Loading history...
$end_date_time of type object<DateTime> is not a sub-type of object<SugarDateTime>. It seems like you assume a child class of the class DateTime to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. Loading history...
|
|||
| 352 | 1 | $seedProjectTask = new ProjectTask(); |
|
| 353 | 1 | $projectTaskList = $seedProjectTask->get_full_list("", $where); |
|
| 354 | 1 | if (is_array($projectTaskList)) |
|
| 355 | { |
||
| 356 | foreach($projectTaskList as $projectTask) |
||
| 357 | { |
||
| 358 | $str .= $this->createSugarIcalTodo($user_bean, $projectTask, "ProjectTask", $dtstamp); |
||
| 359 | } |
||
| 360 | } |
||
| 361 | |||
| 362 | 1 | if ($taskAsVTODO) { |
|
| 363 | 1 | require_once('modules/Tasks/Task.php'); |
|
| 364 | 1 | $where = "tasks.assigned_user_id='{$user_bean->id}' ". |
|
| 365 | 1 | "AND (tasks.status IS NULL OR (tasks.status!='Deferred')) ". |
|
| 366 | 1 | "AND (tasks.date_start IS NULL OR " . CalendarActivity::get_occurs_within_where_clause('tasks', '', $start_date_time, $end_date_time, 'date_start', 'month') . ")"; |
|
|
0 ignored issues
–
show
$start_date_time of type object<DateTime> is not a sub-type of object<SugarDateTime>. It seems like you assume a child class of the class DateTime to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. Loading history...
$end_date_time of type object<DateTime> is not a sub-type of object<SugarDateTime>. It seems like you assume a child class of the class DateTime to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. Loading history...
|
|||
| 367 | 1 | $seedTask = new Task(); |
|
| 368 | 1 | $taskList = $seedTask->get_full_list("", $where); |
|
| 369 | 1 | if (is_array($taskList)) |
|
| 370 | { |
||
| 371 | foreach($taskList as $task) |
||
| 372 | { |
||
| 373 | $str .= $this->createSugarIcalTodo($user_bean, $task, "Tasks", $dtstamp); |
||
| 374 | } |
||
| 375 | } |
||
| 376 | } |
||
| 377 | |||
| 378 | 1 | return $str; |
|
| 379 | } |
||
| 380 | |||
| 381 | /** |
||
| 382 | * Gets the time zone for the given user. |
||
| 383 | * |
||
| 384 | * @param User $current_user the user |
||
| 385 | * @return DateTimeZone the user's timezone |
||
| 386 | */ |
||
| 387 | 1 | protected function getUserTimezone($current_user) |
|
| 388 | { |
||
| 389 | 1 | $gmtTZ = new DateTimeZone("UTC"); |
|
| 390 | 1 | $userTZName = TimeDate::userTimezone($current_user); |
|
| 391 | 1 | if (!empty($userTZName)) |
|
| 392 | { |
||
| 393 | 1 | $tz = new DateTimeZone($userTZName); |
|
| 394 | } else |
||
| 395 | { |
||
| 396 | $tz = $gmtTZ; |
||
| 397 | } |
||
| 398 | 1 | return $tz; |
|
| 399 | } |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Gets the daylight savings range for the given user. |
||
| 403 | * |
||
| 404 | * @param User $current_user the user |
||
| 405 | * @param integer $year the year |
||
| 406 | * @return array the start and end transitions of daylight savings |
||
| 407 | */ |
||
| 408 | 1 | protected function getDSTRange($current_user, $year) |
|
| 409 | { |
||
| 410 | 1 | $tz = $this->getUserTimezone($current_user); |
|
| 411 | 1 | $idx = 0; |
|
| 412 | 1 | $result = array(); |
|
| 413 | |||
| 414 | 1 | if (version_compare(PHP_VERSION, '5.3.0') >= 0) |
|
| 415 | { |
||
| 416 | 1 | $year_date = SugarDateTime::createFromFormat("Y", $year, new DateTimeZone("UTC")); |
|
| 417 | 1 | $year_end = clone $year_date; |
|
| 418 | 1 | $year_end->setDate((int) $year, 12, 31); |
|
| 419 | 1 | $year_end->setTime(23, 59, 59); |
|
| 420 | 1 | $year_date->setDate((int) $year, 1, 1); |
|
| 421 | 1 | $year_date->setTime(0, 0, 0); |
|
| 422 | |||
| 423 | 1 | $transitions = $tz->getTransitions($year_date->getTimestamp(), $year_end->getTimestamp()); |
|
| 424 | 1 | foreach($transitions as $transition) { |
|
| 425 | 1 | if($transition['isdst']) { |
|
| 426 | break; |
||
| 427 | } |
||
| 428 | 1 | $idx++; |
|
| 429 | } |
||
| 430 | } else { |
||
| 431 | $transitions = $tz->getTransitions(); |
||
| 432 | |||
| 433 | $idx = 0; |
||
| 434 | foreach($transitions as $transition) { |
||
| 435 | if($transition['isdst'] && intval(substr($transition["time"], 0, 4)) == intval(date("Y"))) { |
||
| 436 | break; |
||
| 437 | } |
||
| 438 | $idx++; |
||
| 439 | } |
||
| 440 | } |
||
| 441 | |||
| 442 | 1 | if (empty($transitions[$idx]["isdst"])) { |
|
| 443 | // No DST transitions found |
||
| 444 | 1 | return $result; |
|
| 445 | } |
||
| 446 | $result["start"] = $transitions[$idx]; // DST begins here |
||
| 447 | // scan till DST ends |
||
| 448 | while (isset($transitions[$idx]) && $transitions[$idx]["isdst"]) $idx++; |
||
| 449 | if(isset($transitions[$idx])) { |
||
| 450 | $result["end"] = $transitions[$idx]; |
||
| 451 | } |
||
| 452 | return $result; |
||
| 453 | } |
||
| 454 | |||
| 455 | /** |
||
| 456 | * Gets the timezone string for the current user. |
||
| 457 | * |
||
| 458 | * @return string the full timezone definition including daylight savings for the iCal |
||
| 459 | */ |
||
| 460 | 1 | protected function getTimezoneString() |
|
| 461 | { |
||
| 462 | 1 | global $current_user, $timedate; |
|
| 463 | 1 | $timezoneName = $current_user->getPreference('timezone'); |
|
| 464 | |||
| 465 | 1 | $gmtTZ = new DateTimeZone("UTC"); |
|
| 466 | 1 | $tz = $this->getUserTimezone($current_user); |
|
| 467 | 1 | $dstRange = $this->getDSTRange($current_user, date('Y')); |
|
| 468 | |||
| 469 | 1 | $dstOffset = 0; |
|
| 470 | 1 | $gmtOffset = 0; |
|
| 471 | |||
| 472 | 1 | $ical_array = array(); |
|
| 473 | 1 | $ical_array[] = array("BEGIN", "VTIMEZONE"); |
|
| 474 | 1 | $ical_array[] = array("TZID", $timezoneName); |
|
| 475 | 1 | $ical_array[] = array("X-LIC-LOCATION", $timezoneName); |
|
| 476 | |||
| 477 | 1 | if (array_key_exists('start', $dstRange)) |
|
| 478 | { |
||
| 479 | $dstOffset = ($dstRange['start']['offset'] / 60); |
||
| 480 | $startDate = new DateTime("@" . $dstRange["start"]["ts"], $gmtTZ); |
||
| 481 | $startstamp = strtotime($timedate->asDb($startDate)); |
||
| 482 | $ical_array[] = array("BEGIN", "DAYLIGHT"); |
||
| 483 | $ical_array[] = array("TZOFFSETFROM", $this->convertMinsToHoursAndMins($gmtOffset)); |
||
| 484 | $ical_array[] = array("TZOFFSETTO", $this->convertMinsToHoursAndMins($dstOffset)); |
||
| 485 | $ical_array[] = array("DTSTART", str_replace("Z", "", $this->getUtcTime($startstamp))); |
||
| 486 | $ical_array[] = array("END", "DAYLIGHT"); |
||
| 487 | } |
||
| 488 | |||
| 489 | 1 | if (array_key_exists('end', $dstRange)) |
|
| 490 | { |
||
| 491 | $gmtOffset = ($dstRange['end']['offset'] / 60); |
||
| 492 | $endDate = new DateTime("@" . $dstRange["end"]["ts"], $gmtTZ); |
||
| 493 | $endstamp = strtotime($timedate->asDb($endDate)); |
||
| 494 | $ical_array[] = array("BEGIN", "STANDARD"); |
||
| 495 | $ical_array[] = array("TZOFFSETFROM", $this->convertMinsToHoursAndMins($dstOffset)); |
||
| 496 | $ical_array[] = array("TZOFFSETTO", $this->convertMinsToHoursAndMins($gmtOffset)); |
||
| 497 | $ical_array[] = array("DTSTART", str_replace("Z", "", $this->getUtcTime($endstamp))); |
||
| 498 | $ical_array[] = array("END", "STANDARD"); |
||
| 499 | } |
||
| 500 | |||
| 501 | 1 | $ical_array[] = array("END", "VTIMEZONE"); |
|
| 502 | |||
| 503 | 1 | return vCal::create_ical_string_from_array($ical_array,true); |
|
| 504 | } |
||
| 505 | |||
| 506 | /** |
||
| 507 | * Generates the complete string for the calendar |
||
| 508 | * |
||
| 509 | * @param User $user_focus the user |
||
| 510 | * @param integer $num_months the number of months to search before and after today |
||
| 511 | * @return string the iCal calenar string |
||
| 512 | */ |
||
| 513 | 1 | function getVcalIcal(&$user_focus, $num_months) |
|
| 514 | { |
||
| 515 | 1 | global $current_user, $timedate; |
|
| 516 | 1 | $current_user = $user_focus; |
|
| 517 | |||
| 518 | 1 | $cal_name = $user_focus->first_name. " ". $user_focus->last_name; |
|
| 519 | |||
| 520 | 1 | $ical_array = array(); |
|
| 521 | 1 | $ical_array[] = array("BEGIN", "VCALENDAR"); |
|
| 522 | 1 | $ical_array[] = array("VERSION", "2.0"); |
|
| 523 | 1 | $ical_array[] = array("METHOD", "PUBLISH"); |
|
| 524 | 1 | $ical_array[] = array("X-WR-CALNAME", "$cal_name (SugarCRM)"); |
|
| 525 | 1 | $ical_array[] = array("PRODID", "-//SugarCRM//SugarCRM Calendar//EN"); |
|
| 526 | 1 | $ical_array = array_merge($ical_array,vCal::create_ical_array_from_string($this->getTimezoneString())); |
|
| 527 | 1 | $ical_array[] = array("CALSCALE", "GREGORIAN"); |
|
| 528 | |||
| 529 | 1 | $now_date_time = $timedate->getNow(true); |
|
| 530 | |||
| 531 | 1 | global $sugar_config; |
|
| 532 | 1 | $timeOffset = 2; |
|
| 533 | 1 | if (isset($sugar_config['vcal_time']) && $sugar_config['vcal_time'] != 0 && $sugar_config['vcal_time'] < 13) |
|
| 534 | { |
||
| 535 | 1 | $timeOffset = $sugar_config['vcal_time']; |
|
| 536 | } |
||
| 537 | 1 | if (!empty($num_months)) |
|
| 538 | { |
||
| 539 | 1 | $timeOffset = $num_months; |
|
| 540 | } |
||
| 541 | 1 | $start_date_time = $now_date_time->get("-$timeOffset months"); |
|
| 542 | 1 | $end_date_time = $now_date_time->get("+$timeOffset months"); |
|
| 543 | |||
| 544 | 1 | $utc_now_time = $this->getUtcDateTime($now_date_time); |
|
| 545 | |||
| 546 | 1 | $str = vCal::create_ical_string_from_array($ical_array,true); |
|
| 547 | |||
| 548 | 1 | $str .= $this->createSugarIcal($user_focus,$start_date_time,$end_date_time,$utc_now_time); |
|
| 549 | |||
| 550 | $ical_array = array( |
||
| 551 | 1 | array("DTSTAMP", $utc_now_time) |
|
| 552 | ); |
||
| 553 | 1 | $ical_array[] = array("END", "VCALENDAR"); |
|
| 554 | |||
| 555 | 1 | $str .= vCal::create_ical_string_from_array($ical_array,true); |
|
| 556 | |||
| 557 | 1 | return $str; |
|
| 558 | } |
||
| 559 | |||
| 560 | } |
||
| 561 |
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.
Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.