简体   繁体   English

根据预订系统中的可用房间打印HTML表格

[英]Printing an HTML table, based on available rooms in a booking system

Good day everyone, 今天是个好日子,

I am trying to print an HTML table; 我正在尝试打印HTML表格; given two dates (1st July until 31st July, in the example), it will print the dates on the header. 给定两个日期(在示例中为7月1日至7月31日),它将在页眉上打印日期。 Then, every row will be a room. 然后,每一行都是一个房间。 Then, when a room is booked that day, the cells will have a red background-color, if not, it will remain white. 然后,当天预订房间时,单元格将具有红色背景色,如果没有,它将保持白色。

I am getting lost in an IF to check if a room should be printed red or not. 我迷失在IF中,以检查房间是否应打印为红色。 So far, I get this output: http://jsfiddle.net/KatsuroKurosaki/kCkJD/ 到目前为止,我得到以下输出: http : //jsfiddle.net/KatsuroKurosaki/kCkJD/

And I am trying to achieve this one: http://jsfiddle.net/KatsuroKurosaki/kCkJD/1/ 我正在尝试实现这一目标: http : //jsfiddle.net/KatsuroKurosaki/kCkJD/1/

Based on the DataBase query output: 根据数据库查询输出:

SELECT idsRoom, checkin, checkout
FROM bookings
WHERE checkout >= '2014-07-01' AND checkin <= '2014-07-31'

+---------+------------+------------+
| idsRoom | checkin    | checkout   |
+---------+------------+------------+
| 2       | 2014-06-27 | 2014-07-02 |
| 4       | 2014-07-08 | 2014-07-09 |
| 6,7,8   | 2014-07-18 | 2014-07-22 |
| 14      | 2014-07-31 | 2014-08-02 |
+---------+------------+------------+
4 rows in set (0.00 sec)

Yes, every booking has a checkin and a checkout, as well it must contain at least one room, or more (that's why the ids 6,7,8). 是的,每笔预订都需要办理入住和退房手续,并且必须至少包含一个房间或一个以上的房间(这就是为什么ID 6,7,8)。 I am using PHP 5.5.13, MySQLi prepared statements and Maria DB 10.0.12. 我正在使用PHP 5.5.13,MySQLi准备好的语句和Maria DB 10.0.12。 This is the PHP snippet, that will print the output table: 这是PHP代码段,它将打印输出表:

<?php
/* This will be the received POST date in the future */
$desdeP = "2014-07-01";
$hastaP = "2014-07-31";

/* Database Connection and DateTime objects */
$conn = new MySQLi("localhost","user","password","database"); //Seriusly? Nope ;)
$desde = DateTime::createFromFormat("Y-m-d",$desdeP);
$hasta = DateTime::createFromFormat("Y-m-d",$hastaP);
?>
<!-- Table with date headers -->
<table border="1" cellpadding="0" cellspacing="0" style="min-width:100%;min-height:100%;">
<tr>
    <td>&nbsp;</td>
    <?php
    while($desde<=$hasta){
        echo '<td>'.$desde->format("d-m-Y").'</td>';
        $desde->modify("+1Day");
    }
    ?>
</tr>
<?php
/* Query all the rooms */
$stmt = $conn->prepare("SELECT id, name FROM rooms ORDER BY id;");
$stmt->execute();
$rooms = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$stmt->close();

/* Query all the bookings in the given dates */
$stmt = $conn->prepare("SELECT idsRoom, checkin, checkout
FROM bookings
WHERE checkout >= ? AND checkin <= ?;");
$stmt->bind_param("ss",
    $desdeP,
    $hastaP);
$stmt->execute();
$bookings = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$stmt->close();

foreach($rooms as $k=>$v){ // Every row is a room
    echo '<tr>';
    echo '<td>'.$v['name'].'</td>';
    $desde = DateTime::createFromFormat("Y-m-d",$desdeP);
    $hasta = DateTime::createFromFormat("Y-m-d",$hastaP);
    while($desde<=$hasta){ // For every row, check in the bookings list if available or not
        echo '<td';
        foreach ($bookings as $k2=>$v2){
            $checkin = DateTime::createFromFormat("Y-m-d",$v2['checkin']);
            $checkout = DateTime::createFromFormat("Y-m-d",$v2['checkout']);
            /* HERE remains my question: What mega IF do I need to paint background in red if the room is not available? */
            if( (strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false) && 
                ($checkin < $hasta && $checkout > $desde) && 
                ($checkin >= $desde && $checkout <= $hasta)
            ){
                echo ' style="background-color:red;"';
            }
        }
        echo '>&nbsp;</td>';
        $desde->modify("+1Day");
    }
    echo '</tr>';
}
$conn->close();
?>
</table>

Thanks to all in advance, hope to find some help about it~ 预先感谢大家,希望能对此有所帮助〜

Regards! 问候!

Because your $desde is a running date in your while loop, so you should do the checking that 因为$desdewhile循环中的运行日期,所以您应该检查一下

If $desde is within $checkin and $checkout, then the room is blocked (red) 如果$ desde在$ checkin和$ checkout内,则房间被阻止(红色)

So, by using this logic, this is the only condition you need: 因此,通过使用此逻辑,这是您唯一需要的条件:

if ((strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false) &&
    ($checkin <= $desde && $checkout > $desde)
){
    echo ' style="background-color:red;"';
}

I ran this on my localhost and it works as what you wanted in your example. 我在本地主机上运行它,它可以像您在示例中所需要的那样工作。 Hope it helps. 希望能帮助到你。

After a quick look at the question i noticed that you have a comma separated values in id column. 快速查看问题后,我注意到您在id列中使用逗号分隔值。 That is certainly causing you troubles, and will cause you more troubles in the future. 那肯定会给您带来麻烦,并且将来还会给您带来更多麻烦。 I'm not a database design expert, when I started with programming I was doing the same thing. 我不是数据库设计专家,当我开始编程时,我正在做同样的事情。 I wanted to do something quick and easy, without too much hassle with relationships, and it always turn out into a mess so that eventually had to start over from the beginning, and do it properly. 我想做些简单而又快速的事情,而不必为人际关系带来麻烦,而且它总是变得一团糟,因此最终不得不从头开始,并正确地做。

This design anti-pattern will make querying much more difficult, also, you have to write a lot of code to reinvent the built-in functionality of the database that is lost ( you have already started to do that, strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false ). 这种设计反模式将使查询变得更加困难,而且,您必须编写大量代码来重新发明丢失的数据库的内置功能(您已经开始这样做, strpos(",".$v2['idsRoom'].",",",".$v['id'].",")!==false )。

I took some time to rewrite the example. 我花了一些时间重写示例。 For the range of dates I use the DatePeriod class. 对于日期范围,我使用DatePeriod类。 It can be used in foreach loop so it is suitable for calendars, etc. Also, here are two associative arrays ( $rooms and $bookings ) that are identical like in example. 它可以在foreach循环中使用,因此适用于日历等。此外,这是两个关联数组( $rooms$bookings ),它们与示例中相同。 After converting the $bookings array to separate the idsRoom values it looks like: 转换$bookings数组以分隔idsRoom值后,它看起来像:

Array
(
    [0] => Array ( ... )
    [1] => Array ( ... )
    [2] => Array
        (
            [idsRoom] => 6
            [checkin] => 2014-07-18
            [checkout] => 2014-07-22
        )

    [3] => Array
        (
            [idsRoom] => 7
            [checkin] => 2014-07-18
            [checkout] => 2014-07-22
        )

    [4] => Array
        (
            [idsRoom] => 8
            [checkin] => 2014-07-18
            [checkout] => 2014-07-22
        )

    [5] => Array (... )
)

And finally, loop to print the table: 最后,循环打印表格:

<?php

$range = new DatePeriod( new DateTime( "2014-07-01" ), new DateInterval( 'P1D' ), new DateTime( "2014-08-01" ) );

$rooms = array_map( function( $k, $v ) { return array( 'name' => $v, 'id' => $k ); }, range( 1, 30 ), array_merge( range( 101, 110 ), range( 201, 210 ), range( 301, 310 ) ) );

$bookings_original = array( 
    array( 'idsRoom' => '2',    'checkin' => '2014-06-27', 'checkout' => '2014-07-02' ),
    array( 'idsRoom' => '4',    'checkin' => '2014-07-08', 'checkout' => '2014-07-09' ),
    array( 'idsRoom' => '6,7,8','checkin' => '2014-07-18', 'checkout' => '2014-07-22' ),
    array( 'idsRoom' => '14',   'checkin' => '2014-07-31', 'checkout' => '2014-08-02' )
);

$bookings = array();
foreach( $bookings_original as $item ) {
    foreach( explode( ',', $item['idsRoom'] ) as $room )
        $bookings[] = array_merge( $item, array( 'idsRoom' => $room ) );
}

?>
<table border="1" cellpadding="0" cellspacing="0" style="min-width:100%;min-height:100%;">
    <tr>
        <td>&nbsp;</td>
        <?php foreach( $range as $date ) : ?>
        <td><?php echo $date->format("d-m-Y"); ?></td>
        <?php endforeach; ?>
    </tr>
<?php

foreach( $rooms as $room ) {
    echo "<tr><td>$room[name]</td>" . PHP_EOL;

    foreach( $range as $date ) {
        if (
            array_filter( $bookings, function( $booking ) use ( $room, $date ) {
                return $booking[ 'idsRoom' ] == $room['id'] && $booking['checkin'] <= $date->format( "Y-m-d" ) && $booking['checkout'] > $date->format( "Y-m-d" );
            } ) 
        )
            echo '<td style="background-color:red;"></td>' . PHP_EOL;
        else
            echo '<td></td>' . PHP_EOL;
    }
    echo '</tr>';
}

?>
</table>

Here is one booking design example that might help you with database and relationships between tables. 这是一个预订设计示例 ,可以帮助您了解数据库和表之间的关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM