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