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