Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW add a check on working/opening hours AND entities check (see other PR) #32514

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
67 changes: 65 additions & 2 deletions htdocs/public/bookcal/bookcalAjax.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/bookcal/class/calendar.class.php';

$action = GETPOST('action', 'aZ09');
$id = GETPOSTINT('id');
Expand Down Expand Up @@ -71,6 +72,66 @@

top_httphead('application/json');

//MOD CHECK OPENHOURS
/**
* Check opening hours against availability days in entity conf
* MAIN_INFO_OPENINGHOURS_[weekday] content is used as ref for ranges
* expected ranges format is "HH:MM-HH:MM" minutes are optionals
* multiple range are ';' or ' ' separated
*
* @param int $calid calendar id
* @param int $datetocheckbooking apointement date
* @param string $hourstring apointement start hour
* @param string $minstring apointement start min
* @param int $offsetmin apointement duration
* @return int value 1 OK ; 0 KO
*/
function checkAgainstOpeningHours($calid, $datetocheckbooking, $hourstring, $minstring, $offsetmin)
{
global $conf;
global $db;

$cal = new Calendar($db);
$result = $cal->fetch($calid);
$savconf = $conf;
$conf=new Conf();
$conf->entity = $cal->entity;
$conf->db = $db;
$conf->setValues($db);

$rangesstr = getDolGlobalString('MAIN_INFO_OPENINGHOURS_'. strtoupper(date('l', $datetocheckbooking)));
$rangearr = preg_split("/[\,; ]/", $rangesstr, -1, PREG_SPLIT_NO_EMPTY);

foreach ($rangearr as $r) {
$timelim = explode('-', $r);
$tstart = array();
$tstart[0] = '00';
$tend = array();
$tend[0] = '23';
if ($timelim[0]) {
$tstart = preg_split("/:/", $timelim[0]);
if ($timelim[1]) {
$tend = preg_split("/:/", $timelim[1]);
}
}
if (count($tstart) == 1) {
$tstart[1] = '00';
}
if (count($tend) == 1) {
$tend[1] = '59';
}
$mintime = $datetocheckbooking + $tstart[0] *3600 + $tstart[1] *60;
$maxtime = $datetocheckbooking + $tend[0] *3600 + $tend[1] *60;
$evstart = $datetocheckbooking + intval($hourstring) *3600 + (intval($minstring)+$offsetmin) *60;
$evend = $evstart + $offsetmin*60;
if ($evstart >= $mintime && $evend <= $maxtime) {
return 1;
}
}
$conf = $savconf;
return 0;
}

if ($action == 'verifyavailability') { // Test on permission not required here (anonymous action protected by mitigation of /public/... urls)
$response = array();
if (empty($id)) {
Expand Down Expand Up @@ -131,7 +192,10 @@
if ($min < 10) {
$minstring = "0".$minstring;
}
$response["availability"][$hourstring.":".$minstring] = intval($obj->duration);
//MOD CHECK OPENHOURS
if (checkAgainstOpeningHours($id, $datetocheckbooking, $hourstring, $minstring, $offsetmin)) {
$response["availability"][$hourstring.":".$minstring] = intval($obj->duration);
}
}
}
}
Expand Down Expand Up @@ -181,5 +245,4 @@
$result = $response;
}


echo json_encode($result);
98 changes: 86 additions & 12 deletions htdocs/public/bookcal/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Copyright (C) 2009-2012 Regis Houssin <[email protected]>
* Copyright (C) 2023 anthony Berton <[email protected]>
* Copyright (C) 2024 MDW <[email protected]>
* Copyright (C) 2024 Frédéric France <[email protected]>
* Copyright (C) 2024 Frédéric France <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -21,9 +21,9 @@
*/

/**
* \file htdocs/public/bookcal/index.php
* \ingroup core
* \brief File to offer a way to book a rendez-vous into a public calendar
* \file htdocs/public/bookcal/index.php
* \ingroup core
* \brief File to offer a way to book a rendez-vous into a public calendar
* Example of URL: https://localhost/public/bookcal/index.php?id=...
*/

Expand Down Expand Up @@ -127,10 +127,10 @@
*
* @param string $title Title
* @param string $head Head array
* @param int $disablejs More content into html header
* @param int $disablehead More content into html header
* @param string[]|string $arrayofjs Array of complementary js files
* @param string[]|string $arrayofcss Array of complementary css files
* @param int $disablejs More content into html header
* @param int $disablehead More content into html header
* @param string[]|string $arrayofjs Array of complementary js files
* @param string[]|string $arrayofcss Array of complementary css files
* @return void
*/
function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = [], $arrayofcss = [])
Expand Down Expand Up @@ -194,6 +194,7 @@ function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $
$error = 0;
$idcontact = 0;
$calendar = $object;
$conf->entity = $calendar->entity; // force entity for actioncomm create (its using '$conf->')
$contact = new Contact($db);
$actioncomm = new ActionComm($db);
$nb_post_max = getDolGlobalInt("MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS", 200);
Expand Down Expand Up @@ -223,6 +224,9 @@ function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $
$sql .= " WHERE s.lastname = '".$db->escape(GETPOST("lastname"))."'";
$sql .= " AND s.firstname = '".$db->escape(GETPOST("firstname"))."'";
$sql .= " AND s.email = '".$db->escape(GETPOST("email"))."'";
// cannot use getEntity (we are anonymous) here,
// so we check but only on same entity as known calendar
$sql .= " AND s.entity = ".((int) $calendar->entity);
$resql = $db->query($sql);

if ($resql) {
Expand All @@ -236,6 +240,9 @@ function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $
$contact->firstname = GETPOST("firstname");
$contact->email = GETPOST("email");
$contact->ip = getUserRemoteIP();
// force entity to be same as calendar,
// so cal owner (+other if sharing allowed) can see it
$contact->entity = $calendar->entity;

if (checkNbPostsForASpeceificIp($contact, $nb_post_max) <= 0) {
$error++;
Expand Down Expand Up @@ -267,9 +274,15 @@ function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $
$actioncomm->fk_bookcal_calendar = $id;
$actioncomm->userownerid = $calendar->visibility;
$actioncomm->contact_id = $contact->id;
// force entity to be same as calendar, so cal owner (+other if sharing allowed) can see it
$actioncomm->entity = $calendar->entity;
// set user (=cal owner) to BUSY
$actioncomm->transparency = 1;
$actioncomm->socpeopleassigned = [
$contact->id => [
'id' => $contact->id,
// force entity to be same as calendar
'entity' => $calendar->entity,
'mandatory' => 0,
'answer_status' => 0,
'transparency' =>0,
Expand Down Expand Up @@ -318,6 +331,55 @@ function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $

//print '<div class="">';

/**
* Check if in availability range
*
* @param string $start_date startdate
* @param string $end_date enddate
* @param string $date_from_user date selected
* @return boolean is date selected between start and end
*/
function check_in_range($start_date, $end_date, $date_from_user)
{
// Convert to timestamp
$start_ts = strtotime($start_date);
$end_ts = strtotime($end_date);
$user_ts = strtotime($date_from_user);

// Check that user date is between start & end
return (($user_ts >= $start_ts) && ($user_ts <= $end_ts));
}



/**
* Check if date is in opening days
*
* @param int $daytocheck date
* @param int $calentity entity from calendar
* @param object $db DB, might be useless (global ?)
* @return string opening hours on that day
*/
function checkAgainstOpeningDays($daytocheck, $calentity, $db)
{
global $conf;

$dow_text = date('l', $daytocheck); //no "dol_date" or dol_get_day_of_week
$valuechecked = 'MAIN_INFO_OPENINGHOURS_' . strtoupper($dow_text);
$savconf = $conf;
$conf=new Conf();
$conf->entity = $calentity;
$conf->db = $db;
$conf->setValues($db);
$retval = '' . getDolGlobalString($valuechecked);

if ($retval == '0') {
$retval = '';
}
$conf = $savconf;
return $retval;
}

print '<div class="bookcalpublicarea centpercent center" style="min-width:30%;width:fit-content;height:70%;top:60%;left: 50%;">';
print '<div class="bookcalform" style="min-height:50%">';
if ($action == 'afteradd') {
Expand Down Expand Up @@ -437,9 +499,21 @@ function llxHeaderVierge($title, $head = "", $disablejs = 0, $disablehead = 0, $
foreach ($arrayofavailabilities as $key => $value) {
$startarray = dol_getdate($value->start);
$endarray = dol_getdate($value->end);
for ($i = $startarray['mday']; $i <= $endarray['mday']; $i++) {
if ($todayarray['mon'] >= $startarray['mon'] && $todayarray['mon'] <= $endarray['mon']) {
$arrayofavailabledays[dol_mktime(0, 0, 0, $todayarray['mon'], $i, $todayarray['year'])] = dol_mktime(0, 0, 0, $todayarray['mon'], $i, $todayarray['year']);
if ($value->start > $todaytms) {
$currdate = $value->start;
} else {
$currdate = $todaytms;
}
// Limit computing for big ranges (> 2months)
// TODO: make it check against global ?
$maxdayinfutur = dol_time_plus_duree($currdate, 60, 'd');
if ($value->end < $maxdayinfutur) {
$maxdayinfutur = $value->end;
}
for (; $currdate <= $maxdayinfutur; $currdate = dol_time_plus_duree($currdate, 1, 'd')) {
$currdatearray=dol_getdate($currdate);
if (checkAgainstOpeningDays($currdate, $object->entity, $db) != '') {
$arrayofavailabledays[dol_mktime(0, 0, 0, $currdatearray['mon'], $currdatearray['mday'], $currdatearray['year'])] = dol_mktime(0, 0, 0, $currdatearray['mon'], $currdatearray['mday'], $currdatearray['year']);
}
}
}
Expand Down Expand Up @@ -618,7 +692,7 @@ function generateBookingButtons(timearray, datestring){
/**
* Show event of a particular day
*
* @param int $day Day
* @param int $day Day
* @param int $month Month
* @param int $year Year
* @param int $today Today's day
Expand Down
Loading