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