1<?php 2/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> 3 * Copyright (C) 2003 Eric Seigne <erics@rycks.com> 4 * Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net> 5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com> 6 * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es> 7 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr> 8 * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com> 9 * Copyright (C) 2017 Open-DSI <support@open-dsi.fr> 10 * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr> 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <https://www.gnu.org/licenses/>. 24 */ 25 26 27/** 28 * \file htdocs/comm/action/index.php 29 * \ingroup agenda 30 * \brief Home page of calendar events 31 */ 32 33require '../../main.inc.php'; 34require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; 35require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; 36require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; 37require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; 38require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php'; 39if (!empty($conf->projet->enabled)) { 40 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; 41} 42 43if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW = 3; 44 45if (empty($conf->global->AGENDA_EXT_NB)) $conf->global->AGENDA_EXT_NB = 5; 46$MAXAGENDA = $conf->global->AGENDA_EXT_NB; 47 48$filter = GETPOST("search_filter", 'alpha', 3) ?GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); 49$filtert = GETPOST("search_filtert", "int", 3) ?GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); 50$usergroup = GETPOST("search_usergroup", "int", 3) ?GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); 51$showbirthday = empty($conf->use_javascript_ajax) ?GETPOST("showbirthday", "int") : 1; 52 53// If not choice done on calendar owner (like on left menu link "Agenda"), we filter on user. 54if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) 55{ 56 $filtert = $user->id; 57} 58 59$sortfield = GETPOST("sortfield", 'alpha'); 60$sortorder = GETPOST("sortorder", 'alpha'); 61$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); 62if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 63$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; 64$offset = $limit * $page; 65if (!$sortorder) $sortorder = "ASC"; 66if (!$sortfield) $sortfield = "a.datec"; 67 68// Security check 69$socid = GETPOST("search_socid", "int") ?GETPOST("search_socid", "int") : GETPOST("socid", "int"); 70if ($user->socid) $socid = $user->socid; 71$result = restrictedArea($user, 'agenda', 0, '', 'myactions'); 72if ($socid < 0) $socid = ''; 73 74$canedit = 1; 75if (!$user->rights->agenda->myactions->read) accessforbidden(); 76if (!$user->rights->agenda->allactions->read) $canedit = 0; 77if (!$user->rights->agenda->allactions->read || $filter == 'mine') // If no permission to see all, we show only affected to me 78{ 79 $filtert = $user->id; 80} 81 82$action = GETPOST('action', 'aZ09'); 83$resourceid = GETPOST("search_resourceid", "int"); 84$year = GETPOST("year", "int") ?GETPOST("year", "int") : date("Y"); 85$month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); 86$week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); 87$day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); 88$pid = GETPOST("search_projectid", "int", 3) ?GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); 89$status = GETPOST("search_status", 'aZ09') ?GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' 90$type = GETPOST("search_type", 'aZ09') ?GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); 91$maxprint = (isset($_GET["maxprint"]) ?GETPOST("maxprint") : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); 92$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') 93 94$dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int')); 95if ($dateselect > 0) 96{ 97 $day = GETPOST('dateselectday', 'int'); 98 $month = GETPOST('dateselectmonth', 'int'); 99 $year = GETPOST('dateselectyear', 'int'); 100} 101 102// Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) 103if (GETPOST('search_actioncode', 'array')) 104{ 105 $actioncode = GETPOST('search_actioncode', 'array', 3); 106 if (!count($actioncode)) $actioncode = '0'; 107} else { 108 $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); 109} 110if ($actioncode == '' && empty($actioncodearray)) $actioncode = (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE); 111 112if ($status == '' && !GETPOSTISSET('search_status')) $status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); 113 114$defaultview = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW); 115$defaultview = (empty($user->conf->AGENDA_DEFAULT_VIEW) ? $defaultview : $user->conf->AGENDA_DEFAULT_VIEW); 116if (empty($action) && !GETPOSTISSET('action')) $action = $defaultview; 117if ($action == 'default') // When action is default, we want a calendar view and not the list 118{ 119 $action = (($defaultview != 'show_list') ? $defaultview : 'show_month'); 120} 121if (GETPOST('viewcal', 'restricthtml') && GETPOST('action', 'alpha') != 'show_day' && GETPOST('action', 'alpha') != 'show_week') { 122 $action = 'show_month'; $day = ''; 123} // View by month 124if (GETPOST('viewweek', 'restricthtml') || GETPOST('action', 'alpha') == 'show_week') { 125 $action = 'show_week'; $week = ($week ? $week : date("W")); $day = ($day ? $day : date("d")); 126} // View by week 127if (GETPOST('viewday', 'restricthtml') || GETPOST('action', 'alpha') == 'show_day') { 128 $action = 'show_day'; $day = ($day ? $day : date("d")); 129} // View by day 130 131// Load translation files required by the page 132$langs->loadLangs(array('agenda', 'other', 'commercial')); 133 134// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context 135$hookmanager->initHooks(array('agenda')); 136 137 138/* 139 * Actions 140 */ 141 142if (GETPOST("viewlist", 'alpha') || $action == 'show_list') 143{ 144 $param = ''; 145 if (is_array($_POST)) 146 { 147 foreach ($_POST as $key => $val) 148 { 149 if ($key == 'token') continue; 150 $param .= '&'.$key.'='.urlencode($val); 151 } 152 } 153 if (!preg_match('/action=/', $param)) $param .= ($param ? '&' : '').'action=show_list'; 154 //print $param; 155 header("Location: ".DOL_URL_ROOT.'/comm/action/list.php?'.$param); 156 exit; 157} 158 159if (GETPOST("viewperuser", 'alpha') || $action == 'show_peruser') 160{ 161 $param = ''; 162 if (is_array($_POST)) 163 { 164 foreach ($_POST as $key => $val) 165 { 166 if ($key == 'token') continue; 167 $param .= '&'.$key.'='.urlencode($val); 168 } 169 } 170 //print $param; 171 header("Location: ".DOL_URL_ROOT.'/comm/action/peruser.php?'.$param); 172 exit; 173} 174 175if ($action == 'delete_action') 176{ 177 $event = new ActionComm($db); 178 $event->fetch($actionid); 179 $event->fetch_optionals(); 180 $event->fetch_userassigned(); 181 $event->oldcopy = clone $event; 182 183 $result = $event->delete(); 184} 185 186 187/* 188 * View 189 */ 190$parameters = array( 191 'socid' => $socid, 192 'status' => $status, 193 'year' => $year, 194 'month' => $month, 195 'day' => $day, 196 'type' => $type, 197 'maxprint' => $maxprint, 198 'filter' => $filter, 199 'filtert' => $filtert, 200 'showbirthday' => $showbirthday, 201 'canedit' => $canedit, 202 'optioncss' => $optioncss, 203 'actioncode' => $actioncode, 204 'pid' => $pid, 205 'resourceid' => $resourceid, 206 'usergroup' => $usergroup, 207); 208$reshook = $hookmanager->executeHooks('beforeAgenda', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 209if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 210 211$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:Módulo_Agenda'; 212llxHeader('', $langs->trans("Agenda"), $help_url); 213 214$form = new Form($db); 215$companystatic = new Societe($db); 216$contactstatic = new Contact($db); 217$userstatic = new User($db); 218 219$now = dol_now(); 220$nowarray = dol_getdate($now); 221$nowyear = $nowarray['year']; 222$nowmonth = $nowarray['mon']; 223$nowday = $nowarray['mday']; 224 225$listofextcals = array(); 226 227// Define list of external calendars (global admin setup) 228if (empty($conf->global->AGENDA_DISABLE_EXT)) 229{ 230 $i = 0; 231 while ($i < $MAXAGENDA) 232 { 233 $i++; 234 $source = 'AGENDA_EXT_SRC'.$i; 235 $name = 'AGENDA_EXT_NAME'.$i; 236 $offsettz = 'AGENDA_EXT_OFFSETTZ'.$i; 237 $color = 'AGENDA_EXT_COLOR'.$i; 238 $buggedfile = 'AGENDA_EXT_BUGGEDFILE'.$i; 239 if (!empty($conf->global->$source) && !empty($conf->global->$name)) 240 { 241 // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' 242 $listofextcals[] = array('src'=>$conf->global->$source, 'name'=>$conf->global->$name, 'offsettz'=>$conf->global->$offsettz, 'color'=>$conf->global->$color, 'buggedfile'=>(isset($conf->global->buggedfile) ? $conf->global->buggedfile : 0)); 243 } 244 } 245} 246// Define list of external calendars (user setup) 247if (empty($user->conf->AGENDA_DISABLE_EXT)) 248{ 249 $i = 0; 250 while ($i < $MAXAGENDA) 251 { 252 $i++; 253 $source = 'AGENDA_EXT_SRC_'.$user->id.'_'.$i; 254 $name = 'AGENDA_EXT_NAME_'.$user->id.'_'.$i; 255 $offsettz = 'AGENDA_EXT_OFFSETTZ_'.$user->id.'_'.$i; 256 $color = 'AGENDA_EXT_COLOR_'.$user->id.'_'.$i; 257 $enabled = 'AGENDA_EXT_ENABLED_'.$user->id.'_'.$i; 258 $buggedfile = 'AGENDA_EXT_BUGGEDFILE_'.$user->id.'_'.$i; 259 if (!empty($user->conf->$source) && !empty($user->conf->$name)) 260 { 261 // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' 262 $listofextcals[] = array('src'=>$user->conf->$source, 'name'=>$user->conf->$name, 'offsettz'=>$user->conf->$offsettz, 'color'=>$user->conf->$color, 'buggedfile'=>(isset($user->conf->buggedfile) ? $user->conf->buggedfile : 0)); 263 } 264 } 265} 266 267if (empty($action) || $action == 'show_month') 268{ 269 $prev = dol_get_prev_month($month, $year); 270 $prev_year = $prev['year']; 271 $prev_month = $prev['month']; 272 $next = dol_get_next_month($month, $year); 273 $next_year = $next['year']; 274 $next_month = $next['month']; 275 276 $max_day_in_prev_month = date("t", dol_mktime(0, 0, 0, $prev_month, 1, $prev_year, 'gmt')); // Nb of days in previous month 277 $max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year)); // Nb of days in next month 278 // tmpday is a negative or null cursor to know how many days before the 1st to show on month view (if tmpday=0, 1st is monday) 279 $tmpday = -date("w", dol_mktime(12, 0, 0, $month, 1, $year, 'gmt')) + 2; // date('w') is 0 fo sunday 280 $tmpday += ((isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1) - 1); 281 if ($tmpday >= 1) $tmpday -= 7; // If tmpday is 0 we start with sunday, if -6, we start with monday of previous week. 282 // Define firstdaytoshow and lastdaytoshow (warning: lastdaytoshow is last second to show + 1) 283 $firstdaytoshow = dol_mktime(0, 0, 0, $prev_month, $max_day_in_prev_month + $tmpday, $prev_year, 'tzuserrel'); 284 $next_day = 7 - ($max_day_in_month + 1 - $tmpday) % 7; 285 if ($next_day < 6) $next_day += 7; 286 $lastdaytoshow = dol_mktime(0, 0, 0, $next_month, $next_day, $next_year, 'tzuserrel'); 287} 288if ($action == 'show_week') 289{ 290 $prev = dol_get_first_day_week($day, $month, $year); 291 $prev_year = $prev['prev_year']; 292 $prev_month = $prev['prev_month']; 293 $prev_day = $prev['prev_day']; 294 $first_day = $prev['first_day']; 295 $first_month = $prev['first_month']; 296 $first_year = $prev['first_year']; 297 298 $week = $prev['week']; 299 300 $day = (int) $day; 301 $next = dol_get_next_week($first_day, $week, $first_month, $first_year); 302 $next_year = $next['year']; 303 $next_month = $next['month']; 304 $next_day = $next['day']; 305 306 // Define firstdaytoshow and lastdaytoshow (warning: lastdaytoshow is last second to show + 1) 307 $firstdaytoshow = dol_mktime(0, 0, 0, $first_month, $first_day, $first_year, 'tzuserrel'); 308 $lastdaytoshow = dol_time_plus_duree($firstdaytoshow, 7, 'd'); 309 310 $max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year, 'gmt')); 311 312 $tmpday = $first_day; 313} 314if ($action == 'show_day') 315{ 316 $prev = dol_get_prev_day($day, $month, $year); 317 $prev_year = $prev['year']; 318 $prev_month = $prev['month']; 319 $prev_day = $prev['day']; 320 $next = dol_get_next_day($day, $month, $year); 321 $next_year = $next['year']; 322 $next_month = $next['month']; 323 $next_day = $next['day']; 324 // Define firstdaytoshow and lastdaytoshow (warning: lastdaytoshow is last second to show + 1) 325 $firstdaytoshow = dol_mktime(0, 0, 0, $prev_month, $prev_day, $prev_year, 'tzuserrel'); 326 $lastdaytoshow = dol_mktime(0, 0, 0, $next_month, $next_day, $next_year, 'tzuserrel'); 327} 328//print 'xx'.$prev_year.'-'.$prev_month.'-'.$prev_day; 329//print 'xx'.$next_year.'-'.$next_month.'-'.$next_day; 330//print dol_print_date($firstdaytoshow,'dayhour').' '.dol_print_date($lastdaytoshow,'dayhour'); 331 332/*$title = $langs->trans("DoneAndToDoActions"); 333if ($status == 'done') $title = $langs->trans("DoneActions"); 334if ($status == 'todo') $title = $langs->trans("ToDoActions"); 335*/ 336 337$param = ''; 338if ($actioncode || GETPOSTISSET('search_actioncode')) { 339 if (is_array($actioncode)) { 340 foreach ($actioncode as $str_action) $param .= "&search_actioncode[]=".urlencode($str_action); 341 } else $param .= "&search_actioncode=".urlencode($actioncode); 342} 343if ($resourceid > 0) $param .= "&search_resourceid=".urlencode($resourceid); 344if ($status || GETPOSTISSET('status')) $param .= "&search_status=".urlencode($status); 345if ($filter) $param .= "&search_filter=".urlencode($filter); 346if ($filtert) $param .= "&search_filtert=".urlencode($filtert); 347if ($usergroup) $param .= "&search_usergroup=".urlencode($usergroup); 348if ($socid) $param .= "&search_socid=".urlencode($socid); 349if ($showbirthday) $param .= "&search_showbirthday=1"; 350if ($pid) $param .= "&search_projectid=".urlencode($pid); 351if ($type) $param .= "&search_type=".urlencode($type); 352if ($action == 'show_day' || $action == 'show_week' || $action == 'show_month') $param .= '&action='.urlencode($action); 353$param .= "&maxprint=".urlencode($maxprint); 354 355// Show navigation bar 356if (empty($action) || $action == 'show_month') 357{ 358 $nav = "<a href=\"?year=".$prev_year."&month=".$prev_month.$param."\"><i class=\"fa fa-chevron-left\"></i></a> \n"; 359 $nav .= " <span id=\"month_name\">".dol_print_date(dol_mktime(0, 0, 0, $month, 1, $year), "%b %Y"); 360 $nav .= " </span>\n"; 361 $nav .= " <a href=\"?year=".$next_year."&month=".$next_month.$param."\"><i class=\"fa fa-chevron-right\"></i></a>\n"; 362 if (empty($conf->dol_optimize_smallscreen)) { 363 $nav .= " <a href=\"?year=".$nowyear."&month=".$nowmonth.$param."\">".$langs->trans("Today")."</a> "; 364 } 365 $picto = 'calendar'; 366} 367if ($action == 'show_week') 368{ 369 $nav = "<a href=\"?year=".$prev_year."&month=".$prev_month."&day=".$prev_day.$param."\"><i class=\"fa fa-chevron-left\" title=\"".dol_escape_htmltag($langs->trans("Previous"))."\"></i></a> \n"; 370 $nav .= " <span id=\"month_name\">".dol_print_date(dol_mktime(0, 0, 0, $first_month, $first_day, $first_year), "%Y").", ".$langs->trans("Week")." ".$week; 371 $nav .= " </span>\n"; 372 $nav .= " <a href=\"?year=".$next_year."&month=".$next_month."&day=".$next_day.$param."\"><i class=\"fa fa-chevron-right\" title=\"".dol_escape_htmltag($langs->trans("Next"))."\"></i></a>\n"; 373 if (empty($conf->dol_optimize_smallscreen)) { 374 $nav .= " <a href=\"?year=".$nowyear."&month=".$nowmonth."&day=".$nowday.$param."\">".$langs->trans("Today")."</a> "; 375 } 376 $picto = 'calendarweek'; 377} 378if ($action == 'show_day') 379{ 380 $nav = "<a href=\"?year=".$prev_year."&month=".$prev_month."&day=".$prev_day.$param."\"><i class=\"fa fa-chevron-left\"></i></a> \n"; 381 $nav .= " <span id=\"month_name\">".dol_print_date(dol_mktime(0, 0, 0, $month, $day, $year), "daytextshort"); 382 $nav .= " </span>\n"; 383 $nav .= " <a href=\"?year=".$next_year."&month=".$next_month."&day=".$next_day.$param."\"><i class=\"fa fa-chevron-right\"></i></a>\n"; 384 if (empty($conf->dol_optimize_smallscreen)) { 385 $nav .= " <a href=\"?year=".$nowyear."&month=".$nowmonth."&day=".$nowday.$param."\">".$langs->trans("Today")."</a> "; 386 } 387 $picto = 'calendarday'; 388} 389 390$nav .= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0); 391//$nav .= ' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">'; 392$nav .= '<button type="submit" class="liste_titre button_search" name="button_search_x" value="x"><span class="fa fa-search"></span></button>'; 393 394// Must be after the nav definition 395$param .= '&year='.$year.'&month='.$month.($day ? '&day='.$day : ''); 396//print 'x'.$param; 397 398 399 400 401/*$tabactive = ''; 402if ($action == 'show_month') $tabactive = 'cardmonth'; 403if ($action == 'show_week') $tabactive = 'cardweek'; 404if ($action == 'show_day') $tabactive = 'cardday'; 405if ($action == 'show_list') $tabactive = 'cardlist'; 406if ($action == 'show_pertuser') $tabactive = 'cardperuser'; 407if ($action == 'show_pertype') $tabactive = 'cardpertype'; 408*/ 409 410$paramnoaction = preg_replace('/action=[a-z_]+/', '', $param); 411 412$head = calendars_prepare_head($paramnoaction); 413 414print '<form method="POST" id="searchFormList" class="listactionsfilter" action="'.$_SERVER["PHP_SELF"].'">'."\n"; 415if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">'; 416print '<input type="hidden" name="token" value="'.newToken().'">'; 417 418//print dol_get_fiche_head($head, $tabactive, $langs->trans('Agenda'), 0, 'action'); 419//print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, $listofextcals, $actioncode, $usergroup, '', $resourceid); 420//print dol_get_fiche_end(); 421 422$viewmode = ''; 423$viewmode .= '<a class="btnTitle reposition" href="'.DOL_URL_ROOT.'/comm/action/list.php?action=show_list&restore_lastsearch_values=1">'; 424//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">'; 425$viewmode .= img_picto($langs->trans("List"), 'object_list-alt', 'class="pictoactionview block"'); 426//$viewmode .= '</span>'; 427$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone">'.$langs->trans("ViewList").'</span></a>'; 428 429$viewmode .= '<a class="btnTitle'.($action == 'show_month' ? ' btnTitleSelected' : '').' reposition" href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_month&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'; 430//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">'; 431$viewmode .= img_picto($langs->trans("ViewCal"), 'object_calendar', 'class="pictoactionview block"'); 432//$viewmode .= '</span>'; 433$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone">'.$langs->trans("ViewCal").'</span></a>'; 434 435$viewmode .= '<a class="btnTitle'.($action == 'show_week' ? ' btnTitleSelected' : '').' reposition" href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_week&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'; 436//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">'; 437$viewmode .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview block"'); 438//$viewmode .= '</span>'; 439$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone">'.$langs->trans("ViewWeek").'</span></a>'; 440 441$viewmode .= '<a class="btnTitle'.($action == 'show_day' ? ' btnTitleSelected' : '').' reposition" href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_day&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'; 442//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">'; 443$viewmode .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview block"'); 444//$viewmode .= '</span>'; 445$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone">'.$langs->trans("ViewDay").'</span></a>'; 446 447$viewmode .= '<a class="btnTitle reposition marginrightonly" href="'.DOL_URL_ROOT.'/comm/action/peruser.php?action=show_peruser&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'; 448//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">'; 449$viewmode .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview block"'); 450//$viewmode .= '</span>'; 451$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone">'.$langs->trans("ViewPerUser").'</span></a>'; 452 453$viewmode .= '<span class="marginrightonly"></span>'; 454 455// Add more views from hooks 456$parameters = array(); $object = null; 457$reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action); 458if (empty($reshook)) { 459 $viewmode .= $hookmanager->resPrint; 460} elseif ($reshook > 1) { 461 $viewmode = $hookmanager->resPrint; 462} 463 464 465$newcardbutton = ''; 466if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create) 467{ 468 $tmpforcreatebutton = dol_getdate(dol_now(), true); 469 470 $newparam .= '&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$tmpforcreatebutton['year']; 471 472 //$param='month='.$monthshown.'&year='.$year; 473 $hourminsec = '100000'; 474 $newcardbutton .= dolGetButtonTitle($langs->trans("AddAction"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&datep='.sprintf("%04d%02d%02d", $tmpforcreatebutton['year'], $tmpforcreatebutton['mon'], $tmpforcreatebutton['mday']).$hourminsec.'&backtopage='.urlencode($_SERVER["PHP_SELF"].($newparam ? '?'.$newparam : ''))); 475} 476 477// Define the legend/list of calendard to show 478$s = ''; $link = ''; 479 480$showextcals = $listofextcals; 481 482if (!empty($conf->use_javascript_ajax)) // If javascript on 483{ 484 $s .= "\n".'<!-- Div to calendars selectors -->'."\n"; 485 $s .= '<script type="text/javascript">'."\n"; 486 $s .= 'jQuery(document).ready(function () {'."\n"; 487 $s .= 'jQuery(".check_birthday").click(function() { console.log("Toggle birthday"); jQuery(".family_birthday").toggle(); });'."\n"; 488 $s .= 'jQuery(".family_birthday").toggle();'."\n"; 489 if ($action == "show_week" || $action == "show_month" || empty($action)) 490 { 491 // Code to enable drag and drop 492 $s .= 'jQuery( "div.sortable" ).sortable({connectWith: ".sortable", placeholder: "ui-state-highlight", items: "div.movable", receive: function( event, ui ) {'."\n"; 493 // Code to submit form 494 $s .= 'console.log("submit form to record new event");'."\n"; 495 //$s.='console.log(event.target);'; 496 $s .= 'var newval = jQuery(event.target).closest("div.dayevent").attr("id");'."\n"; 497 $s .= 'console.log("found parent div.dayevent with id = "+newval);'."\n"; 498 $s .= 'var frm=jQuery("#searchFormList");'."\n"; 499 $s .= 'var newurl = ui.item.find("a.cal_event").attr("href");'."\n"; 500 $s .= 'console.log(newurl);'."\n"; 501 $s .= 'frm.attr("action", newurl).children("#newdate").val(newval);frm.submit();}'."\n"; 502 $s .= '});'."\n"; 503 } 504 $s .= '});'."\n"; 505 $s .= '</script>'."\n"; 506 507 // Local calendar 508 $s .= '<div class="nowrap inline-block minheight30"><input type="checkbox" id="check_mytasks" name="check_mytasks" checked disabled> '.$langs->trans("LocalAgenda").' </div>'; 509 510 // External calendars 511 if (is_array($showextcals) && count($showextcals) > 0) 512 { 513 $s .= '<script type="text/javascript">'."\n"; 514 $s .= 'jQuery(document).ready(function () { 515 jQuery("div input[name^=\"check_ext\"]").click(function() { 516 var name = $(this).attr("name"); 517 jQuery(".family_ext" + name.replace("check_ext", "")).toggle(); 518 }); 519 });' . "\n"; 520 $s .= '</script>'."\n"; 521 522 foreach ($showextcals as $val) 523 { 524 $htmlname = md5($val['name']); 525 $s .= '<div class="nowrap inline-block"><input type="checkbox" id="check_ext'.$htmlname.'" name="check_ext'.$htmlname.'" checked> <label for="check_ext'.$htmlname.'">'.$val['name'].'</label> </div>'; 526 } 527 } 528 529 // Birthdays 530 $s .= '<div class="nowrap inline-block"><input type="checkbox" id="check_birthday" name="check_birthday" class="check_birthday"><label for="check_birthday"> <span class="check_birthday_text">'.$langs->trans("AgendaShowBirthdayEvents").'</span></label> </div>'; 531 532 // Calendars from hooks 533 $parameters = array(); $object = null; 534 $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); 535 if (empty($reshook)) 536 { 537 $s .= $hookmanager->resPrint; 538 } elseif ($reshook > 1) 539 { 540 $s = $hookmanager->resPrint; 541 } 542} else // If javascript off 543{ 544 $newparam = $param; // newparam is for birthday links 545 $newparam = preg_replace('/showbirthday=[0-1]/i', 'showbirthday='.(empty($showbirthday) ? 1 : 0), $newparam); 546 if (!preg_match('/showbirthday=/i', $newparam)) $newparam .= '&showbirthday=1'; 547 $link = '<a href="'.dol_escape_htmltag($_SERVER['PHP_SELF']); 548 $link .= '?'.dol_escape_htmltag($newparam); 549 $link .= '">'; 550 if (empty($showbirthday)) $link .= $langs->trans("AgendaShowBirthdayEvents"); 551 else $link .= $langs->trans("AgendaHideBirthdayEvents"); 552 $link .= '</a>'; 553} 554 555// Load events from database into $eventarray 556$eventarray = array(); 557 558$sql = 'SELECT '; 559if ($usergroup > 0) $sql .= " DISTINCT"; 560$sql .= ' a.id, a.label,'; 561$sql .= ' a.datep,'; 562$sql .= ' a.datep2,'; 563$sql .= ' a.percent,'; 564$sql .= ' a.fk_user_author,a.fk_user_action,'; 565$sql .= ' a.transparency, a.priority, a.fulldayevent, a.location,'; 566$sql .= ' a.fk_soc, a.fk_contact, a.fk_project,'; 567$sql .= ' a.fk_element, a.elementtype,'; 568$sql .= ' ca.code as type_code, ca.libelle as type_label, ca.color as type_color'; 569$sql .= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; 570if (!$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; 571// We must filter on resource table 572if ($resourceid > 0) $sql .= ", ".MAIN_DB_PREFIX."element_resources as r"; 573// We must filter on assignement table 574if ($filtert > 0 || $usergroup > 0) $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar"; 575if ($usergroup > 0) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element"; 576$sql .= ' WHERE a.fk_action = ca.id'; 577$sql .= ' AND a.entity IN ('.getEntity('agenda').')'; 578// Condition on actioncode 579if (!empty($actioncode)) 580{ 581 if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) 582 { 583 if ($actioncode == 'AC_NON_AUTO') $sql .= " AND ca.type != 'systemauto'"; 584 elseif ($actioncode == 'AC_ALL_AUTO') $sql .= " AND ca.type = 'systemauto'"; 585 else { 586 if ($actioncode == 'AC_OTH') $sql .= " AND ca.type != 'systemauto'"; 587 if ($actioncode == 'AC_OTH_AUTO') $sql .= " AND ca.type = 'systemauto'"; 588 } 589 } else { 590 if ($actioncode == 'AC_NON_AUTO') $sql .= " AND ca.type != 'systemauto'"; 591 elseif ($actioncode == 'AC_ALL_AUTO') $sql .= " AND ca.type = 'systemauto'"; 592 else { 593 if (is_array($actioncode)) 594 { 595 $sql .= " AND ca.code IN ('".implode("','", $actioncode)."')"; 596 } else { 597 $sql .= " AND ca.code IN ('".implode("','", explode(',', $actioncode))."')"; 598 } 599 } 600 } 601} 602if ($resourceid > 0) $sql .= " AND r.element_type = 'action' AND r.element_id = a.id AND r.resource_id = ".$db->escape($resourceid); 603if ($pid) $sql .= " AND a.fk_project=".$db->escape($pid); 604if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".$user->id.")"; 605if ($socid > 0) $sql .= ' AND a.fk_soc = '.$socid; 606// We must filter on assignement table 607if ($filtert > 0 || $usergroup > 0) $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; 608//var_dump($day.' '.$month.' '.$year); 609if ($action == 'show_day') 610{ 611 $sql .= " AND ("; 612 $sql .= " (a.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'"; 613 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')"; 614 $sql .= " OR "; 615 $sql .= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'"; 616 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')"; 617 $sql .= " OR "; 618 $sql .= " (a.datep < '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'"; 619 $sql .= " AND a.datep2 > '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')"; 620 $sql .= ')'; 621} else { 622 // To limit array 623 $sql .= " AND ("; 624 $sql .= " (a.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, 1, $year) - (60 * 60 * 24 * 7))."'"; // Start 7 days before 625 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, 28, $year) + (60 * 60 * 24 * 10))."')"; // End 7 days after + 3 to go from 28 to 31 626 $sql .= " OR "; 627 $sql .= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, 1, $year) - (60 * 60 * 24 * 7))."'"; 628 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, 28, $year) + (60 * 60 * 24 * 10))."')"; 629 $sql .= " OR "; 630 $sql .= " (a.datep < '".$db->idate(dol_mktime(0, 0, 0, $month, 1, $year) - (60 * 60 * 24 * 7))."'"; 631 $sql .= " AND a.datep2 > '".$db->idate(dol_mktime(23, 59, 59, $month, 28, $year) + (60 * 60 * 24 * 10))."')"; 632 $sql .= ')'; 633} 634if ($type) $sql .= " AND ca.id = ".$type; 635if ($status == '0') { $sql .= " AND a.percent = 0"; } 636if ($status == '-1') { $sql .= " AND a.percent = -1"; } // Not applicable 637if ($status == '50') { $sql .= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started 638if ($status == 'done' || $status == '100') { $sql .= " AND (a.percent = 100)"; } 639if ($status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; } 640// We must filter on assignement table 641if ($filtert > 0 || $usergroup > 0) 642{ 643 $sql .= " AND ("; 644 if ($filtert > 0) $sql .= "ar.fk_element = ".$filtert; 645 if ($usergroup > 0) $sql .= ($filtert > 0 ? " OR " : "")." ugu.fk_usergroup = ".$usergroup; 646 $sql .= ")"; 647} 648// Sort on date 649$sql .= ' ORDER BY datep'; 650//print $sql; 651 652 653dol_syslog("comm/action/index.php", LOG_DEBUG); 654$resql = $db->query($sql); 655if ($resql) 656{ 657 $num = $db->num_rows($resql); 658 659 $MAXONSAMEPAGE = 10000; // Useless to have more. Protection to avoid memory overload when high number of event (for example after a mass import) 660 $i = 0; 661 while ($i < $num && $i < $MAXONSAMEPAGE) 662 { 663 $obj = $db->fetch_object($resql); 664 665 // Discard auto action if option is on 666 if (!empty($conf->global->AGENDA_ALWAYS_HIDE_AUTO) && $obj->type_code == 'AC_OTH_AUTO') 667 { 668 $i++; 669 continue; 670 } 671 672 // Create a new object action 673 $event = new ActionComm($db); 674 675 $event->id = $obj->id; 676 $event->ref = $event->id; 677 678 $event->datep = $db->jdate($obj->datep); // datep and datef are GMT date. Example: 1970-01-01 01:00:00, jdate will return 0 if TZ of PHP server is Europe/Berlin 679 $event->datef = $db->jdate($obj->datep2); 680 //$event->datep_formated_gmt = dol_print_date($event->datep, 'dayhour', 'gmt'); 681 //var_dump($obj->datep); 682 //var_dump($event->datep); 683 684 $event->type_code = $obj->type_code; 685 $event->type_label = $obj->type_label; 686 $event->type_color = $obj->type_color; 687 688 $event->libelle = $obj->label; // deprecated 689 $event->label = $obj->label; 690 $event->percentage = $obj->percent; 691 $event->authorid = $obj->fk_user_author; // user id of creator 692 $event->userownerid = $obj->fk_user_action; // user id of owner 693 $event->fetch_userassigned(); // This load $event->userassigned 694 $event->priority = $obj->priority; 695 $event->fulldayevent = $obj->fulldayevent; 696 $event->location = $obj->location; 697 $event->transparency = $obj->transparency; 698 $event->fk_element = $obj->fk_element; 699 $event->elementtype = $obj->elementtype; 700 701 $event->fk_project = $obj->fk_project; 702 703 $event->thirdparty_id = $obj->fk_soc; 704 $event->contact_id = $obj->fk_contact; 705 706 // Defined date_start_in_calendar and date_end_in_calendar property 707 // They are date start and end of action but modified to not be outside calendar view. 708 $event->date_start_in_calendar = $event->datep; 709 if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar = $event->datef; 710 else $event->date_end_in_calendar = $event->datep; 711 // Define ponctual property 712 if ($event->date_start_in_calendar == $event->date_end_in_calendar) 713 { 714 $event->ponctuel = 1; 715 } 716 717 // Check values 718 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { 719 // This record is out of visible range 720 } else { 721 if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar = $firstdaytoshow; 722 if ($event->date_end_in_calendar >= $lastdaytoshow) $event->date_end_in_calendar = ($lastdaytoshow - 1); 723 724 // Add an entry in actionarray for each day 725 $daycursor = $event->date_start_in_calendar; 726 $annee = dol_print_date($daycursor, '%Y', 'tzuserrel'); 727 $mois = dol_print_date($daycursor, '%m', 'tzuserrel'); 728 $jour = dol_print_date($daycursor, '%d', 'tzuserrel'); 729 //var_dump(dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt')); // Hour at greenwich 730 //var_dump($annee.'-'.$mois.'-'.$jour); 731 732 // Loop on each day covered by action to prepare an index to show on calendar 733 $loop = true; $j = 0; 734 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); 735 do { 736 //if ($event->id==408) 737 //print 'daykey='.$daykey.' '.dol_print_date($daykey, 'dayhour', 'gmt').' '.$event->datep.' '.$event->datef.'<br>'; 738 739 $eventarray[$daykey][] = $event; 740 $j++; 741 742 $daykey += 60 * 60 * 24; 743 if ($daykey > $event->date_end_in_calendar) $loop = false; 744 } while ($loop); 745 746 //print 'Event '.$i.' id='.$event->id.' (start='.dol_print_date($event->datep).'-end='.dol_print_date($event->datef); 747 //print ' startincalendar='.dol_print_date($event->date_start_in_calendar).'-endincalendar='.dol_print_date($event->date_end_in_calendar).') was added in '.$j.' different index key of array<br>'; 748 } 749 $i++; 750 } 751} else { 752 dol_print_error($db); 753} 754//var_dump($eventarray); 755 756// Complete $eventarray with birthdates 757if ($showbirthday) 758{ 759 // Add events in array 760 $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday'; 761 $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp'; 762 $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.$user->id.'))'; 763 $sql .= " AND sp.entity IN (".getEntity('socpeople').")"; 764 if ($action == 'show_day') 765 { 766 $sql .= ' AND MONTH(birthday) = '.$month; 767 $sql .= ' AND DAY(birthday) = '.$day; 768 } else { 769 $sql .= ' AND MONTH(birthday) = '.$month; 770 } 771 $sql .= ' ORDER BY birthday'; 772 773 dol_syslog("comm/action/index.php", LOG_DEBUG); 774 $resql = $db->query($sql); 775 if ($resql) 776 { 777 $num = $db->num_rows($resql); 778 $i = 0; 779 while ($i < $num) 780 { 781 $obj = $db->fetch_object($resql); 782 $event = new ActionComm($db); 783 784 $event->id = $obj->rowid; // We put contact id in action id for birthdays events 785 $event->ref = $event->id; 786 787 $datebirth = dol_stringtotime($obj->birthday, 1); 788 //print 'ee'.$obj->birthday.'-'.$datebirth; 789 $datearray = dol_getdate($datebirth, true); 790 $event->datep = dol_mktime(0, 0, 0, $datearray['mon'], $datearray['mday'], $year, true); // For full day events, date are also GMT but they wont but converted during output 791 $event->datef = $event->datep; 792 $event->type_code = 'BIRTHDAY'; 793 $event->label = $langs->trans("Birthday").' '.dolGetFirstLastname($obj->firstname, $obj->lastname); 794 $event->percentage = 100; 795 $event->fulldayevent = 1; 796 797 $event->date_start_in_calendar = $event->datep; 798 $event->date_end_in_calendar = $event->datef; 799 $event->ponctuel = 0; 800 801 // Add an entry in actionarray for each day 802 $daycursor = $event->date_start_in_calendar; 803 $annee = dol_print_date($daycursor, '%Y'); 804 $mois = dol_print_date($daycursor, '%m'); 805 $jour = dol_print_date($daycursor, '%d'); 806 807 $loop = true; 808 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee); 809 do { 810 $eventarray[$daykey][] = $event; 811 $daykey += 60 * 60 * 24; 812 if ($daykey > $event->date_end_in_calendar) $loop = false; 813 } while ($loop); 814 $i++; 815 } 816 } else { 817 dol_print_error($db); 818 } 819} 820 821if ($conf->global->AGENDA_SHOW_HOLIDAYS) 822{ 823 $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.statut, x.rowid, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.statut as status"; 824 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; 825 $sql .= " WHERE u.rowid = x.fk_user"; 826 $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user) 827 $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved) 828 829 if ($action == 'show_day') { 830 // Request only leaves for the current selected day 831 $sql .= " AND '".$db->escape($year)."-".$db->escape($month)."-".$db->escape($day)."' BETWEEN x.date_debut AND x.date_fin"; // date_debut and date_fin are date without time 832 } elseif ($action == 'show_week') { 833 // TODO: Add filter to reduce database request 834 } elseif ($action == 'show_month') { 835 // TODO: Add filter to reduce database request 836 } 837 838 $resql = $db->query($sql); 839 if ($resql) 840 { 841 $num = $db->num_rows($resql); 842 $i = 0; 843 844 while ($i < $num) 845 { 846 $obj = $db->fetch_object($resql); 847 848 $dateStartArray = dol_getdate(dol_stringtotime($obj->date_start, 1), true); 849 $dateEndArray = dol_getdate(dol_stringtotime($obj->date_end, 1), true); 850 851 $event = new ActionComm($db); 852 853 // Need the id of the leave object for link to it 854 $event->id = $obj->rowid; 855 $event->ref = $event->id; 856 857 $event->type_code = 'HOLIDAY'; 858 $event->datep = dol_mktime(0, 0, 0, $dateStartArray['mon'], $dateStartArray['mday'], $dateStartArray['year'], true); 859 $event->datef = dol_mktime(0, 0, 0, $dateEndArray['mon'], $dateEndArray['mday'], $dateEndArray['year'], true); 860 $event->date_start_in_calendar = $event->datep; 861 $event->date_end_in_calendar = $event->datef; 862 863 if ($obj->status == 3) 864 { 865 // Show no symbol for leave with state "leave approved" 866 $event->percentage = -1; 867 } elseif ($obj->status == 2) 868 { 869 // Show TO-DO symbol for leave with state "leave wait for approval" 870 $event->percentage = 0; 871 } 872 873 if ($obj->halfday == 1) 874 { 875 $event->label = $obj->lastname.' ('.$langs->trans("Morning").')'; 876 } elseif ($obj->halfday == -1) 877 { 878 $event->label = $obj->lastname.' ('.$langs->trans("Afternoon").')'; 879 } else { 880 $event->label = $obj->lastname; 881 } 882 883 $daycursor = $event->date_start_in_calendar; 884 $annee = dol_print_date($daycursor, '%Y'); 885 $mois = dol_print_date($daycursor, '%m'); 886 $jour = dol_print_date($daycursor, '%d'); 887 888 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee); 889 890 do { 891 $eventarray[$daykey][] = $event; 892 893 $daykey += 60 * 60 * 24; 894 } while ($daykey <= $event->date_end_in_calendar); 895 896 $i++; 897 } 898 } 899} 900 901// Complete $eventarray with external import Ical 902if (count($listofextcals)) 903{ 904 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/ical.class.php'; 905 foreach ($listofextcals as $extcal) 906 { 907 $url = $extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics 908 $namecal = $extcal['name']; 909 $offsettz = $extcal['offsettz']; 910 $colorcal = $extcal['color']; 911 $buggedfile = $extcal['buggedfile']; 912 //print "url=".$url." namecal=".$namecal." colorcal=".$colorcal." buggedfile=".$buggedfile; 913 $ical = new ICal(); 914 $ical->parse($url); 915 916 // After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ... 917 //var_dump($ical->cal); exit; 918 $icalevents = array(); 919 if (is_array($ical->get_event_list())) $icalevents = array_merge($icalevents, $ical->get_event_list()); // Add $ical->cal['VEVENT'] 920 if (is_array($ical->get_freebusy_list())) $icalevents = array_merge($icalevents, $ical->get_freebusy_list()); // Add $ical->cal['VFREEBUSY'] 921 922 if (count($icalevents) > 0) 923 { 924 // Duplicate all repeatable events into new entries 925 $moreicalevents = array(); 926 foreach ($icalevents as $icalevent) 927 { 928 if (isset($icalevent['RRULE']) && is_array($icalevent['RRULE'])) //repeatable event 929 { 930 //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow; 931 //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow-1); 932 if ($icalevent['DTSTART;VALUE=DATE']) //fullday event 933 { 934 $datecurstart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1); 935 $datecurend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day 936 } elseif (is_array($icalevent['DTSTART']) && !empty($icalevent['DTSTART']['unixtime'])) 937 { 938 $datecurstart = $icalevent['DTSTART']['unixtime']; 939 $datecurend = $icalevent['DTEND']['unixtime']; 940 if (!empty($ical->cal['DAYLIGHT']['DTSTART']) && $datecurstart) 941 { 942 //var_dump($ical->cal); 943 $tmpcurstart = $datecurstart; 944 $tmpcurend = $datecurend; 945 $tmpdaylightstart = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['DAYLIGHT']['DTSTART']; 946 $tmpdaylightend = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['STANDARD']['DTSTART']; 947 //var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']); 948 // Edit datecurstart and datecurend 949 if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) $datecurstart -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36; 950 else $datecurstart -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36; 951 if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) $datecurend -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36; 952 else $datecurend -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36; 953 } 954 // datecurstart and datecurend are now GMT date 955 //var_dump($datecurstart); var_dump($datecurend); exit; 956 } else { 957 // Not a recongized record 958 dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR); 959 continue; 960 } 961 //print 'xx'.$datecurstart;exit; 962 963 $interval = (empty($icalevent['RRULE']['INTERVAL']) ? 1 : $icalevent['RRULE']['INTERVAL']); 964 $until = empty($icalevent['RRULE']['UNTIL']) ? 0 : dol_stringtotime($icalevent['RRULE']['UNTIL'], 1); 965 $maxrepeat = empty($icalevent['RRULE']['COUNT']) ? 0 : $icalevent['RRULE']['COUNT']; 966 if ($until && ($until + ($datecurend - $datecurstart)) < $firstdaytoshow) continue; // We discard repeatable event that end before start date to show 967 if ($datecurstart >= $lastdaytoshow) continue; // We discard repeatable event that start after end date to show 968 969 $numofevent = 0; 970 while (($datecurstart < $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat))) 971 { 972 if ($datecurend >= $firstdaytoshow) // We add event 973 { 974 $newevent = $icalevent; 975 unset($newevent['RRULE']); 976 if ($icalevent['DTSTART;VALUE=DATE']) 977 { 978 $newevent['DTSTART;VALUE=DATE'] = dol_print_date($datecurstart, '%Y%m%d'); 979 $newevent['DTEND;VALUE=DATE'] = dol_print_date($datecurend + 1, '%Y%m%d'); 980 } else { 981 $newevent['DTSTART'] = $datecurstart; 982 $newevent['DTEND'] = $datecurend; 983 } 984 $moreicalevents[] = $newevent; 985 } 986 // Jump on next occurence 987 $numofevent++; 988 $savdatecurstart = $datecurstart; 989 if ($icalevent['RRULE']['FREQ'] == 'DAILY') 990 { 991 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'd'); 992 $datecurend = dol_time_plus_duree($datecurend, $interval, 'd'); 993 } 994 if ($icalevent['RRULE']['FREQ'] == 'WEEKLY') 995 { 996 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'w'); 997 $datecurend = dol_time_plus_duree($datecurend, $interval, 'w'); 998 } elseif ($icalevent['RRULE']['FREQ'] == 'MONTHLY') 999 { 1000 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'm'); 1001 $datecurend = dol_time_plus_duree($datecurend, $interval, 'm'); 1002 } elseif ($icalevent['RRULE']['FREQ'] == 'YEARLY') 1003 { 1004 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'y'); 1005 $datecurend = dol_time_plus_duree($datecurend, $interval, 'y'); 1006 } 1007 // Test to avoid infinite loop ($datecurstart must increase) 1008 if ($savdatecurstart >= $datecurstart) 1009 { 1010 dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR); 1011 $datecurstart += 3600 * 24 * 7; 1012 $datecurend += 3600 * 24 * 7; 1013 } 1014 } 1015 } 1016 } 1017 $icalevents = array_merge($icalevents, $moreicalevents); 1018 1019 // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray 1020 foreach ($icalevents as $icalevent) 1021 { 1022 //var_dump($icalevent); 1023 1024 //print $icalevent['SUMMARY'].'->'.var_dump($icalevent).'<br>';exit; 1025 if (!empty($icalevent['RRULE'])) continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule. 1026 1027 // Create a new object action 1028 $event = new ActionComm($db); 1029 $addevent = false; 1030 if (isset($icalevent['DTSTART;VALUE=DATE'])) // fullday event 1031 { 1032 // For full day events, date are also GMT but they wont but converted using tz during output 1033 $datestart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1); 1034 $dateend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day 1035 //print 'x'.$datestart.'-'.$dateend;exit; 1036 //print dol_print_date($dateend,'dayhour','gmt'); 1037 $event->fulldayevent = 1; 1038 $addevent = true; 1039 } elseif (!is_array($icalevent['DTSTART'])) // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch) 1040 { 1041 $datestart = $icalevent['DTSTART']; 1042 $dateend = $icalevent['DTEND']; 1043 1044 $datestart += +($offsettz * 3600); 1045 $dateend += +($offsettz * 3600); 1046 1047 $addevent = true; 1048 //var_dump($offsettz); 1049 //var_dump(dol_print_date($datestart, 'dayhour', 'gmt')); 1050 } elseif (isset($icalevent['DTSTART']['unixtime'])) // File contains a local timezone + a TZ (for example when using bluemind) 1051 { 1052 $datestart = $icalevent['DTSTART']['unixtime']; 1053 $dateend = $icalevent['DTEND']['unixtime']; 1054 1055 $datestart += +($offsettz * 3600); 1056 $dateend += +($offsettz * 3600); 1057 1058 // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight' 1059 if ($buggedfile === 'uselocalandtznodaylight') // unixtime is a local date that does not take daylight into account, TZID is +1 for example for 'Europe/Paris' in summer instead of 2 1060 { 1061 // TODO 1062 } 1063 // $buggedfile is set to uselocalandtzdaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtzdaylight' (for example with bluemind) 1064 if ($buggedfile === 'uselocalandtzdaylight') // unixtime is a local date that does take daylight into account, TZID is +2 for example for 'Europe/Paris' in summer 1065 { 1066 $localtzs = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTSTART']['TZID'])); 1067 $localtze = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTEND']['TZID'])); 1068 $localdts = new DateTime(dol_print_date($datestart, 'dayrfc', 'gmt'), $localtzs); 1069 $localdte = new DateTime(dol_print_date($dateend, 'dayrfc', 'gmt'), $localtze); 1070 $tmps = -1 * $localtzs->getOffset($localdts); 1071 $tmpe = -1 * $localtze->getOffset($localdte); 1072 $datestart += $tmps; 1073 $dateend += $tmpe; 1074 //var_dump($datestart); 1075 } 1076 $addevent = true; 1077 } 1078 1079 if ($addevent) 1080 { 1081 $event->id = $icalevent['UID']; 1082 $event->ref = $event->id; 1083 $userId = $userstatic->findUserIdByEmail($namecal); 1084 if (!empty($userId) && $userId > 0) 1085 { 1086 $event->userassigned[$userId] = $userId; 1087 $event->percentage = -1; 1088 } 1089 else { 1090 $event->type_code = "ICALEVENT"; 1091 } 1092 1093 $event->icalname = $namecal; 1094 $event->icalcolor = $colorcal; 1095 $usertime = 0; // We dont modify date because we want to have date into memory datep and datef stored as GMT date. Compensation will be done during output. 1096 $event->datep = $datestart + $usertime; 1097 $event->datef = $dateend + $usertime; 1098 1099 if ($icalevent['SUMMARY']) $event->label = $icalevent['SUMMARY']; 1100 elseif ($icalevent['DESCRIPTION']) $event->label = dol_nl2br($icalevent['DESCRIPTION'], 1); 1101 else $event->label = $langs->trans("ExtSiteNoLabel"); 1102 1103 // Priority (see https://www.kanzaki.com/docs/ical/priority.html) 1104 // LOW = 0 to 4 1105 // MEDIUM = 5 1106 // HIGH = 6 to 9 1107 if ($icalevent['PRIORITY']) $event->priority = $icalevent['PRIORITY']; 1108 1109 // Transparency (see https://www.kanzaki.com/docs/ical/transp.html) 1110 if ($icalevent['TRANSP']) 1111 { 1112 if ($icalevent['TRANSP'] == "TRANSPARENT") $event->transparency = 0; // 0 = available / free 1113 if ($icalevent['TRANSP'] == "OPAQUE") $event->transparency = 1; // 1 = busy 1114 1115 // TODO: MS outlook states 1116 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:TRANSPARENT => Available / Free 1117 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:OPAQUE => Work another place 1118 // X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE + TRANSP:OPAQUE => With reservations 1119 // X-MICROSOFT-CDO-BUSYSTATUS:BUSY + TRANSP:OPAQUE => Busy 1120 // X-MICROSOFT-CDO-BUSYSTATUS:OOF + TRANSP:OPAQUE => Away from the office / off-site 1121 } 1122 1123 if ($icalevent['LOCATION']) $event->location = $icalevent['LOCATION']; 1124 1125 $event->date_start_in_calendar = $event->datep; 1126 1127 if ($event->datef != '' && $event->datef >= $event->datep) $event->date_end_in_calendar = $event->datef; 1128 else $event->date_end_in_calendar = $event->datep; 1129 1130 // Define ponctual property 1131 if ($event->date_start_in_calendar == $event->date_end_in_calendar) 1132 { 1133 $event->ponctuel = 1; 1134 //print 'x'.$datestart.'-'.$dateend;exit; 1135 } 1136 1137 // Add event into $eventarray if date range are ok. 1138 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) 1139 { 1140 //print 'x'.$datestart.'-'.$dateend;exit; 1141 //print 'x'.$datestart.'-'.$dateend;exit; 1142 //print 'x'.$datestart.'-'.$dateend;exit; 1143 // This record is out of visible range 1144 } else { 1145 if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar = $firstdaytoshow; 1146 if ($event->date_end_in_calendar >= $lastdaytoshow) $event->date_end_in_calendar = ($lastdaytoshow - 1); 1147 1148 // Add an entry in actionarray for each day 1149 $daycursor = $event->date_start_in_calendar; 1150 $annee = date('Y', $daycursor); 1151 $mois = date('m', $daycursor); 1152 $jour = date('d', $daycursor); 1153 1154 // Loop on each day covered by action to prepare an index to show on calendar 1155 $loop = true; $j = 0; 1156 // daykey must be date that represent day box in calendar so must be a user time 1157 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee); 1158 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, true, 0); 1159 do { 1160 //if ($event->fulldayevent) print dol_print_date($daykeygmt,'dayhour','gmt').'-'.dol_print_date($daykey,'dayhour','gmt').'-'.dol_print_date($event->date_end_in_calendar,'dayhour','gmt').' '; 1161 $eventarray[$daykey][] = $event; 1162 $daykey += 60 * 60 * 24; $daykeygmt += 60 * 60 * 24; // Add one day 1163 if (($event->fulldayevent ? $daykeygmt : $daykey) > $event->date_end_in_calendar) $loop = false; 1164 } while ($loop); 1165 } 1166 } 1167 } 1168 } 1169 } 1170} 1171 1172 1173 1174// Complete $eventarray with events coming from external module 1175$parameters = array(); $object = null; 1176$reshook = $hookmanager->executeHooks('getCalendarEvents', $parameters, $object, $action); 1177if (!empty($hookmanager->resArray['eventarray'])) { 1178 foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) { 1179 if (!isset($eventarray[$keyDate])) { 1180 $eventarray[$keyDate] = array(); 1181 } 1182 $eventarray[$keyDate] = array_merge($eventarray[$keyDate], $events); 1183 } 1184} 1185 1186// Sort events 1187foreach ($eventarray as $keyDate => &$dateeventarray) 1188{ 1189 usort($dateeventarray, 'sort_events_by_date'); 1190} 1191 1192 1193$maxnbofchar = 0; 1194$cachethirdparties = array(); 1195$cachecontacts = array(); 1196$cacheusers = array(); 1197 1198// Define theme_datacolor array 1199$color_file = DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/theme_vars.inc.php"; 1200if (is_readable($color_file)) 1201{ 1202 include_once $color_file; 1203} 1204if (!is_array($theme_datacolor)) $theme_datacolor = array(array(120, 130, 150), array(200, 160, 180), array(190, 190, 220)); 1205 1206 1207print_barre_liste($langs->trans("Agenda"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1, 'object_action', 0, $nav.'<span class="marginleftonly"></span>'.$newcardbutton, '', $limit, 1, 0, 1, $viewmode); 1208 1209print $s; 1210 1211 1212if (empty($action) || $action == 'show_month') // View by month 1213{ 1214 $newparam = $param; // newparam is for birthday links 1215 $newparam = preg_replace('/showbirthday=/i', 'showbirthday_=', $newparam); // To avoid replacement when replace day= is done 1216 $newparam = preg_replace('/action=show_month&?/i', '', $newparam); 1217 $newparam = preg_replace('/action=show_week&?/i', '', $newparam); 1218 $newparam = preg_replace('/day=[0-9]+&?/i', '', $newparam); 1219 $newparam = preg_replace('/month=[0-9]+&?/i', '', $newparam); 1220 $newparam = preg_replace('/year=[0-9]+&?/i', '', $newparam); 1221 $newparam = preg_replace('/viewcal=[0-9]+&?/i', '', $newparam); 1222 $newparam = preg_replace('/showbirthday_=/i', 'showbirthday=', $newparam); // Restore correct parameter 1223 $newparam .= '&viewcal=1'; 1224 1225 print '<div class="liste_titre liste_titre_bydiv centpercent">'; 1226 print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); 1227 print '</div>'; 1228 1229 print '<div class="div-table-responsive-no-min sectioncalendarbymonth maxscreenheightless300">'; 1230 print '<table width="100%" class="noborder nocellnopadd cal_pannel cal_month">'; 1231 print ' <tr class="liste_titre">'; 1232 // Column title of weeks numbers 1233 echo ' <td align="center">#</td>'; 1234 $i = 0; 1235 while ($i < 7) 1236 { 1237 print ' <td class="center bold uppercase tdfordaytitle">'; 1238 $numdayinweek = (($i + (isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1)) % 7); 1239 if (!empty($conf->dol_optimize_smallscreen)) 1240 { 1241 $labelshort = array(0=>'SundayMin', 1=>'MondayMin', 2=>'TuesdayMin', 3=>'WednesdayMin', 4=>'ThursdayMin', 5=>'FridayMin', 6=>'SaturdayMin'); 1242 print $langs->trans($labelshort[$numdayinweek]); 1243 } else print $langs->trans("Day".$numdayinweek); 1244 print ' </td>'."\n"; 1245 $i++; 1246 } 1247 echo ' </tr>'."\n"; 1248 1249 $todayarray = dol_getdate($now, 'fast'); 1250 $todaytms = dol_mktime(0, 0, 0, $todayarray['mon'], $todayarray['mday'], $todayarray['year']); 1251 1252 // In loops, tmpday contains day nb in current month (can be zero or negative for days of previous month) 1253 //var_dump($eventarray); 1254 for ($iter_week = 0; $iter_week < 6; $iter_week++) { 1255 echo " <tr>\n"; 1256 // Get date of the current day, format 'yyyy-mm-dd' 1257 if ($tmpday <= 0) // If number of the current day is in previous month 1258 { 1259 $currdate0 = sprintf("%04d", $prev_year).sprintf("%02d", $prev_month).sprintf("%02d", $max_day_in_prev_month + $tmpday); 1260 } 1261 elseif ($tmpday <= $max_day_in_month) // If number of the current day is in current month 1262 { 1263 $currdate0 = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $tmpday); 1264 } 1265 else // If number of the current day is in next month 1266 { 1267 $currdate0 = sprintf("%04d", $next_year).sprintf("%02d", $next_month).sprintf("%02d", $tmpday - $max_day_in_month); 1268 } 1269 // Get week number for the targeted date '$currdate0' 1270 $numweek0 = date("W", strtotime(date($currdate0))); 1271 // Show the week number, and define column width 1272 echo ' <td class="center weeknumber opacitymedium" width="2%">'.$numweek0.'</td>'; 1273 1274 for ($iter_day = 0; $iter_day < 7; $iter_day++) { 1275 if ($tmpday <= 0) { 1276 /* Show days before the beginning of the current month (previous month) */ 1277 $style = 'cal_other_month cal_past'; 1278 if ($iter_day == 6) $style .= ' cal_other_month_right'; 1279 echo ' <td class="'.$style.' nowrap tdtop" width="14%">'; 1280 show_day_events($db, $max_day_in_prev_month + $tmpday, $prev_month, $prev_year, $month, $style, $eventarray, $maxprint, $maxnbofchar, $newparam); 1281 echo " </td>\n"; 1282 } elseif ($tmpday <= $max_day_in_month) { 1283 /* Show days of the current month */ 1284 $curtime = dol_mktime(0, 0, 0, $month, $tmpday, $year); 1285 $style = 'cal_current_month'; 1286 if ($iter_day == 6) $style .= ' cal_current_month_right'; 1287 $today = 0; 1288 if ($todayarray['mday'] == $tmpday && $todayarray['mon'] == $month && $todayarray['year'] == $year) $today = 1; 1289 if ($today) $style = 'cal_today'; 1290 if ($curtime < $todaytms) $style .= ' cal_past'; 1291 //var_dump($todayarray['mday']."==".$tmpday." && ".$todayarray['mon']."==".$month." && ".$todayarray['year']."==".$year.' -> '.$style); 1292 echo ' <td class="'.$style.' nowrap tdtop" width="14%">'; 1293 show_day_events($db, $tmpday, $month, $year, $month, $style, $eventarray, $maxprint, $maxnbofchar, $newparam); 1294 echo "</td>\n"; 1295 } else { 1296 /* Show days after the current month (next month) */ 1297 $style = 'cal_other_month'; 1298 if ($iter_day == 6) $style .= ' cal_other_month_right'; 1299 echo ' <td class="'.$style.' nowrap tdtop" width="14%">'; 1300 show_day_events($db, $tmpday - $max_day_in_month, $next_month, $next_year, $month, $style, $eventarray, $maxprint, $maxnbofchar, $newparam); 1301 echo "</td>\n"; 1302 } 1303 $tmpday++; 1304 } 1305 echo " </tr>\n"; 1306 } 1307 print "</table>\n"; 1308 print '</div>'; 1309 1310 print '<input type="hidden" name="actionmove" value="mupdate">'; 1311 print '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($_SERVER['PHP_SELF']).'?'.dol_escape_htmltag($_SERVER['QUERY_STRING']).'">'; 1312 print '<input type="hidden" name="newdate" id="newdate">'; 1313} elseif ($action == 'show_week') { 1314 // View by week 1315 $newparam = $param; // newparam is for birthday links 1316 $newparam = preg_replace('/showbirthday=/i', 'showbirthday_=', $newparam); // To avoid replacement when replace day= is done 1317 $newparam = preg_replace('/action=show_month&?/i', '', $newparam); 1318 $newparam = preg_replace('/action=show_week&?/i', '', $newparam); 1319 $newparam = preg_replace('/day=[0-9]+&?/i', '', $newparam); 1320 $newparam = preg_replace('/month=[0-9]+&?/i', '', $newparam); 1321 $newparam = preg_replace('/year=[0-9]+&?/i', '', $newparam); 1322 $newparam = preg_replace('/viewweek=[0-9]+&?/i', '', $newparam); 1323 $newparam = preg_replace('/showbirthday_=/i', 'showbirthday=', $newparam); // Restore correct parameter 1324 $newparam .= '&viewweek=1'; 1325 1326 print '<div class="liste_titre liste_titre_bydiv centpercent"><div class="divsearchfield">'; 1327 print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); 1328 print '</div></div>'; 1329 1330 print '<div class="div-table-responsive-no-min sectioncalendarbyweek maxscreenheightless300">'; 1331 print '<table width="100%" class="noborder nocellnopadd cal_pannel cal_month">'; 1332 print ' <tr class="liste_titre">'; 1333 $i = 0; 1334 while ($i < 7) { 1335 echo ' <td class="center bold uppercase tdfordaytitle">'.$langs->trans("Day".(($i + (isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : 1)) % 7))."</td>\n"; 1336 $i++; 1337 } 1338 echo " </tr>\n"; 1339 1340 echo " <tr>\n"; 1341 1342 for ($iter_day = 0; $iter_day < 7; $iter_day++) { 1343 // Show days of the current week 1344 $curtime = dol_time_plus_duree($firstdaytoshow, $iter_day, 'd'); // $firstdaytoshow is in timezone of server 1345 $tmpday = dol_print_date($curtime, '%d', 'tzuserrel'); 1346 $tmpmonth = dol_print_date($curtime, '%m', 'tzuserrel'); 1347 $tmpyear = dol_print_date($curtime, '%Y', 'tzuserrel'); 1348 1349 $style = 'cal_current_month'; 1350 if ($iter_day == 6) $style .= ' cal_other_month_right'; 1351 1352 $today = 0; 1353 $todayarray = dol_getdate($now, 'fast'); 1354 if ($todayarray['mday'] == $tmpday && $todayarray['mon'] == $tmpmonth && $todayarray['year'] == $tmpyear) $today = 1; 1355 if ($today) $style = 'cal_today'; 1356 1357 echo ' <td class="'.$style.'" width="14%" valign="top">'; 1358 show_day_events($db, $tmpday, $tmpmonth, $tmpyear, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300); 1359 echo " </td>\n"; 1360 } 1361 echo " </tr>\n"; 1362 1363 print "</table>\n"; 1364 print '</div>'; 1365 1366 echo '<input type="hidden" name="actionmove" value="mupdate">'; 1367 echo '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($_SERVER['PHP_SELF']).'?'.dol_escape_htmltag($_SERVER['QUERY_STRING']).'">'; 1368 echo '<input type="hidden" name="newdate" id="newdate">'; 1369} else // View by day 1370{ 1371 $newparam = $param; // newparam is for birthday links 1372 $newparam = preg_replace('/action=show_month&?/i', '', $newparam); 1373 $newparam = preg_replace('/action=show_week&?/i', '', $newparam); 1374 $newparam = preg_replace('/viewday=[0-9]+&?/i', '', $newparam); 1375 $newparam .= '&viewday=1'; 1376 // Code to show just one day 1377 $style = 'cal_current_month cal_current_month_oneday'; 1378 $today = 0; 1379 $todayarray = dol_getdate($now, 'fast'); 1380 if ($todayarray['mday'] == $day && $todayarray['mon'] == $month && $todayarray['year'] == $year) $today = 1; 1381 //if ($today) $style='cal_today'; 1382 1383 $timestamp = dol_mktime(12, 0, 0, $month, $day, $year); 1384 $arraytimestamp = dol_getdate($timestamp); 1385 1386 print '<div class="liste_titre liste_titre_bydiv centpercent"><div class="divsearchfield">'; 1387 print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); 1388 print '</div></div>'; 1389 1390 print '<div class="div-table-responsive-no-min sectioncalendarbyday maxscreenheightless300">'; 1391 echo '<table class="tagtable centpercent noborder nocellnopadd cal_pannel cal_month noborderbottom" style="margin-bottom: 5px !important;">'; 1392 1393 echo ' <tr class="tagtr liste_titre">'; 1394 echo ' <td class="tagtd center bold uppercase">'.$langs->trans("Day".$arraytimestamp['wday'])."</td>\n"; 1395 echo " </td>\n"; 1396 1397 /* 1398 echo ' <div class="tagtr">'; 1399 echo ' <div class="tagtd width100"></div>'; 1400 echo ' <div class="tagtd center">'; 1401 echo show_day_events($db, $day, $month, $year, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, -1); 1402 echo ' </div>'."\n"; 1403 echo " </div>\n"; 1404 */ 1405 1406 echo '</table>'; 1407 print '</div>'; 1408 1409 /* WIP View per hour */ 1410 $useviewhour = 0; 1411 if ($useviewhour) 1412 { 1413 print '<div class="div-table-responsive-no-min borderbottom">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table 1414 1415 $maxheightwin = (isset($_SESSION["dol_screenheight"]) && $_SESSION["dol_screenheight"] > 500) ? ($_SESSION["dol_screenheight"] - 200) : 660; // Also into index.php file 1416 1417 echo '<div style="max-height: '.$maxheightwin.'px;">'; 1418 echo '<div class="tagtable centpercent calendarviewcontainer">'; 1419 1420 $maxnbofchar = 80; 1421 1422 $tmp = explode('-', $conf->global->MAIN_DEFAULT_WORKING_HOURS); 1423 $minhour = round($tmp[0], 0); 1424 $maxhour = round($tmp[1], 0); 1425 if ($minhour > 23) $minhour = 23; 1426 if ($maxhour < 1) $maxhour = 1; 1427 if ($maxhour <= $minhour) { $maxhour = $minhour + 1; } 1428 1429 $i = 0; 1430 $j = 0; 1431 while ($i < 24) 1432 { 1433 echo ' <div class="tagtr calendarviewcontainertr">'."\n"; 1434 echo ' <div class="tagtd width100 tdtop">'.dol_print_date($i * 3600, 'hour', 'gmt').'</div>'; 1435 echo ' <div class="tagtd '.$style.' tdtop"></div>'."\n"; 1436 echo ' </div>'."\n"; 1437 $i++; 1438 $j++; 1439 } 1440 1441 echo '</div></div>'; 1442 1443 show_day_events($db, $day, $month, $year, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, 1); 1444 1445 print '</div>'; 1446 } else { 1447 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table 1448 1449 show_day_events($db, $day, $month, $year, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, 0); 1450 1451 print '</div>'; 1452 } 1453} 1454 1455print "\n".'</form>'; 1456 1457// End of page 1458llxFooter(); 1459$db->close(); 1460 1461 1462/** 1463 * Show event of a particular day 1464 * 1465 * @param DoliDB $db Database handler 1466 * @param int $day Day 1467 * @param int $month Month 1468 * @param int $year Year 1469 * @param int $monthshown Current month shown in calendar view 1470 * @param string $style Style to use for this day 1471 * @param array $eventarray Array of events 1472 * @param int $maxprint Nb of actions to show each day on month view (0 means no limit) 1473 * @param int $maxnbofchar Nb of characters to show for event line 1474 * @param string $newparam Parameters on current URL 1475 * @param int $showinfo Add extended information (used by day and week view) 1476 * @param int $minheight Minimum height for each event. 60px by default. 1477 * @param string $nonew 0=Add "new entry button", 1=No "new entry button", -1=Only "new entry button" 1478 * @return void 1479 */ 1480function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventarray, $maxprint = 0, $maxnbofchar = 16, $newparam = '', $showinfo = 0, $minheight = 60, $nonew = 0) 1481{ 1482 global $user, $conf, $langs; 1483 global $action, $filter, $filtert, $status, $actioncode, $usergroup; // Filters used into search form 1484 global $theme_datacolor; 1485 global $cachethirdparties, $cachecontacts, $cacheusers, $colorindexused; 1486 1487 $dateint = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day); 1488 1489 //print 'show_day_events day='.$day.' month='.$month.' year='.$year.' dateint='.$dateint; 1490 1491 print "\n"; 1492 1493 $curtime = dol_mktime(0, 0, 0, $month, $day, $year); 1494 $urltoshow = DOL_URL_ROOT.'/comm/action/index.php?action=show_day&day='.str_pad($day, 2, "0", STR_PAD_LEFT).'&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$year.$newparam; 1495 $urltocreate = ''; 1496 if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create) 1497 { 1498 $newparam .= '&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$year; 1499 $hourminsec = '100000'; 1500 $urltocreate = DOL_URL_ROOT.'/comm/action/card.php?action=create&datep='.sprintf("%04d%02d%02d", $year, $month, $day).$hourminsec.'&backtopage='.urlencode($_SERVER["PHP_SELF"].($newparam ? '?'.$newparam : '')); 1501 } 1502 1503 // Line with title of day 1504 print '<div id="dayevent_'.$dateint.'" class="dayevent tagtable centpercent nobordernopadding">'."\n"; 1505 1506 if ($nonew <= 0) 1507 { 1508 print '<div class="tagtr cursorpointer" onclick="window.location=\''.$urltocreate.'\';"><div class="nowrap tagtd"><div class="left inline-block">'; 1509 print '<a class="dayevent-aday" style="color: #666" href="'.$urltoshow.'">'; 1510 if ($showinfo) print dol_print_date($curtime, 'daytextshort'); 1511 else print dol_print_date($curtime, '%d'); 1512 print '</a>'; 1513 print '</div><div class="nowrap floatright inline-block marginrightonly">'; 1514 if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create) 1515 { 1516 print '<a class="cursoradd" href="'.$urltocreate.'">'; // Explicit link, usefull for nojs interfaces 1517 print img_picto($langs->trans("NewAction"), 'edit_add.png'); 1518 print '</a>'; 1519 } 1520 print '</div></div></div>'."\n"; 1521 } 1522 1523 if ($nonew < 0) 1524 { 1525 print '</div>'; 1526 return; 1527 } 1528 1529 // Line with td contains all div of each events 1530 print '<div class="tagtr">'; 1531 print '<div class="tagtd centpercent agendacell sortable">'; 1532 1533 //$curtime = dol_mktime (0, 0, 0, $month, $day, $year); 1534 $i = 0; $numother = 0; $numbirthday = 0; $numical = 0; $numicals = array(); 1535 $ymd = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day); 1536 1537 $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0 1538 $nextindextouse = is_array($colorindexused) ?count($colorindexused) : 0; // At first run this is 0, so fist user has 0, next 1, ... 1539 //var_dump($colorindexused); 1540 1541 foreach ($eventarray as $daykey => $notused) { // daykey is the 'YYYYMMDD' to show according to user 1542 $annee = dol_print_date($daykey, '%Y', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD' 1543 $mois = dol_print_date($daykey, '%m', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD' 1544 $jour = dol_print_date($daykey, '%d', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD' 1545 1546 //print 'event daykey='.$daykey.' dol_print_date(daykey)='.dol_print_date($daykey, 'dayhour', 'gmt').' jour='.$jour.' mois='.$mois.' annee='.$annee."<br>\n"; 1547 1548 if ($day == $jour && $month == $mois && $year == $annee) 1549 { 1550 foreach ($eventarray[$daykey] as $index => $event) 1551 { 1552 if ($i < $maxprint || $maxprint == 0 || !empty($conf->global->MAIN_JS_SWITCH_AGENDA)) 1553 { 1554 $keysofuserassigned = array_keys($event->userassigned); 1555 $ponct = ($event->date_start_in_calendar == $event->date_end_in_calendar); 1556 1557 // Define $color (Hex string like '0088FF') and $cssclass of event 1558 $color = -1; $cssclass = ''; $colorindex = -1; 1559 if (in_array($user->id, $keysofuserassigned)) 1560 { 1561 $cssclass = 'family_mytasks'; 1562 1563 if (empty($cacheusers[$event->userownerid])) 1564 { 1565 $newuser = new User($db); 1566 $newuser->fetch($event->userownerid); 1567 $cacheusers[$event->userownerid] = $newuser; 1568 } 1569 //var_dump($cacheusers[$event->userownerid]->color); 1570 1571 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) 1572 if (!empty($cacheusers[$event->userownerid]->color)) $color = $cacheusers[$event->userownerid]->color; 1573 } elseif ($event->type_code == 'ICALEVENT') // Event come from external ical file 1574 { 1575 $numical++; 1576 if (!empty($event->icalname)) { 1577 if (!isset($numicals[dol_string_nospecial($event->icalname)])) { 1578 $numicals[dol_string_nospecial($event->icalname)] = 0; 1579 } 1580 $numicals[dol_string_nospecial($event->icalname)]++; 1581 } 1582 1583 $color = ($event->icalcolor ? $event->icalcolor : -1); 1584 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other'); 1585 } elseif ($event->type_code == 'BIRTHDAY') 1586 { 1587 $numbirthday++; $colorindex = 2; $cssclass = 'family_birthday unmovable'; $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]); 1588 } else { 1589 $numother++; 1590 $color = ($event->icalcolor ? $event->icalcolor : -1); 1591 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other'); 1592 1593 if (empty($cacheusers[$event->userownerid])) 1594 { 1595 $newuser = new User($db); 1596 $newuser->fetch($event->userownerid); 1597 $cacheusers[$event->userownerid] = $newuser; 1598 } 1599 //var_dump($cacheusers[$event->userownerid]->color); 1600 1601 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) 1602 if (!empty($cacheusers[$event->userownerid]->color)) $color = $cacheusers[$event->userownerid]->color; 1603 } 1604 1605 if ($color < 0) // Color was not set on user card. Set color according to color index. 1606 { 1607 // Define color index if not yet defined 1608 $idusertouse = ($event->userownerid ? $event->userownerid : 0); 1609 if (isset($colorindexused[$idusertouse])) 1610 { 1611 $colorindex = $colorindexused[$idusertouse]; // Color already assigned to this user 1612 } else { 1613 $colorindex = $nextindextouse; 1614 $colorindexused[$idusertouse] = $colorindex; 1615 if (!empty($theme_datacolor[$nextindextouse + 1])) $nextindextouse++; // Prepare to use next color 1616 } 1617 //print '|'.($color).'='.($idusertouse?$idusertouse:0).'='.$colorindex.'<br>'; 1618 // Define color 1619 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]); 1620 } 1621 $cssclass = $cssclass.' '.$cssclass.'_day_'.$ymd; 1622 1623 // Defined style to disable drag and drop feature 1624 if ($event->type_code == 'AC_OTH_AUTO') 1625 { 1626 $cssclass .= " unmovable"; 1627 } elseif ($event->type_code == 'ICALEVENT') 1628 { 1629 $cssclass .= " unmovable"; 1630 } elseif ($event->date_end_in_calendar && date('Ymd', $event->date_start_in_calendar) != date('Ymd', $event->date_end_in_calendar)) { 1631 $tmpyearend = date('Y', $event->date_end_in_calendar); 1632 $tmpmonthend = date('m', $event->date_end_in_calendar); 1633 $tmpdayend = date('d', $event->date_end_in_calendar); 1634 if ($tmpyearend != $annee || $tmpmonthend != $mois || $tmpdayend != $jour) 1635 { 1636 $cssclass .= " unmovable"; 1637 } 1638 } else { 1639 if ($user->rights->agenda->allactions->create || 1640 (($event->authorid == $user->id || $event->userownerid == $user->id) && $user->rights->agenda->myactions->create)) 1641 { 1642 $cssclass .= " movable cursormove"; 1643 } else { 1644 $cssclass .= " unmovable"; 1645 } 1646 } 1647 1648 $h = ''; $nowrapontd = 1; 1649 if ($action == 'show_day') { $h = 'height: 100%; '; $nowrapontd = 0; } 1650 if ($action == 'show_week') { $h = 'height: 100%; '; $nowrapontd = 0; } 1651 1652 // Show rect of event 1653 print "\n"; 1654 print '<!-- start event '.$i.' -->'."\n"; 1655 print '<div id="event_'.$ymd.'_'.$i.'" class="event '.$cssclass.'"'; 1656 //print ' style="height: 100px;'; 1657 //print ' position: absolute; top: 40px; width: 50%;'; 1658 //print '"'; 1659 print '>'; 1660 1661 //var_dump($event->userassigned); 1662 //var_dump($event->transparency); 1663 print '<table class="centpercent cal_event'; 1664 print (empty($event->transparency) ? ' cal_event_notbusy' : ' cal_event_busy'); 1665 //if (empty($event->transparency) && empty($conf->global->AGENDA_NO_TRANSPARENT_ON_NOT_BUSY)) print ' opacitymedium'; // Not busy 1666 print '" style="'.$h; 1667 $colortouse = $color; 1668 // If colortouse is similar than background, we force to change it. 1669 if (empty($event->transparency) && empty($conf->global->AGENDA_NO_TRANSPARENT_ON_NOT_BUSY)) 1670 { 1671 print 'background: #f0f0f0;'; 1672 print 'border-left: 5px solid #'.$colortouse.';'; 1673 } else { 1674 print 'background: #f0f0f0;'; 1675 print 'border-left: 5px solid #'.dol_color_minus($colortouse, -3).';'; 1676 //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($colortouse, -3).'), to(#'.dol_color_minus($colortouse, -1).'));'; 1677 } 1678 //print 'background: #'.$colortouse.';'; 1679 //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($color, -3).'), to(#'.dol_color_minus($color, -1).'));'; 1680 //if (! empty($event->transparency)) print 'background: #'.$color.'; background: -webkit-gradient(linear, left top, left bottom, from(#'.$color.'), to(#'.dol_color_minus($color,1).'));'; 1681 //else print 'background-color: transparent !important; background: none; border: 1px solid #bbb;'; 1682 //print ' -moz-border-radius:4px;"'; 1683 //print 'border: 1px solid #ccc" width="100%"'; 1684 print '">'; 1685 print '<tr>'; 1686 print '<td class="tdoverflow nobottom centpercent '.($nowrapontd ? 'nowrap ' : '').'cal_event'.($event->type_code == 'BIRTHDAY' ? ' cal_event_birthday' : '').'">'; 1687 1688 $daterange = ''; 1689 1690 if ($event->type_code == 'BIRTHDAY') // It's a birthday 1691 { 1692 print $event->getNomUrl(1, $maxnbofchar, 'cal_event', 'birthday', 'contact'); 1693 } elseif ($event->type_code == 'HOLIDAY') 1694 { 1695 print $event->getNomUrl(1, $maxnbofchar, 'cal_event', 'holiday', 'user'); 1696 } elseif ($event->type_code != 'BIRTHDAY' && $event->type_code != 'HOLIDAY') 1697 { 1698 // Picto 1699 if (empty($event->fulldayevent)) 1700 { 1701 //print $event->getNomUrl(2).' '; 1702 } 1703 1704 // Date 1705 if (empty($event->fulldayevent)) 1706 { 1707 // Show hours (start ... end) 1708 $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel'); 1709 $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel'); 1710 $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel'); 1711 $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel'); 1712 $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel'); 1713 $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel'); 1714 1715 // Hour start 1716 if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) 1717 { 1718 $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel'); 1719 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) 1720 { 1721 if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) 1722 $daterange .= '-'; 1723 //else 1724 //print '...'; 1725 } 1726 } 1727 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) 1728 { 1729 if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) 1730 { 1731 $daterange .= '...'; 1732 } 1733 } 1734 // Hour end 1735 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) 1736 { 1737 if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) 1738 $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel'); 1739 } 1740 } else { 1741 if ($showinfo) 1742 { 1743 print $langs->trans("EventOnFullDay")."<br>\n"; 1744 } 1745 } 1746 1747 // Show title 1748 $titletoshow = $daterange; 1749 $titletoshow .= ($titletoshow ? ' ' : '').($event->label ? $event->label : $event->libelle); 1750 1751 if ($event->type_code != 'ICALEVENT') { 1752 $savlabel = $event->label ? $event->label : $event->libelle; 1753 $event->label = $titletoshow; 1754 $event->libelle = $titletoshow; 1755 // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user. 1756 $titletoshow = $event->getNomUrl(0, $maxnbofchar, 'cal_event cal_event_title', '', 0, 0); 1757 $event->label = $savlabel; 1758 $event->libelle = $savlabel; 1759 } 1760 1761 // Loop on each assigned user 1762 $listofusertoshow = ''; 1763 $posuserassigned = 0; 1764 foreach ($event->userassigned as $tmpid => $tmpdata) 1765 { 1766 if (!$posuserassigned && $titletoshow) $listofusertoshow .= '<br>'; 1767 $posuserassigned++; 1768 if (empty($cacheusers[$tmpid])) 1769 { 1770 $newuser = new User($db); 1771 $newuser->fetch($tmpid); 1772 $cacheusers[$tmpid] = $newuser; 1773 } 1774 1775 $listofusertoshow .= $cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'paddingright valigntextbottom'); 1776 } 1777 1778 print $titletoshow; 1779 print $listofusertoshow; 1780 1781 if ($event->type_code == 'ICALEVENT') print '<br>('.dol_trunc($event->icalname, $maxnbofchar).')'; 1782 1783 $thirdparty_id = ($event->thirdparty_id > 0 ? $event->thirdparty_id : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0)); 1784 $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->contact->id > 0) ? $event->contact->id : 0)); 1785 1786 // If action related to company / contact 1787 $linerelatedto = ''; 1788 if ($thirdparty_id > 0) 1789 { 1790 if (!isset($cachethirdparties[$thirdparty_id]) || !is_object($cachethirdparties[$thirdparty_id])) 1791 { 1792 $thirdparty = new Societe($db); 1793 $thirdparty->fetch($thirdparty_id); 1794 $cachethirdparties[$thirdparty_id] = $thirdparty; 1795 } else $thirdparty = $cachethirdparties[$thirdparty_id]; 1796 if (!empty($thirdparty->id)) $linerelatedto .= $thirdparty->getNomUrl(1, '', 0); 1797 } 1798 if (!empty($contact_id) && $contact_id > 0) 1799 { 1800 if (!is_object($cachecontacts[$contact_id])) 1801 { 1802 $contact = new Contact($db); 1803 $contact->fetch($contact_id); 1804 $cachecontacts[$contact_id] = $contact; 1805 } else $contact = $cachecontacts[$contact_id]; 1806 if ($linerelatedto) $linerelatedto .= ' '; 1807 if (!empty($contact->id)) $linerelatedto .= $contact->getNomUrl(1, '', 0); 1808 } 1809 if (!empty($event->fk_element) && $event->fk_element > 0 && !empty($event->elementtype) && !empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) 1810 { 1811 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; 1812 if ($linerelatedto) $linerelatedto .= '<br>'; 1813 $linerelatedto .= dolGetElementUrl($event->fk_element, $event->elementtype, 1); 1814 } 1815 if ($linerelatedto) print '<br>'.$linerelatedto; 1816 } 1817 1818 // Show location 1819 if ($showinfo) 1820 { 1821 if ($event->location) 1822 { 1823 print '<br>'; 1824 print $langs->trans("Location").': '.$event->location; 1825 } 1826 } 1827 1828 print '</td>'; 1829 // Status - Percent 1830 $withstatus = 0; 1831 if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') 1832 { 1833 $withstatus = 1; 1834 if ($event->percentage >= 0) $withstatus = 2; 1835 } 1836 print '<td class="nobottom right nowrap cal_event_right'.($withstatus >= 2 ? ' cal_event_right_status' : '').'">'; 1837 if ($withstatus) print $event->getLibStatut(3, 1); 1838 else print ' '; 1839 print '</td></tr></table>'; 1840 print '</div><!-- end event '.$i.' -->'."\n"; 1841 $i++; 1842 } else { 1843 print '<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action='.$action.'&maxprint=0&month='.$monthshown.'&year='.$year; 1844 print ($status ? '&status='.$status : '').($filter ? '&filter='.$filter : ''); 1845 print ($filtert ? '&search_filtert='.$filtert : ''); 1846 print ($usergroup ? '&search_usergroup='.$usergroup : ''); 1847 print ($actioncode != '' ? '&search_actioncode='.$actioncode : ''); 1848 print '">'.img_picto("all", "1downarrow_selected.png").' ...'; 1849 print ' +'.(count($eventarray[$daykey]) - $maxprint); 1850 print '</a>'; 1851 break; 1852 //$ok=false; // To avoid to show twice the link 1853 } 1854 } 1855 1856 break; 1857 } 1858 } 1859 if (!$i) { // No events 1860 print ' '; 1861 } 1862 1863 if (!empty($conf->global->MAIN_JS_SWITCH_AGENDA) && $i > $maxprint && $maxprint) 1864 { 1865 print '<div id="more_'.$ymd.'">'.img_picto("all", "1downarrow_selected.png").' +'.$langs->trans("More").'...</div>'; 1866 //print ' +'.(count($eventarray[$daykey])-$maxprint); 1867 print '<script type="text/javascript">'."\n"; 1868 print 'jQuery(document).ready(function () {'."\n"; 1869 print 'jQuery("#more_'.$ymd.'").click(function() { reinit_day_'.$ymd.'(); });'."\n"; 1870 1871 print 'function reinit_day_'.$ymd.'() {'."\n"; 1872 print 'var nb=0;'."\n"; 1873 // TODO Loop on each element of day $ymd and start to toggle once $maxprint has been reached 1874 print 'jQuery(".family_mytasks_day_'.$ymd.'").toggle();'; 1875 print '}'."\n"; 1876 1877 print '});'."\n"; 1878 1879 print '</script>'."\n"; 1880 } 1881 1882 print '</div></div>'; // td tr 1883 1884 print '</div>'; // table 1885 print "\n"; 1886} 1887 1888 1889/** 1890 * Change color with a delta 1891 * 1892 * @param string $color Color 1893 * @param int $minus Delta (1 = 16 unit). Positive value = darker color, Negative value = brighter color. 1894 * @param int $minusunit Minus unit 1895 * @return string New color 1896 */ 1897function dol_color_minus($color, $minus, $minusunit = 16) 1898{ 1899 $newcolor = $color; 1900 if ($minusunit == 16) 1901 { 1902 $newcolor[0] = dechex(max(min(hexdec($newcolor[0]) - $minus, 15), 0)); 1903 $newcolor[2] = dechex(max(min(hexdec($newcolor[2]) - $minus, 15), 0)); 1904 $newcolor[4] = dechex(max(min(hexdec($newcolor[4]) - $minus, 15), 0)); 1905 } else { 1906 // Not yet implemented 1907 } 1908 return $newcolor; 1909} 1910 1911/** 1912 * Sort events by date 1913 * 1914 * @param object $a Event A 1915 * @param object $b Event B 1916 * @return int < 0 if event A should be before event B, > 0 otherwise, 0 if they have the exact same time slot 1917 */ 1918function sort_events_by_date($a, $b) 1919{ 1920 // Sort holidays at first 1921 if ($a->type_code === 'HOLIDAY') 1922 { 1923 return -1; 1924 } 1925 1926 if ($b->type_code === 'HOLIDAY') 1927 { 1928 return 1; 1929 } 1930 1931 // datep => Event start time 1932 // datef => Event end time 1933 1934 // Events have different start time 1935 if ($a->datep !== $b->datep) 1936 { 1937 return $a->datep - $b->datep; 1938 } 1939 1940 // Events have same start time and no end time 1941 if ((!is_numeric($b->datef)) || (!is_numeric($a->datef))) 1942 { 1943 return sort_events_by_percentage($a, $b); 1944 } 1945 1946 // Events have the same start time and same end time 1947 if ($b->datef === $a->datef) 1948 { 1949 return sort_events_by_percentage($a, $b); 1950 } 1951 1952 // Events have the same start time, but have different end time -> longest event first 1953 return $b->datef - $a->datef; 1954} 1955 1956/** 1957 * Sort events by percentage 1958 * 1959 * @param object $a Event A 1960 * @param object $b Event B 1961 * @return int < 0 if event A should be before event B, > 0 otherwise, 0 if they have the exact same percentage 1962 */ 1963function sort_events_by_percentage($a, $b) 1964{ 1965 // Sort events with no percentage before each other 1966 // (usefull to sort holidays, sick days or similar on the top) 1967 1968 if ($a->percentage < 0) 1969 { 1970 return -1; 1971 } 1972 1973 if ($b->percentage < 0) 1974 { 1975 return 1; 1976 } 1977 1978 return $b->percentage - $a->percentage; 1979} 1980