The Developer Fastlane

« 365 days to become a developer » challenge

PHP: Dates

November 5, 2020

Exercise

Result

Click on one of the images above to access the exercise's website

Exercise instruction

  • Show a list of opening hours slots for each day of the week.
  • We want to highlight the current day in the list (with date() function). The line will be wether red (if the shop is closed at current time) or green (if it's open)
  • An alert box will show up on the top of the list, displaying a message saying wether the store is open right now (green box) or not (red box).
  • As the website is managed in France and traduced in american, the timeslots are entered in 24-hours format. That's why it will be necessary to create a function to translate the timeslots into 12-hours format (am / pm).

Go to the code

Course (learn the basics)

Constants

  • We use the function define() to set a new constant variable. Then we can give it any name.
  • By convention, it will be writen in capital letters.
  • Creating a config.php file is a good way to store constant variables.

Inside config.php:
Code
define('TIMESLOTS', [
    [8, 12],
    [14, 19]
]); 

The date() function + date formating

Go to: PHP doc > Date/Time functions > date()

For the sake of the exercise we need to use the date() function with some "format character" from the "DateTime::format" object-oriented style:
  • date('w'): The "w" character allows to check if the current day is the same as the one inside the list
  • date('G'): The "G" character allows us to check if the current time (in 24-hour format) is contained INSIDE the timeslots we entered previously inside the contant's array. If this is the case, this means that the shop is opened right now.

Exercise's code

contact.php

Code

<?php 
$title = 'Contact us';
require 'header.php';
require_once 'config.php';
?>

<p class="lead mb-5">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Adipisci cupiditate in iusto vel asperiores impedit non. Provident hic illum adipisci optio laboriosam consequuntur voluptatem, temporibus asperiores doloremque ratione atque facere!</p>
<div class="row">
  <div class="col-md-7">
    <h2 class="pb-3">Send us a message</h2>
    <form>
      <div class="form-group">
        <label for="exampleInputEmail1">Email address</label>
        <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
        <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
      </div>
      <div class="form-group">
        <label for="exampleInputPassword1">Message</label>
        <textarea class="form-control" id="exampleInputPassword1" placeholder="Type your message"></textarea>
      </div>
      <button type="submit" class="btn btn-primary">Send</button>
    </form>
  </div>
  <div class="col-md-5">
    <h2 class="pb-3">Visit the shop</h2>
     <?php 
      $isOpen = contact_visit(TIMESLOTS);
      contact_visit_alert($isOpen);
      contact_visit_ul(TIMESLOTS, $isOpen);
     ?>
  </div>
</div>

<?php require 'footer.php'; ?>

header.php

Code
<?php 
require 'functions.php';
?>

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="Edouard Proust">
    <meta name="generator" content="The Developer Fastlane">
    <title><?php title_dyn($title) ?></title>

    <link rel="canonical" href="https://getbootstrap.com/docs/4.5/examples/starter-template/">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link rel="stylesheet" href="assets/style.css">
    
<!-- Favicons -->
<link rel="apple-touch-icon" href="/docs/4.5/assets/img/favicons/apple-touch-icon.png" sizes="180x180">
<link rel="icon" href="/docs/4.5/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png">
<link rel="icon" href="/docs/4.5/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png">
<link rel="manifest" href="/docs/4.5/assets/img/favicons/manifest.json">
<link rel="mask-icon" href="/docs/4.5/assets/img/favicons/safari-pinned-tab.svg" color="#563d7c">
<link rel="icon" href="/docs/4.5/assets/img/favicons/favicon.ico">
<meta name="msapplication-config" content="/docs/4.5/assets/img/favicons/browserconfig.xml">
<meta name="theme-color" content="#563d7c">


    <style>
      .bd-placeholder-img {
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
      }

      @media (min-width: 768px) {
        .bd-placeholder-img-lg {
          font-size: 3.5rem;
        }
      }
    </style>

  </head>
  <body>
    <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4">
  <div class="navbar-brand" href="<?= dirbase() ?>">Dates in PHP</div>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <?= nav_menu('nav-link') ?>
    </ul>
      <button onclick="location.href='/'" type="button" class="btn btn-secondary my-2 my-sm-0">⯇ Go back to index</button>
  </div>
</nav>

<main role="main" class="container">
  <div class="starter-template">
    <h1><?= $title ?></h1>

config.php

Code
<?php 
define('DAYS',
    [
        'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday'
    ]
);
define('TIMESLOTS',
    [
        [
            
        ],
        [
            [9, 13],[14, 20]
        ],
        [
            [8, 13],[14, 20]
        ],
        [
            [8, 12]
        ],
        [
            [8, 13],[14, 20]
        ],
        [
            [8, 13],[14, 20]
        ],
        [
            
        ],
    ]
);

functions.php

Code
<?php
function contact_visit($weekSlots): array
{
  $open['day'] = $open['hour'] = 0;
  $today = (int)date('w');
  $now = (int)date('G');  
  if(!empty($weekSlots[$today])) {
    (int)$open['day'] = 1;
  }
  foreach ($weekSlots[$today] as $slot) {
    if ($now >= $slot[0] && $now < $slot[1] ) {
      (int)$open['hour'] = 1;
    }
  }
  return $open;
}
function contact_visit_ul(array $weekSlots, array $isOpen): array
{
  foreach (DAYS as $d => $day) { 
    $style = '';
    if($d === (int)date('w')) {
      if($isOpen['hour'] === 1) { 
        $color = "green";
      } else {
        $color = "red";
      }
      $style = "style='color:$color'";
    }
    ?><li <?= $style ?> >
      <b><?= $day ?></b>: <?php
      if(empty($weekSlots[$d])) { 
        echo 'closed';
      } else {
        contact_visit_li($weekSlots[$d]);
      } ?>
    </li><?php
  }
  return $isOpen;
}
function contact_visit_li(array $daySlots)
{
  $line = [];
  foreach ($daySlots as $slot) {
    for ($i=0; $i<count($slot); $i++) { // Formating from 24-hour format to 12-hour Am format
      if($slot[$i] > 12) {
        $slot[$i] = ($slot[$i] - 12) . ' pm';
      } else {
        $slot[$i] .= ' am';
      }
    }
    $line[] = "$slot[0] - $slot[1]";
  }
  echo implode(' / ', $line);
}
function contact_visit_alert(array $isOpen) 
{
  if(array_sum($isOpen) === 2) {
    echo '<div class="alert alert-success" role="alert">The store is open.</div>';
  } else {
    echo '<div class="alert alert-danger" role="alert">The store is now closed, please come back tomorrow!</div>';
  }
}

function title_dyn(string $var = 'The Developer Fastlane'): void 
{
    if (isset($var)) {
        echo $var; 
    } else {
        echo 'The Developer Fastlane';
    }
}

function nav_item($link, $title, $aClass) 
{
  $class = 'nav-item';
  if (strpos($_SERVER["SCRIPT_NAME"], $link) !== false) {
    $class .= $class . ' active';
  }
    $html = '<li class="' . $class . '">
      <a class="' . $aClass . '" href="' . $link . '">' . $title . '</a>
    </li>';
  return $html;
}

function nav_menu(string $aClass=''): string
{
  return 
    nav_item('index.php', 'Home', $aClass) .
    nav_item('contact.php', 'Contact', $aClass);
}
© 2020 - Edouard Proust | The Developer Fastlane