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