dolibarr 24.0.0-beta
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)."-".$db->escape($month)."-".$db->escape($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 $event->datep = (int) $db->jdate($obj->date_start) + (int) ((empty($obj->halfday) || $obj->halfday == 1 ? 0 : 12) * 60 * 60);
1214 $event->datef = (int) $db->jdate($obj->date_end) + (int) ((empty($obj->halfday) || $obj->halfday == -1 ? 24 : 12) * 60 * 60 - 1);
1215 $event->date_start_in_calendar = $event->datep;
1216 $event->date_end_in_calendar = $event->datef;
1217
1218 if ($obj->status == 3) {
1219 // Show no symbol for leave with state "leave approved"
1220 $event->percentage = -1;
1221 } elseif ($obj->status == 2) {
1222 // Show TO-DO symbol for leave with state "leave wait for approval"
1223 $event->percentage = 0;
1224 }
1225
1226 $event->label = $langs->trans("Holiday");
1227
1228 $daycursor = $event->date_start_in_calendar;
1229 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1230 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1231 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1232
1233 $daycursorend = $event->date_end_in_calendar;
1234 $anneeend = (int) dol_print_date($daycursorend, '%Y', 'tzuserrel');
1235 $moisend = (int) dol_print_date($daycursorend, '%m', 'tzuserrel');
1236 $jourend = (int) dol_print_date($daycursorend, '%d', 'tzuserrel');
1237
1238 // daykey must be date that represent day box in calendar so must be a user time
1239 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1240 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1241 $ifornbofdays = 0;
1242 do {
1243 $ifornbofdays++;
1244
1245 $firstdayofholiday = ($ifornbofdays == 1);
1246 $lastdayofholiday = ($daykeygmt == dol_get_first_hour($event->date_end_in_calendar, 'gmt'));
1247
1248 /*
1249 var_dump(dol_print_date($daykeygmt, 'dayhour', 'gmt'));
1250 var_dump(dol_print_date(dol_get_first_hour($event->date_end_in_calendar, 'gmt'), 'dayhour', 'gmt'));
1251 var_dump($lastdayofholiday);
1252 var_dump($obj->halfday);
1253 */
1254
1255 if ((in_array($obj->halfday, array(1, 2)) == 1 && $lastdayofholiday) || (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday)) {
1256 // We create a copy of event because we want tochange the label
1257 $newevent = dol_clone($event, 1);
1258 if (in_array($obj->halfday, array(1, 2)) && $lastdayofholiday) {
1259 $newevent->label .= ' ('.$langs->trans("Morning").')';
1260 } elseif (in_array($obj->halfday, array(-1, 2)) && $firstdayofholiday) {
1261 $newevent->label .= ' ('.$langs->trans("Afternoon").')';
1262 }
1263 $eventarray[$daykey][] = $newevent; // We need to use ->gtTypePicto, getXXXon object, so clone must be PHP clone.
1264 } else {
1265 $eventarray[$daykey][] = $event; // We can use the event unchanged
1266 }
1267
1268 $daykey += 60 * 60 * 24;
1269 $daykeygmt += 60 * 60 * 24;
1270 } while ($daykey <= $event->date_end_in_calendar);
1271
1272 $i++;
1273 }
1274 }
1275}
1276
1277// EXTERNAL CALENDAR
1278// Complete $eventarray with external import Ical
1279if (count($listofextcals)) {
1280 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/ical.class.php';
1281
1282 foreach ($listofextcals as $key => $extcal) {
1283 $url = $extcal['src']; // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics
1284 $namecal = $extcal['name'];
1285 $offsettz = $extcal['offsettz'];
1286 $colorcal = $extcal['color'];
1287 $buggedfile = $extcal['buggedfile'];
1288
1289 $pathforcachefile = dol_sanitizePathName($conf->user->dir_temp).'/'.dol_sanitizeFileName('extcal_'.$namecal.'_user'.$user->id).'.cache';
1290 //var_dump($pathforcachefile);exit;
1291
1292 $ical = new ICal();
1293 $ical->parse($url, $pathforcachefile, $DELAYFORCACHE);
1294 if ($ical->error) {
1295 // Save error message for extcal
1296 $listofextcals[$key]['error'] = $ical->error;
1297 $s .= '<br><div class="warning">'.dol_escape_htmltag($listofextcals[$key]['name']).': '.$url.'<br>Error message: '.dol_escape_htmltag($ical->error).'</div>';
1298 }
1299
1300 // After this $ical->cal['VEVENT'] contains array of events, $ical->cal['DAYLIGHT'] contains daylight info, $ical->cal['STANDARD'] contains non daylight info, ...
1301 //var_dump($ical->cal); exit;
1302 $icalevents = array();
1303 $tmparray = $ical->get_event_list();
1304 if (is_array($tmparray)) {
1305 $icalevents = array_merge($icalevents, $tmparray); // Add $ical->cal['VEVENT']
1306 }
1307 $tmparray = $ical->get_freebusy_list();
1308 if (is_array($tmparray)) {
1309 $icalevents = array_merge($icalevents, $tmparray); // Add $ical->cal['VFREEBUSY']
1310 }
1311
1312 $nbevents += count($icalevents);
1313
1314 if (count($icalevents) > 0) {
1315 // Duplicate all repeatable events into new entries
1316 $moreicalevents = array();
1317 foreach ($icalevents as $icalevent) {
1318 if (isset($icalevent['RRULE']) && is_array($icalevent['RRULE'])) { //repeatable event
1319 //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow;
1320 //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=($lastdaytoshow-1);
1321 if ($icalevent['DTSTART;VALUE=DATE']) { //fullday event
1322 $datecurstart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1);
1323 $datecurend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day
1324 } elseif (is_array($icalevent['DTSTART']) && !empty($icalevent['DTSTART']['unixtime'])) {
1325 $datecurstart = $icalevent['DTSTART']['unixtime'];
1326 $datecurend = $icalevent['DTEND']['unixtime'];
1327 if (!empty($ical->cal['DAYLIGHT']['DTSTART']) && $datecurstart) {
1328 //var_dump($ical->cal);
1329 $tmpcurstart = $datecurstart;
1330 $tmpcurend = $datecurend;
1331 $tmpdaylightstart = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['DAYLIGHT']['DTSTART'];
1332 $tmpdaylightend = dol_mktime(0, 0, 0, 1, 1, 1970, 1) + (int) $ical->cal['STANDARD']['DTSTART'];
1333 //var_dump($tmpcurstart);var_dump($tmpcurend); var_dump($ical->cal['DAYLIGHT']['DTSTART']);var_dump($ical->cal['STANDARD']['DTSTART']);
1334 // Edit datecurstart and datecurend
1335 if ($tmpcurstart >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) {
1336 $datecurstart -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36;
1337 } else {
1338 $datecurstart -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36;
1339 }
1340 if ($tmpcurend >= $tmpdaylightstart && $tmpcurstart < $tmpdaylightend) {
1341 $datecurend -= ((int) $ical->cal['DAYLIGHT']['TZOFFSETTO']) * 36;
1342 } else {
1343 $datecurend -= ((int) $ical->cal['STANDARD']['TZOFFSETTO']) * 36;
1344 }
1345 }
1346 // datecurstart and datecurend are now GMT date
1347 //var_dump($datecurstart); var_dump($datecurend); exit;
1348 } else {
1349 // Not a recognized record
1350 dol_syslog("Found a not recognized repeatable record with unknown date start", LOG_ERR);
1351 continue;
1352 }
1353 //print 'xx'.$datecurstart;exit;
1354
1355 $interval = (empty($icalevent['RRULE']['INTERVAL']) ? 1 : $icalevent['RRULE']['INTERVAL']);
1356 $until = empty($icalevent['RRULE']['UNTIL']) ? 0 : dol_stringtotime($icalevent['RRULE']['UNTIL'], 1);
1357 $maxrepeat = empty($icalevent['RRULE']['COUNT']) ? 0 : $icalevent['RRULE']['COUNT'];
1358 if ($until && ($until + ($datecurend - $datecurstart)) < $firstdaytoshow) {
1359 continue; // We discard repeatable event that end before start date to show
1360 }
1361 if ($datecurstart >= $lastdaytoshow) {
1362 continue; // We discard repeatable event that start after end date to show
1363 }
1364
1365 $numofevent = 0;
1366 while (($datecurstart < $lastdaytoshow) && (empty($maxrepeat) || ($numofevent < $maxrepeat))) {
1367 if ($datecurend >= $firstdaytoshow) { // We add event
1368 $newevent = $icalevent;
1369 unset($newevent['RRULE']);
1370 if ($icalevent['DTSTART;VALUE=DATE']) {
1371 $newevent['DTSTART;VALUE=DATE'] = dol_print_date($datecurstart, '%Y%m%d');
1372 $newevent['DTEND;VALUE=DATE'] = dol_print_date($datecurend + 1, '%Y%m%d');
1373 } else {
1374 $newevent['DTSTART'] = $datecurstart;
1375 $newevent['DTEND'] = $datecurend;
1376 }
1377 $moreicalevents[] = $newevent;
1378 }
1379 // Jump on next occurrence
1380 $numofevent++;
1381 $savdatecurstart = $datecurstart;
1382 if ($icalevent['RRULE']['FREQ'] == 'DAILY') {
1383 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'd');
1384 $datecurend = dol_time_plus_duree($datecurend, $interval, 'd');
1385 }
1386 if ($icalevent['RRULE']['FREQ'] == 'WEEKLY') {
1387 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'w');
1388 $datecurend = dol_time_plus_duree($datecurend, $interval, 'w');
1389 } elseif ($icalevent['RRULE']['FREQ'] == 'MONTHLY') {
1390 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'm');
1391 $datecurend = dol_time_plus_duree($datecurend, $interval, 'm');
1392 } elseif ($icalevent['RRULE']['FREQ'] == 'YEARLY') {
1393 $datecurstart = dol_time_plus_duree($datecurstart, $interval, 'y');
1394 $datecurend = dol_time_plus_duree($datecurend, $interval, 'y');
1395 }
1396 // Test to avoid infinite loop ($datecurstart must increase)
1397 if ($savdatecurstart >= $datecurstart) {
1398 dol_syslog("Found a rule freq ".$icalevent['RRULE']['FREQ']." not managed by dolibarr code. Assume 1 week frequency.", LOG_ERR);
1399 $datecurstart += 3600 * 24 * 7;
1400 $datecurend += 3600 * 24 * 7;
1401 }
1402 }
1403 }
1404 }
1405 $icalevents = array_merge($icalevents, $moreicalevents);
1406
1407 // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray
1408 foreach ($icalevents as $icalevent) {
1409 //var_dump($icalevent);
1410
1411 //print $icalevent['SUMMARY'].'->';
1412 //var_dump($icalevent);exit;
1413 if (!empty($icalevent['RRULE'])) {
1414 continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule.
1415 }
1416
1417 // Create a new object action
1418 $event = new ActionComm($db);
1419 $addevent = false;
1420 if (isset($icalevent['DTSTART;VALUE=DATE'])) { // fullday event
1421 // For full day events, date are also GMT but they won't but converted using tz during output
1422 $datestart = dol_stringtotime($icalevent['DTSTART;VALUE=DATE'], 1);
1423 if (empty($icalevent['DTEND;VALUE=DATE'])) {
1424 $dateend = $datestart + 86400 - 1;
1425 } else {
1426 $dateend = dol_stringtotime($icalevent['DTEND;VALUE=DATE'], 1) - 1; // We remove one second to get last second of day
1427 }
1428 //print 'x'.$datestart.'-'.$dateend;exit;
1429 //print dol_print_date($dateend,'dayhour','gmt');
1430 $event->fulldayevent = 1;
1431 $addevent = true;
1432 } elseif (!is_array($icalevent['DTSTART'])) { // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch)
1433 $datestart = $icalevent['DTSTART'];
1434 $dateend = empty($icalevent['DTEND']) ? $datestart : $icalevent['DTEND'];
1435
1436 $datestart += +($offsettz * 3600);
1437 $dateend += +($offsettz * 3600);
1438
1439 $addevent = true;
1440 //var_dump($offsettz);
1441 //var_dump(dol_print_date($datestart, 'dayhour', 'gmt'));
1442 } elseif (isset($icalevent['DTSTART']['unixtime'])) { // File contains a local timezone + a TZ (for example when using bluemind)
1443 $datestart = $icalevent['DTSTART']['unixtime'];
1444 $dateend = $icalevent['DTEND']['unixtime'];
1445
1446 $datestart += +($offsettz * 3600);
1447 $dateend += +($offsettz * 3600);
1448
1449 // $buggedfile is set to uselocalandtznodaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtznodaylight'
1450 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
1451 // TODO
1452 }
1453 // $buggedfile is set to uselocalandtzdaylight if conf->global->AGENDA_EXT_BUGGEDFILEx = 'uselocalandtzdaylight' (for example with bluemind)
1454 if ($buggedfile === 'uselocalandtzdaylight') { // unixtime is a local date that does take daylight into account, TZID is +2 for example for 'Europe/Paris' in summer
1455 $localtzs = new DateTimeZone((string) preg_replace('/"/', '', $icalevent['DTSTART']['TZID']));
1456 $localtze = new DateTimeZone((string) preg_replace('/"/', '', $icalevent['DTEND']['TZID']));
1457 $localdts = new DateTime(dol_print_date($datestart, 'dayrfc', 'gmt'), $localtzs);
1458 $localdte = new DateTime(dol_print_date($dateend, 'dayrfc', 'gmt'), $localtze);
1459 $tmps = -1 * $localtzs->getOffset($localdts);
1460 $tmpe = -1 * $localtze->getOffset($localdte);
1461 $datestart += $tmps;
1462 $dateend += $tmpe;
1463 //var_dump($datestart);
1464 }
1465 $addevent = true;
1466 }
1467
1468 if ($addevent) {
1469 $event->id = $icalevent['UID'];
1470 $event->ref = (string) $event->id;
1471 $userId = $userstatic->findUserIdByEmail($namecal);
1472 if (!empty($userId) && $userId > 0) {
1473 $event->userassigned[$userId] = $userId;
1474 $event->percentage = -1;
1475 }
1476
1477 $event->type_code = "ICALEVENT";
1478 $event->type_label = $namecal;
1479 $event->type_color = $colorcal;
1480 $event->type = 'icalevent';
1481 $event->type_picto = 'rss';
1482
1483 $event->icalname = $namecal;
1484 $event->icalcolor = $colorcal;
1485 $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.
1486 $event->datep = (int) ($datestart + $usertime);
1487 $event->datef = (int) ($dateend + $usertime);
1488
1489 if (isset($icalevent['SUMMARY']) && $icalevent['SUMMARY']) {
1490 $event->label = dol_string_nohtmltag($icalevent['SUMMARY']);
1491 } elseif (isset($icalevent['DESCRIPTION']) && $icalevent['DESCRIPTION']) {
1492 $event->label = dol_nl2br(dol_string_nohtmltag($icalevent['DESCRIPTION']), 1);
1493 } else {
1494 $event->label = $langs->trans("ExtSiteNoLabel");
1495 }
1496
1497 // Priority (see https://www.kanzaki.com/docs/ical/priority.html)
1498 // LOW = 0 to 4
1499 // MEDIUM = 5
1500 // HIGH = 6 to 9
1501 if (!empty($icalevent['PRIORITY'])) {
1502 $event->priority = $icalevent['PRIORITY'];
1503 }
1504
1505 // Transparency (see https://www.kanzaki.com/docs/ical/transp.html)
1506 if (!empty($icalevent['TRANSP'])) {
1507 if ($icalevent['TRANSP'] == "TRANSPARENT") {
1508 $event->transparency = 0; // 0 = available / free
1509 }
1510 if ($icalevent['TRANSP'] == "OPAQUE") {
1511 $event->transparency = 1; // 1 = busy
1512 }
1513
1514 // TODO: MS outlook states
1515 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:TRANSPARENT => Available / Free
1516 // X-MICROSOFT-CDO-BUSYSTATUS:FREE + TRANSP:OPAQUE => Work another place
1517 // X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE + TRANSP:OPAQUE => With reservations
1518 // X-MICROSOFT-CDO-BUSYSTATUS:BUSY + TRANSP:OPAQUE => Busy
1519 // X-MICROSOFT-CDO-BUSYSTATUS:OOF + TRANSP:OPAQUE => Away from the office / off-site
1520 }
1521
1522 if (!empty($icalevent['LOCATION'])) {
1523 $event->location = $icalevent['LOCATION'];
1524 }
1525
1526 $event->date_start_in_calendar = $event->datep;
1527
1528 if ((int) $event->datef != 0 && $event->datef >= $event->datep) {
1529 $event->date_end_in_calendar = $event->datef;
1530 } else {
1531 $event->date_end_in_calendar = $event->datep;
1532 }
1533
1534 // Add event into $eventarray if date range are ok.
1535 if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) {
1536 //print 'x'.$datestart.'-'.$dateend;exit;
1537 //print 'x'.$datestart.'-'.$dateend;exit;
1538 //print 'x'.$datestart.'-'.$dateend;exit;
1539 // This record is out of visible range
1540 } else {
1541 if ($event->date_start_in_calendar < $firstdaytoshow) {
1542 $event->date_start_in_calendar = $firstdaytoshow;
1543 }
1544 if ($event->date_end_in_calendar >= $lastdaytoshow) {
1545 $event->date_end_in_calendar = ($lastdaytoshow - 1);
1546 }
1547
1548 // Add an entry in actionarray for each day
1549 $daycursor = $event->date_start_in_calendar;
1550 $annee = (int) dol_print_date($daycursor, '%Y', 'tzuserrel');
1551 $mois = (int) dol_print_date($daycursor, '%m', 'tzuserrel');
1552 $jour = (int) dol_print_date($daycursor, '%d', 'tzuserrel');
1553
1554 // Loop on each day covered by action to prepare an index to show on calendar
1555 $loop = true;
1556 $j = 0;
1557 // daykey must be date that represent day box in calendar so must be a user time
1558 $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1559 $daykeygmt = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt');
1560 do {
1561 //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').' ';
1562 $eventarray[$daykey][] = $event;
1563 $daykey += 60 * 60 * 24;
1564 $daykeygmt += 60 * 60 * 24; // Add one day
1565 if (($event->fulldayevent ? $daykeygmt : $daykey) > $event->date_end_in_calendar) {
1566 $loop = false;
1567 }
1568 } while ($loop);
1569 }
1570 }
1571 }
1572 }
1573 }
1574}
1575
1576// Complete $eventarray with events coming from external module
1577$parameters = array();
1578$object = null;
1579$reshook = $hookmanager->executeHooks('getCalendarEvents', $parameters, $object, $action);
1580if (!empty($hookmanager->resArray['eventarray'])) {
1581 foreach ($hookmanager->resArray['eventarray'] as $keyDate => $events) {
1582 if (!isset($eventarray[$keyDate])) {
1583 $eventarray[$keyDate] = array();
1584 }
1585 $eventarray[$keyDate] = array_merge($eventarray[$keyDate], $events);
1586 }
1587}
1588
1589// Sort events
1590foreach ($eventarray as $keyDate => &$dateeventarray) {
1591 usort($dateeventarray, 'sort_events_by_date');
1592}
1593
1594
1595$maxnbofchar = 0;
1596$cachethirdparties = array();
1597$cachecontacts = array();
1598$cacheusers = array();
1599// default values
1601 array(137, 86, 161),
1602 array(60, 147, 183),
1603 array(250, 190, 80),
1604 array(80, 166, 90),
1605 array(190, 190, 100),
1606 array(91, 115, 247),
1607 array(140, 140, 220),
1608 array(190, 120, 120),
1609 array(115, 125, 150),
1610 array(100, 170, 20),
1611 array(150, 135, 125),
1612 array(85, 135, 150),
1613 array(150, 135, 80),
1614 array(150, 80, 150)
1615);
1616
1617// Define theme_datacolor array
1618$color_file = DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/theme_vars.inc.php";
1619if (is_readable($color_file)) {
1620 global $theme_datacolor;
1621 include $color_file;
1623}
1624
1625$massactionbutton = '';
1626
1627print_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);
1628
1629if ($nbevents > $MAXONSAMEPAGE) {
1630 print info_admin('Number of results has been truncated to '.$MAXONSAMEPAGE, 0, 0, 'warning').'<br>';
1631}
1632
1633// Show div with list of calendars
1634print $s;
1635
1636
1637if (empty($mode) || $mode == 'show_month') { // View by month
1638 $newparam = $param; // newparam is for birthday links
1639 $newparam = preg_replace('/check_birthday=/i', 'check_birthday_=', $newparam); // To avoid replacement when replace day= is done
1640 $newparam = preg_replace('/mode=show_month&?/i', '', $newparam);
1641 $newparam = preg_replace('/mode=show_week&?/i', '', $newparam);
1642 $newparam = preg_replace('/day=[0-9]+&?/i', '', $newparam);
1643 $newparam = preg_replace('/month=[0-9]+&?/i', '', $newparam);
1644 $newparam = preg_replace('/year=[0-9]+&?/i', '', $newparam);
1645 $newparam = preg_replace('/viewcal=[0-9]+&?/i', '', $newparam);
1646 $newparam = preg_replace('/check_birthday_=/i', 'check_birthday=', $newparam); // Restore correct parameter
1647 $newparam .= '&viewcal=1';
1648
1649 print '<div class="liste_titre liste_titre_bydiv centpercent">';
1650 print_actions_filter($form, $canedit, $status, $year, $month, $day, $check_birthday, '', $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroupids, '', $resourceid, $search_categ_cus);
1651 print '</div>';
1652
1653 print '<div class="div-table-responsive-no-min sectioncalendarbymonth maxscreenheightless300">';
1654 print '<table class="centpercent noborder nocellnopadd cal_pannel cal_month listwithfilterbefore">';
1655 print ' <tr class="liste_titre sticky">';
1656 // Column title of weeks numbers
1657 echo ' <td class="center">#</td>';
1658 $i = 0;
1659 while ($i < 7) {
1660 print ' <td class="center bold uppercase tdfordaytitle'.($i == 0 ? ' borderleft' : '').'">';
1661 $numdayinweek = (($i + (getDolGlobalInt('MAIN_START_WEEK', 1))) % 7);
1662 if (!empty($conf->dol_optimize_smallscreen)) {
1663 $labelshort = array(0 => 'SundayMin', 1 => 'MondayMin', 2 => 'TuesdayMin', 3 => 'WednesdayMin', 4 => 'ThursdayMin', 5 => 'FridayMin', 6 => 'SaturdayMin');
1664 print $langs->trans($labelshort[$numdayinweek]);
1665 } else {
1666 print $langs->trans("Day".$numdayinweek);
1667 }
1668 print ' </td>'."\n";
1669 $i++;
1670 }
1671 echo ' </tr>'."\n";
1672
1673 $todayarray = dol_getdate($now, true);
1674 $todaytms = dol_mktime(0, 0, 0, $todayarray['mon'], $todayarray['mday'], $todayarray['year']);
1675
1676 // In loops, tmpday contains day nb in current month (can be zero or negative for days of previous month)
1677 //var_dump($eventarray);
1678 for ($iter_week = 0; $iter_week < 6; $iter_week++) {
1679 echo " <tr>\n";
1680 // Get date of the current day, format 'yyyy-mm-dd'
1681 if ($tmpday <= 0) { // If number of the current day is in previous month
1682 $currdate0 = sprintf("%04d", $prev_year).sprintf("%02d", $prev_month).sprintf("%02d", $max_day_in_prev_month + $tmpday);
1683 } elseif ($tmpday <= $max_day_in_month) { // If number of the current day is in current month
1684 $currdate0 = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $tmpday);
1685 } else { // If number of the current day is in next month
1686 $currdate0 = sprintf("%04d", $next_year).sprintf("%02d", $next_month).sprintf("%02d", $tmpday - $max_day_in_month);
1687 }
1688 // Get week number for the targeted date '$currdate0'
1689 $numweek0 = date("W", strtotime(date($currdate0)));
1690 // Show the week number, and define column width
1691 echo ' <td class="center weeknumber opacitymedium" width="2%">'.$numweek0.'</td>';
1692
1693 for ($iter_day = 0; $iter_day < 7; $iter_day++) {
1694 if ($tmpday <= 0) {
1695 /* Show days before the beginning of the current month (previous month) */
1696 $style = 'cal_other_month cal_past';
1697 if ($iter_day == 6) {
1698 $style .= ' cal_other_month_right';
1699 }
1700 echo ' <td class="'.$style.' nowrap tdtop" width="14%">';
1701 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1702 show_day_events($db, $max_day_in_prev_month + $tmpday, $prev_month, $prev_year, $month, $style, $eventarray, $maxprint, $maxnbofchar, $newparam);
1703 echo " </td>\n";
1704 } elseif ($tmpday <= $max_day_in_month) {
1705 /* Show days of the current month */
1706 $curtime = dol_mktime(0, 0, 0, $month, $tmpday, $year);
1707 $style = 'cal_current_month';
1708 if ($iter_day == 6) {
1709 $style .= ' cal_current_month_right';
1710 }
1711 $today = 0;
1712 if ($todayarray['mday'] == $tmpday && $todayarray['mon'] == $month && $todayarray['year'] == $year) {
1713 $today = 1;
1714 }
1715 if ($today) {
1716 $style = 'cal_today';
1717 }
1718 if ($curtime < $todaytms) {
1719 $style .= ' cal_past';
1720 }
1721 //var_dump($todayarray['mday']."==".$tmpday." && ".$todayarray['mon']."==".$month." && ".$todayarray['year']."==".$year.' -> '.$style);
1722 echo ' <td class="'.$style.' nowrap tdtop" width="14%">';
1723 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1724 show_day_events($db, $tmpday, $month, $year, $month, $style, $eventarray, $maxprint, $maxnbofchar, $newparam, 0, 60, 0, $bookcalcalendars);
1725 echo "</td>\n";
1726 } else {
1727 /* Show days after the current month (next month) */
1728 $style = 'cal_other_month';
1729 if ($iter_day == 6) {
1730 $style .= ' cal_other_month_right';
1731 }
1732 echo ' <td class="'.$style.' nowrap tdtop" width="14%">';
1733 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1734 show_day_events($db, $tmpday - $max_day_in_month, $next_month, $next_year, $month, $style, $eventarray, $maxprint, $maxnbofchar, $newparam);
1735 echo "</td>\n";
1736 }
1737 $tmpday++;
1738 }
1739 echo " </tr>\n";
1740 }
1741 print "</table>\n";
1742 print '</div>';
1743
1744 print '<input type="hidden" name="actionmove" value="mupdate">';
1745 print '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($_SERVER['PHP_SELF']).'?mode=show_month&'.dol_escape_htmltag($_SERVER['QUERY_STRING']).'">';
1746 print '<input type="hidden" name="newdate" id="newdate">';
1747} elseif ($mode == 'show_week') {
1748 // View by week
1749 $newparam = $param; // newparam is for birthday links
1750 $newparam = preg_replace('/check_birthday=/i', 'check_birthday_=', $newparam); // To avoid replacement when replace day= is done
1751 $newparam = preg_replace('/mode=show_month&?/i', '', $newparam);
1752 $newparam = preg_replace('/mode=show_week&?/i', '', $newparam);
1753 $newparam = preg_replace('/day=[0-9]+&?/i', '', $newparam);
1754 $newparam = preg_replace('/month=[0-9]+&?/i', '', $newparam);
1755 $newparam = preg_replace('/year=[0-9]+&?/i', '', $newparam);
1756 $newparam = preg_replace('/viewweek=[0-9]+&?/i', '', $newparam);
1757 $newparam = preg_replace('/check_birthday_=/i', 'check_birthday=', $newparam); // Restore correct parameter
1758 $newparam .= '&viewweek=1';
1759
1760 print '<div class="liste_titre liste_titre_bydiv centpercent">';
1761 print_actions_filter($form, $canedit, $status, $year, $month, $day, $check_birthday, '', $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroupids, '', $resourceid);
1762 print '</div>';
1763
1764 print '<div class="div-table-responsive-no-min sectioncalendarbyweek maxscreenheightless300">';
1765 print '<table class="centpercent noborder nocellnopadd cal_pannel cal_month listwithfilterbefore">';
1766 print ' <tr class="liste_titre">';
1767 $i = 0;
1768 while ($i < 7) {
1769 echo ' <td class="center bold uppercase tdfordaytitle">'.$langs->trans("Day".(($i + (getDolGlobalInt('MAIN_START_WEEK', 1))) % 7))."</td>\n";
1770 $i++;
1771 }
1772 echo " </tr>\n";
1773
1774 echo ' <tr class="trcalweek">'."\n";
1775
1776 for ($iter_day = 0; $iter_day < 7; $iter_day++) {
1777 // Show days of the current week
1778 $curtime = dol_time_plus_duree($firstdaytoshow, $iter_day, 'd'); // $firstdaytoshow is in timezone of server
1779 $tmpday = (int) dol_print_date($curtime, '%d', 'tzuserrel');
1780 $tmpmonth = (int) dol_print_date($curtime, '%m', 'tzuserrel');
1781 $tmpyear = (int) dol_print_date($curtime, '%Y', 'tzuserrel');
1782
1783 $style = 'cal_current_month';
1784 if ($iter_day == 6) {
1785 $style .= ' cal_other_month_right';
1786 }
1787
1788 $today = 0;
1789 $todayarray = dol_getdate($now, true);
1790 if ($todayarray['mday'] == $tmpday && $todayarray['mon'] == $tmpmonth && $todayarray['year'] == $tmpyear) {
1791 $today = 1;
1792 }
1793 if ($today) {
1794 $style = 'cal_today';
1795 }
1796
1797 echo ' <td class="'.$style.'" width="14%" valign="top">';
1798 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1799 show_day_events($db, $tmpday, $tmpmonth, $tmpyear, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, 0, $bookcalcalendars);
1800 echo " </td>\n";
1801 }
1802 echo " </tr>\n";
1803
1804 print "</table>\n";
1805 print '</div>';
1806
1807 echo '<input type="hidden" name="actionmove" value="mupdate">';
1808 echo '<input type="hidden" name="backtopage" value="'.dol_escape_htmltag($_SERVER['PHP_SELF']).'?mode=show_week&'.dol_escape_htmltag($_SERVER['QUERY_STRING']).'">';
1809 echo '<input type="hidden" name="newdate" id="newdate">';
1810} else { // View by day
1811 $newparam = $param; // newparam is for birthday links
1812 $newparam = preg_replace('/mode=show_month&?/i', '', $newparam);
1813 $newparam = preg_replace('/mode=show_week&?/i', '', $newparam);
1814 $newparam = preg_replace('/viewday=[0-9]+&?/i', '', $newparam);
1815 $newparam .= '&viewday=1';
1816 // Code to show just one day
1817 $style = 'cal_current_month cal_current_month_oneday';
1818 $today = 0;
1819 $todayarray = dol_getdate($now, true);
1820 if ($todayarray['mday'] == $day && $todayarray['mon'] == $month && $todayarray['year'] == $year) {
1821 $today = 1;
1822 }
1823 //if ($today) $style='cal_today';
1824
1825 $timestamp = dol_mktime(12, 0, 0, $month, $day, $year);
1826 $arraytimestamp = dol_getdate($timestamp);
1827
1828 print '<div class="liste_titre liste_titre_bydiv centpercent">';
1829 print_actions_filter($form, $canedit, $status, $year, $month, $day, $check_birthday, '', $filtert, '', $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid);
1830 print '</div>';
1831
1832 print '<div class="div-table-responsive-no-min sectioncalendarbyday maxscreenheightless300">';
1833 echo '<table class="tagtable centpercent noborder nocellnopadd cal_pannel cal_month listwithfilterbefore" style="margin-bottom: 10px !important;">';
1834
1835 echo ' <tr class="tagtr liste_titre">';
1836 echo ' <td class="tagtd center bold uppercase">'.$langs->trans("Day".$arraytimestamp['wday'])."</td>\n";
1837 echo " </tr>\n";
1838
1839 /*
1840 echo ' <div class="tagtr">';
1841 echo ' <div class="tagtd width100"></div>';
1842 echo ' <div class="tagtd center">';
1843 echo show_day_events($db, $day, $month, $year, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, -1);
1844 echo ' </div>'."\n";
1845 echo " </div>\n";
1846 */
1847
1848 print '<tr class="trcalday"><td class="tdtop">';
1849
1850 /* WIP View per hour */
1851 $useviewhour = 0;
1852 if ($useviewhour) {
1853 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
1854
1855 $maxheightwin = (isset($_SESSION["dol_screenheight"]) && $_SESSION["dol_screenheight"] > 500) ? ($_SESSION["dol_screenheight"] - 200) : 660; // Also into index.php file
1856
1857 echo '<div style="max-height: '.$maxheightwin.'px;">';
1858 echo '<div class="tagtable centpercent calendarviewcontainer">';
1859
1860 $maxnbofchar = 80;
1861
1862 $tmp = explode('-', getDolGlobalString('MAIN_DEFAULT_WORKING_HOURS'));
1863 $minhour = round((float) $tmp[0], 0);
1864 $maxhour = round((float) $tmp[1], 0);
1865 if ($minhour > 23) {
1866 $minhour = 23;
1867 }
1868 if ($maxhour < 1) {
1869 $maxhour = 1;
1870 }
1871 if ($maxhour <= $minhour) {
1872 $maxhour = $minhour + 1;
1873 }
1874
1875 $i = 0;
1876 $j = 0;
1877 while ($i < 24) {
1878 echo ' <div class="tagtr calendarviewcontainertr">'."\n";
1879 echo ' <div class="tagtd width100 tdtop">'.dol_print_date($i * 3600, 'hour', 'gmt').'</div>';
1880 echo ' <div class="tagtd '.$style.' tdtop"></div>'."\n";
1881 echo ' </div>'."\n";
1882 $i++;
1883 $j++;
1884 }
1885
1886 echo '</div></div>';
1887
1888 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1889 show_day_events($db, $day, $month, $year, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, 1, $bookcalcalendars);
1890
1891 print '</div>';
1892 } else {
1893 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
1894
1895 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1896 show_day_events($db, $day, $month, $year, $month, $style, $eventarray, 0, $maxnbofchar, $newparam, 1, 300, 0, $bookcalcalendars);
1897
1898 print '</div>';
1899 }
1900
1901
1902 print '</td></tr>';
1903
1904 echo '</table>';
1905 print '</div>';
1906}
1907
1908print "\n".'</form>';
1909
1910// End of page
1911llxFooter();
1912$db->close();
1913
1914
1934function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventarray, $maxprint = 0, $maxnbofchar = 16, $newparam = '', $showinfo = 0, $minheight = 60, $nonew = 0, $bookcalcalendarsarray = array())
1935{
1936 global $user, $conf, $langs;
1937 global $action, $mode, $filter, $filtert, $status, $actioncode, $usergroup; // Filters used into search form
1938 global $theme_datacolor;
1939 global $cachethirdparties, $cachecontacts, $cacheusers, $colorindexused;
1940 global $hookmanager;
1941
1942 '@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
1943 @phan-var-force User[] $cacheusers
1944 @phan-var-force array<int<0,3>> $colorindexused';
1951 if ($conf->use_javascript_ajax) { // Enable the "Show more button..."
1952 $conf->global->MAIN_JS_SWITCH_AGENDA = 1;
1953 }
1954
1955 $dateint = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day);
1956 $datenowint = dol_print_date(dol_now(), "%Y%m%d");
1957 //print 'show_day_events day='.$day.' month='.$month.' year='.$year.' dateint='.$dateint.' datenowint='.$datenowint;
1958
1959 print "\n";
1960
1961 $curtime = dol_mktime(0, 0, 0, $month, $day, $year);
1962 $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;
1963 $urltocreate = '';
1964 if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
1965 $newparam .= '&month='.str_pad((string) $month, 2, "0", STR_PAD_LEFT).'&year='.$year;
1966 $hourminsec = getDolGlobalString('AGENDA_DEFAULT_BEGIN_TIME');
1967 if (empty($hourminsec) || !preg_match('/^[0-9]{6}$/', $hourminsec)) {
1968 $hourminsec = '100000';
1969 }
1970 $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 : ''));
1971 }
1972
1973 // Line with title of day
1974 print '<div id="dayevent_'.$dateint.'" class="dayevent tagtable centpercent nobordernopadding">'."\n";
1975
1976 if ($nonew <= 0) {
1977 print '<div class="tagtr cursorpointer" onclick="window.location=\''.$urltocreate.'\';"><div class="nowrap tagtd"><div class="left inline-block">';
1978 print '<a class="dayevent-aday" style="color: #666" href="'.$urltoshow.'">';
1979 print($datenowint == $dateint ? '<span class="badgeliketopmenu">' : '');
1980 if ($showinfo) {
1981 print dol_print_date($curtime, 'daytextshort');
1982 } else {
1983 print dol_print_date($curtime, '%d');
1984 }
1985 print($datenowint == $dateint ? '</span>' : '');
1986 print '</a>';
1987 print '</div><div class="nowrap floatright inline-block marginrightonly">';
1988 if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
1989 print '<a class="cursoradd" href="'.$urltocreate.'">'; // Explicit link, useful for nojs interfaces
1990 print img_picto($langs->trans("NewAction"), 'edit_add.png');
1991 print '</a>';
1992 }
1993 print '</div></div></div>'."\n";
1994 }
1995
1996 if ($nonew < 0) {
1997 print '</div>';
1998 return;
1999 }
2000
2001 // Line with td contains all div of each events
2002 print '<div class="tagtr">';
2003 print '<div class="tagtd centpercent agendacell sortable">';
2004
2005 //$curtime = dol_mktime (0, 0, 0, $month, $day, $year);
2006 $i = 0;
2007 $ireallyshown = 0;
2008 $itoshow = 0;
2009 $numother = 0;
2010 $numbirthday = 0;
2011 $numical = 0;
2012 $numicals = array();
2013 $ymd = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day);
2014
2015 $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0
2016 $nextindextouse = is_array($colorindexused) ? count($colorindexused) : 0; // At first run this is 0, so fist user has 0, next 1, ...
2017 //var_dump($colorindexused);
2018
2019 include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
2020 $tmpholiday = new Holiday($db);
2021
2022 foreach ($eventarray as $daykey => $notused) { // daykey is the 'YYYYMMDD' to show according to user
2023 $annee = (int) dol_print_date($daykey, '%Y', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD'
2024 $mois = (int) dol_print_date($daykey, '%m', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD'
2025 $jour = (int) dol_print_date($daykey, '%d', 'gmt'); // We use gmt because we want the value represented by string 'YYYYMMDD'
2026
2027 //print 'event daykey='.$daykey.' dol_print_date(daykey)='.dol_print_date($daykey, 'dayhour', 'gmt').' jour='.$jour.' mois='.$mois.' annee='.$annee."<br>\n";
2028 //print 'event daykey='.$daykey.' dol_print_date(daykey)='.dol_print_date($daykey, 'dayhour', 'gmt').' day='.$day.' month='.$month.' year='.$year."<br>\n";
2029
2030 if ($day == $jour && $month == $mois && $year == $annee) {
2031 foreach ($eventarray[$daykey] as $index => $event) {
2032 if ($i < $maxprint || $maxprint == 0 || getDolGlobalString('MAIN_JS_SWITCH_AGENDA')) {
2033 $keysofuserassigned = array_keys($event->userassigned);
2034
2035 // Define $color (Hex string like '0088FF') and $cssclass of event
2036 $color = -1;
2037 $cssclass = '';
2038 $colorindex = -1;
2039 if (in_array($user->id, $keysofuserassigned)) {
2040 $cssclass = 'family_mytasks';
2041
2042 if (empty($cacheusers[$event->userownerid])) {
2043 $newuser = new User($db);
2044 $newuser->fetch($event->userownerid);
2045 $cacheusers[$event->userownerid] = $newuser;
2046 }
2047 //var_dump($cacheusers[$event->userownerid]->color);
2048
2049 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
2050 if (!empty($cacheusers[$event->userownerid]->color)) {
2051 $color = $cacheusers[$event->userownerid]->color;
2052 }
2053
2054 /* May be we need this: if (getDolGlobalString('AGENDA_USE_COLOR_PER_EVENT_TYPE')) {
2055 $color = $event->type_color;
2056 }*/
2057 } elseif ($event->type_code == 'ICALEVENT') { // Event come from external ical file
2058 $numical++;
2059 if (!empty($event->icalname)) {
2060 if (!isset($numicals[dol_string_nospecial($event->icalname)])) {
2061 $numicals[dol_string_nospecial($event->icalname)] = 0;
2062 }
2063 $numicals[dol_string_nospecial($event->icalname)]++;
2064 }
2065
2066 $color = ($event->icalcolor ? $event->icalcolor : -1);
2067 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other');
2068 } elseif ($event->type_code == 'BIRTHDAY') {
2069 $numbirthday++;
2070 $colorindex = 2;
2071 $cssclass = 'family_birthday ';
2072 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2073 } elseif ($event->type == 'bookcal_calendar') {
2074 $numbirthday++;
2075 $colorindex = 3;
2076 $cssclass = 'family_bookcal_calendar_'.(!empty($bookcalcalendarsarray["availabilitieslink"]) ? $bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar] : "");
2077 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2078 } else {
2079 $numother++;
2080 $color = ($event->icalcolor ? $event->icalcolor : -1);
2081 $cssclass = (!empty($event->icalname) ? 'family_ext'.md5($event->icalname) : 'family_other');
2082
2083 if (empty($cacheusers[$event->userownerid])) {
2084 $newuser = new User($db);
2085 $newuser->fetch($event->userownerid);
2086 $cacheusers[$event->userownerid] = $newuser;
2087 }
2088 //var_dump($cacheusers[$event->userownerid]->color);
2089
2090 // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event)
2091 if (!empty($cacheusers[$event->userownerid]->color)) {
2092 $color = $cacheusers[$event->userownerid]->color;
2093 }
2094 }
2095
2096 if ($color < 0) { // Color was not set on user card. Set color according to color index.
2097 // Define color index if not yet defined
2098 $idusertouse = ($event->userownerid ? $event->userownerid : 0);
2099 if (isset($colorindexused[$idusertouse])) {
2100 $colorindex = $colorindexused[$idusertouse]; // Color already assigned to this user
2101 } else {
2102 $colorindex = $nextindextouse;
2103 $colorindexused[$idusertouse] = $colorindex;
2104 if (!empty($theme_datacolor[$nextindextouse + 1])) {
2105 $nextindextouse++; // Prepare to use next color
2106 }
2107 }
2108 if (isset($theme_datacolor[$colorindex])) {
2109 $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
2110 } elseif (getDolGlobalString('THEME_ELDY_BACKBODY')) {
2111 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2112 $color = colorArrayToHex(colorStringToArray(getDolGlobalString('THEME_ELDY_BACKBODY'), array()), '');
2113 } else {
2114 $color = "ffffff";
2115 }
2116 }
2117 $cssclass = $cssclass.' eventday_'.$ymd;
2118
2119 // Defined style to disable drag and drop feature
2120 if ($event->type_code == 'AC_OTH_AUTO') {
2121 $cssclass .= " unmovable";
2122 } elseif ($event->type_code == 'HOLIDAY') {
2123 $cssclass .= " unmovable";
2124 } elseif ($event->type_code == 'BIRTHDAY') {
2125 $cssclass .= " unmovable";
2126 } elseif ($event->type_code == 'ICALEVENT') {
2127 $cssclass .= " unmovable";
2128 } 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)) {
2129 // If the event is on several days
2130 $tmpyearend = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel');
2131 $tmpmonthend = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel');
2132 $tmpdayend = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel');
2133 //var_dump($tmpyearend.' '.$tmpmonthend.' '.$tmpdayend);
2134 if ($tmpyearend != $annee || $tmpmonthend != $mois || $tmpdayend != $jour) {
2135 $cssclass .= " unmovable unmovable-mustusefirstdaytodrag";
2136 } else {
2137 $cssclass .= ' movable cursormove';
2138 }
2139 } else {
2140 if ($user->hasRight('agenda', 'allactions', 'create') ||
2141 (($event->authorid == $user->id || $event->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'))) {
2142 $cssclass .= " movable cursormove";
2143 } else {
2144 $cssclass .= " unmovable";
2145 }
2146 }
2147
2148 $h = '';
2149 $nowrapontd = 1;
2150 if ($mode == 'show_day') {
2151 $h = 'height: 100%; ';
2152 $nowrapontd = 0;
2153 }
2154 if ($mode == 'show_week') {
2155 $h = 'height: 100%; ';
2156 $nowrapontd = 0;
2157 }
2158
2159 // Show event box
2160 print "\n";
2161 print '<!-- start event '.$i.' -->'."\n";
2162
2163 $morecss = '';
2164 if ($maxprint && $ireallyshown >= $maxprint) {
2165 $morecss = 'showifmore';
2166 }
2167 if ($event->type == 'birthdate' && !GETPOST('check_birthday')) {
2168 $morecss = 'hidden';
2169 }
2170 if ($event->type == 'holiday' && !GETPOST('check_holiday')) {
2171 $morecss = 'hidden';
2172 }
2173 /* I comment this because it hides event recorded from bookcal online page
2174 if ($event->type == 'bookcal_calendar' && !GETPOST('check_bookcal_calendar_'.$bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar])) {
2175 $morecss = 'hidden';
2176 } */
2177 if ($morecss != 'hidden') {
2178 $itoshow++;
2179 }
2180 if ($morecss != 'showifmore' && $morecss != 'hidden') {
2181 $ireallyshown++;
2182 }
2183
2184 //var_dump($event->type.' - '.$morecss.' - '.$cssclass.' - '.$i.' - '.$ireallyshown.' - '.$itoshow);
2185 if (isModEnabled("bookcal") && $event->type == 'bookcal_calendar') {
2186 print '<div id="event_'.$ymd.'_'.$i.'" class="event family_'.$event->type.'_'.$bookcalcalendarsarray["availabilitieslink"][$event->fk_bookcal_calendar].' '.$cssclass.($morecss ? ' '.$morecss : '').'"';
2187 } else {
2188 print '<div id="event_'.$ymd.'_'.$i.'" class="event family_'.$event->type.' '.$cssclass.($morecss ? ' '.$morecss : '').'"';
2189 }
2190 //print ' style="height: 100px;';
2191 //print ' position: absolute; top: 40px; width: 50%;';
2192 //print '"';
2193 print '>';
2194
2195 //var_dump($event->userassigned);
2196 //var_dump($event->transparency);
2197 print '<table class="centpercent cal_event';
2198 print(empty($event->transparency) ? ' cal_event_notbusy' : ' cal_event_busy');
2199 //if (empty($event->transparency) && empty($conf->global->AGENDA_NO_TRANSPARENT_ON_NOT_BUSY)) print ' opacitymedium'; // Not busy
2200 print '" style="'.$h;
2201 $colortouse = $color;
2202 // If colortouse is similar than background, we force to change it.
2203 if (empty($event->transparency) && !getDolGlobalString('AGENDA_NO_TRANSPARENT_ON_NOT_BUSY')) {
2204 print 'background: #f0f0f0;';
2205 print 'border-left: 5px solid #'.$colortouse.';';
2206 } else {
2207 print 'background: #f0f0f0;';
2208 print 'border-left: 5px solid #'.dol_color_minus($colortouse, -3).';';
2209 //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($colortouse, -3).'), to(#'.dol_color_minus($colortouse, -1).'));';
2210 }
2211 //print 'background: #'.$colortouse.';';
2212 //print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($color, -3).'), to(#'.dol_color_minus($color, -1).'));';
2213 //if (!empty($event->transparency)) print 'background: #'.$color.'; background: -webkit-gradient(linear, left top, left bottom, from(#'.$color.'), to(#'.dol_color_minus($color,1).'));';
2214 //else print 'background-color: transparent !important; background: none; border: 1px solid #bbb;';
2215 //print ' -moz-border-radius:4px;"';
2216 //print 'border: 1px solid #ccc" width="100%"';
2217 print '">';
2218
2219 // First the tr of the event (only one tr for event is used, but several td)
2220 print '<tr>';
2221 print '<td class="tdoverflow nobottom small centpercent '.($nowrapontd ? 'nowrap ' : '').'cal_event'.($event->type_code == 'BIRTHDAY' ? ' cal_event_birthday' : '').'">';
2222 print '<!-- left section of event -->';
2223
2224 $daterange = '';
2225
2226 $parameters = array();
2227 $reshook = $hookmanager->executeHooks('eventOptions', $parameters, $event, $action); // Note that $action and $object may have been modified by some hooks
2228 if ($reshook < 0) {
2229 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2230 } else {
2231 '@phan-var-force ActionComm $event';
2232 if (empty($reshook)) {
2233 // Other calendar
2234 /*
2235 if (empty($event->fulldayevent)) {
2236 //print $event->getNomUrl(2).' ';
2237 }
2238 */
2239
2240 if ($event->type_code == 'BIRTHDAY') {
2241 // It's birthday calendar
2242 $picb = img_picto('', 'birthday-cake', 'class="pictofixedwidth"');
2243 print $picb.$langs->trans("Birthday").'<br>';
2244 }
2245
2246 // Date
2247 if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY') {
2248 if (empty($event->fulldayevent)) {
2249 // Show hours (start ... end)
2250 $tmpyearstart = dol_print_date($event->date_start_in_calendar, '%Y', 'tzuserrel');
2251 $tmpmonthstart = dol_print_date($event->date_start_in_calendar, '%m', 'tzuserrel');
2252 $tmpdaystart = dol_print_date($event->date_start_in_calendar, '%d', 'tzuserrel');
2253 $tmpyearend = dol_print_date($event->date_end_in_calendar, '%Y', 'tzuserrel');
2254 $tmpmonthend = dol_print_date($event->date_end_in_calendar, '%m', 'tzuserrel');
2255 $tmpdayend = dol_print_date($event->date_end_in_calendar, '%d', 'tzuserrel');
2256
2257 // Hour start
2258 if ($tmpyearstart == $annee && $tmpmonthstart == $mois && $tmpdaystart == $jour) {
2259 $daterange .= dol_print_date($event->date_start_in_calendar, 'hour', 'tzuserrel');
2260 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) {
2261 if ($tmpyearstart == $tmpyearend && $tmpmonthstart == $tmpmonthend && $tmpdaystart == $tmpdayend) {
2262 $daterange .= '-';
2263 }
2264 //else
2265 //print '...';
2266 }
2267 }
2268 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) {
2269 if ($tmpyearstart != $tmpyearend || $tmpmonthstart != $tmpmonthend || $tmpdaystart != $tmpdayend) {
2270 $daterange .= '...';
2271 }
2272 }
2273 // Hour end
2274 if ($event->date_end_in_calendar && $event->date_start_in_calendar != $event->date_end_in_calendar) {
2275 if ($tmpyearend == $annee && $tmpmonthend == $mois && $tmpdayend == $jour) {
2276 $daterange .= dol_print_date($event->date_end_in_calendar, 'hour', 'tzuserrel');
2277 }
2278 }
2279 } else {
2280 if ($showinfo) {
2281 print $langs->trans("EventOnFullDay")."<br>\n";
2282 }
2283 }
2284 }
2285
2286 // Show title
2287 $titletoshow = $daterange;
2288 $titletoshow .= ($titletoshow ? ' ' : '').dol_escape_htmltag($event->label);
2289
2290 if ($event->type_code != 'ICALEVENT' && $event->type_code != 'BIRTHDAY') {
2291 $savlabel = $event->label;
2292 $event->label = $titletoshow;
2293 // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user.
2294 $titletoshow = (($event->type_picto || $event->type_code) ? $event->getTypePicto() : '');
2295 $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 '...'
2296 $event->label = $savlabel;
2297 }
2298
2299 // Loop on each assigned user
2300 $listofusertoshow = '';
2301 $posuserassigned = 0;
2302 foreach ($event->userassigned as $tmpid => $tmpdata) {
2303 if (!$posuserassigned && $titletoshow) {
2304 $listofusertoshow .= '<br>';
2305 }
2306 $posuserassigned++;
2307 if (empty($cacheusers[$tmpid])) {
2308 $newuser = new User($db);
2309 $newuser->fetch($tmpid);
2310 $cacheusers[$tmpid] = $newuser;
2311 }
2312
2313 $listofusertoshow .= $cacheusers[$tmpid]->getNomUrl(-3, '', 0, 0, 0, 0, '', 'valignmiddle inline-block');
2314 }
2315
2316 if ($event->type_code != 'BIRTHDAY' && $event->type_code != 'HOLIDAY') {
2317 print $titletoshow;
2318 print $listofusertoshow.' &nbsp;';
2319 }
2320
2321 if ($event->type_code == 'ICALEVENT') {
2322 print '<br>('.dol_trunc($event->icalname, $maxnbofchar).')';
2323 }
2324
2325 $thirdparty_id = ($event->socid > 0 ? $event->socid : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0));
2326 $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->contact->id > 0) ? $event->contact->id : 0));
2327
2328 // If action related to company / contact
2329 $linerelatedto = '';
2330 if ($thirdparty_id > 0) {
2331 if (!isset($cachethirdparties[$thirdparty_id]) || !is_object($cachethirdparties[$thirdparty_id])) {
2332 $thirdparty = new Societe($db);
2333 $thirdparty->fetch($thirdparty_id);
2334 $cachethirdparties[$thirdparty_id] = $thirdparty;
2335 } else {
2336 $thirdparty = $cachethirdparties[$thirdparty_id];
2337 }
2338 if (!empty($thirdparty->id)) {
2339 $linerelatedto .= $thirdparty->getNomUrl(1, '', 0, 0, -1, 0, '', 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large
2340 }
2341 }
2342 if (!empty($contact_id) && $contact_id > 0) {
2343 if (empty($cachecontacts[$contact_id]) || !is_object($cachecontacts[$contact_id])) {
2344 $contact = new Contact($db);
2345 $contact->fetch($contact_id);
2346 $cachecontacts[$contact_id] = $contact;
2347 } else {
2348 $contact = $cachecontacts[$contact_id];
2349 }
2350 if ($linerelatedto) {
2351 $linerelatedto .= '&nbsp;';
2352 }
2353 if (!empty($contact->id)) {
2354 $linerelatedto .= $contact->getNomUrl(1, '', 0, '', -1, 0, 'valignmiddle inline'); // using inline-block make the content completely replace with ... when too large
2355 }
2356 }
2357 if (!empty($event->fk_element) && $event->fk_element > 0 && !empty($event->elementtype) && getDolGlobalString('AGENDA_SHOW_LINKED_OBJECT')) {
2358 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2359 if ($linerelatedto) {
2360 $linerelatedto .= '<br>';
2361 }
2362 $linerelatedto .= dolGetElementUrl($event->fk_element, $event->elementtype, 1);
2363 }
2364 if ($linerelatedto) {
2365 print ' '.$linerelatedto;
2366 }
2367 } elseif (!empty($reshook)) {
2368 print $hookmanager->resPrint;
2369 }
2370 }
2371
2372 if ($event->type_code == 'HOLIDAY') {
2373 // It's holiday calendar
2374 $tmpholiday->fetch($event->id);
2375
2376 print $tmpholiday->getNomUrl(1, -1, 0, 'valignmiddle inline-block');
2377
2378 $tmpid = $tmpholiday->fk_user;
2379 if (empty($cacheusers[$tmpid])) {
2380 $newuser = new User($db);
2381 $newuser->fetch($tmpid);
2382 $cacheusers[$tmpid] = $newuser;
2383 }
2384
2385 $listofusertoshow = '';
2386 $listofusertoshow .= "\n".'<br>'.$cacheusers[$tmpid]->getNomUrl(-1, '', 0, 0, 0, 0, '', 'paddingright valignmiddle inline-block')."\n";
2387 print $listofusertoshow;
2388 }
2389
2390 // Show location
2391 if ($showinfo) {
2392 if ($event->location) {
2393 print '<br>';
2394 print $langs->trans("Location").': '.$event->location;
2395 }
2396 }
2397
2398 print '</td>';
2399
2400 // Status - Percent
2401 $withstatus = 0;
2402 if ($event->type_code != 'HOLIDAY' && $event->type_code != 'BIRTHDAY' && $event->type_code != 'ICALEVENT') {
2403 $withstatus = 1;
2404 if ($event->percentage >= 0) {
2405 $withstatus = 2;
2406 }
2407 }
2408 print '<td class="nobottom right nowrap cal_event_right'.($withstatus >= 2 ? ' cal_event_right_status' : '').'">';
2409 if ($withstatus) {
2410 print $event->getLibStatut(3, 1);
2411 } else {
2412 print '&nbsp;';
2413 }
2414 print '</td></tr></table>';
2415 print '</div><!-- end event '.$i.' -->'."\n";
2416
2417 $i++;
2418 } else {
2419 print '<a href="'.DOL_URL_ROOT.'/comm/action/index.php?mode='.$mode.'&maxprint=0&month='.((int) $monthshown).'&year='.((int) $year);
2420 print($status ? '&status='.$status : '').($filter ? '&filter='.urlencode($filter) : '');
2421 print($filtert ? '&search_filtert='.urlencode((string) $filtert) : '');
2422 print($usergroup ? '&search_usergroup='.urlencode((string) $usergroup) : '');
2423 print($actioncode != '' ? '&search_actioncode='.urlencode($actioncode) : '');
2424 print '">'.img_picto("all", "1downarrow_selected.png").' ...';
2425 print ' +'.(count($eventarray[$daykey]) - $maxprint);
2426 print '</a>';
2427 break;
2428 //$ok=false; // To avoid to show twice the link
2429 }
2430 }
2431
2432 break;
2433 }
2434 }
2435 if (!$i) { // No events
2436 print '&nbsp;';
2437 }
2438
2439 if (getDolGlobalString('MAIN_JS_SWITCH_AGENDA') && $itoshow > $ireallyshown && $maxprint) {
2440 print '<div class="center cursorpointer" id="more_'.$ymd.'">'.img_picto("All", "angle-double-down", 'class="warning"').' +'.($itoshow - $ireallyshown).'</div>';
2441 //print ' +'.(count($eventarray[$daykey])-$maxprint);
2442
2443 print '<script type="text/javascript">'."\n";
2444 print 'jQuery(document).ready(function () {'."\n";
2445 print ' var open=0;'."\n";
2446 print ' jQuery("#more_'.$ymd.'").click(function() { console.log("Click on showmore for '.$ymd.'"); reinit_day_'.$ymd.'(); event.stopImmediatePropagation(); });'."\n";
2447 print ' function reinit_day_'.$ymd.'() {'."\n";
2448 print ' jQuery(".eventday_'.$ymd.'.showifmore").toggle();'."\n";
2449 print ' open = open + 1; if (open > 1) { open = 0; }'."\n";
2450 print ' if (open) { ';
2451 print ' jQuery("#more_'.$ymd.'").html(\''.img_picto("All", "angle-double-up", 'class="warning"').'\');'."\n";
2452 print ' } else { ';
2453 print ' jQuery("#more_'.$ymd.'").html(\''.img_picto("All", "angle-double-down", 'class="warning"').' +'.($itoshow - $ireallyshown).'\');'."\n";
2454 print ' }'."\n";
2455 print ' }'."\n";
2456 print '});'."\n";
2457 print '</script>'."\n";
2458 }
2459
2460 print '</div></div>'; // td tr
2461
2462 print '</div>'; // table
2463 print "\n";
2464}
2465
2466
2475function dol_color_minus($color, $minus, $minusunit = 16)
2476{
2477 $newcolor = $color;
2478 if ($minusunit == 16 && is_array($newcolor)) {
2479 $newcolor[0] = dechex(max(min(hexdec($newcolor[0]) - $minus, 15), 0));
2480 $newcolor[2] = dechex(max(min(hexdec($newcolor[2]) - $minus, 15), 0));
2481 $newcolor[4] = dechex(max(min(hexdec($newcolor[4]) - $minus, 15), 0));
2482 } else {
2483 // Not yet implemented
2484 }
2485 return $newcolor;
2486}
2487
2495function sort_events_by_date($a, $b)
2496{
2497 // Sort holidays at first
2498 if ($a->type_code === 'HOLIDAY') {
2499 return -1;
2500 }
2501 if ($b->type_code === 'HOLIDAY') {
2502 return 1;
2503 }
2504
2505 // datep => Event start time
2506 // datef => Event end time
2507
2508 // Events have different start time
2509 if ($a->datep !== $b->datep) {
2510 return (int) ($a->datep - $b->datep);
2511 }
2512
2513 // Events have same start time and no end time
2514 if ((!is_numeric($b->datef)) || (!is_numeric($a->datef))) {
2515 return sort_events_by_percentage($a, $b);
2516 }
2517
2518 // Events have the same start time and same end time
2519 if ($b->datef === $a->datef) {
2520 return sort_events_by_percentage($a, $b);
2521 }
2522
2523 // Events have the same start time, but have different end time -> longest event first
2524 return (int) ($b->datef - $a->datef);
2525}
2526
2534function sort_events_by_percentage($a, $b)
2535{
2536 // Sort events with no percentage before each other
2537 // (useful to sort holidays, sick days or similar on the top)
2538
2539 if ($a->percentage < 0) {
2540 return -1;
2541 }
2542
2543 if ($b->percentage < 0) {
2544 return 1;
2545 }
2546
2547 return (int) ($b->percentage - $a->percentage);
2548}
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:1600
$cacheusers
Definition index.php:1598
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:168
dol_get_prev_month($month, $year)
Return previous month.
Definition date.lib.php:523
dol_get_first_hour($date, $gm='tzserver')
Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
Definition date.lib.php:664
dol_get_next_day($day, $month, $year)
Return next day.
Definition date.lib.php:508
dol_get_next_week($day, $week, $month, $year)
Return next week.
Definition date.lib.php:582
dol_get_first_day_week($day, $month, $year, $gm=false)
Return first day of week for a date.
Definition date.lib.php:679
dol_get_prev_day($day, $month, $year)
Return previous day.
Definition date.lib.php:492
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:604
dol_get_next_month($month, $year)
Return next month.
Definition date.lib.php:542
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:126
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:435
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:623
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='')
Show information in HTML for admin users or standard users.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_sanitizePathName($str, $newstr='_', $unaccent=0, $allowdash=0)
Clean a string to use it as a path name.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolUserString($key, $default='', $tmpuser=null)
Return Dolibarr user constant string value.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition inc.php:426
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as date
Definition receipt.php:487
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.