Overide reguliere tijden
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
ID-DAY-STARTTIME-ENDTIME-DATE-TYPE
1-maandag-gesloten-NULL-NULL-regular
2-dinsdag-10:00-18:30-NULL-regular
3-woensdag-10:00-18:30-NULL-regular
4-donderdag-10:00-18:30-NULL-regular
5-vrijdag-10:00-18:30-NULL-regular
6-zaterdag-10:00-18:00-NULL-regular
7-zondag-gesloten-NULL-NULL-regular
8-vrijdag-11:00-14:00-2019/04/12-exception
9-zondag-12:00-18:00-2019/04/14-exception
etc
1-maandag-gesloten-NULL-NULL-regular
2-dinsdag-10:00-18:30-NULL-regular
3-woensdag-10:00-18:30-NULL-regular
4-donderdag-10:00-18:30-NULL-regular
5-vrijdag-10:00-18:30-NULL-regular
6-zaterdag-10:00-18:00-NULL-regular
7-zondag-gesloten-NULL-NULL-regular
8-vrijdag-11:00-14:00-2019/04/12-exception
9-zondag-12:00-18:00-2019/04/14-exception
etc
Als ik nu een query maak laad hij alles onder elkaar. Maar als ik voor deze week een uitzondering heb zoals de zondag, hoe kan deze dan overschrijven?
Output nu:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
maandag gesloten
dinsdag 10:00 - 18:30
woensdag 10:00 - 18:30
donderdag 10:00 - 18:30
vrijdag 10:00 - 18:30
zaterdag 10:00 - 18:00
zondag gesloten
vrijdag 11:00 - 14:00
zondag 12:00 - 18:00
dinsdag 10:00 - 18:30
woensdag 10:00 - 18:30
donderdag 10:00 - 18:30
vrijdag 10:00 - 18:30
zaterdag 10:00 - 18:00
zondag gesloten
vrijdag 11:00 - 14:00
zondag 12:00 - 18:00
Output zoals het zou moeten:
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
maandag gesloten
dinsdag 10:00 - 18:30
woensdag 10:00 - 18:30
donderdag 10:00 - 18:30
vrijdag 11:00 - 14:00
zaterdag 10:00 - 18:00
zondag 12:00 - 18:00
dinsdag 10:00 - 18:30
woensdag 10:00 - 18:30
donderdag 10:00 - 18:30
vrijdag 11:00 - 14:00
zaterdag 10:00 - 18:00
zondag 12:00 - 18:00
Hoe kan ik dit het makkelijkste aanpakken?
Sowieso zou ik voor TYPE een int of een char(1) nemen (0/null/"r" = regular, 1/"x" = exception).
Waarom je STARTTIME en ENDTIME nog als twee aparte waarden opslaan als het toch geen echte tijden zijn (maar platte tekst). Kun je er net zo goed een enkele string van maken (zoals bij "gesloten" toch al gebeurt).
Moet het perse allemaal in een query, of mag het ook met een stukje PHP (het is hier tenslotten *PHPhulp* hè). Dat laatste is wel het makkelijkst: eerst de regular tijden ophalen (en sorteren op ID, alhoewel een aparte kolom voor de volgorde netter zou zijn), en dan voor "de week" kijken of er uitzonderingen zijn.
Aanpassen naar smaak.
veldnaam type is tinyint(1 of 0) en de tijdvelden zijn time.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SELECT *, if( starttime > 0, if(type = 0 ,'Afwijkende openingstijden', 'Open'), 'Gesloten' ) as 'opm'
FROM shophours
WHERE
( starttime > 0 AND type = 1 ) OR
( starttime = 0 AND type = 1 AND `day` IN( 'Maandag','Zondag' ) )
ORDER BY FIELD( `day`, 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag' )
LIMIT 50;
SELECT *, if( starttime > 0, if(type = 0 ,'Afwijkende openingstijden', 'Open'), 'gesloten') as 'opm'
FROM shophours
WHERE
( starttime > 0 AND type = 1 ) OR
( starttime = 0 AND type = 1 AND `day` = 'Maandag' ) OR
( `date` = '2019-04-14' )
ORDER BY FIELD( `day`, 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag' )
LIMIT 50;
SELECT *, if( starttime > 0, if(type = 0 ,'Afwijkende openingstijden', 'Open'), 'Gesloten' ) as 'opm'
FROM shophours
WHERE
( starttime > 0 AND type = 1 AND `date` = 0 AND `day` <> 'Vrijdag' ) OR
( starttime = 0 AND type = 1 AND `day` IN( 'Maandag', 'Zondag' ) ) OR
( starttime = 0 AND type = 1 AND `day` = 'Maandag' ) OR
( `date` = '2019-04-12' )
ORDER BY FIELD( `day`, 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag' )
LIMIT 50;
FROM shophours
WHERE
( starttime > 0 AND type = 1 ) OR
( starttime = 0 AND type = 1 AND `day` IN( 'Maandag','Zondag' ) )
ORDER BY FIELD( `day`, 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag' )
LIMIT 50;
SELECT *, if( starttime > 0, if(type = 0 ,'Afwijkende openingstijden', 'Open'), 'gesloten') as 'opm'
FROM shophours
WHERE
( starttime > 0 AND type = 1 ) OR
( starttime = 0 AND type = 1 AND `day` = 'Maandag' ) OR
( `date` = '2019-04-14' )
ORDER BY FIELD( `day`, 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag' )
LIMIT 50;
SELECT *, if( starttime > 0, if(type = 0 ,'Afwijkende openingstijden', 'Open'), 'Gesloten' ) as 'opm'
FROM shophours
WHERE
( starttime > 0 AND type = 1 AND `date` = 0 AND `day` <> 'Vrijdag' ) OR
( starttime = 0 AND type = 1 AND `day` IN( 'Maandag', 'Zondag' ) ) OR
( starttime = 0 AND type = 1 AND `day` = 'Maandag' ) OR
( `date` = '2019-04-12' )
ORDER BY FIELD( `day`, 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag' )
LIMIT 50;
De velden start en end time Kan door de gebruiker worden ingevuld in het administratie dashboard. De vaste dagen staan al vast in de tabel dat zijn de ID's 1 t/m 7.
Daarnaast kan de gebruiker ook een datum invullen met de tijden die dan gelden. En deze moeten dan overschreven worden voor die week waarin de datum valt.
De week mag inclusief vandaag 7 dagen hebben zoals in mijn eerste post aangegeven.
Als dit met php makkelijk is of beter is dan mag dit natuurlijk in PHP zijn :)
Het gaat niet om wie wat invult, maar om wat er in de database zit en hoe je dat eruit haalt.
Ik heb 3 voorbeelden gegeven op basis van je gegegevens.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
function get_all_records($sql){
global $conn;
$query = $conn->query($sql);
$result = [];
while($row = $result->fetch_assoc()) $result[array_shift($row)] = $row;
return $result;
}
$sql = "select SH.DAY,SH.STARTTIME,SH.ENDTIME from SHOPHOURS SH where SH.TYPE = ";
$shop_hours = array_merge(
get_all_records($sql . "0 order by SH.ID"),
get_all_records($sql . "1 and YEARWEEK(`DATE`) = '201915'")
);
global $conn;
$query = $conn->query($sql);
$result = [];
while($row = $result->fetch_assoc()) $result[array_shift($row)] = $row;
return $result;
}
$sql = "select SH.DAY,SH.STARTTIME,SH.ENDTIME from SHOPHOURS SH where SH.TYPE = ";
$shop_hours = array_merge(
get_all_records($sql . "0 order by SH.ID"),
get_all_records($sql . "1 and YEARWEEK(`DATE`) = '201915'")
);
Levert een array $shop_hours met als key de DAY van de week (in de juiste volgorde), en in de value een array met START- en ENDTIME.
Thanks ik ga hier mee aan de slag :)
@Rob
"als het toch geen echte tijden zijn (maar platte tekst)" hoe zou jij de tijden dan opslaan met strtotime?
Ik heb de start en de eindtijd apart zodat je nog eventueel een functie kan maken met bijvoorbeeld sluit over 15 minuten.
Gewijzigd op 12/04/2019 22:56:52 door Jop B
TIME of gewoon als een INT (seconden na middernacht). Dan kun je d'r inderdaad echt mee rekenen.
Als een INDELING TABEL
id [int(11) ai]
day [varchar(255)]
starttime [time]
endtime[time]
date [date]
type [int(1)] (0 = regulier) (1 = afwijkend)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$conn = new mysqli($dbhost, $dbusername, $dbpassword, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
function get_all_records($sql){
global $conn;
$result = $conn->query($sql);
$result = [];
while($row = $result->fetch_assoc()) $result[array_shift($row)] = $row;
return $result;
}
$sql = "SELECT day, starttime, endtime FROM schedule WHERE type = ";
$shop_hours = array_merge(
get_all_records($sql . "0 ORDER BY id"),
get_all_records($sql . "1 and YEARWEEK('DATE') = '201915'")
);
echo $shop_hours;
?>
$conn = new mysqli($dbhost, $dbusername, $dbpassword, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
function get_all_records($sql){
global $conn;
$result = $conn->query($sql);
$result = [];
while($row = $result->fetch_assoc()) $result[array_shift($row)] = $row;
return $result;
}
$sql = "SELECT day, starttime, endtime FROM schedule WHERE type = ";
$shop_hours = array_merge(
get_all_records($sql . "0 ORDER BY id"),
get_all_records($sql . "1 and YEARWEEK('DATE') = '201915'")
);
echo $shop_hours;
?>
Het enigste wat ik nu terug krijg is de connection succesfully
Gewijzigd op 13/04/2019 00:19:45 door Jop B
$shop_hours is een array, die zul je dus met var_dump($shop_hours) of print_r($shop_hours) moeten tonen.
Als je dit vraagstuk van een afstandje bekijkt dan heb je in principe een soort van roostersjabloon (zij het abstract) dat meestal wel klopt. Vervolgens vertaal je dit naar een (concreet) weekrooster. Wat je dus ook zou kunnen doen is voor dit laatste een (wederom concrete) tabel introduceren. Het sjabloon zou je dan als aardappelstempel kunnen gebruiken voor het invullen van een weekrooster waarbij je een weeknummer of iets dergelijks toevoegt.
Bijkomend voordeel (als dit interessant is of kan zijn voor statistiek) is dat je een history opbouwt van wanneer het filiaal concreet open was. En over filiaal gesproken, dit kun je dus nog verder uitbreiden naar een variant waarbij verschillende filialen (ten opzichte van elkaar) afwijkende openingstijden hebben.
Op deze manier heb je een redelijk generiek stuk software wat ook vaker inzetbaar zou kunnen zijn.
Vaak is men op deze site (vrijwel alleen) met specifieke implementaties bezig. Daar is in principe niks mis mee en die zijn vaak ook prima voor wat er moet gebeuren en wellicht nog belangrijker, de aanpak wordt ook onderbouwd, maar dit zou je er niet van moeten weerhouden om gewoon eens wat op een blaadje te kliederen of wat te mijmeren over wat er nu concreet zou moeten gebeuren. Dat is nog altijd minder werk dan code kloppen en wellicht levert dat nieuwe ideeën en/of perspectieven op.
Ik heb regel 6 aangepast
Nu krijg ik de array terug
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Array (
[maandag] => Array ( [starttime] => 10:00:00 [endtime] => 18:30:00 )
[dinsdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:00:00 )
[woensdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:30:00 )
[donderdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:30:00 )
[vrijdag] => Array ( [starttime] => 10:00:00 [endtime] => 22:00:00 )
[zaterdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:00:00 )
[zondag] => Array ( [starttime] => 12:00:00 [endtime] => 18:00:00 )
)
[maandag] => Array ( [starttime] => 10:00:00 [endtime] => 18:30:00 )
[dinsdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:00:00 )
[woensdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:30:00 )
[donderdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:30:00 )
[vrijdag] => Array ( [starttime] => 10:00:00 [endtime] => 22:00:00 )
[zaterdag] => Array ( [starttime] => 10:00:00 [endtime] => 18:00:00 )
[zondag] => Array ( [starttime] => 12:00:00 [endtime] => 18:00:00 )
)
Gewijzigd op 13/04/2019 19:40:12 door Jop B
** garantie tot de deur **
[zondag] = vandaag
[maandag]
[dinsdag]
[woensdag]
[donderdag]
[vrijdag]
[zaterdag]
[maandag] = vandaag
[dinsdag]
[woensdag]
[donderdag]
[vrijdag]
[zaterdag]
[zondag]
[dinsdag] = vandaag
[woensdag]
[donderdag]
[vrijdag]
[zaterdag]
[zondag]
[maandag]
Dat het steeds een dag opschuift? Of kun je dan met PHP een een switch day maken en dan per dag een output geven?
maandag: mod(1+7-3,7) = 5
dinsdag: mod(2+7-3,7) = 6
woensdag: mod(3+7-3,7) = 0
donderdag: mod(4+7-3,7) = 1
vrijdag: mod(5+7-3,7) = 2
zaterdag: mod(6+7-3,7) = 3
zondag: mod(7+7-3,7) = 4
Als je dus op deze waarde sorteer komt het netjes in de volgorde woensdag ("vandaag") t/m dinsdag.
In eerste instantie is het zaak dat de query alle benodigde gegevens ophaalt, liefst in een zo kant-en-klaar mogelijk formaat. Stel dat je later de indelingsweergave van het rooster weer wilt veranderen, als je alle logica in je query stopt zul je dan je SQL-code moeten veranderen. Ik denk dat het aanpassen van PHP-code om data wat anders weer te geven makkelijker is dan een complete query omschrijven.
Begrijp mij niet verkeerd, de ene aanpak is niet beter of slechter dan de ander, maar ik zou gaan voor een strategie waarbij alles zo simpel mogelijk blijft en ik denk dat een soort van gespreide aanpak je hiermee kan helpen.
@thomas,
Wat jij bedoeld is alle data wat in de tabel zit laden in een array en vervolgens mij PHP het gaan sorteren hoe en welke data je wilt laten zien?
Natuurlijk zijn openingstijden klein qua data maar als je nu een hoop data moet laden en dan nog met PHPmoet gaan sorteren is het dan niet sneller om dit al gelijk in de SQL query te doen?
Zelf zou ik hier gewoon voor het gemak gaan dat je alles in 1x kant-en-klaar hebt. Daarnaast kun je dit soort dingen natuurlijk prima cachen.
Gewijzigd op 18/04/2019 20:21:15 door Rob Doemaarwat