dolibarr 23.0.4
peruser.php
Go to the documentation of this file.
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-2014 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) 2018-2025 Frédéric France <frederic.france@free.fr>
9 * Copyright (C) 2023 Florian HENRY <florian.henry@scopen.fr>
10 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
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
33// Load Dolibarr environment
34require '../../main.inc.php';
42require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
43require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
44require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
45require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
46require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
49require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
50
51$MAXAGENDA = getDolGlobalString('AGENDA_EXT_NB', 5);
52$DELAYFORCACHE = 300; // 300 seconds
53
54$disabledefaultvalues = GETPOSTINT('disabledefaultvalues');
55
56$action = GETPOST('action', 'aZ09');
57
58$check_holiday = GETPOSTINT('check_holiday');
59$filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3);
60$filtert = GETPOST("search_filtert", "intcomma", 3) ? GETPOST("search_filtert", "intcomma", 3) : GETPOST("filtert", "intcomma", 3);
61$usergroup = GETPOSTINT("search_usergroup", 3) ? GETPOSTINT("search_usergroup", 3) : GETPOSTINT("usergroup", 3);
62$showbirthday = getDolGlobalInt('AGENDA_ENABLE_SHOW_BIRTHDAY_PER_USER'); // disabled by default
63
64$sortfield = GETPOST('sortfield', 'aZ09comma');
65$sortorder = GETPOST('sortorder', 'aZ09comma');
66$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
67if (empty($page) || $page == -1) {
68 $page = 0;
69} // If $page is not defined, or '' or -1
70$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
71$offset = $limit * $page;
72if (!$sortorder) {
73 $sortorder = "ASC";
74}
75if (!$sortfield) {
76 $sortfield = "a.datec";
77}
78
79// Security check
80$socid = GETPOSTINT("search_socid") ? GETPOSTINT("search_socid") : GETPOSTINT("socid");
81if ($user->socid) {
82 $socid = $user->socid;
83}
84if ($socid < 0) {
85 $socid = '';
86}
87
88$canedit = 1; // can read events of others
89if (!$user->hasRight('agenda', 'myactions', 'read')) {
91}
92if (!$user->hasRight('agenda', 'allactions', 'read')) {
93 $canedit = 0;
94}
95if (!$user->hasRight('agenda', 'allactions', 'read') || $filter == 'mine') { // If no permission to see all, we show only affected to me
96 $filtert = (string) $user->id;
97}
98
99$mode = 'show_peruser';
100$resourceid = GETPOSTINT("search_resourceid") ? GETPOSTINT("search_resourceid") : GETPOSTINT("resourceid");
101$year = GETPOSTINT("year") ? GETPOSTINT("year") : date("Y");
102$month = GETPOSTINT("month") ? GETPOSTINT("month") : date("m");
103$week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W");
104$day = GETPOSTINT("day") ? GETPOSTINT("day") : date("d");
105$pid = GETPOSTISSET("search_projectid") ? GETPOSTINT("search_projectid", 3) : GETPOSTINT("projectid", 3);
106$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1
107$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09');
108$maxprint = GETPOSTISSET("maxprint") ? GETPOSTINT("maxprint") : getDolGlobalInt('AGENDA_MAX_EVENTS_DAY_VIEW', 3);
109$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
110$search_categ_cus = GETPOSTINT("search_categ_cus", 3) ? GETPOSTINT("search_categ_cus", 3) : 0;
111// Set actioncode (this code must be same for setting actioncode into peruser, listacton and index)
112if (GETPOST('search_actioncode', 'array:aZ09')) {
113 $actioncode = GETPOST('search_actioncode', 'array:aZ09', 3);
114 if (!count($actioncode)) {
115 $actioncode = '0';
116 }
117} else {
118 $actioncode = GETPOST("search_actioncode", "alpha", 3) ? GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode", "alpha") == '0' ? '0' : ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE') || $disabledefaultvalues) ? '' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE')));
119}
120
121$dateselect = dol_mktime(0, 0, 0, GETPOSTINT('dateselectmonth'), GETPOSTINT('dateselectday'), GETPOSTINT('dateselectyear'));
122if ($dateselect > 0) {
123 $day = GETPOSTINT('dateselectday');
124 $month = GETPOSTINT('dateselectmonth');
125 $year = GETPOSTINT('dateselectyear');
126}
127
128// working hours
129$tmp = getDolGlobalString('MAIN_DEFAULT_WORKING_HOURS', '9-18');
130$tmp = str_replace(' ', '', $tmp); // FIX 7533
131$tmparray = explode('-', $tmp);
132$begin_h = GETPOSTISSET('begin_h') ? GETPOSTINT('begin_h') : ($tmparray[0] != '' ? $tmparray[0] : 9);
133$end_h = GETPOSTISSET('end_h') ? GETPOSTINT('end_h') : ($tmparray[1] != '' ? $tmparray[1] : 18);
134if ($begin_h < 0 || $begin_h > 23) {
135 $begin_h = 9;
136}
137if ($end_h < 1 || $end_h > 24) {
138 $end_h = 18;
139}
140if ($end_h <= $begin_h) {
141 $end_h = $begin_h + 1;
142}
143
144// working days
145$tmp = getDolGlobalString('MAIN_DEFAULT_WORKING_DAYS', '1-5');
146$tmp = str_replace(' ', '', $tmp); // FIX 7533
147$tmparray = explode('-', $tmp);
148$begin_d = GETPOSTISSET('begin_d') ? GETPOSTINT('begin_d') : ($tmparray[0] != '' ? $tmparray[0] : 1);
149$end_d = GETPOSTISSET('end_d') ? GETPOSTINT('end_d') : ($tmparray[1] != '' ? $tmparray[1] : 5);
150if ($begin_d < 1 || $begin_d > 7) {
151 $begin_d = 1;
152}
153if ($end_d < 1 || $end_d > 7) {
154 $end_d = 7;
155}
156if ($end_d < $begin_d) {
157 $end_d = $begin_d + 1;
158}
159
160if ($status == '' && !GETPOSTISSET('search_status')) {
161 $status = ((!getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS') || $disabledefaultvalues) ? '' : getDolGlobalString('AGENDA_DEFAULT_FILTER_STATUS'));
162}
163
164if (empty($mode) && !GETPOSTISSET('mode')) {
165 $mode = getDolGlobalString('AGENDA_DEFAULT_VIEW', 'show_peruser');
166}
167
168// View by month
169if (GETPOST('viewcal', 'alpha') && $mode != 'show_day' && $mode != 'show_week' && $mode != 'show_peruser') {
170 $mode = 'show_month';
171 $day = '';
172}
173// View by week
174if (GETPOST('viewweek', 'alpha') || $mode == 'show_week') {
175 $mode = 'show_week';
176 $week = ($week ? $week : date("W"));
177 $day = ($day ? $day : date("d"));
178}
179// View by day
180if (GETPOST('viewday', 'alpha') || $mode == 'show_day') {
181 $mode = 'show_day';
182 $day = ($day ? $day : date("d"));
183}
184
185$object = new ActionComm($db);
186
187// Load translation files required by the page
188$langs->loadLangs(array('users', 'agenda', 'other', 'commercial'));
189
190// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
191$hookmanager->initHooks(array('agenda'));
192
193$result = restrictedArea($user, 'agenda', 0, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id');
194if ($user->socid && $socid) {
195 $result = restrictedArea($user, 'societe', $socid);
196}
197
198$search_status = $status;
199
200
201/*
202 * Actions
203 */
204
205// None
206
207
208/*
209 * View
210 */
211
212$parameters = array(
213 'socid' => $socid,
214 'status' => $status,
215 'year' => $year,
216 'month' => $month,
217 'day' => $day,
218 'type' => $type,
219 'maxprint' => $maxprint,
220 'filter' => $filter,
221 'filtert' => $filtert,
222 'showbirthday' => $showbirthday,
223 'canedit' => $canedit,
224 'optioncss' => $optioncss,
225 'actioncode' => $actioncode,
226 'pid' => $pid,
227 'resourceid' => $resourceid,
228 'usergroup' => $usergroup,
229);
230$reshook = $hookmanager->executeHooks('beforeAgendaPerUser', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
231if ($reshook < 0) {
232 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
233}
234
235$form = new Form($db);
236$companystatic = new Societe($db);
237
238$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&oacute;dulo_Agenda|DE:Modul_Terminplanung';
239llxHeader('', $langs->trans("Agenda"), $help_url);
240
241$now = dol_now();
242$nowarray = dol_getdate($now);
243$nowyear = $nowarray['year'];
244$nowmonth = $nowarray['mon'];
245$nowday = $nowarray['mday'];
246
247
248$listofextcals = array();
249
250// Define list of all external calendars (global setup)
251if (!getDolGlobalString('AGENDA_DISABLE_EXT')) {
252 $i = 0;
253 while ($i < $MAXAGENDA) {
254 $i++;
255 $source = 'AGENDA_EXT_SRC'.$i;
256 $name = 'AGENDA_EXT_NAME'.$i;
257 $offsettz = 'AGENDA_EXT_OFFSETTZ'.$i;
258 $color = 'AGENDA_EXT_COLOR'.$i;
259 $default = 'AGENDA_EXT_ACTIVEBYDEFAULT'.$i;
260 $buggedfile = 'AGENDA_EXT_BUGGEDFILE'.$i;
261 if (getDolGlobalString($source) && getDolGlobalString($name)) {
262 // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight'
263 $listofextcals[] = array(
264 'type' => 'globalsetup',
265 'src' => getDolGlobalString($source),
267 'offsettz' => (int) getDolGlobalInt($offsettz, 0),
268 'color' => dol_string_nohtmltag(getDolGlobalString($color)),
269 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
270 'default' => dol_string_nohtmltag(getDolGlobalString($default)),
271 'buggedfile' => dol_string_nohtmltag(getDolGlobalString('buggedfile', ''))
272 );
273 }
274 }
275}
276
277// Define list of external calendars (user setup)
278if (!getDolUserString('AGENDA_DISABLE_EXT')) {
279 $i = 0;
280 while ($i < $MAXAGENDA) {
281 $i++;
282 $source = 'AGENDA_EXT_SRC_'.$user->id.'_'.$i;
283 $name = 'AGENDA_EXT_NAME_'.$user->id.'_'.$i;
284 $offsettz = 'AGENDA_EXT_OFFSETTZ_'.$user->id.'_'.$i;
285 $color = 'AGENDA_EXT_COLOR_'.$user->id.'_'.$i;
286 $enabled = 'AGENDA_EXT_ENABLED_'.$user->id.'_'.$i;
287 $default = 'AGENDA_EXT_ACTIVEBYDEFAULT_'.$user->id.'_'.$i;
288 $buggedfile = 'AGENDA_EXT_BUGGEDFILE_'.$user->id.'_'.$i;
289
290 if (getDolUserString($source) && getDolUserString($name)) {
291 // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight'
292 $listofextcals[] = array(
293 'type' => 'usersetup',
294 'src' => getDolUserString($source),
295 'name' => dol_string_nohtmltag(getDolUserString($name)),
296 'offsettz' => (int) (empty($user->conf->$offsettz) ? 0 : $user->conf->$offsettz),
297 'color' => dol_string_nohtmltag(getDolUserString($color)),
298 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
299 'default' => dol_string_nohtmltag(getDolUserString($default)),
300 'buggedfile' => dol_string_nohtmltag(isset($user->conf->buggedfile) ? $user->conf->buggedfile : '')
301 );
302 }
303 }
304}
305
306
307$prev = dol_get_first_day_week($day, $month, $year);
308$first_day = $prev['first_day'];
309$first_month = $prev['first_month'];
310$first_year = $prev['first_year'];
311
312$week = $prev['week'];
313
314$day = (int) $day;
315$next = dol_get_next_week($day, (int) $week, $month, $year);
316$next_year = $next['year'];
317$next_month = $next['month'];
318$next_day = $next['day'];
319
320$max_day_in_month = date("t", dol_mktime(0, 0, 0, $month, 1, $year));
321
322$tmpday = $first_day;
323//print 'xx'.$prev_year.'-'.$prev_month.'-'.$prev_day;
324//print 'xx'.$next_year.'-'.$next_month.'-'.$next_day;
325
326$title = $langs->trans("DoneAndToDoActions");
327if ($status == 'done') {
328 $title = $langs->trans("DoneActions");
329}
330if ($status == 'todo') {
331 $title = $langs->trans("ToDoActions");
332}
333
334$param = '';
335if (($actioncode && $actioncode !== '-1') || GETPOSTISSET('search_actioncode')) {
336 if (is_array($actioncode)) {
337 foreach ($actioncode as $str_action) {
338 if ($str_action != '-1') {
339 $param .= "&search_actioncode[]=".urlencode($str_action);
340 }
341 }
342 } else {
343 $param .= "&search_actioncode=".urlencode($actioncode);
344 }
345}
346if ($resourceid > 0) {
347 $param .= "&search_resourceid=".urlencode((string) ($resourceid));
348}
349
350if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) {
351 $param .= "&search_status=".urlencode($status);
352}
353if ($filter) {
354 $param .= "&search_filter=".urlencode((string) $filter);
355}
356if ($filtert) {
357 $param .= "&search_filtert=".urlencode((string) $filtert);
358}
359if ($usergroup > 0) {
360 $param .= "&search_usergroup=".urlencode((string) ($usergroup));
361}
362if ($socid > 0) {
363 $param .= "&search_socid=".urlencode((string) ($socid));
364}
365if ($showbirthday) { // Always false @phpstan-ignore-line
366 $param .= "&search_showbirthday=1";
367}
368if ($pid) {
369 $param .= "&search_projectid=".urlencode((string) ($pid));
370}
371if ($type) {
372 $param .= "&search_type=".urlencode($type);
373}
374if ($mode != 'show_peruser') {
375 $param .= '&mode='.urlencode((string) $mode);
376}
377if ($begin_h != '') {
378 $param .= '&begin_h='.((int) $begin_h);
379}
380if ($end_h != '') {
381 $param .= '&end_h='.((int) $end_h);
382}
383if ($begin_d != '') {
384 $param .= '&begin_d='.((int) $begin_d);
385}
386if ($end_d != '') {
387 $param .= '&end_d='.((int) $end_d);
388}
389if ($search_categ_cus != 0) {
390 $param .= '&search_categ_cus='.urlencode((string) ($search_categ_cus));
391}
392$param .= "&maxprint=".urlencode((string) ($maxprint));
393
394$paramnoactionodate = $param;
395
396$prev = dol_get_first_day_week($day, $month, $year);
397//print "day=".$day." month=".$month." year=".$year;
398//var_dump($prev); exit;
399$prev_year = $prev['prev_year'];
400$prev_month = $prev['prev_month'];
401$prev_day = $prev['prev_day'];
402$first_day = $prev['first_day'];
403$first_month = $prev['first_month'];
404$first_year = $prev['first_year'];
405
406$week = $prev['week'];
407
408$day = (int) $day;
409$next = dol_get_next_week($first_day, (int) $week, $first_month, $first_year);
410$next_year = $next['year'];
411$next_month = $next['month'];
412$next_day = $next['day'];
413
414// Define firstdaytoshow and lastdaytoshow. Warning: lastdaytoshow is last second to show + 1
415// $firstdaytoshow and lastdaytoshow become a gmt dates to use to search/compare because first_xxx are in tz idea and we used tzuserrel
416$firstdaytoshow = dol_mktime(0, 0, 0, $first_month, $first_day, $first_year, 'tzuserrel');
417$nb_weeks_to_show = (getDolGlobalString('AGENDA_NB_WEEKS_IN_VIEW_PER_USER')) ? ((int) $conf->global->AGENDA_NB_WEEKS_IN_VIEW_PER_USER * 7) : 7;
418$lastdaytoshow = dol_time_plus_duree($firstdaytoshow, $nb_weeks_to_show, 'd');
419//print $firstday.'-'.$first_month.'-'.$first_year;
420//print dol_print_date($firstdaytoshow, 'dayhour', 'gmt');
421//print dol_print_date($lastdaytoshow,'dayhour', 'gmt');
422
423$max_day_in_month = idate("t", dol_mktime(0, 0, 0, $month, 1, $year, 'gmt'));
424
425$tmpday = $first_day;
426$picto = 'calendarweek';
427
428// Show navigation bar
429$nav = '<div class="navselectiondate inline-block nowraponall">';
430$nav .= "<a href=\"?year=".$prev_year."&amp;month=".$prev_month."&amp;day=".$prev_day.$param."\"><i class=\"fa fa-chevron-left\" title=\"".dol_escape_htmltag($langs->trans("Previous"))."\"></i></a> &nbsp; \n";
431$nav .= " <span id=\"month_name\">".dol_print_date(dol_mktime(0, 0, 0, $first_month, $first_day, $first_year), "%Y").", ".$langs->trans("WeekShort")." ".$week;
432$nav .= " </span>\n";
433$nav .= " &nbsp; <a href=\"?year=".$next_year."&amp;month=".$next_month."&amp;day=".$next_day.$param."\"><i class=\"fa fa-chevron-right\" title=\"".dol_escape_htmltag($langs->trans("Next"))."\"></i></a>\n";
434if (empty($conf->dol_optimize_smallscreen)) {
435 $nav .= ' <a href="?year='.$nowyear.'&month='.$nowmonth.'&day='.$nowday.$param.'" class="datenowlink marginleftonly marginrightonly">'.$langs->trans("Today").'</a> ';
436}
437$nav .= '</div>';
438$nav .= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0);
439//$nav .= ' <input type="submit" class="button button-save" name="submitdateselect" value="'.$langs->trans("Refresh").'">';
440$nav .= '<button type="submit" class="liste_titre button_search valignmiddle" name="button_search_x" value="x"><span class="fa fa-search"></span></button>';
441
442// Must be after the nav definition
443$paramnodate = $param;
444$param .= '&year='.$year.'&month='.$month.($day ? '&day='.$day : '');
445//print 'x'.$param;
446
447
448$paramnoaction = preg_replace('/mode=[a-z_]+/', '', preg_replace('/action=[a-z_]+/', '', $param));
449$paramnoactionodate = preg_replace('/mode=[a-z_]+/', '', preg_replace('/action=[a-z_]+/', '', $paramnodate));
450
451$head = calendars_prepare_head($paramnoaction);
452
453print '<form method="POST" id="searchFormList" class="listactionsfilter" action="'.$_SERVER["PHP_SELF"].'">'."\n";
454if ($optioncss != '') {
455 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
456}
457print '<input type="hidden" name="token" value="'.newToken().'">';
458print '<input type="hidden" name="mode" value="'.$mode.'">';
459
460
461$mode = 'show_peruser';
462$massactionbutton = '';
463
464
465$viewmode = '<div class="navmode inline-block">';
466
467$viewmode .= '<a class="btnTitle reposition" href="'.DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&restore_lastsearch_values=1'.$paramnoactionodate.'">';
468//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">';
469$viewmode .= img_picto($langs->trans("List"), 'object_calendarlist', 'class="imgforviewmode pictoactionview block"');
470//$viewmode .= '</span>';
471$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone inline-block width75 divoverflow">'.$langs->trans("ViewList").'</span></a>';
472
473$viewmode .= '<a class="btnTitle reposition" href="'.DOL_URL_ROOT.'/comm/action/index.php?mode=show_month&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').$paramnoactionodate.'">';
474//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">';
475$viewmode .= img_picto($langs->trans("ViewCal"), 'object_calendarmonth', 'class="pictoactionview block"');
476//$viewmode .= '</span>';
477$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone inline-block width75 divoverflow">'.$langs->trans("ViewCal").'</span></a>';
478
479$viewmode .= '<a class="btnTitle reposition" href="'.DOL_URL_ROOT.'/comm/action/index.php?mode=show_week&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').$paramnoactionodate.'">';
480//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">';
481$viewmode .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview block"');
482//$viewmode .= '</span>';
483$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone inline-block width75 divoverflow">'.$langs->trans("ViewWeek").'</span></a>';
484
485$viewmode .= '<a class="btnTitle reposition" href="'.DOL_URL_ROOT.'/comm/action/index.php?mode=show_day&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').$paramnoactionodate.'">';
486//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">';
487$viewmode .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview block"');
488//$viewmode .= '</span>';
489$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone inline-block width75 divoverflow">'.$langs->trans("ViewDay").'</span></a>';
490
491$viewmode .= '<a class="btnTitle btnTitleSelected reposition marginrightonly" href="'.DOL_URL_ROOT.'/comm/action/peruser.php?mode=show_peruser&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').$paramnoactionodate.'">';
492//$viewmode .= '<span class="fa paddingleft imgforviewmode valignmiddle btnTitle-icon">';
493$viewmode .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview block"');
494//$viewmode .= '</span>';
495$viewmode .= '<span class="valignmiddle text-plus-circle btnTitle-label hideonsmartphone inline-block width75 divoverflow" title="'.dolPrintHTML($langs->trans("ViewPerUser")).'">'.$langs->trans("ViewPerUser").'</span></a>';
496
497// Add more views from hooks
498$parameters = array();
499$object = null;
500$reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action);
501if (empty($reshook)) {
502 $viewmode .= $hookmanager->resPrint;
503} elseif ($reshook > 1) {
504 $viewmode = $hookmanager->resPrint;
505}
506
507$viewmode .= '</div>';
508
509$viewmode .= '<span class="marginrightonly"></span>';
510
511
512$newparam = '';
513$newcardbutton = '';
514if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
515 $tmpforcreatebutton = dol_getdate(dol_now('tzuserrel'), true);
516
517 $newparam .= '&month='.urlencode(str_pad((string) $month, 2, "0", STR_PAD_LEFT)).'&year='.((int) $tmpforcreatebutton['year']);
518 if ($begin_h !== '') {
519 $newparam .= '&begin_h='.((int) $begin_h);
520 }
521 if ($end_h !== '') {
522 $newparam .= '&end_h='.((int) $end_h);
523 }
524 if ($begin_d !== '') {
525 $newparam .= '&begin_d='.((int) $begin_d);
526 }
527 if ($end_d !== '') {
528 $newparam .= '&end_d='.((int) $end_d);
529 }
530
531 $urltocreateaction = DOL_URL_ROOT.'/comm/action/card.php?action=create';
532 $urltocreateaction .= '&apyear='.$tmpforcreatebutton['year'].'&apmonth='.$tmpforcreatebutton['mon'].'&apday='.$tmpforcreatebutton['mday'].'&aphour='.$tmpforcreatebutton['hours'].'&apmin='.$tmpforcreatebutton['minutes'];
533 $urltocreateaction .= '&backtopage='.urlencode($_SERVER["PHP_SELF"].'?'.$newparam);
534
535 $newcardbutton .= dolGetButtonTitle($langs->trans("AddAction"), '', 'fa fa-plus-circle', $urltocreateaction);
536}
537
538
539$link = '';
540
541// Define the legend/list of calendard to show
542$s = '';
543
544$showextcals = $listofextcals;
545$bookcalcalendars = array();
546
547// Load Bookcal Calendars
548if (isModEnabled("bookcal")) {
549 $sql = "SELECT ba.rowid, bc.label, bc.ref, bc.rowid as id_cal";
550 $sql .= " FROM ".MAIN_DB_PREFIX."bookcal_availabilities as ba";
551 $sql .= " JOIN ".MAIN_DB_PREFIX."bookcal_calendar as bc";
552 $sql .= " ON bc.rowid = ba.fk_bookcal_calendar";
553 $sql .= " WHERE bc.status = 1";
554 $sql .= " AND ba.status = 1";
555 $sql .= " AND bc.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda
556 if (!empty($filtert) && $filtert != '-1' && $filtert != '-2') {
557 $sql .= " AND bc.visibility IN (".$db->sanitize($filtert, 0, 0, 0, 0).")";
558 }
559 $resql = $db->query($sql);
560 if ($resql) {
561 $num = $db->num_rows($resql);
562 $i = 0;
563 while ($i < $num) {
564 $objp = $db->fetch_object($resql);
565 $label = !empty($objp->label) ? $objp->label : $objp->ref;
566 $bookcalcalendars["calendars"][] = array("id" => $objp->id_cal, "label" => $label);
567 $bookcalcalendars["availabilitieslink"][$objp->rowid] = $objp->id_cal;
568 $i++;
569 }
570 } else {
571 dol_print_error($db);
572 }
573}
574
575if (!empty($conf->use_javascript_ajax)) { // If javascript on
576 $s .= "\n".'<!-- Div to calendars selectors -->'."\n";
577
578 $s .= '<script type="text/javascript">'."\n";
579 $s .= 'jQuery(document).ready(function () {'."\n";
580 $s .= 'jQuery(".check_birthday").click(function() { console.log("Click on .check_birthday so we toggle class .peruser_birthday"); jQuery(".peruser_birthday").addClass("peruser_birthday_imp"); });'."\n";
581 $s .= 'jQuery(".check_holiday").click(function() { console.log("Click on .check_holiday so we toggle class .peruser_holiday"); if (jQuery(".peruser_holiday").hasClass("peruser_holiday_imp")) { jQuery(".peruser_holiday").removeClass("peruser_holiday_imp"); } else { jQuery(".peruser_holiday").addClass("peruser_holiday_imp"); } });'."\n";
582 if (isModEnabled("bookcal") && !empty($bookcalcalendars["calendars"])) {
583 foreach ($bookcalcalendars["calendars"] as $key => $value) {
584 $s .= 'jQuery(".check_bookcal_calendar_'.$value['id'].'").click(function() { console.log("Toggle Bookcal Calendar '.$value['id'].'"); jQuery(".family_bookcal_calendar_'.$value['id'].'").toggle(); });'."\n";
585 }
586 }
587 $s .= '});'."\n";
588 $s .= '</script>'."\n";
589
590 // Local calendar
591 $s .= '<div class="nowrap inline-block minheight30"><input type="checkbox" id="check_mytasks" name="check_mytasks" value="1" class="check_mytasks" checked disabled><label class="labelcalendar"><span class="check_holiday_text"> '.$langs->trans("LocalAgenda").' &nbsp; </span></label></div>';
592
593 // Holiday calendar
594 if ($user->hasRight("holiday", "read")) {
595 $s .= '
596 <div class="nowrap inline-block minheight30"><input type="checkbox" id="check_holiday" name="check_holiday" value="1" class="marginleftonly check_holiday"' . ($check_holiday ? ' checked' : '') . '>
597 <label for="check_holiday" class="labelcalendar">
598 <span class="check_holiday_text">' . $langs->trans("Holidays") . '</span>
599 </label> &nbsp;
600 </div>';
601 }
602
603 // External calendars
604 if (count($showextcals) > 0) {
605 foreach ($showextcals as $val) {
606 $htmlname = md5($val['name']); // not used for security purpose, only to get a string with no special char
607
608 $s .= '<script type="text/javascript">'."\n";
609 $s .= 'jQuery(document).ready(function () {'."\n";
610 $s .= ' jQuery("#check_ext'.$htmlname.'").click(function() {';
611 $s .= ' /* alert("'.$htmlname.'"); */';
612 $s .= ' jQuery(".family_ext'.$htmlname.'").toggle();';
613 $s .= ' });'."\n";
614 $s .= '});'."\n";
615 $s .= '</script>'."\n";
616 $s .= '<div class="nowrap float"><input type="checkbox" id="check_ext'.$htmlname.'" name="check_ext'.$htmlname.'" checked> '.$val ['name'].' &nbsp; </div>';
617 }
618 }
619
620 // Birthdays
621 //$s.='<div class="nowrap float"><input type="checkbox" id="check_birthday" name="check_birthday"> '.$langs->trans("AgendaShowBirthdayEvents").' &nbsp; </div>';
622
623 // Bookcal Calendar
624 /*
625 if (isModEnabled("bookcal")) {
626 if (!empty($bookcalcalendars["calendars"])) {
627 foreach ($bookcalcalendars["calendars"] as $key => $value) {
628 $label = $value['label'];
629 $s .= '<div class="nowrap inline-block minheight30">';
630 $s .= '<input '.(GETPOST('check_bookcal_calendar_'.$value['id']) ? "checked" : "").' type="checkbox" id="check_bookcal_calendar_'.$value['id'].'" name="check_bookcal_calendar_'.$value['id'].'" class="check_bookcal_calendar_'.$value['id'].'">';
631 $s .= '<label for="check_bookcal_calendar_'.$value['id'].'" class="labelcalendar">';
632 $s .= '<span class="check_bookcal_calendar_'.$value['id'].'_text">'.$langs->trans("AgendaShowBookcalCalendar", $label).'</span>';
633 $s .= '</label> &nbsp; </div>';
634 }
635 }
636 }
637 */
638
639 // Calendars from hooks
640 $parameters = array();
641 $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action);
642 if (empty($reshook)) {
643 $s .= $hookmanager->resPrint;
644 } elseif ($reshook > 1) {
645 $s = $hookmanager->resPrint;
646 }
647
648 $s .= "\n".'<!-- End div to calendars selectors -->'."\n";
649} else { // If javascript off
650 $newparam = $param; // newparam is for birthday links
651 $newparam = preg_replace('/showbirthday=[0-1]/i', 'showbirthday='.($showbirthday ? '1' : '0'), $newparam); // Always false @phpstan-ignore-line
652 if (!preg_match('/showbirthday=/i', $newparam)) {
653 $newparam .= '&showbirthday=1';
654 }
655 $link = '<a href="'.$_SERVER['PHP_SELF'].'?'.dol_escape_htmltag($newparam);
656 $link .= '">';
657 if ($showbirthday) { // Always false @phpstan-ignore-line
658 $link .= $langs->trans("AgendaShowBirthdayEvents");
659 } else {
660 $link .= $langs->trans("AgendaHideBirthdayEvents");
661 }
662 $link .= '</a>';
663}
664
665
666// Load events from database into $eventarray
667$eventarray = array();
668
669
670// DEFAULT CALENDAR + AUTOEVENT CALENDAR + CONFERENCEBOOTH CALENDAR
671$sql = "SELECT";
672if ($usergroup > 0) {
673 $sql .= " DISTINCT";
674}
675$sql .= " a.id, a.label,";
676$sql .= " a.datep,";
677$sql .= " a.datep2,";
678$sql .= " a.percent,";
679$sql .= " a.fk_user_author, a.fk_user_action,";
680$sql .= " a.transparency, a.priority, a.fulldayevent, a.location,";
681$sql .= " a.fk_soc, a.fk_contact, a.fk_project, a.fk_bookcal_calendar,";
682$sql .= " a.fk_element, a.elementtype,";
683$sql .= " ca.code as type_code, ca.libelle as type_label, ca.color as type_color, ca.type as type_type, ca.picto as type_picto";
684
685$parameters = array();
686$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
687$sql .= $hookmanager->resPrint;
688
689$sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm as ca, ".MAIN_DB_PREFIX."actioncomm as a";
690// We must filter on resource table
691if ($resourceid > 0) {
692 $sql .= ", ".MAIN_DB_PREFIX."element_resources as r";
693}
694
695// We must filter on assignment table
696if (($filtert != '-1' && $filtert != '-2') || $usergroup > 0) {
697 // TODO Replace with a AND EXISTS
698 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as ar";
699 $sql .= " ON ar.fk_actioncomm = a.id AND ar.element_type = 'user'";
700 if ($filtert != '' && $filtert != '-1' && $filtert != '-2' && $filtert != '-3') {
701 $sql .= " AND ar.fk_element IN (".$db->sanitize($filtert).")";
702 } elseif ($filtert == '-3') {
703 $sql .= " AND ar.fk_element IN (".$db->sanitize(implode(',', $user->getAllChildIds(1))).")";
704 }
705 if ($usergroup > 0) {
706 $sql .= " INNER JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element AND ugu.fk_usergroup = ".((int) $usergroup);
707 }
708}
709
710$sql .= " WHERE a.fk_action = ca.id";
711$sql .= " AND a.entity IN (".getEntity('agenda').")"; // bookcal is a "virtual view" of agenda
712
713// Condition on actioncode
714if (!empty($actioncode)) {
715 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
716 if ((is_array($actioncode) && in_array('AC_NON_AUTO', $actioncode)) || $actioncode == 'AC_NON_AUTO') {
717 $sql .= " AND ca.type != 'systemauto'";
718 } elseif ((is_array($actioncode) && in_array('AC_ALL_AUTO', $actioncode)) || $actioncode == 'AC_ALL_AUTO') {
719 $sql .= " AND ca.type = 'systemauto'";
720 } else {
721 if ((is_array($actioncode) && in_array('AC_OTH', $actioncode)) || $actioncode == 'AC_OTH') {
722 $sql .= " AND ca.type != 'systemauto'";
723 }
724 if ((is_array($actioncode) && in_array('AC_OTH_AUTO', $actioncode)) || $actioncode == 'AC_OTH_AUTO') {
725 $sql .= " AND ca.type = 'systemauto'";
726 }
727 }
728 } else {
729 if ((is_array($actioncode) && in_array('AC_NON_AUTO', $actioncode)) || $actioncode === 'AC_NON_AUTO') {
730 $sql .= " AND ca.type != 'systemauto'";
731 } elseif ((is_array($actioncode) && in_array('AC_ALL_AUTO', $actioncode)) || $actioncode === 'AC_ALL_AUTO') {
732 $sql .= " AND ca.type = 'systemauto'";
733 } elseif ((is_array($actioncode) && !in_array('-1', $actioncode) && !in_array('-3', $actioncode)) || ($actioncode !== '-1' && $actioncode !== '-3')) {
734 if (is_array($actioncode)) {
735 foreach ($actioncode as $key => $val) {
736 if ($val == '-1' || $val == '-2') {
737 unset($actioncode[$key]);
738 }
739 }
740 if (!empty($actioncode)) {
741 $sql .= " AND ca.code IN (".$db->sanitize("'".implode("','", $actioncode)."'", 1).")";
742 }
743 } else {
744 $sql .= " AND ca.code IN (".$db->sanitize("'".implode("','", explode(',', $actioncode))."'", 1).")";
745 }
746 }
747 }
748}
749if ($resourceid > 0) {
750 $sql .= " AND r.element_type = 'action' AND r.element_id = a.id AND r.resource_id = ".((int) $resourceid);
751}
752if ($pid) {
753 $sql .= " AND a.fk_project = ".((int) $pid);
754}
755// If the internal user must only see his customers, force searching by him
756$search_sale = 0;
757if (isModEnabled("societe") && !$user->hasRight('societe', 'client', 'voir')) {
758 $search_sale = $user->id;
759}
760// Search on sale representative
761if ($search_sale && $search_sale != '-1') {
762 if ($search_sale == -2) {
763 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = a.fk_soc)";
764 } elseif ($search_sale > 0) {
765 $sql .= " AND (a.fk_soc IS NULL OR EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = a.fk_soc AND sc.fk_user = ".((int) $search_sale)."))";
766 }
767}
768// Search on socid
769if ($socid) {
770 $sql .= " AND a.fk_soc = ".((int) $socid);
771}
772
773if ($mode == 'show_day') {
774 $sql .= " AND (";
775 $sql .= " (a.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'";
776 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')";
777 $sql .= " OR ";
778 $sql .= " (a.datep2 BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'";
779 $sql .= " AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')";
780 $sql .= " OR ";
781 $sql .= " (a.datep < '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year, 'tzuserrel'))."'";
782 $sql .= " AND a.datep2 > '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year, 'tzuserrel'))."')";
783 $sql .= ")";
784} else {
785 // To limit array
786 $sql .= " AND (";
787 $sql .= " (a.datep BETWEEN '".$db->idate($firstdaytoshow - (60 * 60 * 24 * 2))."'"; // Start 2 day before $firstdaytoshow
788 $sql .= " AND '".$db->idate($lastdaytoshow + (60 * 60 * 24 * 2))."')"; // End 2 day after $lastdaytoshow
789 $sql .= " OR ";
790 $sql .= " (a.datep2 BETWEEN '".$db->idate($firstdaytoshow - (60 * 60 * 24 * 2))."'";
791 $sql .= " AND '".$db->idate($lastdaytoshow + (60 * 60 * 24 * 2))."')";
792 $sql .= " OR ";
793 $sql .= " (a.datep < '".$db->idate($firstdaytoshow - (60 * 60 * 24 * 2))."'";
794 $sql .= " AND a.datep2 > '".$db->idate($lastdaytoshow + (60 * 60 * 24 * 2))."')";
795 $sql .= ")";
796}
797if ($type) {
798 $sql .= " AND ca.id = ".((int) $type);
799}
800if ($status == '0') {
801 // To do (not started)
802 $sql .= " AND a.percent = 0";
803}
804if ($status === 'na') {
805 // Not applicable
806 $sql .= " AND a.percent = -1";
807}
808if ($status == '50') {
809 // Running already started
810 $sql .= " AND (a.percent > 0 AND a.percent < 100)";
811}
812if ($status == 'done' || $status == '100') {
813 $sql .= " AND (a.percent = 100)";
814}
815if ($status == 'todo') {
816 $sql .= " AND (a.percent >= 0 AND a.percent < 100)";
817}
818// We must filter on assignment table
819if (($filtert > 0 || $filtert == -3) || $usergroup > 0) {
820 // TODO Replace with a AND EXISTS
821 $sql .= " AND (";
822 if ($filtert > 0) {
823 $sql .= "ar.fk_element = ".((int) $filtert);
824 } elseif ($filtert == -3) {
825 $sql .= "ar.fk_element IN (".$db->sanitize(implode(',', $user->getAllChildIds(1))).")";
826 }
827 if ($usergroup > 0) {
828 $sql .= ($filtert > 0 ? " OR " : "")." ugu.fk_usergroup = ".((int) $usergroup);
829 }
830 $sql .= ")";
831}
832
833// Search in categories, -1 is all and -2 is no categories
834if ($search_categ_cus != -1) {
835 if ($search_categ_cus == -2) {
836 $sql .= " AND NOT EXISTS (SELECT ca.fk_actioncomm FROM ".MAIN_DB_PREFIX."categorie_actioncomm as ca WHERE ca.fk_actioncomm = a.id)";
837 } elseif ($search_categ_cus > 0) {
838 $sql .= " AND EXISTS (SELECT ca.fk_actioncomm FROM ".MAIN_DB_PREFIX."categorie_actioncomm as ca WHERE ca.fk_actioncomm = a.id AND ca.fk_categorie IN (".$db->sanitize((string) $search_categ_cus)."))";
839 }
840}
841// Sort on date
842$sql .= $db->order("fk_user_action, datep");
843//print $sql;
844
845dol_syslog("comm/action/peruser.php", LOG_DEBUG);
846$resql = $db->query($sql);
847if ($resql) {
848 $num = $db->num_rows($resql);
849
850 $MAXONSAMEPAGE = 10000; // Useless to have more. Protection to avoid memory overload when high number of event (for example after a mass import)
851 $i = 0;
852 while ($i < $num && $i < $MAXONSAMEPAGE) {
853 $obj = $db->fetch_object($resql);
854 //print $obj->fk_user_action.' '.$obj->id."<br>";
855
856 // Discard auto action if option is on
857 if (getDolGlobalString('AGENDA_ALWAYS_HIDE_AUTO') && $obj->type_code == 'AC_OTH_AUTO') {
858 $i++;
859 continue;
860 }
861
862 $datep = $db->jdate($obj->datep);
863 $datep2 = $db->jdate($obj->datep2);
864
865
866 // Create a new object action
867 $event = new ActionComm($db);
868
869 $event->id = $obj->id;
870 $event->ref = (string) $event->id;
871
872 $event->fulldayevent = $obj->fulldayevent;
873
874 // event->datep and event->datef must be GMT date.
875 if ($event->fulldayevent) {
876 $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
877 $event->datep = $db->jdate($obj->datep, $tzforfullday ? 'tzuser' : 'tzserver'); // If saved in $tzforfullday = gmt, we must invert date to be in user tz
878 $event->datef = $db->jdate($obj->datep2, $tzforfullday ? 'tzuser' : 'tzserver');
879 } else {
880 // Example: $obj->datep = '1970-01-01 01:00:00', jdate will return 0 if TZ of PHP server is Europe/Berlin (+1)
881 $event->datep = $db->jdate($obj->datep, 'tzserver');
882 $event->datef = $db->jdate($obj->datep2, 'tzserver');
883 }
884 //$event->datep_formated_gmt = dol_print_date($event->datep, 'dayhour', 'gmt');
885 //var_dump($obj->id.' '.$obj->datep.' '.dol_print_date($obj->datep, 'dayhour', 'gmt'));
886 //var_dump($obj->id.' '.$event->datep.' '.dol_print_date($event->datep, 'dayhour', 'gmt'));
887
888 $event->type_code = $obj->type_code;
889 $event->type_label = $obj->type_label;
890 $event->type_color = $obj->type_color;
891 $event->type = $obj->type_type;
892 $event->type_picto = $obj->type_picto;
893
894 $event->label = $obj->label;
895 $event->percentage = $obj->percent;
896 $event->authorid = $obj->fk_user_author; // user id of creator
897 $event->userownerid = $obj->fk_user_action; // user id of owner
898 $event->fetch_userassigned(); // This load $event->userassigned
899
900 $event->priority = $obj->priority;
901 $event->location = $obj->location;
902 $event->transparency = $obj->transparency;
903 $event->fk_element = $obj->fk_element;
904 $event->elementid = $obj->fk_element;
905 $event->elementtype = $obj->elementtype;
906
907 $event->fk_project = $obj->fk_project;
908
909 $event->socid = $obj->fk_soc;
910 $event->contact_id = $obj->fk_contact;
911 $event->fk_bookcal_calendar = $obj->fk_bookcal_calendar;
912 if (!empty($event->fk_bookcal_calendar)) {
913 $event->type = "bookcal_calendar";
914 }
915
916 // Defined date_start_in_calendar and date_end_in_calendar property
917 // They are date start and end of action but modified to not be outside calendar view.
918 $event->date_start_in_calendar = $event->datep;
919 if ($event->datef != '' && $event->datef >= $event->datep) {
920 $event->date_end_in_calendar = $event->datef;
921 } else {
922 $event->date_end_in_calendar = $event->datep;
923 }
924
925 //print '<br>'.$i.' - eventid='.$event->id.' '.dol_print_date($event->date_start_in_calendar, 'dayhour').' '.dol_print_date($firstdaytoshow, 'dayhour').' - '.dol_print_date($event->date_end_in_calendar, 'dayhour').' '.dol_print_date($lastdaytoshow, 'dayhour').'<br>'."\n";
926
927 // Check values
928 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) {
929 // This record is out of visible range
930 unset($event);
931 } else {
932 if ($event->date_start_in_calendar < $firstdaytoshow) {
933 $event->date_start_in_calendar = $firstdaytoshow;
934 }
935 if ($event->date_end_in_calendar >= $lastdaytoshow) {
936 $event->date_end_in_calendar = ($lastdaytoshow - 1);
937 }
938
939 // Add an entry in actionarray for each day
940 $daycursor = $event->date_start_in_calendar;
941 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
942 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
943 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
944
945 $daycursorend = $event->date_end_in_calendar;
946 $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel');
947 $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel');
948 $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel');
949
950 // Loop on each day covered by action to prepare an index to show on calendar
951 $loop = true;
952 $j = 0;
953 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz
954 $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz
955 /*
956 print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'<br>';
957 print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'<br>';
958 print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'<br>';
959 print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'<br>';
960 print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'<br>';
961 print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'<br>';
962 */
963 do {
964 //if ($event->id==408)
965 //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'gmt').' - '.dol_print_date($event->datep, 'dayhour', 'gmt').' '.dol_print_date($event->datef, 'dayhour', 'gmt').'<br>';
966 //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'tzuserrel').' - '.dol_print_date($event->datep, 'dayhour', 'tzuserrel').' '.dol_print_date($event->datef, 'dayhour', 'tzuserrel').'<br>';
967
968 $eventarray[$daykey][] = $event;
969 $j++;
970
971 $daykey += 60 * 60 * 24;
972 //if ($daykey > $event->date_end_in_calendar) {
973 if ($daykey > $daykeyend) {
974 $loop = false;
975 }
976 } while ($loop);
977 //var_dump($eventarray);
978 //print 'Event '.$i.' id='.$event->id.' (start='.dol_print_date($event->datep).'-end='.dol_print_date($event->datef);
979 //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>';
980 }
981
982 $parameters['obj'] = $obj;
983 $reshook = $hookmanager->executeHooks('hookEventElements', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks
984 $event = $hookmanager->resPrint;
985 if ($reshook < 0) {
986 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
987 }
988
989 $i++;
990 }
991 $db->free($resql);
992} else {
993 dol_print_error($db);
994}
995//var_dump($eventarray);
996
997
998// BIRTHDATES CALENDAR
999// Complete $eventarray with birthdates
1000if ($showbirthday) { // always false @phpstan-ignore-line
1001 // Add events in array
1002 $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday';
1003 $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp';
1004 $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.((int) $user->id).'))';
1005 $sql .= " AND sp.entity IN (".getEntity('contact').")";
1006 if ($mode == 'show_day') {
1007 $sql .= ' AND MONTH(birthday) = '.((int) $month);
1008 $sql .= ' AND DAY(birthday) = '.((int) $day);
1009 } else {
1010 $sql .= ' AND MONTH(birthday) = '.((int) $month);
1011 }
1012 $sql .= ' ORDER BY birthday';
1013
1014 dol_syslog("comm/action/index.php", LOG_DEBUG);
1015 $resql = $db->query($sql);
1016 if ($resql) {
1017 $num = $db->num_rows($resql);
1018 $i = 0;
1019 while ($i < $num) {
1020 $obj = $db->fetch_object($resql);
1021
1022 $event = new ActionComm($db);
1023
1024 $event->id = $obj->rowid; // We put contact id in action id for birthdays events
1025 $event->ref = (string) $event->id;
1026
1027 $datebirth = dol_stringtotime($obj->birthday, 1);
1028 //print 'ee'.$obj->birthday.'-'.$datebirth;
1029 $datearray = dol_getdate($datebirth, true);
1030 $event->datep = dol_mktime(0, 0, 0, $datearray['mon'], $datearray['mday'], $year, true); // For full day events, date are also GMT but they won't but converted during output
1031 $event->datef = $event->datep;
1032
1033 $event->type_code = 'BIRTHDAY';
1034 $event->type_label = '';
1035 $event->type_color = '';
1036 $event->type = 'birthdate';
1037 $event->type_picto = 'birthdate';
1038
1039 $event->label = $langs->trans("Birthday").' '.dolGetFirstLastname($obj->firstname, $obj->lastname);
1040 $event->percentage = 100;
1041 $event->fulldayevent = 1;
1042
1043 $event->contact_id = $obj->rowid;
1044
1045 $event->date_start_in_calendar = $db->jdate($event->datep);
1046 $event->date_end_in_calendar = $db->jdate($event->datef);
1047
1048 // Add an entry in eventarray for each day
1049 $daycursor = $event->datep;
1050 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1051 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1052 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1053
1054 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1055
1056 $eventarray[$daykey][] = $event;
1057
1058 /*$loop = true;
1059 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee);
1060 do {
1061 $eventarray[$daykey][] = $event;
1062 $daykey += 60 * 60 * 24;
1063 if ($daykey > $event->date_end_in_calendar) $loop = false;
1064 } while ($loop);
1065 */
1066 $i++;
1067 }
1068 } else {
1069 dol_print_error($db);
1070 }
1071}
1072
1073// LEAVE-HOLIDAY CALENDAR
1074if ($user->hasRight("holiday", "read")) {
1075 $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";
1076 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u";
1077 $sql .= " WHERE u.rowid = x.fk_user";
1078 $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user)
1079 $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved)
1080 // Restrict on current month (we get more, but we will filter later)
1081 $sql .= " AND x.date_debut < '".$db->idate(dol_get_last_day($year, $month))."'";
1082 $sql .= " AND x.date_fin >= '".$db->idate(dol_get_first_day($year, $month))."'";
1083 if (!$user->hasRight('holiday', 'readall')) {
1084 $sql .= " AND x.fk_user IN(".$db->sanitize(implode(", ", $user->getAllChildIds(1))).") ";
1085 }
1086
1087 $resql = $db->query($sql);
1088 if ($resql) {
1089 $num = $db->num_rows($resql);
1090 $i = 0;
1091
1092 while ($i < $num) {
1093 $obj = $db->fetch_object($resql);
1094
1095 $event = new ActionComm($db);
1096
1097 // Need the id of the leave object for link to it
1098 $event->id = $obj->rowid;
1099 $event->ref = (string) $event->id;
1100
1101 $event->type_code = 'HOLIDAY';
1102 $event->type_label = '';
1103 $event->type_color = '';
1104 $event->type = 'holiday';
1105 $event->type_picto = 'holiday';
1106
1107 // date_debut and date_fin are dates without time, so they must be read and rendered in GMT to
1108 // stay independent from the server and user timezones (otherwise the calendar day box is shifted).
1109 $event->datep = $db->jdate($obj->date_start, 'gmt') + (empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12) * 60 * 60;
1110 $event->datef = $db->jdate($obj->date_end, 'gmt') + (empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1;
1111 $event->date_start_in_calendar = $event->datep;
1112 $event->date_end_in_calendar = $event->datef;
1113
1114 $event->transparency = 1;
1115
1116 $event->userownerid = $obj->uid; // user id of owner
1117 $event->userassigned = array($obj->uid => array('id' => $obj->uid, 'transparency' => 1));
1118
1119 if ($obj->status == 3) {
1120 // Show no symbol for leave with state "leave approved"
1121 $event->percentage = -1;
1122 } elseif ($obj->status == 2) {
1123 // Show TO-DO symbol for leave with state "leave wait for approval"
1124 $event->percentage = 0;
1125 }
1126
1127
1128 $daycursor = $event->date_start_in_calendar;
1129 $annee = (int) dol_print_date($daycursor, '%Y', 'gmt');
1130 $mois = (int) dol_print_date($daycursor, '%m', 'gmt');
1131 $jour = (int) dol_print_date($daycursor, '%d', 'gmt');
1132
1133 $daycursorend = $event->date_end_in_calendar;
1134 $anneeend = (int) dol_print_date($daycursorend, '%Y', 'gmt');
1135 $moisend = (int) dol_print_date($daycursorend, '%m', 'gmt');
1136 $jourend = (int) dol_print_date($daycursorend, '%d', 'gmt');
1137
1138 // daykey must be date that represent day box in calendar so must be a user time
1139 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1140 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1141 $ifornbofdays = 0;
1142 do {
1143 $ifornbofdays++;
1144
1145 $firstdayofholiday = ($ifornbofdays == 1);
1146 $lastdayofholiday = ($daykeygmt == dol_get_first_hour($event->date_end_in_calendar, 'gmt'));
1147
1148 //var_dump(dol_print_date($daykeygmt, 'dayhour', 'gmt'));
1149
1150 if ((in_array($obj->halfday, array(1, 2)) == 1 && $lastdayofholiday) || (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday)) {
1151 // We create a copy of event because we want tochange the label
1152 $newevent = dol_clone($event, 1);
1153 if (in_array($obj->halfday, array(1, 2)) && $lastdayofholiday) {
1154 $newevent->label .= ' ('.$langs->trans("Morning").')';
1155 } elseif (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday) {
1156 $newevent->label .= ' ('.$langs->trans("Afternoon").')';
1157 }
1158 $eventarray[$daykey][] = $newevent; // We need to use ->gtTypePicto, getXXXon object, so clone must be PHP clone.
1159 } else {
1160 $eventarray[$daykey][] = $event; // We can use the event unchanged
1161 }
1162
1163 $daykey += 60 * 60 * 24;
1164 $daykeygmt += 60 * 60 * 24;
1165 } while ($daykey <= $event->date_end_in_calendar);
1166
1167 $i++;
1168 }
1169 }
1170}
1171
1172// EXTERNAL CALENDAR
1173// Complete $eventarray with external import Ical
1174if (count($listofextcals)) {
1175 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/ical.class.php';
1176
1177 foreach ($listofextcals as $key => $extcal) {
1178 $url = $extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics
1179 $namecal = $extcal['name'];
1180 $offsettz = $extcal['offsettz'];
1181 $colorcal = $extcal['color'];
1182 $buggedfile = $extcal['buggedfile'];
1183
1184 $pathforcachefile = dol_sanitizePathName($conf->user->dir_temp).'/'.dol_sanitizeFileName('extcal_'.$namecal.'_user'.$user->id).'.cache';
1185 //var_dump($pathforcachefile);exit;
1186
1187 $ical = new ICal();
1188 $ical->parse($url, $pathforcachefile, $DELAYFORCACHE);
1189 if ($ical->error) {
1190 // Save error message for extcal
1191 $listofextcals[$key]['error'] = $ical->error;
1192 $s .= '<br><div class="warning">'.dol_escape_htmltag($listofextcals[$key]['name']).': '.$url.'<br>Error message: '.dol_escape_htmltag($ical->error).'</div>';
1193 }
1194
1195 // After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ...
1196 //var_dump($ical->cal); exit;
1197 $icalevents = array();
1198 if (is_array($ical->get_event_list())) {
1199 $icalevents = array_merge($icalevents, $ical->get_event_list()); // Add $ical->cal['VEVENT']
1200 }
1201 if (is_array($ical->get_freebusy_list())) {
1202 $icalevents = array_merge($icalevents, $ical->get_freebusy_list()); // Add $ical->cal['VFREEBUSY']
1203 }
1204
1205 if (count($icalevents) > 0) {
1206 // Duplicate all repeatable events into new entries
1207 $moreicalevents = array();
1208 foreach ($icalevents as $icalevent) {
1209 if (isset($icalevent['RRULE']) && is_array($icalevent['RRULE'])) { //repeatable event
1210 //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow;
1211 //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow-1);
1212 if ($icalevent['DTSTART;VALUE=DATE']) { //fullday event
1213 $datecurstart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1);
1214 $datecurend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day
1215 } elseif (is_array($icalevent['DTSTART']) && !empty($icalevent['DTSTART']['unixtime'])) {
1216 $datecurstart = $icalevent['DTSTART']['unixtime']; // can't be empty
1217 $datecurend = $icalevent['DTEND']['unixtime'];
1218 if (!empty($ical->cal['DAYLIGHT']['DTSTART']) /* && $datecurstart */) {
1219 //var_dump($ical->cal);
1220 $tmpcurstart = $datecurstart;
1221 $tmpcurend = $datecurend;
1222 $tmpdaylightstart = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['DAYLIGHT']['DTSTART'];
1223 $tmpdaylightend = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['STANDARD']['DTSTART'];
1224 //var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']);
1225 // Edit datecurstart and datecurend
1226 if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) {
1227 $datecurstart -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36;
1228 } else {
1229 $datecurstart -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36;
1230 }
1231 if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) {
1232 $datecurend -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36;
1233 } else {
1234 $datecurend -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36;
1235 }
1236 }
1237 // datecurstart and datecurend are now GMT date
1238 //var_dump($datecurstart); var_dump($datecurend); exit;
1239 } else {
1240 // Not a recognized record
1241 dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR);
1242 continue;
1243 }
1244 //print 'xx'.$datecurstart;exit;
1245
1246 $interval = (empty($icalevent['RRULE']['INTERVAL']) ? 1 : $icalevent['RRULE']['INTERVAL']);
1247 $until = empty($icalevent['RRULE']['UNTIL']) ? 0 : dol_stringtotime($icalevent['RRULE']['UNTIL'], 1);
1248 $maxrepeat = empty($icalevent['RRULE']['COUNT']) ? 0 : $icalevent['RRULE']['COUNT'];
1249 if ($until && ($until + ($datecurend - $datecurstart)) < $firstdaytoshow) {
1250 continue; // We discard repeatable event that end before start date to show
1251 }
1252 if ($datecurstart >= $lastdaytoshow) {
1253 continue; // We discard repeatable event that start after end date to show
1254 }
1255
1256 $numofevent = 0;
1257 while (($datecurstart < $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat))) {
1258 if ($datecurend >= $firstdaytoshow) { // We add event
1259 $newevent = $icalevent;
1260 unset($newevent['RRULE']);
1261 if ($icalevent['DTSTART;VALUE=DATE']) {
1262 $newevent['DTSTART;VALUE=DATE'] = dol_print_date($datecurstart, '%Y%m%d');
1263 $newevent['DTEND;VALUE=DATE'] = dol_print_date($datecurend + 1, '%Y%m%d');
1264 } else {
1265 $newevent['DTSTART'] = $datecurstart;
1266 $newevent['DTEND'] = $datecurend;
1267 }
1268 $moreicalevents[] = $newevent;
1269 }
1270 // Jump on next occurrence
1271 $numofevent++;
1272 $savdatecurstart = $datecurstart;
1273 if ($icalevent['RRULE']['FREQ'] == 'DAILY') {
1274 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'd');
1275 $datecurend = dol_time_plus_duree($datecurend, $interval, 'd');
1276 }
1277 if ($icalevent['RRULE']['FREQ'] == 'WEEKLY') {
1278 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'w');
1279 $datecurend = dol_time_plus_duree($datecurend, $interval, 'w');
1280 } elseif ($icalevent['RRULE']['FREQ'] == 'MONTHLY') {
1281 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'm');
1282 $datecurend = dol_time_plus_duree($datecurend, $interval, 'm');
1283 } elseif ($icalevent['RRULE']['FREQ'] == 'YEARLY') {
1284 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'y');
1285 $datecurend = dol_time_plus_duree($datecurend, $interval, 'y');
1286 }
1287 // Test to avoid infinite loop ($datecurstart must increase)
1288 if ($savdatecurstart >= $datecurstart) {
1289 dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR);
1290 $datecurstart += 3600 * 24 * 7;
1291 $datecurend += 3600 * 24 * 7;
1292 }
1293 }
1294 }
1295 }
1296 $icalevents = array_merge($icalevents, $moreicalevents);
1297
1298 // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray
1299 foreach ($icalevents as $icalevent) {
1300 //var_dump($icalevent);
1301
1302 //print $icalevent['SUMMARY'].'->';
1303 //var_dump($icalevent);exit;
1304 if (!empty($icalevent['RRULE'])) {
1305 continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule.
1306 }
1307
1308 // Create a new object action
1309 $event = new ActionComm($db);
1310 $addevent = false;
1311 $datestart = null;
1312 $dateend = null;
1313 if (isset($icalevent['DTSTART;VALUE=DATE'])) { // fullday event
1314 // For full day events, date are also GMT but they won't but converted using tz during output
1315 $datestart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1);
1316 if (empty($icalevent['DTEND;VALUE=DATE'])) {
1317 $dateend = $datestart + 86400 - 1;
1318 } else {
1319 $dateend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day
1320 }
1321 //print 'x'.$datestart.'-'.$dateend;exit;
1322 //print dol_print_date($dateend,'dayhour','gmt');
1323 $event->fulldayevent = 1;
1324 $addevent = true;
1325 } elseif (!is_array($icalevent['DTSTART'])) { // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch)
1326 $datestart = $icalevent['DTSTART'];
1327 $dateend = empty($icalevent['DTEND']) ? $datestart : $icalevent['DTEND'];
1328
1329 $datestart += +($offsettz * 3600);
1330 $dateend += +($offsettz * 3600);
1331
1332 $addevent = true;
1333 //var_dump($offsettz);
1334 //var_dump(dol_print_date($datestart, 'dayhour', 'gmt'));
1335 } elseif (isset($icalevent['DTSTART']['unixtime'])) { // File contains a local timezone + a TZ (for example when using bluemind)
1336 $datestart = $icalevent['DTSTART']['unixtime'];
1337 $dateend = $icalevent['DTEND']['unixtime'];
1338
1339 $datestart += +($offsettz * 3600);
1340 $dateend += +($offsettz * 3600);
1341
1342 // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight'
1343 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
1344 // TODO
1345 }
1346 // $buggedfile is set to uselocalandtzdaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtzdaylight' (for example with bluemind)
1347 if ($buggedfile === 'uselocalandtzdaylight') { // unixtime is a local date that does take daylight into account, TZID is +2 for example for 'Europe/Paris' in summer
1348 $localtzs = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTSTART']['TZID']));
1349 $localtze = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTEND']['TZID']));
1350 $localdts = new DateTime(dol_print_date($datestart, 'dayrfc', 'gmt'), $localtzs);
1351 $localdte = new DateTime(dol_print_date($dateend, 'dayrfc', 'gmt'), $localtze);
1352 $tmps = -1 * $localtzs->getOffset($localdts);
1353 $tmpe = -1 * $localtze->getOffset($localdte);
1354 $datestart += $tmps;
1355 $dateend += $tmpe;
1356 //var_dump($datestart);
1357 }
1358 $addevent = true;
1359 }
1360
1361 if ($addevent && $datestart !== null && $dateend !== null) {
1362 $event->id = $icalevent['UID'];
1363 $event->ref = (string) $event->id;
1364 $userstatic = new User($db);
1365 $userId = $userstatic->findUserIdByEmail($namecal);
1366 if (!empty($userId) && $userId > 0) {
1367 $event->userassigned[$userId] = [
1368 'id' => $userId,
1369 'transparency' => 1,
1370 ];
1371 $event->percentage = -1;
1372 }
1373
1374 $event->type_code = "ICALEVENT";
1375 $event->type_label = $namecal;
1376 $event->type_color = $colorcal;
1377 $event->type = 'icalevent';
1378 $event->type_picto = 'rss';
1379
1380 $event->icalname = $namecal;
1381 $event->icalcolor = $colorcal;
1382 $usertime = 0; // We don't modify date because we want to have date into memory datep and datef stored as GMT date. Compensation will be done during output.
1383 $event->datep = $datestart + $usertime;
1384 $event->datef = $dateend + $usertime;
1385
1386 if (isset($icalevent['SUMMARY']) && $icalevent['SUMMARY']) {
1387 $event->label = dol_string_nohtmltag($icalevent['SUMMARY']);
1388 } elseif (isset($icalevent['DESCRIPTION']) && $icalevent['DESCRIPTION']) {
1389 $event->label = dol_nl2br(dol_string_nohtmltag($icalevent['DESCRIPTION']), 1);
1390 } else {
1391 $event->label = $langs->trans("ExtSiteNoLabel");
1392 }
1393
1394 // Priority (see https://www.kanzaki.com/docs/ical/priority.html)
1395 // LOW = 0 to 4
1396 // MEDIUM = 5
1397 // HIGH = 6 to 9
1398 if (!empty($icalevent['PRIORITY'])) {
1399 $event->priority = $icalevent['PRIORITY'];
1400 }
1401
1402 // Transparency (see https://www.kanzaki.com/docs/ical/transp.html)
1403 if (!empty($icalevent['TRANSP'])) {
1404 if ($icalevent['TRANSP'] == "TRANSPARENT") {
1405 $event->transparency = 0; // 0 = available / free
1406 }
1407 if ($icalevent['TRANSP'] == "OPAQUE") {
1408 $event->transparency = 1; // 1 = busy
1409 }
1410
1411 // TODO: MS outlook states
1412 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:TRANSPARENT => Available / Free
1413 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:OPAQUE => Work another place
1414 // X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE + TRANSP:OPAQUE => With reservations
1415 // X-MICROSOFT-CDO-BUSYSTATUS:BUSY + TRANSP:OPAQUE => Busy
1416 // X-MICROSOFT-CDO-BUSYSTATUS:OOF + TRANSP:OPAQUE => Away from the office / off-site
1417 }
1418
1419 if (!empty($icalevent['LOCATION'])) {
1420 $event->location = $icalevent['LOCATION'];
1421 }
1422
1423 $event->date_start_in_calendar = $event->datep;
1424
1425 if ($event->datef != '' && $event->datef >= $event->datep) {
1426 $event->date_end_in_calendar = $event->datef;
1427 } else {
1428 $event->date_end_in_calendar = $event->datep;
1429 }
1430
1431 // Add event into $eventarray if date range are ok.
1432 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) {
1433 //print 'x'.$datestart.'-'.$dateend;exit;
1434 //print 'x'.$datestart.'-'.$dateend;exit;
1435 //print 'x'.$datestart.'-'.$dateend;exit;
1436 // This record is out of visible range
1437 } else {
1438 if ($event->date_start_in_calendar < $firstdaytoshow) {
1439 $event->date_start_in_calendar = $firstdaytoshow;
1440 }
1441 if ($event->date_end_in_calendar >= $lastdaytoshow) {
1442 $event->date_end_in_calendar = ($lastdaytoshow - 1);
1443 }
1444
1445 // Add an entry in actionarray for each day
1446 $daycursor = $event->date_start_in_calendar;
1447 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1448 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1449 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1450
1451 // Loop on each day covered by action to prepare an index to show on calendar
1452 $loop = true;
1453 $j = 0;
1454 // daykey must be date that represent day box in calendar so must be a user time
1455 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1456 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1457 do {
1458 //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').' ';
1459 $eventarray[$daykey][] = $event;
1460 $daykey += 60 * 60 * 24;
1461 $daykeygmt += 60 * 60 * 24; // Add one day
1462 if (($event->fulldayevent ? $daykeygmt : $daykey) > $event->date_end_in_calendar) {
1463 $loop = false;
1464 }
1465 } while ($loop);
1466 }
1467 }
1468 }
1469 }
1470 }
1471}
1472
1473// Complete $eventarray with events coming from external module
1474$parameters = array();
1475$object = null;
1476$reshook = $hookmanager->executeHooks('getCalendarEvents', $parameters, $object, $action);
1477if (!empty($hookmanager->resArray['eventarray'])) {
1478 foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) {
1479 if (!isset($eventarray[$keyDate])) {
1480 $eventarray[$keyDate] = array();
1481 }
1482 $eventarray[$keyDate] = array_merge($eventarray[$keyDate], $events);
1483 }
1484}
1485
1486// Sort events
1487/*
1488foreach ($eventarray as $keyDate => &$dateeventarray) {
1489 usort($dateeventarray, 'sort_events_by_date');
1490}
1491*/
1492
1493$maxnbofchar = 18;
1494$cachethirdparties = array();
1495$cachecontacts = array();
1496$cacheusers = array();
1497// default values
1498$theme_datacolor = array(
1499 array(137, 86, 161),
1500 array(60, 147, 183),
1501 array(250, 190, 80),
1502 array(80, 166, 90),
1503 array(190, 190, 100),
1504 array(91, 115, 247),
1505 array(140, 140, 220),
1506 array(190, 120, 120),
1507 array(115, 125, 150),
1508 array(100, 170, 20),
1509 array(150, 135, 125),
1510 array(85, 135, 150),
1511 array(150, 135, 80),
1512 array(150, 80, 150)
1513);
1514// Define theme_datacolor array
1515$color_file = DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/theme_vars.inc.php";
1516if (is_readable($color_file)) {
1517 include $color_file;
1518 global $theme_datacolor;
1519}
1520
1521$massactionbutton = '';
1522
1523$num = 0;
1524
1525print_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);
1526
1527$link = '';
1528
1529// Show div with list of calendars
1530print $s;
1531
1532// Top filters
1533print '<div class="liste_titre liste_titre_bydiv centpercent">';
1534print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, '', (string) $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid, $search_categ_cus);
1535print '</div>';
1536
1537
1538$newparam = $param; // newparam is for birthday links
1539$newparam = preg_replace('/showbirthday=/i', 'showbirthday_=', $newparam); // To avoid replacement when replace day= is done
1540$newparam = preg_replace('/mode=show_month&?/i', '', $newparam);
1541$newparam = preg_replace('/mode=show_week&?/i', '', $newparam);
1542$newparam = preg_replace('/day=[0-9]+&?/i', '', $newparam);
1543$newparam = preg_replace('/month=[0-9]+&?/i', '', $newparam);
1544$newparam = preg_replace('/year=[0-9]+&?/i', '', $newparam);
1545$newparam = preg_replace('/viewweek=[0-9]+&?/i', '', $newparam);
1546$newparam = preg_replace('/showbirthday_=/i', 'showbirthday=', $newparam); // Restore correct parameter
1547$newparam .= '&viewweek=1';
1548
1549echo '<input type="hidden" name="actionmove" value="mupdate">';
1550echo '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($_SERVER['PHP_SELF']).'?'.dol_escape_htmltag($_SERVER['QUERY_STRING']).'">';
1551echo '<input type="hidden" name="newdate" id="newdate">';
1552
1553
1554// Line header with list of days
1555
1556//print "begin_d=".$begin_d." end_d=".$end_d;
1557
1558$currentdaytoshow = $firstdaytoshow;
1559echo '<div class="div-table-responsive">';
1560//print dol_print_date($currentdaytoshow, 'dayhour', 'gmt');
1561
1562$colorsbytype = array();
1563
1564while ($currentdaytoshow < $lastdaytoshow) {
1565 echo '<table class="centpercent noborder nocellnopadd cal_month cal_peruser listwithfilterbefore">';
1566
1567 echo '<tr class="liste_titre">';
1568 echo '<td class="nopaddingtopimp nopaddingbottomimp nowraponsmartphone">';
1569
1570 if ($canedit /* && $mode == 'show_peruser' */) { // mode is forced to show_peruser
1571 // Filter on days
1572 print '<span class="hideonsmartphone" title="'.$langs->trans("VisibleDaysRange").'">';
1573 print img_picto('', 'clock', 'class="fawidth30 inline-block marginleftonly"');
1574 print $langs->trans("DaysOfWeek").'</span>';
1575 print "\n";
1576 print '<div class="ui-grid-a inline-block"><div class="ui-block-a nowraponall">';
1577 print '<input type="number" class="shortbis" name="begin_d" value="'.$begin_d.'" min="1" max="7">';
1578 if (empty($conf->dol_use_jmobile)) {
1579 print ' - ';
1580 } else {
1581 print '</div><div class="ui-block-b">';
1582 }
1583 print '<input type="number" class="shortbis" name="end_d" value="'.$end_d.'" min="1" max="7">';
1584 print '</div></div>';
1585 }
1586
1587 print '</td>';
1588 $i = 0; // 0 = sunday,
1589 while ($i < 7) {
1590 if (($i + 1) < $begin_d || ($i + 1) > $end_d) {
1591 $i++;
1592 continue;
1593 }
1594 echo '<td align="center" colspan="'.($end_h - $begin_h).'">';
1595 echo '<span class="bold spandayofweek">'.$langs->trans("Day".(($i + getDolGlobalInt('MAIN_START_WEEK', 1)) % 7)).'</span>';
1596 print "<br>";
1597 if ($i) {
1598 $valtoshow = dol_time_plus_duree($currentdaytoshow, $i, 'd');
1599 } else {
1600 $valtoshow = $currentdaytoshow;
1601 }
1602 if (dol_print_date($valtoshow, '%Y%m%d') == dol_print_date(dol_now(), '%Y%m%d')) {
1603 echo '<span class="badgeneutral">';
1604 }
1605 print dol_print_date($valtoshow, 'dayreduceformat', 'tzuserrel');
1606 if (dol_print_date($valtoshow, '%Y%m%d') == dol_print_date(dol_now(), '%Y%m%d')) {
1607 echo '</span>';
1608 }
1609 echo "</td>\n";
1610 $i++;
1611 }
1612 echo "</tr>\n";
1613
1614 echo '<tr class="liste_titre">';
1615 echo '<td>';
1616
1617 // Filter on hours
1618 print '<span class="hideonsmartphone" title="'.$langs->trans("VisibleTimeRange").'">';
1619 print img_picto('', 'clock', 'class="fawidth30 inline-block marginleftonly"');
1620 print $langs->trans("Hours").'</span>';
1621 print "\n";
1622 print '<div class="ui-grid-a inline-block"><div class="ui-block-a nowraponall">';
1623 print '<input type="number" class="shortbis" name="begin_h" value="'.$begin_h.'" min="0" max="23">';
1624 if (empty($conf->dol_use_jmobile)) {
1625 print ' - ';
1626 } else {
1627 print '</div><div class="ui-block-b">';
1628 }
1629 print '<input type="number" class="shortbis" name="end_h" value="'.$end_h.'" min="1" max="24">';
1630 if (empty($conf->dol_use_jmobile)) {
1631 print ' '.$langs->trans("HourShort");
1632 }
1633 print '</div></div>';
1634
1635 echo '</td>';
1636 $i = 0;
1637 while ($i < 7) {
1638 if (($i + 1) < $begin_d || ($i + 1) > $end_d) {
1639 $i++;
1640 continue;
1641 }
1642 for ($h = $begin_h; $h < $end_h; $h++) {
1643 echo '<td class="center">';
1644 print '<small style="font-family: courier">'.sprintf("%02d", $h).'</small>';
1645 print "</td>";
1646 }
1647 echo "</td>\n";
1648 $i++;
1649 }
1650 echo "</tr>\n";
1651
1652
1653 // Define $usernames
1654 $usernames = array(); //init
1655 $usernamesid = array();
1656 /* Use this to have list of users only if users have events */
1657 if (getDolGlobalString('AGENDA_SHOWOWNERONLY_ONPERUSERVIEW')) {
1658 foreach ($eventarray as $daykey => $notused) {
1659 // Get all assigned users for each event
1660 foreach ($eventarray[$daykey] as $index => $event) {
1661 $event->fetch_userassigned();
1662 $listofuserid = $event->userassigned;
1663 foreach ($listofuserid as $userid => $tmp) {
1664 if (!in_array($userid, $usernamesid)) {
1665 $usernamesid[$userid] = $userid;
1666 }
1667 }
1668 }
1669 }
1670 } else {
1671 /* Use this list to have lines of all users to show */
1672 $sql = "SELECT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity";
1673 $sql .= " FROM ".$db->prefix()."user as u";
1674 if (isModEnabled('multicompany') && getDolGlobalInt('MULTICOMPANY_TRANSVERSE_MODE')) {
1675 $sql .= " WHERE u.rowid IN (";
1676 $sql .= " SELECT ug.fk_user FROM ".$db->prefix()."usergroup_user as ug";
1677 $sql .= " WHERE ug.entity IN (".getEntity('usergroup').")";
1678 if ($usergroup > 0) {
1679 $sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
1680 }
1681 $sql .= ")";
1682 } else {
1683 if ($usergroup > 0) {
1684 $sql .= " LEFT JOIN ".$db->prefix()."usergroup_user as ug ON u.rowid = ug.fk_user";
1685 }
1686 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1687 if ($usergroup > 0) {
1688 $sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
1689 }
1690 }
1691 $sql .= " AND u.statut = 1";
1692 if ($filtert > 0) {
1693 $sql .= " AND u.rowid = ".((int) $filtert);
1694 }
1695 if ($usergroup > 0) {
1696 $sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
1697 }
1698 if ($user->socid > 0) {
1699 // External users should see only contacts of their company
1700 $sql .= " AND u.fk_soc = ".((int) $user->socid);
1701 }
1702 // Filter on users in hierarchy
1703 if (!$canedit || $filtert == '-3') { // If we can't read event of others
1704 if (!$user->hasRight('user', 'user', 'lire') || $filtert == '-3') {
1705 $usersInHierarchy = $user->getAllChildIds(1);
1706 $sql .= " AND u.rowid IN (".$db->sanitize(implode(',', $usersInHierarchy)).")";
1707 }
1708 }
1709
1710 //print $sql;
1711 $resql = $db->query($sql);
1712 if ($resql) {
1713 $num = $db->num_rows($resql);
1714 $i = 0;
1715 if ($num) {
1716 while ($i < $num) {
1717 $obj = $db->fetch_object($resql);
1718 $usernamesid[$obj->rowid] = $obj->rowid;
1719 $i++;
1720 }
1721 }
1722 } else {
1723 dol_print_error($db);
1724 }
1725 }
1726 //var_dump($usernamesid);
1727 foreach ($usernamesid as $id) {
1728 $tmpuser = new User($db);
1729 $result = $tmpuser->fetch($id);
1730 $usernames[] = $tmpuser;
1731 }
1732
1733 // Load array of colors by type
1734 $labelbytype = array();
1735 $sql = "SELECT code, color, libelle as label FROM ".MAIN_DB_PREFIX."c_actioncomm ORDER BY position";
1736 $resql = $db->query($sql);
1737 while ($obj = $db->fetch_object($resql)) {
1738 $colorsbytype[$obj->code] = $obj->color;
1739 $labelbytype[$obj->code] = $obj->label;
1740 }
1741
1742 // Loop on each user to show calendar
1743 $todayarray = dol_getdate($now, true);
1744 $sav = $tmpday;
1745 $showheader = true;
1746 $var = false;
1747 foreach ($usernames as $username) {
1748 //if ($username->login != 'admin') continue;
1749
1750 $var = !$var;
1751
1752 echo "<tr>";
1753 echo '<td class="tdoverflowmax100 cal_current_month cal_peruserviewname'.($var ? ' cal_impair' : '').' nopaddingtopimp nopaddingbottomimp noheightimp">';
1754 print '<span class="paddingrightimp">';
1755 print $username->getNomUrl(-1, '', 0, 0, 20, 1, '', 'paddingleft');
1756 print '</span>';
1757 print '</td>';
1758 $tmpday = $sav;
1759
1760 // Lopp on each day of week
1761 $i = 0;
1762 for ($iter_day = 0; $iter_day < 8; $iter_day++) {
1763 if (($i + 1) < $begin_d || ($i + 1) > $end_d) {
1764 $i++;
1765 continue;
1766 }
1767
1768 // Show days of the current week
1769 $curtime = dol_time_plus_duree($currentdaytoshow, $iter_day, 'd');
1770 // $curtime is a gmt time, but we want the day, month, year in user TZ
1771 $tmpday = (int) dol_print_date($curtime, "%d", "tzuserrel");
1772 $tmpmonth = (int) dol_print_date($curtime, "%m", "tzuserrel");
1773 $tmpyear = (int) dol_print_date($curtime, "%Y", "tzuserrel");
1774 //var_dump($curtime.' '.$tmpday.' '.$tmpmonth.' '.$tmpyear);
1775
1776 $style = 'cal_current_month';
1777 if ($iter_day == 6) {
1778 $style .= ' cal_other_month';
1779 }
1780 $today = 0;
1781 if ($todayarray['mday'] == $tmpday && $todayarray['mon'] == $tmpmonth && $todayarray['year'] == $tmpyear) {
1782 $today = 1;
1783 }
1784 if ($today) {
1785 $style = 'cal_today_peruser';
1786 }
1787
1788 show_day_events2($username, $tmpday, $tmpmonth, $tmpyear, 0, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, $showheader, $colorsbytype, $var);
1789
1790 $i++;
1791 }
1792 echo "</tr>\n";
1793 $showheader = false;
1794 }
1795
1796 echo "</table>\n";
1797 echo "<br>";
1798
1799 $currentdaytoshow = dol_time_plus_duree($currentdaytoshow, 7, 'd');
1800}
1801
1802echo '</div>';
1803
1804if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
1805 $langs->load("commercial");
1806 print '<br>'.$langs->trans("Legend").': <br>';
1807 foreach ($colorsbytype as $code => $color) {
1808 if ($color) {
1809 print '<div style="float: left; padding: 2px; margin-right: 6px;"><div style="background: #'.$color.'; width:16px; float: left; margin-right: 4px;">&nbsp;</div>';
1810 print $langs->trans("Action".$code) != "Action".$code ? $langs->trans("Action".$code) : $labelbytype[$code];
1811 //print $code;
1812 print '</div>';
1813 }
1814 }
1815 //$color=sprintf("%02x%02x%02x",$theme_datacolor[0][0],$theme_datacolor[0][1],$theme_datacolor[0][2]);
1816 print '<div style="float: left; padding: 2px; margin-right: 6px;"><div class="peruser_busy" style="width:16px; float: left; margin-right: 4px;">&nbsp;</div>';
1817 print $langs->trans("Other");
1818 print '</div>';
1819 /* TODO Show this if at least one cumulated event
1820 print '<div style="float: left; padding: 2px; margin-right: 6px;"><div style="background: #222222; width:16px; float: left; margin-right: 4px;">&nbsp;</div>';
1821 print $langs->trans("SeveralEvents");
1822 print '</div>';
1823 */
1824}
1825
1826print "\n".'</form>';
1827
1828print "\n";
1829
1830// Add js code to manage click on a box
1831print '<script type="text/javascript">
1832jQuery(document).ready(function() {
1833 jQuery(".onclickopenref").click(function() {
1834 var ref=$(this).attr(\'ref\');
1835 var res = ref.split("_");
1836 var type = res[0];
1837 var userid = res[1];
1838 var year = res[2];
1839 var month = res[3];
1840 var day = res[4];
1841 var hour = res[5];
1842 var min = res[6];
1843 var ids = res[7];
1844
1845 console.log("We click on a class onclickopenref in page peruser with ref="+ref+" type="+type);
1846
1847 if (ids == \'none\') /* No event */
1848 {
1849 /* alert(\'no event\'); */
1850 url = "'.DOL_URL_ROOT.'/comm/action/card.php?action=create&assignedtouser="+userid+"&datep="+year+month+day+hour+min+"00&backtopage='.urlencode($_SERVER["PHP_SELF"].'?year='.$year.'&month='.$month.'&day='.$day.($begin_h !== '' ? '&begin_h='.$begin_h : '').($end_h !== '' ? '&end_h='.$end_h : '').($begin_d !== '' ? '&begin_d='.$begin_d : '').($end_d !== '' ? '&end_d='.$end_d : '')).'"
1851 window.location.href = url;
1852 }
1853 else if (ids.indexOf(",") > -1) /* There is several events */
1854 {
1855 /* alert(\'several events\'); */
1856 url = "'.DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&search_actioncode="+jQuery("#search_actioncode").val()+"&search_status="+jQuery("#selectsearch_status").val()+"&filtert="+userid+"&dateselectyear="+year+"&dateselectmonth="+month+"&dateselectday="+day;
1857 window.location.href = url;
1858 } else { /* One event */
1859 /* alert(\'one event\'); */
1860 if (type == \'holiday\') {
1861 url = "'.DOL_URL_ROOT.'/holiday/card.php?id="+ids
1862 } else {
1863 url = "'.DOL_URL_ROOT.'/comm/action/card.php?action=view&id="+ids
1864 }
1865 window.location.href = url;
1866 }
1867 });
1868});
1869</script>';
1870
1871// End of page
1872llxFooter();
1873$db->close();
1874
1875
1876
1877
1898function show_day_events2($username, $day, $month, $year, $monthshown, $style, &$eventarray, $maxprint = 0, $maxnbofchar = 16, $newparam = '', $showinfo = 0, $minheight = 60, $showheader = false, $colorsbytype = array(), $var = false)
1899{
1900 global $db;
1901 global $user, $conf, $langs, $hookmanager, $action;
1902 global $filter, $filtert, $status, $actioncode; // Filters used into search form
1903 global $theme_datacolor; // Array with a list of different we can use (come from theme)
1904 global $cachethirdparties, $cachecontacts, $cacheusers, $cacheprojects, $colorindexused;
1905 global $begin_h, $end_h;
1906
1907 $cases1 = array(); // Color first half hour
1908 $cases2 = array(); // Color second half hour
1909 $cases3 = array(); // Color third half hour
1910 $cases4 = array(); // Color 4th half hour
1911
1918 '
1919 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases1
1920 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases2
1921 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases3
1922 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases4
1923 ';
1924
1925 $i = 0;
1926 $numother = 0;
1927 $numbirthday = 0;
1928 $numical = 0;
1929 $numicals = array();
1930 //$ymd = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day);
1931
1932 $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0
1933 $nextindextouse = count($colorindexused); // At first run this is 0, so first user has 0, next 1, ...
1934 //if ($username->id && $day==1) {
1935 //var_dump($eventarray);
1936 //}
1937 //var_dump("------ username=".$username->login." for day=".$day);
1938
1939 // We are in a particular day for $username, now we scan all events
1940 foreach ($eventarray as $daykey => $notused) {
1941 $annee = (int) dol_print_date($daykey, '%Y', 'tzuserrel');
1942 $mois = (int) dol_print_date($daykey, '%m', 'tzuserrel');
1943 $jour = (int) dol_print_date($daykey, '%d', 'tzuserrel');
1944 //var_dump("daykey=$daykey day=$day jour=$jour, month=$month mois=$mois, year=$year annee=$annee ".dol_print_date($daykey, 'dayhour', 'gmt'));
1945 //var_dump($notused);
1946
1947 if ($day == $jour && (int) $month == $mois && $year == $annee) { // Is it the day we are looking for when calling function ?
1948 //var_dump("day=$day jour=$jour month=$month mois=$mois year=$year annee=$annee");
1949
1950 // Scan all events for this date
1951 foreach ($eventarray[$daykey] as $index => $event) {
1952 //print 'daykey='.$daykey.'='.dol_print_date($daykey, 'dayhour', 'gmt').' '.$year.'-'.$month.'-'.$day.' -> The event id '.$event->id.' index '.$index.' is open for this daykey '.$annee.'-'.$mois.'-'.$jour."<br>\n";
1953 //var_dump($event);
1954
1955 $keysofuserassigned = array_keys($event->userassigned);
1956
1957 if (!in_array($username->id, $keysofuserassigned)) {
1958 continue; // We discard record if event is from another user than user we want to show
1959 }
1960 //if ($username->id != $event->userownerid) continue; // We discard record if event is from another user than user we want to show
1961
1962 $parameters = array();
1963 $reshook = $hookmanager->executeHooks('formatEvent', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks
1964 if ($reshook < 0) {
1965 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1966 }
1967
1968 // Define $color (Hex string like '0088FF') and $cssclass of event
1969 $color = -1;
1970 $cssclass = '';
1971 $colorindex = -1;
1972
1973 if ($event->type_code == 'HOLIDAY') {
1974 $cssclass = 'family_holiday';
1975 }
1976
1977 if (in_array($user->id, $keysofuserassigned)) {
1978 $cssclass = 'family_mytasks';
1979
1980 if (empty($cacheusers[$event->userownerid])) {
1981 $newuser = new User($db);
1982 $newuser->fetch($event->userownerid);
1983 $cacheusers[$event->userownerid] = $newuser;
1984 }
1985 //var_dump($cacheusers[$event->userownerid]->color);
1986
1987 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
1988 if (!empty($cacheusers[$event->userownerid]->color)) {
1989 $color = $cacheusers[$event->userownerid]->color;
1990 }
1991
1992 if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
1993 $color = $event->type_color;
1994 }
1995 } elseif ($event->type_code == 'ICALEVENT') {
1996 $numical++;
1997 if (!empty($event->icalname)) {
1998 if (!isset($numicals[dol_string_nospecial($event->icalname)])) {
1999 $numicals[dol_string_nospecial($event->icalname)] = 0;
2000 }
2001 $numicals[dol_string_nospecial($event->icalname)]++;
2002 }
2003
2004 $color = $event->icalcolor;
2005 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other unsortable');
2006 } elseif ($event->type_code == 'BIRTHDAY') {
2007 $numbirthday++;
2008 $colorindex = 2;
2009 $cssclass = 'family_birthday unsortable';
2010 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2011 } else {
2012 $numother++;
2013 $color = ($event->icalcolor ? $event->icalcolor : -1);
2014 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other');
2015
2016 if (empty($cacheusers[$event->userownerid])) {
2017 $newuser = new User($db);
2018 $newuser->fetch($event->userownerid);
2019 $cacheusers[$event->userownerid] = $newuser;
2020 }
2021 //var_dump($cacheusers[$event->userownerid]->color);
2022
2023 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
2024 if (!empty($cacheusers[$event->userownerid]->color)) {
2025 $color = $cacheusers[$event->userownerid]->color;
2026 }
2027
2028 if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
2029 $color = $event->type_color;
2030 }
2031 }
2032
2033 if ($color < 0) { // Color was not set on user card. Set color according to color index.
2034 // Define color index if not yet defined
2035 $idusertouse = ($event->userownerid ? $event->userownerid : 0);
2036 if (isset($colorindexused[$idusertouse])) {
2037 $colorindex = $colorindexused[$idusertouse]; // Color already assigned to this user
2038 } else {
2039 $colorindex = $nextindextouse;
2040 $colorindexused[$idusertouse] = $colorindex;
2041 if (!empty($theme_datacolor[$nextindextouse + 1])) {
2042 $nextindextouse++; // Prepare to use next color
2043 }
2044 }
2045 // Define color
2046 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2047 }
2048
2049 // Define all rects with event (cases1 is first quarter hour, cases2 is second quarter hour, cases3 is second thirds hour, cases4 is 4th quarter hour)
2050 for ($h = $begin_h; $h < $end_h; $h++) {
2051 //if ($username->id == 1 && $day==1) print 'h='.$h;
2052 $newcolor = ''; //init
2053 if (empty($event->fulldayevent)) {
2054 $a = dol_mktime((int) $h, 0, 0, $month, $day, $year, 'tzuserrel', 0);
2055 $b = dol_mktime((int) $h, 15, 0, $month, $day, $year, 'tzuserrel', 0);
2056 $b1 = dol_mktime((int) $h, 30, 0, $month, $day, $year, 'tzuserrel', 0);
2057 $b2 = dol_mktime((int) $h, 45, 0, $month, $day, $year, 'tzuserrel', 0);
2058 $c = dol_mktime((int) $h + 1, 0, 0, $month, $day, $year, 'tzuserrel', 0);
2059
2060 $dateendtouse = $event->date_end_in_calendar;
2061 if ($dateendtouse == $event->date_start_in_calendar) {
2062 $dateendtouse++;
2063 }
2064
2065 //print dol_print_date($event->date_start_in_calendar,'dayhour').'-'.dol_print_date($a,'dayhour').'-'.dol_print_date($b,'dayhour').'<br>';
2066 if ($event->date_start_in_calendar < $b && $dateendtouse > $a) {
2067 $busy = $event->transparency;
2068 $cases1[$h][$event->id]['busy'] = $busy;
2069 $cases1[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2070 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2071 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2072 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2073 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2074 $cases1[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2075 } else {
2076 $cases1[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2077 }
2078 }
2079 if ($event->label) {
2080 $cases1[$h][$event->id]['string'] .= ' - '.$event->label;
2081 }
2082 $cases1[$h][$event->id]['typecode'] = $event->type_code;
2083 if ($event->type_code == 'HOLIDAY') {
2084 $cases1[$h][$event->id]['css'] = 'peruser_holiday ';
2085 if (GETPOSTINT('check_holiday')) {
2086 $cases1[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2087 }
2088 } else {
2089 $cases1[$h][$event->id]['color'] = $color;
2090
2091 if ($event->fk_project > 0) {
2092 if (empty($cacheprojects[$event->fk_project])) {
2093 $tmpproj = new Project($db);
2094 $tmpproj->fetch($event->fk_project);
2095 $cacheprojects[$event->fk_project] = $tmpproj;
2096 }
2097 $cases1[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2098 }
2099 if ($event->socid > 0) {
2100 if (empty($cachethirdparties[$event->socid])) {
2101 $tmpthirdparty = new Societe($db);
2102 $tmpthirdparty->fetch($event->socid);
2103 $cachethirdparties[$event->socid] = $tmpthirdparty;
2104 }
2105 $cases1[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2106 }
2107 if ($event->contact_id > 0) {
2108 if (empty($cachecontacts[$event->contact_id])) {
2109 $tmpcontact = new Contact($db);
2110 $tmpcontact->fetch($event->contact_id);
2111 $cachecontacts[$event->contact_id] = $tmpcontact;
2112 }
2113 $cases1[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2114 }
2115 }
2116 }
2117 if ($event->date_start_in_calendar < $b1 && $dateendtouse > $b) {
2118 $busy = $event->transparency;
2119 $cases2[$h][$event->id]['busy'] = $busy;
2120 $cases2[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2121 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2122 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2123 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2124 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2125 $cases2[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2126 } else {
2127 $cases2[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2128 }
2129 }
2130 if ($event->label) {
2131 $cases2[$h][$event->id]['string'] .= ' - '.$event->label;
2132 }
2133 $cases2[$h][$event->id]['typecode'] = $event->type_code;
2134 if ($event->type_code == 'HOLIDAY') {
2135 $cases2[$h][$event->id]['css'] = 'peruser_holiday ';
2136 if (GETPOSTINT('check_holiday')) {
2137 $cases2[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2138 }
2139 } else {
2140 $cases2[$h][$event->id]['color'] = $color;
2141
2142 if ($event->fk_project > 0) {
2143 if (empty($cacheprojects[$event->fk_project])) {
2144 $tmpproj = new Project($db);
2145 $tmpproj->fetch($event->fk_project);
2146 $cacheprojects[$event->fk_project] = $tmpproj;
2147 }
2148 $cases2[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2149 }
2150 if ($event->socid > 0) {
2151 if (empty($cachethirdparties[$event->socid])) {
2152 $tmpthirdparty = new Societe($db);
2153 $tmpthirdparty->fetch($event->socid);
2154 $cachethirdparties[$event->socid] = $tmpthirdparty;
2155 }
2156 $cases2[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2157 }
2158 if ($event->contact_id > 0) {
2159 if (empty($cachecontacts[$event->contact_id])) {
2160 $tmpcontact = new Contact($db);
2161 $tmpcontact->fetch($event->contact_id);
2162 $cachecontacts[$event->contact_id] = $tmpcontact;
2163 }
2164 $cases2[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2165 }
2166 }
2167 }
2168 if ($event->date_start_in_calendar < $b2 && $dateendtouse > $b1) {
2169 $busy = $event->transparency;
2170 $cases3[$h][$event->id]['busy'] = $busy;
2171 $cases3[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2172 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2173 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2174 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2175 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2176 $cases3[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2177 } else {
2178 $cases3[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2179 }
2180 }
2181 if ($event->label) {
2182 $cases3[$h][$event->id]['string'] .= ' - '.$event->label;
2183 }
2184 $cases3[$h][$event->id]['typecode'] = $event->type_code;
2185 if ($event->type_code == 'HOLIDAY') {
2186 $cases3[$h][$event->id]['css'] .= 'peruser_holiday ';
2187 if (GETPOSTINT('check_holiday')) {
2188 $cases3[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2189 }
2190 } else {
2191 $cases3[$h][$event->id]['color'] = $color;
2192
2193 if ($event->fk_project > 0) {
2194 if (empty($cacheprojects[$event->fk_project])) {
2195 $tmpproj = new Project($db);
2196 $tmpproj->fetch($event->fk_project);
2197 $cacheprojects[$event->fk_project] = $tmpproj;
2198 }
2199 $cases3[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2200 }
2201 if ($event->socid > 0) {
2202 if (empty($cachethirdparties[$event->socid])) {
2203 $tmpthirdparty = new Societe($db);
2204 $tmpthirdparty->fetch($event->socid);
2205 $cachethirdparties[$event->socid] = $tmpthirdparty;
2206 }
2207 $cases3[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2208 }
2209 if ($event->contact_id > 0) {
2210 if (empty($cachecontacts[$event->contact_id])) {
2211 $tmpcontact = new Contact($db);
2212 $tmpcontact->fetch($event->contact_id);
2213 $cachecontacts[$event->contact_id] = $tmpcontact;
2214 }
2215 $cases3[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2216 }
2217 }
2218 }
2219 if ($event->date_start_in_calendar < $c && $dateendtouse > $b2) {
2220 $busy = $event->transparency;
2221 $cases4[$h][$event->id]['busy'] = $busy;
2222 $cases4[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2223 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2224 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2225 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2226 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2227 $cases4[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2228 } else {
2229 $cases4[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2230 }
2231 }
2232 if ($event->label) {
2233 $cases4[$h][$event->id]['string'] .= ' - '.$event->label;
2234 }
2235 $cases4[$h][$event->id]['typecode'] = $event->type_code;
2236 if ($event->type_code == 'HOLIDAY') {
2237 $cases4[$h][$event->id]['css'] = 'peruser_holiday ';
2238 if (GETPOSTINT('check_holiday')) {
2239 $cases4[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2240 }
2241 } else {
2242 $cases4[$h][$event->id]['color'] = $color;
2243
2244 if ($event->fk_project > 0) {
2245 if (empty($cacheprojects[$event->fk_project])) {
2246 $tmpproj = new Project($db);
2247 $tmpproj->fetch($event->fk_project);
2248 $cacheprojects[$event->fk_project] = $tmpproj;
2249 }
2250 $cases4[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2251 }
2252 if ($event->socid > 0) {
2253 if (empty($cachethirdparties[$event->socid])) {
2254 $tmpthirdparty = new Societe($db);
2255 $tmpthirdparty->fetch($event->socid);
2256 $cachethirdparties[$event->socid] = $tmpthirdparty;
2257 }
2258 $cases4[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2259 }
2260 if ($event->contact_id > 0) {
2261 if (empty($cachecontacts[$event->contact_id])) {
2262 $tmpcontact = new Contact($db);
2263 $tmpcontact->fetch($event->contact_id);
2264 $cachecontacts[$event->contact_id] = $tmpcontact;
2265 }
2266 $cases4[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2267 }
2268 }
2269 }
2270 } else {
2271 $busy = $event->transparency;
2272 $cases1[$h][$event->id]['busy'] = $busy;
2273 $cases2[$h][$event->id]['busy'] = $busy;
2274 $cases3[$h][$event->id]['busy'] = $busy;
2275 $cases4[$h][$event->id]['busy'] = $busy;
2276 $cases1[$h][$event->id]['string'] = $event->label;
2277 $cases2[$h][$event->id]['string'] = $event->label;
2278 $cases3[$h][$event->id]['string'] = $event->label;
2279 $cases4[$h][$event->id]['string'] = $event->label;
2280 $cases1[$h][$event->id]['typecode'] = $event->type_code;
2281 $cases2[$h][$event->id]['typecode'] = $event->type_code;
2282 $cases3[$h][$event->id]['typecode'] = $event->type_code;
2283 $cases4[$h][$event->id]['typecode'] = $event->type_code;
2284 $cases1[$h][$event->id]['color'] = $color;
2285 $cases2[$h][$event->id]['color'] = $color;
2286 $cases3[$h][$event->id]['color'] = $color;
2287 $cases4[$h][$event->id]['color'] = $color;
2288 $cases1[$h][$event->id]['css'] = '';
2289 $cases2[$h][$event->id]['css'] = '';
2290 $cases3[$h][$event->id]['css'] = '';
2291 $cases4[$h][$event->id]['css'] = '';
2292 }
2293 }
2294 $i++;
2295 }
2296
2297 break; // We found the date we were looking for. No need to search anymore.
2298 }
2299 }
2300
2301 // Now output $casesX from start hour to end hour
2302 for ($h = $begin_h; $h < $end_h; $h++) {
2303 $color1 = '';
2304 $color2 = '';
2305 $color3 = '';
2306 $color4 = '';
2307 $style1 = 'onclickopenref ';
2308 $style2 = 'onclickopenref ';
2309 $style3 = 'onclickopenref ';
2310 $style4 = 'onclickopenref ';
2311 $string1 = '&nbsp;';
2312 $string2 = '&nbsp;';
2313 $string3 = '&nbsp;';
2314 $string4 = '&nbsp;';
2315 $title1 = '';
2316 $title2 = '';
2317 $title3 = '';
2318 $title4 = '';
2319 if (isset($cases1[$h])) {
2320 //$title1.=count($cases1[$h]).' '.(count($cases1[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2321 if (count($cases1[$h]) > 1) {
2322 $title1 .= count($cases1[$h]).' '.(count($cases1[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2323 }
2324
2325 foreach ($cases1[$h] as $id => $ev) {
2326 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2327 $style1 .= ' peruser_busy';
2328 } else {
2329 $style1 .= 'peruser_notbusy ';
2330 }
2331 if (!empty($ev['css'])) {
2332 $style1 .= $ev['css'].' ';
2333 }
2334 }
2335 }
2336 if (isset($cases2[$h])) {
2337 //$title2.=count($cases2[$h]).' '.(count($cases2[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2338 if (count($cases2[$h]) > 1) {
2339 $title2 .= count($cases2[$h]).' '.(count($cases2[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2340 }
2341
2342 foreach ($cases2[$h] as $id => $ev) {
2343 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2344 $style2 .= ' peruser_busy';
2345 } else {
2346 $style2 .= 'peruser_notbusy ';
2347 }
2348 if (!empty($ev['css'])) {
2349 $style2 .= $ev['css'].' ';
2350 }
2351 }
2352 }
2353 if (isset($cases3[$h])) {
2354 //$title3.=count($cases3[$h]).' '.(count($cases3[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2355 if (count($cases3[$h]) > 1) {
2356 $title3 .= count($cases3[$h]).' '.(count($cases3[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2357 }
2358
2359 foreach ($cases3[$h] as $id => $ev) {
2360 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2361 $style3 .= ' peruser_busy';
2362 } else {
2363 $style3 .= 'peruser_notbusy ';
2364 }
2365 if (!empty($ev['css'])) {
2366 $style3 .= $ev['css'].' ';
2367 }
2368 }
2369 }
2370 if (isset($cases4[$h])) {
2371 //$title4.=count($cases3[$h]).' '.(count($cases3[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2372 if (count($cases4[$h]) > 1) {
2373 $title4 .= count($cases4[$h]).' '.(count($cases4[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2374 }
2375
2376 foreach ($cases4[$h] as $id => $ev) {
2377 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2378 $style4 .= ' peruser_busy';
2379 } else {
2380 $style4 .= 'peruser_notbusy ';
2381 }
2382 if (!empty($ev['css'])) {
2383 $style4 .= $ev['css'].' ';
2384 }
2385 }
2386 }
2387
2388 $ids1 = '';
2389 $ids2 = '';
2390 $ids3 = '';
2391 $ids4 = '';
2392 if (!empty($cases1[$h]) && is_array($cases1[$h]) && count($cases1[$h]) && array_keys($cases1[$h])) {
2393 $ids1 = implode(', ', array_keys($cases1[$h]));
2394 }
2395 if (!empty($cases2[$h]) && is_array($cases2[$h]) && count($cases2[$h]) && array_keys($cases2[$h])) {
2396 $ids2 = implode(', ', array_keys($cases2[$h]));
2397 }
2398 if (!empty($cases3[$h]) && is_array($cases3[$h]) && count($cases3[$h]) && array_keys($cases3[$h])) {
2399 $ids3 = implode(',', array_keys($cases3[$h]));
2400 }
2401 if (!empty($cases4[$h]) && is_array($cases4[$h]) && count($cases4[$h]) && array_keys($cases4[$h])) {
2402 $ids4 = implode(',', array_keys($cases4[$h]));
2403 }
2404
2405 if ($h == $begin_h) {
2406 echo '<td class="'.$style.'_peruserleft cal_peruser'.($var ? ' cal_impair '.$style.'_impair' : '').'">';
2407 } else {
2408 echo '<td class="'.$style.' cal_peruser'.($var ? ' cal_impair '.$style.'_impair' : '').'">';
2409 }
2410
2411 // only 1 event in first quarter
2412 $ref1 = 'ref';
2413 if (!empty($cases1[$h]) && is_array($cases1[$h]) && count($cases1[$h]) == 1) {
2414 $output = array_slice($cases1[$h], 0, 1);
2415 if ($output[0]['typecode'] == 'HOLIDAY') {
2416 $ref1 = 'holiday';
2417 $title1 = $langs->trans("Holiday");
2418 } else {
2419 $title1 = $langs->trans("Ref").' '.$ids1.($title1 ? ' - '.$title1 : '');
2420 if ($output[0]['string']) {
2421 $title1 .= ' - '.$output[0]['string'];
2422 }
2423 }
2424 if ($output[0]['color']) {
2425 $color1 = $output[0]['color'];
2426 }
2427 } elseif (!empty($cases1[$h]) && is_array($cases1[$h]) && count($cases1[$h]) > 1) {
2428 $title1 = $langs->trans("Ref").' '.$ids1.($title1 ? ' - '.$title1 : '');
2429 $color1 = '222222';
2430 }
2431
2432 // only 1 event in second quarter
2433 $ref2 = 'ref';
2434 if (!empty($cases2[$h]) && is_array($cases2[$h]) && count($cases2[$h]) == 1) {
2435 $output = array_slice($cases2[$h], 0, 1);
2436 if ($output[0]['typecode'] == 'HOLIDAY') {
2437 $ref2 = 'holiday';
2438 $title2 = $langs->trans("Holiday");
2439 } else {
2440 $title2 = $langs->trans("Ref").' '.$ids2.($title2 ? ' - '.$title2 : '');
2441 if ($output[0]['string']) {
2442 $title2 .= ' - '.$output[0]['string'];
2443 }
2444 }
2445 if ($output[0]['color']) {
2446 $color2 = $output[0]['color'];
2447 }
2448 } elseif (!empty($cases2[$h]) && is_array($cases2[$h]) && count($cases2[$h]) > 1) {
2449 $title2 = $langs->trans("Ref").' '.$ids2.($title2 ? ' - '.$title2 : '');
2450 $color2 = '222222';
2451 }
2452
2453 // only 1 event in third quarter
2454 $ref3 = 'ref';
2455 if (!empty($cases3[$h]) && is_array($cases3[$h]) && count($cases3[$h]) == 1) {
2456 $output = array_slice($cases3[$h], 0, 1);
2457 if ($output[0]['typecode'] == 'HOLIDAY') {
2458 $ref3 = 'holiday';
2459 $title3 = $langs->trans("Holiday");
2460 } else {
2461 $title3 = $langs->trans("Ref").' '.$ids3.($title3 ? ' - '.$title3 : '');
2462 if ($output[0]['string']) {
2463 $title3 .= ' - '.$output[0]['string'];
2464 }
2465 }
2466 if ($output[0]['color']) {
2467 $color3 = $output[0]['color'];
2468 }
2469 } elseif (!empty($cases3[$h]) && is_array($cases3[$h]) && count($cases3[$h]) > 1) {
2470 $title3 = $langs->trans("Ref").' '.$ids3.($title3 ? ' - '.$title3 : '');
2471 $color3 = '222222';
2472 }
2473
2474 // only 1 event in fourth quarter
2475 $ref4 = 'ref';
2476 if (!empty($cases4[$h]) && is_array($cases4[$h]) && count($cases4[$h]) == 1) {
2477 $output = array_slice($cases4[$h], 0, 1);
2478 if ($output[0]['typecode'] == 'HOLIDAY') {
2479 $ref4 = 'holiday';
2480 $title4 = $langs->trans("Holiday");
2481 } else {
2482 $title4 = $langs->trans("Ref").' '.$ids4.($title4 ? ' - '.$title4 : '');
2483 if ($output[0]['string']) {
2484 $title4 .= ' - '.$output[0]['string'];
2485 }
2486 }
2487 if ($output[0]['color']) {
2488 $color4 = $output[0]['color'];
2489 }
2490 } elseif (!empty($cases4[$h]) && is_array($cases4[$h]) && count($cases4[$h]) > 1) {
2491 $title4 = $langs->trans("Ref").' '.$ids4.($title4 ? ' - '.$title4 : '');
2492 $color4 = '222222';
2493 }
2494
2495 print '<table class="nobordernopadding case centpercent">';
2496 print '<tr>';
2497 print '<td ';
2498 if (preg_match('/peruser_notbusy/', $style1)) {
2499 print 'style="border: 1px solid #'.($color1 ? $color1 : "888").' !important" ';
2500 } elseif ($color1) {
2501 print 'style="background: #'.$color1.'; "';
2502 }
2503 print 'class="';
2504 print $style1;
2505 print 'center'.($title1 ? ' classfortooltip' : '').($title1 ? ' cursorpointer' : '').'"';
2506 print 'ref="'.$ref1.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_00_'.($ids1 ? $ids1 : 'none').'"';
2507 print ($title1 ? ' title="'.$title1.'"' : '').'>';
2508 print $string1;
2509 print '</td>';
2510
2511 print '<td ';
2512 if (preg_match('/peruser_notbusy/', $style2)) {
2513 print 'style="border: 1px solid #'.($color2 ? $color2 : "888").' !important" ';
2514 } elseif ($color2) {
2515 print 'style="background: #'.$color2.'; "';
2516 }
2517 print 'class="';
2518 print $style2;
2519 print 'center'.($title2 ? ' classfortooltip' : '').($title2 ? ' cursorpointer' : '').'"';
2520 print ' ref="'.$ref2.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_15_'.($ids2 ? $ids2 : 'none').'"';
2521 print ($title2 ? ' title="'.$title2.'"' : '').'>';
2522 print $string2;
2523 print '</td>';
2524
2525 print '<td ';
2526 if (preg_match('/peruser_notbusy/', $style3)) {
2527 print 'style="border: 1px solid #'.($color3 ? $color3 : "888").' !important" ';
2528 } elseif ($color3) {
2529 print 'style="background: #'.$color3.'; "';
2530 }
2531 print 'class="';
2532 print $style3;
2533 print 'center'.($title3 ? ' classfortooltip' : '').($title3 ? ' cursorpointer' : '').'"';
2534 print ' ref="'.$ref3.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_30_'.($ids3 ? $ids3 : 'none').'"';
2535 print ($title3 ? ' title="'.$title3.'"' : '').'>';
2536 print $string3;
2537 print '</td>';
2538
2539 print '<td ';
2540 if (preg_match('/peruser_notbusy/', $style4)) {
2541 print 'style="border: 1px solid #'.($color4 ? $color4 : "888").' !important" ';
2542 } elseif ($color4) {
2543 print 'style="background: #'.$color4.'; "';
2544 }
2545 print 'class="';
2546 print $style4;
2547 print 'center'.($title4 ? ' classfortooltip' : '').($title4 ? ' cursorpointer' : '').'"';
2548 print ' ref="'.$ref4.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_45_'.($ids4 ? $ids4 : 'none').'"';
2549 print ($title4 ? ' title="'.$title4.'"' : '').'>';
2550 print $string4;
2551 print '</td>';
2552
2553 print '</tr>';
2554 print '</table>';
2555 print '</td>';
2556 }
2557}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
print_actions_filter( $form, $canedit, $status, $year, $month, $day, $showbirthday, $filtera, $filtert, $filtered, $pid, $socid, $action, $showextcals=array(), $actioncode='', $usergroupid=0, $excludetype='', $resourceid=0, $search_categ_cus=0, $search_import_key='')
Show filter form in agenda view.
calendars_prepare_head($param)
Define head array for tabs of agenda setup pages.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
$c
Definition line.php:331
Class to manage agenda events (actions)
Class to manage contact/addresses.
Class to manage generation of HTML components Only common components must be here.
Class to read/parse ICal calendars.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
$theme_datacolor
Definition index.php:1599
$cacheusers
Definition index.php:1597
dol_get_first_hour($date, $gm='tzserver')
Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
Definition date.lib.php:663
dol_get_next_week($day, $week, $month, $year)
Return next week.
Definition date.lib.php:581
dol_get_first_day_week($day, $month, $year, $gm=false)
Return first day of week for a date.
Definition date.lib.php:678
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:603
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:434
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:622
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_string_nospecial($str, $newstr='_', $badcharstoreplace='', $badcharstoremove='', $keepspaces=0)
Clean a string from all punctuation characters to use it as a ref or login.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_sanitizePathName($str, $newstr='_', $unaccent=0, $allowdash=0)
Clean a string to use it as a path name.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolUserString($key, $default='', $tmpuser=null)
Return Dolibarr user constant string value.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition inc.php:426
if(getDolGlobalString( 'TAKEPOS_SHOW_CUSTOMER')) print $langs trans('Date')." left Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right PaymentTypeShortLIQ right SELECT p pos_change as p datep as date
Definition receipt.php:464
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.