dolibarr 23.0.3
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 $event->datep = $db->jdate($obj->date_start) + (empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12) * 60 * 60;
1108 $event->datef = $db->jdate($obj->date_end) + (empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1;
1109 $event->date_start_in_calendar = $event->datep;
1110 $event->date_end_in_calendar = $event->datef;
1111
1112 $event->transparency = 1;
1113
1114 $event->userownerid = $obj->uid; // user id of owner
1115 $event->userassigned = array($obj->uid => array('id' => $obj->uid, 'transparency' => 1));
1116
1117 if ($obj->status == 3) {
1118 // Show no symbol for leave with state "leave approved"
1119 $event->percentage = -1;
1120 } elseif ($obj->status == 2) {
1121 // Show TO-DO symbol for leave with state "leave wait for approval"
1122 $event->percentage = 0;
1123 }
1124
1125
1126 $daycursor = $event->date_start_in_calendar;
1127 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1128 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1129 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1130
1131 $daycursorend = $event->date_end_in_calendar;
1132 $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel');
1133 $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel');
1134 $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel');
1135
1136 // daykey must be date that represent day box in calendar so must be a user time
1137 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1138 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1139 $ifornbofdays = 0;
1140 do {
1141 $ifornbofdays++;
1142
1143 $firstdayofholiday = ($ifornbofdays == 1);
1144 $lastdayofholiday = ($daykeygmt == dol_get_first_hour($event->date_end_in_calendar, 'gmt'));
1145
1146 //var_dump(dol_print_date($daykeygmt, 'dayhour', 'gmt'));
1147
1148 if ((in_array($obj->halfday, array(1, 2)) == 1 && $lastdayofholiday) || (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday)) {
1149 // We create a copy of event because we want tochange the label
1150 $newevent = dol_clone($event, 1);
1151 if (in_array($obj->halfday, array(1, 2)) && $lastdayofholiday) {
1152 $newevent->label .= ' ('.$langs->trans("Morning").')';
1153 } elseif (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday) {
1154 $newevent->label .= ' ('.$langs->trans("Afternoon").')';
1155 }
1156 $eventarray[$daykey][] = $newevent; // We need to use ->gtTypePicto, getXXXon object, so clone must be PHP clone.
1157 } else {
1158 $eventarray[$daykey][] = $event; // We can use the event unchanged
1159 }
1160
1161 $daykey += 60 * 60 * 24;
1162 $daykeygmt += 60 * 60 * 24;
1163 } while ($daykey <= $event->date_end_in_calendar);
1164
1165 $i++;
1166 }
1167 }
1168}
1169
1170// EXTERNAL CALENDAR
1171// Complete $eventarray with external import Ical
1172if (count($listofextcals)) {
1173 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/ical.class.php';
1174
1175 foreach ($listofextcals as $key => $extcal) {
1176 $url = $extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics
1177 $namecal = $extcal['name'];
1178 $offsettz = $extcal['offsettz'];
1179 $colorcal = $extcal['color'];
1180 $buggedfile = $extcal['buggedfile'];
1181
1182 $pathforcachefile = dol_sanitizePathName($conf->user->dir_temp).'/'.dol_sanitizeFileName('extcal_'.$namecal.'_user'.$user->id).'.cache';
1183 //var_dump($pathforcachefile);exit;
1184
1185 $ical = new ICal();
1186 $ical->parse($url, $pathforcachefile, $DELAYFORCACHE);
1187 if ($ical->error) {
1188 // Save error message for extcal
1189 $listofextcals[$key]['error'] = $ical->error;
1190 $s .= '<br><div class="warning">'.dol_escape_htmltag($listofextcals[$key]['name']).': '.$url.'<br>Error message: '.dol_escape_htmltag($ical->error).'</div>';
1191 }
1192
1193 // After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ...
1194 //var_dump($ical->cal); exit;
1195 $icalevents = array();
1196 if (is_array($ical->get_event_list())) {
1197 $icalevents = array_merge($icalevents, $ical->get_event_list()); // Add $ical->cal['VEVENT']
1198 }
1199 if (is_array($ical->get_freebusy_list())) {
1200 $icalevents = array_merge($icalevents, $ical->get_freebusy_list()); // Add $ical->cal['VFREEBUSY']
1201 }
1202
1203 if (count($icalevents) > 0) {
1204 // Duplicate all repeatable events into new entries
1205 $moreicalevents = array();
1206 foreach ($icalevents as $icalevent) {
1207 if (isset($icalevent['RRULE']) && is_array($icalevent['RRULE'])) { //repeatable event
1208 //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow;
1209 //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow-1);
1210 if ($icalevent['DTSTART;VALUE=DATE']) { //fullday event
1211 $datecurstart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1);
1212 $datecurend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day
1213 } elseif (is_array($icalevent['DTSTART']) && !empty($icalevent['DTSTART']['unixtime'])) {
1214 $datecurstart = $icalevent['DTSTART']['unixtime']; // can't be empty
1215 $datecurend = $icalevent['DTEND']['unixtime'];
1216 if (!empty($ical->cal['DAYLIGHT']['DTSTART']) /* && $datecurstart */) {
1217 //var_dump($ical->cal);
1218 $tmpcurstart = $datecurstart;
1219 $tmpcurend = $datecurend;
1220 $tmpdaylightstart = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['DAYLIGHT']['DTSTART'];
1221 $tmpdaylightend = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['STANDARD']['DTSTART'];
1222 //var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']);
1223 // Edit datecurstart and datecurend
1224 if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) {
1225 $datecurstart -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36;
1226 } else {
1227 $datecurstart -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36;
1228 }
1229 if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) {
1230 $datecurend -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36;
1231 } else {
1232 $datecurend -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36;
1233 }
1234 }
1235 // datecurstart and datecurend are now GMT date
1236 //var_dump($datecurstart); var_dump($datecurend); exit;
1237 } else {
1238 // Not a recognized record
1239 dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR);
1240 continue;
1241 }
1242 //print 'xx'.$datecurstart;exit;
1243
1244 $interval = (empty($icalevent['RRULE']['INTERVAL']) ? 1 : $icalevent['RRULE']['INTERVAL']);
1245 $until = empty($icalevent['RRULE']['UNTIL']) ? 0 : dol_stringtotime($icalevent['RRULE']['UNTIL'], 1);
1246 $maxrepeat = empty($icalevent['RRULE']['COUNT']) ? 0 : $icalevent['RRULE']['COUNT'];
1247 if ($until && ($until + ($datecurend - $datecurstart)) < $firstdaytoshow) {
1248 continue; // We discard repeatable event that end before start date to show
1249 }
1250 if ($datecurstart >= $lastdaytoshow) {
1251 continue; // We discard repeatable event that start after end date to show
1252 }
1253
1254 $numofevent = 0;
1255 while (($datecurstart < $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat))) {
1256 if ($datecurend >= $firstdaytoshow) { // We add event
1257 $newevent = $icalevent;
1258 unset($newevent['RRULE']);
1259 if ($icalevent['DTSTART;VALUE=DATE']) {
1260 $newevent['DTSTART;VALUE=DATE'] = dol_print_date($datecurstart, '%Y%m%d');
1261 $newevent['DTEND;VALUE=DATE'] = dol_print_date($datecurend + 1, '%Y%m%d');
1262 } else {
1263 $newevent['DTSTART'] = $datecurstart;
1264 $newevent['DTEND'] = $datecurend;
1265 }
1266 $moreicalevents[] = $newevent;
1267 }
1268 // Jump on next occurrence
1269 $numofevent++;
1270 $savdatecurstart = $datecurstart;
1271 if ($icalevent['RRULE']['FREQ'] == 'DAILY') {
1272 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'd');
1273 $datecurend = dol_time_plus_duree($datecurend, $interval, 'd');
1274 }
1275 if ($icalevent['RRULE']['FREQ'] == 'WEEKLY') {
1276 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'w');
1277 $datecurend = dol_time_plus_duree($datecurend, $interval, 'w');
1278 } elseif ($icalevent['RRULE']['FREQ'] == 'MONTHLY') {
1279 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'm');
1280 $datecurend = dol_time_plus_duree($datecurend, $interval, 'm');
1281 } elseif ($icalevent['RRULE']['FREQ'] == 'YEARLY') {
1282 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'y');
1283 $datecurend = dol_time_plus_duree($datecurend, $interval, 'y');
1284 }
1285 // Test to avoid infinite loop ($datecurstart must increase)
1286 if ($savdatecurstart >= $datecurstart) {
1287 dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR);
1288 $datecurstart += 3600 * 24 * 7;
1289 $datecurend += 3600 * 24 * 7;
1290 }
1291 }
1292 }
1293 }
1294 $icalevents = array_merge($icalevents, $moreicalevents);
1295
1296 // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray
1297 foreach ($icalevents as $icalevent) {
1298 //var_dump($icalevent);
1299
1300 //print $icalevent['SUMMARY'].'->';
1301 //var_dump($icalevent);exit;
1302 if (!empty($icalevent['RRULE'])) {
1303 continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule.
1304 }
1305
1306 // Create a new object action
1307 $event = new ActionComm($db);
1308 $addevent = false;
1309 $datestart = null;
1310 $dateend = null;
1311 if (isset($icalevent['DTSTART;VALUE=DATE'])) { // fullday event
1312 // For full day events, date are also GMT but they won't but converted using tz during output
1313 $datestart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1);
1314 if (empty($icalevent['DTEND;VALUE=DATE'])) {
1315 $dateend = $datestart + 86400 - 1;
1316 } else {
1317 $dateend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day
1318 }
1319 //print 'x'.$datestart.'-'.$dateend;exit;
1320 //print dol_print_date($dateend,'dayhour','gmt');
1321 $event->fulldayevent = 1;
1322 $addevent = true;
1323 } elseif (!is_array($icalevent['DTSTART'])) { // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch)
1324 $datestart = $icalevent['DTSTART'];
1325 $dateend = empty($icalevent['DTEND']) ? $datestart : $icalevent['DTEND'];
1326
1327 $datestart += +($offsettz * 3600);
1328 $dateend += +($offsettz * 3600);
1329
1330 $addevent = true;
1331 //var_dump($offsettz);
1332 //var_dump(dol_print_date($datestart, 'dayhour', 'gmt'));
1333 } elseif (isset($icalevent['DTSTART']['unixtime'])) { // File contains a local timezone + a TZ (for example when using bluemind)
1334 $datestart = $icalevent['DTSTART']['unixtime'];
1335 $dateend = $icalevent['DTEND']['unixtime'];
1336
1337 $datestart += +($offsettz * 3600);
1338 $dateend += +($offsettz * 3600);
1339
1340 // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight'
1341 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
1342 // TODO
1343 }
1344 // $buggedfile is set to uselocalandtzdaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtzdaylight' (for example with bluemind)
1345 if ($buggedfile === 'uselocalandtzdaylight') { // unixtime is a local date that does take daylight into account, TZID is +2 for example for 'Europe/Paris' in summer
1346 $localtzs = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTSTART']['TZID']));
1347 $localtze = new DateTimeZone(preg_replace('/"/', '', $icalevent['DTEND']['TZID']));
1348 $localdts = new DateTime(dol_print_date($datestart, 'dayrfc', 'gmt'), $localtzs);
1349 $localdte = new DateTime(dol_print_date($dateend, 'dayrfc', 'gmt'), $localtze);
1350 $tmps = -1 * $localtzs->getOffset($localdts);
1351 $tmpe = -1 * $localtze->getOffset($localdte);
1352 $datestart += $tmps;
1353 $dateend += $tmpe;
1354 //var_dump($datestart);
1355 }
1356 $addevent = true;
1357 }
1358
1359 if ($addevent && $datestart !== null && $dateend !== null) {
1360 $event->id = $icalevent['UID'];
1361 $event->ref = (string) $event->id;
1362 $userstatic = new User($db);
1363 $userId = $userstatic->findUserIdByEmail($namecal);
1364 if (!empty($userId) && $userId > 0) {
1365 $event->userassigned[$userId] = [
1366 'id' => $userId,
1367 'transparency' => 1,
1368 ];
1369 $event->percentage = -1;
1370 }
1371
1372 $event->type_code = "ICALEVENT";
1373 $event->type_label = $namecal;
1374 $event->type_color = $colorcal;
1375 $event->type = 'icalevent';
1376 $event->type_picto = 'rss';
1377
1378 $event->icalname = $namecal;
1379 $event->icalcolor = $colorcal;
1380 $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.
1381 $event->datep = $datestart + $usertime;
1382 $event->datef = $dateend + $usertime;
1383
1384 if (isset($icalevent['SUMMARY']) && $icalevent['SUMMARY']) {
1385 $event->label = dol_string_nohtmltag($icalevent['SUMMARY']);
1386 } elseif (isset($icalevent['DESCRIPTION']) && $icalevent['DESCRIPTION']) {
1387 $event->label = dol_nl2br(dol_string_nohtmltag($icalevent['DESCRIPTION']), 1);
1388 } else {
1389 $event->label = $langs->trans("ExtSiteNoLabel");
1390 }
1391
1392 // Priority (see https://www.kanzaki.com/docs/ical/priority.html)
1393 // LOW = 0 to 4
1394 // MEDIUM = 5
1395 // HIGH = 6 to 9
1396 if (!empty($icalevent['PRIORITY'])) {
1397 $event->priority = $icalevent['PRIORITY'];
1398 }
1399
1400 // Transparency (see https://www.kanzaki.com/docs/ical/transp.html)
1401 if (!empty($icalevent['TRANSP'])) {
1402 if ($icalevent['TRANSP'] == "TRANSPARENT") {
1403 $event->transparency = 0; // 0 = available / free
1404 }
1405 if ($icalevent['TRANSP'] == "OPAQUE") {
1406 $event->transparency = 1; // 1 = busy
1407 }
1408
1409 // TODO: MS outlook states
1410 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:TRANSPARENT => Available / Free
1411 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:OPAQUE => Work another place
1412 // X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE + TRANSP:OPAQUE => With reservations
1413 // X-MICROSOFT-CDO-BUSYSTATUS:BUSY + TRANSP:OPAQUE => Busy
1414 // X-MICROSOFT-CDO-BUSYSTATUS:OOF + TRANSP:OPAQUE => Away from the office / off-site
1415 }
1416
1417 if (!empty($icalevent['LOCATION'])) {
1418 $event->location = $icalevent['LOCATION'];
1419 }
1420
1421 $event->date_start_in_calendar = $event->datep;
1422
1423 if ($event->datef != '' && $event->datef >= $event->datep) {
1424 $event->date_end_in_calendar = $event->datef;
1425 } else {
1426 $event->date_end_in_calendar = $event->datep;
1427 }
1428
1429 // Add event into $eventarray if date range are ok.
1430 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) {
1431 //print 'x'.$datestart.'-'.$dateend;exit;
1432 //print 'x'.$datestart.'-'.$dateend;exit;
1433 //print 'x'.$datestart.'-'.$dateend;exit;
1434 // This record is out of visible range
1435 } else {
1436 if ($event->date_start_in_calendar < $firstdaytoshow) {
1437 $event->date_start_in_calendar = $firstdaytoshow;
1438 }
1439 if ($event->date_end_in_calendar >= $lastdaytoshow) {
1440 $event->date_end_in_calendar = ($lastdaytoshow - 1);
1441 }
1442
1443 // Add an entry in actionarray for each day
1444 $daycursor = $event->date_start_in_calendar;
1445 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1446 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1447 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1448
1449 // Loop on each day covered by action to prepare an index to show on calendar
1450 $loop = true;
1451 $j = 0;
1452 // daykey must be date that represent day box in calendar so must be a user time
1453 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1454 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1455 do {
1456 //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').' ';
1457 $eventarray[$daykey][] = $event;
1458 $daykey += 60 * 60 * 24;
1459 $daykeygmt += 60 * 60 * 24; // Add one day
1460 if (($event->fulldayevent ? $daykeygmt : $daykey) > $event->date_end_in_calendar) {
1461 $loop = false;
1462 }
1463 } while ($loop);
1464 }
1465 }
1466 }
1467 }
1468 }
1469}
1470
1471// Complete $eventarray with events coming from external module
1472$parameters = array();
1473$object = null;
1474$reshook = $hookmanager->executeHooks('getCalendarEvents', $parameters, $object, $action);
1475if (!empty($hookmanager->resArray['eventarray'])) {
1476 foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) {
1477 if (!isset($eventarray[$keyDate])) {
1478 $eventarray[$keyDate] = array();
1479 }
1480 $eventarray[$keyDate] = array_merge($eventarray[$keyDate], $events);
1481 }
1482}
1483
1484// Sort events
1485/*
1486foreach ($eventarray as $keyDate => &$dateeventarray) {
1487 usort($dateeventarray, 'sort_events_by_date');
1488}
1489*/
1490
1491$maxnbofchar = 18;
1492$cachethirdparties = array();
1493$cachecontacts = array();
1494$cacheusers = array();
1495// default values
1496$theme_datacolor = array(
1497 array(137, 86, 161),
1498 array(60, 147, 183),
1499 array(250, 190, 80),
1500 array(80, 166, 90),
1501 array(190, 190, 100),
1502 array(91, 115, 247),
1503 array(140, 140, 220),
1504 array(190, 120, 120),
1505 array(115, 125, 150),
1506 array(100, 170, 20),
1507 array(150, 135, 125),
1508 array(85, 135, 150),
1509 array(150, 135, 80),
1510 array(150, 80, 150)
1511);
1512// Define theme_datacolor array
1513$color_file = DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/theme_vars.inc.php";
1514if (is_readable($color_file)) {
1515 include $color_file;
1516 global $theme_datacolor;
1517}
1518
1519$massactionbutton = '';
1520
1521$num = 0;
1522
1523print_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);
1524
1525$link = '';
1526
1527// Show div with list of calendars
1528print $s;
1529
1530// Top filters
1531print '<div class="liste_titre liste_titre_bydiv centpercent">';
1532print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, '', (string) $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid, $search_categ_cus);
1533print '</div>';
1534
1535
1536$newparam = $param; // newparam is for birthday links
1537$newparam = preg_replace('/showbirthday=/i', 'showbirthday_=', $newparam); // To avoid replacement when replace day= is done
1538$newparam = preg_replace('/mode=show_month&?/i', '', $newparam);
1539$newparam = preg_replace('/mode=show_week&?/i', '', $newparam);
1540$newparam = preg_replace('/day=[0-9]+&?/i', '', $newparam);
1541$newparam = preg_replace('/month=[0-9]+&?/i', '', $newparam);
1542$newparam = preg_replace('/year=[0-9]+&?/i', '', $newparam);
1543$newparam = preg_replace('/viewweek=[0-9]+&?/i', '', $newparam);
1544$newparam = preg_replace('/showbirthday_=/i', 'showbirthday=', $newparam); // Restore correct parameter
1545$newparam .= '&viewweek=1';
1546
1547echo '<input type="hidden" name="actionmove" value="mupdate">';
1548echo '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($_SERVER['PHP_SELF']).'?'.dol_escape_htmltag($_SERVER['QUERY_STRING']).'">';
1549echo '<input type="hidden" name="newdate" id="newdate">';
1550
1551
1552// Line header with list of days
1553
1554//print "begin_d=".$begin_d." end_d=".$end_d;
1555
1556$currentdaytoshow = $firstdaytoshow;
1557echo '<div class="div-table-responsive">';
1558//print dol_print_date($currentdaytoshow, 'dayhour', 'gmt');
1559
1560$colorsbytype = array();
1561
1562while ($currentdaytoshow < $lastdaytoshow) {
1563 echo '<table class="centpercent noborder nocellnopadd cal_month cal_peruser listwithfilterbefore">';
1564
1565 echo '<tr class="liste_titre">';
1566 echo '<td class="nopaddingtopimp nopaddingbottomimp nowraponsmartphone">';
1567
1568 if ($canedit /* && $mode == 'show_peruser' */) { // mode is forced to show_peruser
1569 // Filter on days
1570 print '<span class="hideonsmartphone" title="'.$langs->trans("VisibleDaysRange").'">';
1571 print img_picto('', 'clock', 'class="fawidth30 inline-block marginleftonly"');
1572 print $langs->trans("DaysOfWeek").'</span>';
1573 print "\n";
1574 print '<div class="ui-grid-a inline-block"><div class="ui-block-a nowraponall">';
1575 print '<input type="number" class="shortbis" name="begin_d" value="'.$begin_d.'" min="1" max="7">';
1576 if (empty($conf->dol_use_jmobile)) {
1577 print ' - ';
1578 } else {
1579 print '</div><div class="ui-block-b">';
1580 }
1581 print '<input type="number" class="shortbis" name="end_d" value="'.$end_d.'" min="1" max="7">';
1582 print '</div></div>';
1583 }
1584
1585 print '</td>';
1586 $i = 0; // 0 = sunday,
1587 while ($i < 7) {
1588 if (($i + 1) < $begin_d || ($i + 1) > $end_d) {
1589 $i++;
1590 continue;
1591 }
1592 echo '<td align="center" colspan="'.($end_h - $begin_h).'">';
1593 echo '<span class="bold spandayofweek">'.$langs->trans("Day".(($i + getDolGlobalInt('MAIN_START_WEEK', 1)) % 7)).'</span>';
1594 print "<br>";
1595 if ($i) {
1596 $valtoshow = dol_time_plus_duree($currentdaytoshow, $i, 'd');
1597 } else {
1598 $valtoshow = $currentdaytoshow;
1599 }
1600 if (dol_print_date($valtoshow, '%Y%m%d') == dol_print_date(dol_now(), '%Y%m%d')) {
1601 echo '<span class="badgeneutral">';
1602 }
1603 print dol_print_date($valtoshow, 'dayreduceformat', 'tzuserrel');
1604 if (dol_print_date($valtoshow, '%Y%m%d') == dol_print_date(dol_now(), '%Y%m%d')) {
1605 echo '</span>';
1606 }
1607 echo "</td>\n";
1608 $i++;
1609 }
1610 echo "</tr>\n";
1611
1612 echo '<tr class="liste_titre">';
1613 echo '<td>';
1614
1615 // Filter on hours
1616 print '<span class="hideonsmartphone" title="'.$langs->trans("VisibleTimeRange").'">';
1617 print img_picto('', 'clock', 'class="fawidth30 inline-block marginleftonly"');
1618 print $langs->trans("Hours").'</span>';
1619 print "\n";
1620 print '<div class="ui-grid-a inline-block"><div class="ui-block-a nowraponall">';
1621 print '<input type="number" class="shortbis" name="begin_h" value="'.$begin_h.'" min="0" max="23">';
1622 if (empty($conf->dol_use_jmobile)) {
1623 print ' - ';
1624 } else {
1625 print '</div><div class="ui-block-b">';
1626 }
1627 print '<input type="number" class="shortbis" name="end_h" value="'.$end_h.'" min="1" max="24">';
1628 if (empty($conf->dol_use_jmobile)) {
1629 print ' '.$langs->trans("HourShort");
1630 }
1631 print '</div></div>';
1632
1633 echo '</td>';
1634 $i = 0;
1635 while ($i < 7) {
1636 if (($i + 1) < $begin_d || ($i + 1) > $end_d) {
1637 $i++;
1638 continue;
1639 }
1640 for ($h = $begin_h; $h < $end_h; $h++) {
1641 echo '<td class="center">';
1642 print '<small style="font-family: courier">'.sprintf("%02d", $h).'</small>';
1643 print "</td>";
1644 }
1645 echo "</td>\n";
1646 $i++;
1647 }
1648 echo "</tr>\n";
1649
1650
1651 // Define $usernames
1652 $usernames = array(); //init
1653 $usernamesid = array();
1654 /* Use this to have list of users only if users have events */
1655 if (getDolGlobalString('AGENDA_SHOWOWNERONLY_ONPERUSERVIEW')) {
1656 foreach ($eventarray as $daykey => $notused) {
1657 // Get all assigned users for each event
1658 foreach ($eventarray[$daykey] as $index => $event) {
1659 $event->fetch_userassigned();
1660 $listofuserid = $event->userassigned;
1661 foreach ($listofuserid as $userid => $tmp) {
1662 if (!in_array($userid, $usernamesid)) {
1663 $usernamesid[$userid] = $userid;
1664 }
1665 }
1666 }
1667 }
1668 } else {
1669 /* Use this list to have lines of all users to show */
1670 $sql = "SELECT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity";
1671 $sql .= " FROM ".$db->prefix()."user as u";
1672 if (isModEnabled('multicompany') && getDolGlobalInt('MULTICOMPANY_TRANSVERSE_MODE')) {
1673 $sql .= " WHERE u.rowid IN (";
1674 $sql .= " SELECT ug.fk_user FROM ".$db->prefix()."usergroup_user as ug";
1675 $sql .= " WHERE ug.entity IN (".getEntity('usergroup').")";
1676 if ($usergroup > 0) {
1677 $sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
1678 }
1679 $sql .= ")";
1680 } else {
1681 if ($usergroup > 0) {
1682 $sql .= " LEFT JOIN ".$db->prefix()."usergroup_user as ug ON u.rowid = ug.fk_user";
1683 }
1684 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1685 if ($usergroup > 0) {
1686 $sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
1687 }
1688 }
1689 $sql .= " AND u.statut = 1";
1690 if ($filtert > 0) {
1691 $sql .= " AND u.rowid = ".((int) $filtert);
1692 }
1693 if ($usergroup > 0) {
1694 $sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
1695 }
1696 if ($user->socid > 0) {
1697 // External users should see only contacts of their company
1698 $sql .= " AND u.fk_soc = ".((int) $user->socid);
1699 }
1700 // Filter on users in hierarchy
1701 if (!$canedit || $filtert == '-3') { // If we can't read event of others
1702 if (!$user->hasRight('user', 'user', 'lire') || $filtert == '-3') {
1703 $usersInHierarchy = $user->getAllChildIds(1);
1704 $sql .= " AND u.rowid IN (".$db->sanitize(implode(',', $usersInHierarchy)).")";
1705 }
1706 }
1707
1708 //print $sql;
1709 $resql = $db->query($sql);
1710 if ($resql) {
1711 $num = $db->num_rows($resql);
1712 $i = 0;
1713 if ($num) {
1714 while ($i < $num) {
1715 $obj = $db->fetch_object($resql);
1716 $usernamesid[$obj->rowid] = $obj->rowid;
1717 $i++;
1718 }
1719 }
1720 } else {
1721 dol_print_error($db);
1722 }
1723 }
1724 //var_dump($usernamesid);
1725 foreach ($usernamesid as $id) {
1726 $tmpuser = new User($db);
1727 $result = $tmpuser->fetch($id);
1728 $usernames[] = $tmpuser;
1729 }
1730
1731 // Load array of colors by type
1732 $labelbytype = array();
1733 $sql = "SELECT code, color, libelle as label FROM ".MAIN_DB_PREFIX."c_actioncomm ORDER BY position";
1734 $resql = $db->query($sql);
1735 while ($obj = $db->fetch_object($resql)) {
1736 $colorsbytype[$obj->code] = $obj->color;
1737 $labelbytype[$obj->code] = $obj->label;
1738 }
1739
1740 // Loop on each user to show calendar
1741 $todayarray = dol_getdate($now, true);
1742 $sav = $tmpday;
1743 $showheader = true;
1744 $var = false;
1745 foreach ($usernames as $username) {
1746 //if ($username->login != 'admin') continue;
1747
1748 $var = !$var;
1749
1750 echo "<tr>";
1751 echo '<td class="tdoverflowmax100 cal_current_month cal_peruserviewname'.($var ? ' cal_impair' : '').' nopaddingtopimp nopaddingbottomimp noheightimp">';
1752 print '<span class="paddingrightimp">';
1753 print $username->getNomUrl(-1, '', 0, 0, 20, 1, '', 'paddingleft');
1754 print '</span>';
1755 print '</td>';
1756 $tmpday = $sav;
1757
1758 // Lopp on each day of week
1759 $i = 0;
1760 for ($iter_day = 0; $iter_day < 8; $iter_day++) {
1761 if (($i + 1) < $begin_d || ($i + 1) > $end_d) {
1762 $i++;
1763 continue;
1764 }
1765
1766 // Show days of the current week
1767 $curtime = dol_time_plus_duree($currentdaytoshow, $iter_day, 'd');
1768 // $curtime is a gmt time, but we want the day, month, year in user TZ
1769 $tmpday = (int) dol_print_date($curtime, "%d", "tzuserrel");
1770 $tmpmonth = (int) dol_print_date($curtime, "%m", "tzuserrel");
1771 $tmpyear = (int) dol_print_date($curtime, "%Y", "tzuserrel");
1772 //var_dump($curtime.' '.$tmpday.' '.$tmpmonth.' '.$tmpyear);
1773
1774 $style = 'cal_current_month';
1775 if ($iter_day == 6) {
1776 $style .= ' cal_other_month';
1777 }
1778 $today = 0;
1779 if ($todayarray['mday'] == $tmpday && $todayarray['mon'] == $tmpmonth && $todayarray['year'] == $tmpyear) {
1780 $today = 1;
1781 }
1782 if ($today) {
1783 $style = 'cal_today_peruser';
1784 }
1785
1786 show_day_events2($username, $tmpday, $tmpmonth, $tmpyear, 0, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, $showheader, $colorsbytype, $var);
1787
1788 $i++;
1789 }
1790 echo "</tr>\n";
1791 $showheader = false;
1792 }
1793
1794 echo "</table>\n";
1795 echo "<br>";
1796
1797 $currentdaytoshow = dol_time_plus_duree($currentdaytoshow, 7, 'd');
1798}
1799
1800echo '</div>';
1801
1802if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
1803 $langs->load("commercial");
1804 print '<br>'.$langs->trans("Legend").': <br>';
1805 foreach ($colorsbytype as $code => $color) {
1806 if ($color) {
1807 print '<div style="float: left; padding: 2px; margin-right: 6px;"><div style="background: #'.$color.'; width:16px; float: left; margin-right: 4px;">&nbsp;</div>';
1808 print $langs->trans("Action".$code) != "Action".$code ? $langs->trans("Action".$code) : $labelbytype[$code];
1809 //print $code;
1810 print '</div>';
1811 }
1812 }
1813 //$color=sprintf("%02x%02x%02x",$theme_datacolor[0][0],$theme_datacolor[0][1],$theme_datacolor[0][2]);
1814 print '<div style="float: left; padding: 2px; margin-right: 6px;"><div class="peruser_busy" style="width:16px; float: left; margin-right: 4px;">&nbsp;</div>';
1815 print $langs->trans("Other");
1816 print '</div>';
1817 /* TODO Show this if at least one cumulated event
1818 print '<div style="float: left; padding: 2px; margin-right: 6px;"><div style="background: #222222; width:16px; float: left; margin-right: 4px;">&nbsp;</div>';
1819 print $langs->trans("SeveralEvents");
1820 print '</div>';
1821 */
1822}
1823
1824print "\n".'</form>';
1825
1826print "\n";
1827
1828// Add js code to manage click on a box
1829print '<script type="text/javascript">
1830jQuery(document).ready(function() {
1831 jQuery(".onclickopenref").click(function() {
1832 var ref=$(this).attr(\'ref\');
1833 var res = ref.split("_");
1834 var type = res[0];
1835 var userid = res[1];
1836 var year = res[2];
1837 var month = res[3];
1838 var day = res[4];
1839 var hour = res[5];
1840 var min = res[6];
1841 var ids = res[7];
1842
1843 console.log("We click on a class onclickopenref in page peruser with ref="+ref+" type="+type);
1844
1845 if (ids == \'none\') /* No event */
1846 {
1847 /* alert(\'no event\'); */
1848 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 : '')).'"
1849 window.location.href = url;
1850 }
1851 else if (ids.indexOf(",") > -1) /* There is several events */
1852 {
1853 /* alert(\'several events\'); */
1854 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;
1855 window.location.href = url;
1856 } else { /* One event */
1857 /* alert(\'one event\'); */
1858 if (type == \'holiday\') {
1859 url = "'.DOL_URL_ROOT.'/holiday/card.php?id="+ids
1860 } else {
1861 url = "'.DOL_URL_ROOT.'/comm/action/card.php?action=view&id="+ids
1862 }
1863 window.location.href = url;
1864 }
1865 });
1866});
1867</script>';
1868
1869// End of page
1870llxFooter();
1871$db->close();
1872
1873
1874
1875
1896function 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)
1897{
1898 global $db;
1899 global $user, $conf, $langs, $hookmanager, $action;
1900 global $filter, $filtert, $status, $actioncode; // Filters used into search form
1901 global $theme_datacolor; // Array with a list of different we can use (come from theme)
1902 global $cachethirdparties, $cachecontacts, $cacheusers, $cacheprojects, $colorindexused;
1903 global $begin_h, $end_h;
1904
1905 $cases1 = array(); // Color first half hour
1906 $cases2 = array(); // Color second half hour
1907 $cases3 = array(); // Color third half hour
1908 $cases4 = array(); // Color 4th half hour
1909
1916 '
1917 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases1
1918 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases2
1919 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases3
1920 @phan-var-force array<int,array<int,array<string,string|int|bool>>> $cases4
1921 ';
1922
1923 $i = 0;
1924 $numother = 0;
1925 $numbirthday = 0;
1926 $numical = 0;
1927 $numicals = array();
1928 //$ymd = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day);
1929
1930 $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0
1931 $nextindextouse = count($colorindexused); // At first run this is 0, so first user has 0, next 1, ...
1932 //if ($username->id && $day==1) {
1933 //var_dump($eventarray);
1934 //}
1935 //var_dump("------ username=".$username->login." for day=".$day);
1936
1937 // We are in a particular day for $username, now we scan all events
1938 foreach ($eventarray as $daykey => $notused) {
1939 $annee = (int) dol_print_date($daykey, '%Y', 'tzuserrel');
1940 $mois = (int) dol_print_date($daykey, '%m', 'tzuserrel');
1941 $jour = (int) dol_print_date($daykey, '%d', 'tzuserrel');
1942 //var_dump("daykey=$daykey day=$day jour=$jour, month=$month mois=$mois, year=$year annee=$annee ".dol_print_date($daykey, 'dayhour', 'gmt'));
1943 //var_dump($notused);
1944
1945 if ($day == $jour && (int) $month == $mois && $year == $annee) { // Is it the day we are looking for when calling function ?
1946 //var_dump("day=$day jour=$jour month=$month mois=$mois year=$year annee=$annee");
1947
1948 // Scan all events for this date
1949 foreach ($eventarray[$daykey] as $index => $event) {
1950 //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";
1951 //var_dump($event);
1952
1953 $keysofuserassigned = array_keys($event->userassigned);
1954
1955 if (!in_array($username->id, $keysofuserassigned)) {
1956 continue; // We discard record if event is from another user than user we want to show
1957 }
1958 //if ($username->id != $event->userownerid) continue; // We discard record if event is from another user than user we want to show
1959
1960 $parameters = array();
1961 $reshook = $hookmanager->executeHooks('formatEvent', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks
1962 if ($reshook < 0) {
1963 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1964 }
1965
1966 // Define $color (Hex string like '0088FF') and $cssclass of event
1967 $color = -1;
1968 $cssclass = '';
1969 $colorindex = -1;
1970
1971 if ($event->type_code == 'HOLIDAY') {
1972 $cssclass = 'family_holiday';
1973 }
1974
1975 if (in_array($user->id, $keysofuserassigned)) {
1976 $cssclass = 'family_mytasks';
1977
1978 if (empty($cacheusers[$event->userownerid])) {
1979 $newuser = new User($db);
1980 $newuser->fetch($event->userownerid);
1981 $cacheusers[$event->userownerid] = $newuser;
1982 }
1983 //var_dump($cacheusers[$event->userownerid]->color);
1984
1985 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
1986 if (!empty($cacheusers[$event->userownerid]->color)) {
1987 $color = $cacheusers[$event->userownerid]->color;
1988 }
1989
1990 if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
1991 $color = $event->type_color;
1992 }
1993 } elseif ($event->type_code == 'ICALEVENT') {
1994 $numical++;
1995 if (!empty($event->icalname)) {
1996 if (!isset($numicals[dol_string_nospecial($event->icalname)])) {
1997 $numicals[dol_string_nospecial($event->icalname)] = 0;
1998 }
1999 $numicals[dol_string_nospecial($event->icalname)]++;
2000 }
2001
2002 $color = $event->icalcolor;
2003 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other unsortable');
2004 } elseif ($event->type_code == 'BIRTHDAY') {
2005 $numbirthday++;
2006 $colorindex = 2;
2007 $cssclass = 'family_birthday unsortable';
2008 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2009 } else {
2010 $numother++;
2011 $color = ($event->icalcolor ? $event->icalcolor : -1);
2012 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other');
2013
2014 if (empty($cacheusers[$event->userownerid])) {
2015 $newuser = new User($db);
2016 $newuser->fetch($event->userownerid);
2017 $cacheusers[$event->userownerid] = $newuser;
2018 }
2019 //var_dump($cacheusers[$event->userownerid]->color);
2020
2021 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
2022 if (!empty($cacheusers[$event->userownerid]->color)) {
2023 $color = $cacheusers[$event->userownerid]->color;
2024 }
2025
2026 if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
2027 $color = $event->type_color;
2028 }
2029 }
2030
2031 if ($color < 0) { // Color was not set on user card. Set color according to color index.
2032 // Define color index if not yet defined
2033 $idusertouse = ($event->userownerid ? $event->userownerid : 0);
2034 if (isset($colorindexused[$idusertouse])) {
2035 $colorindex = $colorindexused[$idusertouse]; // Color already assigned to this user
2036 } else {
2037 $colorindex = $nextindextouse;
2038 $colorindexused[$idusertouse] = $colorindex;
2039 if (!empty($theme_datacolor[$nextindextouse + 1])) {
2040 $nextindextouse++; // Prepare to use next color
2041 }
2042 }
2043 // Define color
2044 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2045 }
2046
2047 // 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)
2048 for ($h = $begin_h; $h < $end_h; $h++) {
2049 //if ($username->id == 1 && $day==1) print 'h='.$h;
2050 $newcolor = ''; //init
2051 if (empty($event->fulldayevent)) {
2052 $a = dol_mktime((int) $h, 0, 0, $month, $day, $year, 'tzuserrel', 0);
2053 $b = dol_mktime((int) $h, 15, 0, $month, $day, $year, 'tzuserrel', 0);
2054 $b1 = dol_mktime((int) $h, 30, 0, $month, $day, $year, 'tzuserrel', 0);
2055 $b2 = dol_mktime((int) $h, 45, 0, $month, $day, $year, 'tzuserrel', 0);
2056 $c = dol_mktime((int) $h + 1, 0, 0, $month, $day, $year, 'tzuserrel', 0);
2057
2058 $dateendtouse = $event->date_end_in_calendar;
2059 if ($dateendtouse == $event->date_start_in_calendar) {
2060 $dateendtouse++;
2061 }
2062
2063 //print dol_print_date($event->date_start_in_calendar,'dayhour').'-'.dol_print_date($a,'dayhour').'-'.dol_print_date($b,'dayhour').'<br>';
2064 if ($event->date_start_in_calendar < $b && $dateendtouse > $a) {
2065 $busy = $event->transparency;
2066 $cases1[$h][$event->id]['busy'] = $busy;
2067 $cases1[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2068 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2069 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2070 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2071 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2072 $cases1[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2073 } else {
2074 $cases1[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2075 }
2076 }
2077 if ($event->label) {
2078 $cases1[$h][$event->id]['string'] .= ' - '.$event->label;
2079 }
2080 $cases1[$h][$event->id]['typecode'] = $event->type_code;
2081 if ($event->type_code == 'HOLIDAY') {
2082 $cases1[$h][$event->id]['css'] = 'peruser_holiday ';
2083 if (GETPOSTINT('check_holiday')) {
2084 $cases1[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2085 }
2086 } else {
2087 $cases1[$h][$event->id]['color'] = $color;
2088
2089 if ($event->fk_project > 0) {
2090 if (empty($cacheprojects[$event->fk_project])) {
2091 $tmpproj = new Project($db);
2092 $tmpproj->fetch($event->fk_project);
2093 $cacheprojects[$event->fk_project] = $tmpproj;
2094 }
2095 $cases1[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2096 }
2097 if ($event->socid > 0) {
2098 if (empty($cachethirdparties[$event->socid])) {
2099 $tmpthirdparty = new Societe($db);
2100 $tmpthirdparty->fetch($event->socid);
2101 $cachethirdparties[$event->socid] = $tmpthirdparty;
2102 }
2103 $cases1[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2104 }
2105 if ($event->contact_id > 0) {
2106 if (empty($cachecontacts[$event->contact_id])) {
2107 $tmpcontact = new Contact($db);
2108 $tmpcontact->fetch($event->contact_id);
2109 $cachecontacts[$event->contact_id] = $tmpcontact;
2110 }
2111 $cases1[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2112 }
2113 }
2114 }
2115 if ($event->date_start_in_calendar < $b1 && $dateendtouse > $b) {
2116 $busy = $event->transparency;
2117 $cases2[$h][$event->id]['busy'] = $busy;
2118 $cases2[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2119 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2120 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2121 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2122 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2123 $cases2[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2124 } else {
2125 $cases2[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2126 }
2127 }
2128 if ($event->label) {
2129 $cases2[$h][$event->id]['string'] .= ' - '.$event->label;
2130 }
2131 $cases2[$h][$event->id]['typecode'] = $event->type_code;
2132 if ($event->type_code == 'HOLIDAY') {
2133 $cases2[$h][$event->id]['css'] = 'peruser_holiday ';
2134 if (GETPOSTINT('check_holiday')) {
2135 $cases2[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2136 }
2137 } else {
2138 $cases2[$h][$event->id]['color'] = $color;
2139
2140 if ($event->fk_project > 0) {
2141 if (empty($cacheprojects[$event->fk_project])) {
2142 $tmpproj = new Project($db);
2143 $tmpproj->fetch($event->fk_project);
2144 $cacheprojects[$event->fk_project] = $tmpproj;
2145 }
2146 $cases2[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2147 }
2148 if ($event->socid > 0) {
2149 if (empty($cachethirdparties[$event->socid])) {
2150 $tmpthirdparty = new Societe($db);
2151 $tmpthirdparty->fetch($event->socid);
2152 $cachethirdparties[$event->socid] = $tmpthirdparty;
2153 }
2154 $cases2[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2155 }
2156 if ($event->contact_id > 0) {
2157 if (empty($cachecontacts[$event->contact_id])) {
2158 $tmpcontact = new Contact($db);
2159 $tmpcontact->fetch($event->contact_id);
2160 $cachecontacts[$event->contact_id] = $tmpcontact;
2161 }
2162 $cases2[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2163 }
2164 }
2165 }
2166 if ($event->date_start_in_calendar < $b2 && $dateendtouse > $b1) {
2167 $busy = $event->transparency;
2168 $cases3[$h][$event->id]['busy'] = $busy;
2169 $cases3[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2170 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2171 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2172 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2173 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2174 $cases3[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2175 } else {
2176 $cases3[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2177 }
2178 }
2179 if ($event->label) {
2180 $cases3[$h][$event->id]['string'] .= ' - '.$event->label;
2181 }
2182 $cases3[$h][$event->id]['typecode'] = $event->type_code;
2183 if ($event->type_code == 'HOLIDAY') {
2184 $cases3[$h][$event->id]['css'] .= 'peruser_holiday ';
2185 if (GETPOSTINT('check_holiday')) {
2186 $cases3[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2187 }
2188 } else {
2189 $cases3[$h][$event->id]['color'] = $color;
2190
2191 if ($event->fk_project > 0) {
2192 if (empty($cacheprojects[$event->fk_project])) {
2193 $tmpproj = new Project($db);
2194 $tmpproj->fetch($event->fk_project);
2195 $cacheprojects[$event->fk_project] = $tmpproj;
2196 }
2197 $cases3[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2198 }
2199 if ($event->socid > 0) {
2200 if (empty($cachethirdparties[$event->socid])) {
2201 $tmpthirdparty = new Societe($db);
2202 $tmpthirdparty->fetch($event->socid);
2203 $cachethirdparties[$event->socid] = $tmpthirdparty;
2204 }
2205 $cases3[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2206 }
2207 if ($event->contact_id > 0) {
2208 if (empty($cachecontacts[$event->contact_id])) {
2209 $tmpcontact = new Contact($db);
2210 $tmpcontact->fetch($event->contact_id);
2211 $cachecontacts[$event->contact_id] = $tmpcontact;
2212 }
2213 $cases3[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2214 }
2215 }
2216 }
2217 if ($event->date_start_in_calendar < $c && $dateendtouse > $b2) {
2218 $busy = $event->transparency;
2219 $cases4[$h][$event->id]['busy'] = $busy;
2220 $cases4[$h][$event->id]['string'] = dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel');
2221 if ($event->date_end_in_calendar && $event->date_end_in_calendar != $event->date_start_in_calendar) {
2222 $tmpa = dol_getdate($event->date_start_in_calendar, true);
2223 $tmpb = dol_getdate($event->date_end_in_calendar, true);
2224 if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
2225 $cases4[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2226 } else {
2227 $cases4[$h][$event->id]['string'] .= '-'.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel');
2228 }
2229 }
2230 if ($event->label) {
2231 $cases4[$h][$event->id]['string'] .= ' - '.$event->label;
2232 }
2233 $cases4[$h][$event->id]['typecode'] = $event->type_code;
2234 if ($event->type_code == 'HOLIDAY') {
2235 $cases4[$h][$event->id]['css'] = 'peruser_holiday ';
2236 if (GETPOSTINT('check_holiday')) {
2237 $cases4[$h][$event->id]['css'] .= 'peruser_holiday_imp ';
2238 }
2239 } else {
2240 $cases4[$h][$event->id]['color'] = $color;
2241
2242 if ($event->fk_project > 0) {
2243 if (empty($cacheprojects[$event->fk_project])) {
2244 $tmpproj = new Project($db);
2245 $tmpproj->fetch($event->fk_project);
2246 $cacheprojects[$event->fk_project] = $tmpproj;
2247 }
2248 $cases4[$h][$event->id]['string'] .= ', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title;
2249 }
2250 if ($event->socid > 0) {
2251 if (empty($cachethirdparties[$event->socid])) {
2252 $tmpthirdparty = new Societe($db);
2253 $tmpthirdparty->fetch($event->socid);
2254 $cachethirdparties[$event->socid] = $tmpthirdparty;
2255 }
2256 $cases4[$h][$event->id]['string'] .= ', '.$cachethirdparties[$event->socid]->name;
2257 }
2258 if ($event->contact_id > 0) {
2259 if (empty($cachecontacts[$event->contact_id])) {
2260 $tmpcontact = new Contact($db);
2261 $tmpcontact->fetch($event->contact_id);
2262 $cachecontacts[$event->contact_id] = $tmpcontact;
2263 }
2264 $cases4[$h][$event->id]['string'] .= ', '.$cachecontacts[$event->contact_id]->getFullName($langs);
2265 }
2266 }
2267 }
2268 } else {
2269 $busy = $event->transparency;
2270 $cases1[$h][$event->id]['busy'] = $busy;
2271 $cases2[$h][$event->id]['busy'] = $busy;
2272 $cases3[$h][$event->id]['busy'] = $busy;
2273 $cases4[$h][$event->id]['busy'] = $busy;
2274 $cases1[$h][$event->id]['string'] = $event->label;
2275 $cases2[$h][$event->id]['string'] = $event->label;
2276 $cases3[$h][$event->id]['string'] = $event->label;
2277 $cases4[$h][$event->id]['string'] = $event->label;
2278 $cases1[$h][$event->id]['typecode'] = $event->type_code;
2279 $cases2[$h][$event->id]['typecode'] = $event->type_code;
2280 $cases3[$h][$event->id]['typecode'] = $event->type_code;
2281 $cases4[$h][$event->id]['typecode'] = $event->type_code;
2282 $cases1[$h][$event->id]['color'] = $color;
2283 $cases2[$h][$event->id]['color'] = $color;
2284 $cases3[$h][$event->id]['color'] = $color;
2285 $cases4[$h][$event->id]['color'] = $color;
2286 $cases1[$h][$event->id]['css'] = '';
2287 $cases2[$h][$event->id]['css'] = '';
2288 $cases3[$h][$event->id]['css'] = '';
2289 $cases4[$h][$event->id]['css'] = '';
2290 }
2291 }
2292 $i++;
2293 }
2294
2295 break; // We found the date we were looking for. No need to search anymore.
2296 }
2297 }
2298
2299 // Now output $casesX from start hour to end hour
2300 for ($h = $begin_h; $h < $end_h; $h++) {
2301 $color1 = '';
2302 $color2 = '';
2303 $color3 = '';
2304 $color4 = '';
2305 $style1 = 'onclickopenref ';
2306 $style2 = 'onclickopenref ';
2307 $style3 = 'onclickopenref ';
2308 $style4 = 'onclickopenref ';
2309 $string1 = '&nbsp;';
2310 $string2 = '&nbsp;';
2311 $string3 = '&nbsp;';
2312 $string4 = '&nbsp;';
2313 $title1 = '';
2314 $title2 = '';
2315 $title3 = '';
2316 $title4 = '';
2317 if (isset($cases1[$h])) {
2318 //$title1.=count($cases1[$h]).' '.(count($cases1[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2319 if (count($cases1[$h]) > 1) {
2320 $title1 .= count($cases1[$h]).' '.(count($cases1[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2321 }
2322
2323 foreach ($cases1[$h] as $id => $ev) {
2324 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2325 $style1 .= ' peruser_busy';
2326 } else {
2327 $style1 .= 'peruser_notbusy ';
2328 }
2329 if (!empty($ev['css'])) {
2330 $style1 .= $ev['css'].' ';
2331 }
2332 }
2333 }
2334 if (isset($cases2[$h])) {
2335 //$title2.=count($cases2[$h]).' '.(count($cases2[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2336 if (count($cases2[$h]) > 1) {
2337 $title2 .= count($cases2[$h]).' '.(count($cases2[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2338 }
2339
2340 foreach ($cases2[$h] as $id => $ev) {
2341 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2342 $style2 .= ' peruser_busy';
2343 } else {
2344 $style2 .= 'peruser_notbusy ';
2345 }
2346 if (!empty($ev['css'])) {
2347 $style2 .= $ev['css'].' ';
2348 }
2349 }
2350 }
2351 if (isset($cases3[$h])) {
2352 //$title3.=count($cases3[$h]).' '.(count($cases3[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2353 if (count($cases3[$h]) > 1) {
2354 $title3 .= count($cases3[$h]).' '.(count($cases3[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2355 }
2356
2357 foreach ($cases3[$h] as $id => $ev) {
2358 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2359 $style3 .= ' peruser_busy';
2360 } else {
2361 $style3 .= 'peruser_notbusy ';
2362 }
2363 if (!empty($ev['css'])) {
2364 $style3 .= $ev['css'].' ';
2365 }
2366 }
2367 }
2368 if (isset($cases4[$h])) {
2369 //$title4.=count($cases3[$h]).' '.(count($cases3[$h])==1?$langs->trans("Event"):$langs->trans("Events"));
2370 if (count($cases4[$h]) > 1) {
2371 $title4 .= count($cases4[$h]).' '.(count($cases4[$h]) == 1 ? $langs->trans("Event") : $langs->trans("Events"));
2372 }
2373
2374 foreach ($cases4[$h] as $id => $ev) {
2375 if (!empty($ev['busy']) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2376 $style4 .= ' peruser_busy';
2377 } else {
2378 $style4 .= 'peruser_notbusy ';
2379 }
2380 if (!empty($ev['css'])) {
2381 $style4 .= $ev['css'].' ';
2382 }
2383 }
2384 }
2385
2386 $ids1 = '';
2387 $ids2 = '';
2388 $ids3 = '';
2389 $ids4 = '';
2390 if (!empty($cases1[$h]) && is_array($cases1[$h]) && count($cases1[$h]) && array_keys($cases1[$h])) {
2391 $ids1 = implode(', ', array_keys($cases1[$h]));
2392 }
2393 if (!empty($cases2[$h]) && is_array($cases2[$h]) && count($cases2[$h]) && array_keys($cases2[$h])) {
2394 $ids2 = implode(', ', array_keys($cases2[$h]));
2395 }
2396 if (!empty($cases3[$h]) && is_array($cases3[$h]) && count($cases3[$h]) && array_keys($cases3[$h])) {
2397 $ids3 = implode(',', array_keys($cases3[$h]));
2398 }
2399 if (!empty($cases4[$h]) && is_array($cases4[$h]) && count($cases4[$h]) && array_keys($cases4[$h])) {
2400 $ids4 = implode(',', array_keys($cases4[$h]));
2401 }
2402
2403 if ($h == $begin_h) {
2404 echo '<td class="'.$style.'_peruserleft cal_peruser'.($var ? ' cal_impair '.$style.'_impair' : '').'">';
2405 } else {
2406 echo '<td class="'.$style.' cal_peruser'.($var ? ' cal_impair '.$style.'_impair' : '').'">';
2407 }
2408
2409 // only 1 event in first quarter
2410 $ref1 = 'ref';
2411 if (!empty($cases1[$h]) && is_array($cases1[$h]) && count($cases1[$h]) == 1) {
2412 $output = array_slice($cases1[$h], 0, 1);
2413 if ($output[0]['typecode'] == 'HOLIDAY') {
2414 $ref1 = 'holiday';
2415 $title1 = $langs->trans("Holiday");
2416 } else {
2417 $title1 = $langs->trans("Ref").' '.$ids1.($title1 ? ' - '.$title1 : '');
2418 if ($output[0]['string']) {
2419 $title1 .= ' - '.$output[0]['string'];
2420 }
2421 }
2422 if ($output[0]['color']) {
2423 $color1 = $output[0]['color'];
2424 }
2425 } elseif (!empty($cases1[$h]) && is_array($cases1[$h]) && count($cases1[$h]) > 1) {
2426 $title1 = $langs->trans("Ref").' '.$ids1.($title1 ? ' - '.$title1 : '');
2427 $color1 = '222222';
2428 }
2429
2430 // only 1 event in second quarter
2431 $ref2 = 'ref';
2432 if (!empty($cases2[$h]) && is_array($cases2[$h]) && count($cases2[$h]) == 1) {
2433 $output = array_slice($cases2[$h], 0, 1);
2434 if ($output[0]['typecode'] == 'HOLIDAY') {
2435 $ref2 = 'holiday';
2436 $title2 = $langs->trans("Holiday");
2437 } else {
2438 $title2 = $langs->trans("Ref").' '.$ids2.($title2 ? ' - '.$title2 : '');
2439 if ($output[0]['string']) {
2440 $title2 .= ' - '.$output[0]['string'];
2441 }
2442 }
2443 if ($output[0]['color']) {
2444 $color2 = $output[0]['color'];
2445 }
2446 } elseif (!empty($cases2[$h]) && is_array($cases2[$h]) && count($cases2[$h]) > 1) {
2447 $title2 = $langs->trans("Ref").' '.$ids2.($title2 ? ' - '.$title2 : '');
2448 $color2 = '222222';
2449 }
2450
2451 // only 1 event in third quarter
2452 $ref3 = 'ref';
2453 if (!empty($cases3[$h]) && is_array($cases3[$h]) && count($cases3[$h]) == 1) {
2454 $output = array_slice($cases3[$h], 0, 1);
2455 if ($output[0]['typecode'] == 'HOLIDAY') {
2456 $ref3 = 'holiday';
2457 $title3 = $langs->trans("Holiday");
2458 } else {
2459 $title3 = $langs->trans("Ref").' '.$ids3.($title3 ? ' - '.$title3 : '');
2460 if ($output[0]['string']) {
2461 $title3 .= ' - '.$output[0]['string'];
2462 }
2463 }
2464 if ($output[0]['color']) {
2465 $color3 = $output[0]['color'];
2466 }
2467 } elseif (!empty($cases3[$h]) && is_array($cases3[$h]) && count($cases3[$h]) > 1) {
2468 $title3 = $langs->trans("Ref").' '.$ids3.($title3 ? ' - '.$title3 : '');
2469 $color3 = '222222';
2470 }
2471
2472 // only 1 event in fourth quarter
2473 $ref4 = 'ref';
2474 if (!empty($cases4[$h]) && is_array($cases4[$h]) && count($cases4[$h]) == 1) {
2475 $output = array_slice($cases4[$h], 0, 1);
2476 if ($output[0]['typecode'] == 'HOLIDAY') {
2477 $ref4 = 'holiday';
2478 $title4 = $langs->trans("Holiday");
2479 } else {
2480 $title4 = $langs->trans("Ref").' '.$ids4.($title4 ? ' - '.$title4 : '');
2481 if ($output[0]['string']) {
2482 $title4 .= ' - '.$output[0]['string'];
2483 }
2484 }
2485 if ($output[0]['color']) {
2486 $color4 = $output[0]['color'];
2487 }
2488 } elseif (!empty($cases4[$h]) && is_array($cases4[$h]) && count($cases4[$h]) > 1) {
2489 $title4 = $langs->trans("Ref").' '.$ids4.($title4 ? ' - '.$title4 : '');
2490 $color4 = '222222';
2491 }
2492
2493 print '<table class="nobordernopadding case centpercent">';
2494 print '<tr>';
2495 print '<td ';
2496 if (preg_match('/peruser_notbusy/', $style1)) {
2497 print 'style="border: 1px solid #'.($color1 ? $color1 : "888").' !important" ';
2498 } elseif ($color1) {
2499 print 'style="background: #'.$color1.'; "';
2500 }
2501 print 'class="';
2502 print $style1;
2503 print 'center'.($title1 ? ' classfortooltip' : '').($title1 ? ' cursorpointer' : '').'"';
2504 print 'ref="'.$ref1.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_00_'.($ids1 ? $ids1 : 'none').'"';
2505 print ($title1 ? ' title="'.$title1.'"' : '').'>';
2506 print $string1;
2507 print '</td>';
2508
2509 print '<td ';
2510 if (preg_match('/peruser_notbusy/', $style2)) {
2511 print 'style="border: 1px solid #'.($color2 ? $color2 : "888").' !important" ';
2512 } elseif ($color2) {
2513 print 'style="background: #'.$color2.'; "';
2514 }
2515 print 'class="';
2516 print $style2;
2517 print 'center'.($title2 ? ' classfortooltip' : '').($title2 ? ' cursorpointer' : '').'"';
2518 print ' ref="'.$ref2.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_15_'.($ids2 ? $ids2 : 'none').'"';
2519 print ($title2 ? ' title="'.$title2.'"' : '').'>';
2520 print $string2;
2521 print '</td>';
2522
2523 print '<td ';
2524 if (preg_match('/peruser_notbusy/', $style3)) {
2525 print 'style="border: 1px solid #'.($color3 ? $color3 : "888").' !important" ';
2526 } elseif ($color3) {
2527 print 'style="background: #'.$color3.'; "';
2528 }
2529 print 'class="';
2530 print $style3;
2531 print 'center'.($title3 ? ' classfortooltip' : '').($title3 ? ' cursorpointer' : '').'"';
2532 print ' ref="'.$ref3.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_30_'.($ids3 ? $ids3 : 'none').'"';
2533 print ($title3 ? ' title="'.$title3.'"' : '').'>';
2534 print $string3;
2535 print '</td>';
2536
2537 print '<td ';
2538 if (preg_match('/peruser_notbusy/', $style4)) {
2539 print 'style="border: 1px solid #'.($color4 ? $color4 : "888").' !important" ';
2540 } elseif ($color4) {
2541 print 'style="background: #'.$color4.'; "';
2542 }
2543 print 'class="';
2544 print $style4;
2545 print 'center'.($title4 ? ' classfortooltip' : '').($title4 ? ' cursorpointer' : '').'"';
2546 print ' ref="'.$ref4.'_'.$username->id.'_'.sprintf("%04d", $year).'_'.sprintf("%02d", $month).'_'.sprintf("%02d", $day).'_'.sprintf("%02d", $h).'_45_'.($ids4 ? $ids4 : 'none').'"';
2547 print ($title4 ? ' title="'.$title4.'"' : '').'>';
2548 print $string4;
2549 print '</td>';
2550
2551 print '</tr>';
2552 print '</table>';
2553 print '</td>';
2554 }
2555}
$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:1597
$cacheusers
Definition index.php:1595
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.