| Author | Dave Jarvis <email> |
|---|---|
| Date | 2026-01-18 00:36:36 GMT-0800 |
| Commit | 18db5c0759b383ec03355d67a38445cce239887e |
| Parent | 9c9677f |
| } | ||
| - public function process( array $apiResponse, int $statusCode ) { | ||
| + public function process( array $response, int $statusCode ) { | ||
| $this->statusCode = $statusCode; | ||
| + | ||
| if( $statusCode === 201 ) { | ||
| - $this->summary = $apiResponse; | ||
| + $this->summary = $response; | ||
| } else { | ||
| - $this->errorMessage = $apiResponse[ 'shipping_address' ][ 'detail' ] | ||
| - [ 'errors' ][ 0 ][ 'message' ] ?? $apiResponse[ 'detail' ] ?? | ||
| - "An unexpected error occurred (HTTP $statusCode)."; | ||
| + $this->errorMessage = $response[ 'shipping_address' ][ 'detail' ] | ||
| + [ 'errors' ][ 0 ][ 'message' ] | ||
| + ?? $response[ 'detail' ] | ||
| + ?? "An unexpected error occurred (HTTP $statusCode)."; | ||
| } | ||
| } | ||
| $currency = $this->escape( $this->summary[ 'currency' ] ); | ||
| ?> | ||
| - <h2>Order summary</h2> | ||
| <section> | ||
| <p class="address"> | ||
| </tr> | ||
| </table> | ||
| + <form action="payment.php" method="post"> | ||
| + <button type="submit">Proceed to payment</button> | ||
| + </form> | ||
| </section> | ||
| <?php | ||
| <?php | ||
| class Session { | ||
| + // Eliminates the session data after this duration (in seconds). | ||
| + private const LIFETIME = 3600; | ||
| + | ||
| public function __construct() { | ||
| if( session_status() === PHP_SESSION_NONE ) { | ||
| session_start(); | ||
| + $this->validateSession(); | ||
| + } | ||
| + } | ||
| + | ||
| + private function validateSession() { | ||
| + if( isset( $_SESSION['last_activity'] ) ) { | ||
| + $elapsed = time() - $_SESSION['last_activity']; | ||
| + | ||
| + if( $elapsed > self::LIFETIME ) { | ||
| + session_unset(); | ||
| + session_destroy(); | ||
| + session_start(); | ||
| + } | ||
| } | ||
| + | ||
| + $_SESSION['last_activity'] = time(); | ||
| } | ||
| public function write( $key, $value ) { | ||
| $_SESSION[ $key ] = $value; | ||
| + } | ||
| + | ||
| + public function read( $key ) { | ||
| + return $_SESSION[ $key ] ?? null; | ||
| } | ||
| } |
| +<?php | ||
| +require_once 'Configuration.php'; | ||
| +require_once 'Address.php'; | ||
| +require_once 'Order.php'; | ||
| +require_once 'Publisher.php'; | ||
| +require_once 'Session.php'; | ||
| + | ||
| +$config = new Configuration(); | ||
| +$address = new Address( $_POST ); | ||
| +$order = new Order(); | ||
| +$publisher = new Publisher(); | ||
| +$session = new Session(); | ||
| + | ||
| +$config->load(); | ||
| +$config->configure( $publisher ); | ||
| +$valid = $address->process( [ | ||
| + "city", "country", "postcode", "state", "street1", "phone", "name", "email" ] | ||
| +); | ||
| +$address->export( $session ); | ||
| +?> | ||
| +<!DOCTYPE html> | ||
| +<html> | ||
| +<head> | ||
| + <meta charset="utf-8"> | ||
| + <title>autónoma – order summary</title> | ||
| + <link rel="stylesheet" href="main.css"> | ||
| +</head> | ||
| +<body> | ||
| + <h1>autónoma – order summary</h1> | ||
| + <div class="payment-content"> | ||
| + <?php | ||
| + if( $valid ) { | ||
| + $publisher->process( $address, $order ); | ||
| + $order->render(); | ||
| + } else { | ||
| + $address->render(); | ||
| + } | ||
| + ?> | ||
| + </div> | ||
| +</body> | ||
| +</html> | ||
| <body> | ||
| <h1>autónoma – shipping</h1> | ||
| - <form action="payment.php" method="post"> | ||
| + <form action="calculate.php" method="post"> | ||
| <p> | ||
| Provide the mailing address. If this is a gift, provide the recipient’s | ||
| <p> | ||
| - <button type="submit">Proceed to payment</button> | ||
| + <button type="submit">Proceed to order</button> | ||
| </p> | ||
| </form> | ||
| form p:nth-of-type(10), | ||
| form p:nth-of-type(11), | ||
| -form p:nth-of-type(12) { | ||
| +form p:nth-of-type(12), | ||
| +form p:last-of-type { | ||
| grid-column: span 2; | ||
| } | ||
| .payment-content section { | ||
| - border-top: 1px solid #eee; | ||
| - padding-top: 1em; | ||
| margin-top: 1em; | ||
| } | ||
| <?php | ||
| -require_once 'Configuration.php'; | ||
| -require_once 'Address.php'; | ||
| -require_once 'Order.php'; | ||
| -require_once 'Publisher.php'; | ||
| require_once 'Session.php'; | ||
| -$config = new Configuration(); | ||
| -$address = new Address( $_POST ); | ||
| -$order = new Order(); | ||
| -$publisher = new Publisher(); | ||
| $session = new Session(); | ||
| +$address = $session->read( 'user_address' ); | ||
| -$config->load(); | ||
| -$config->configure( $publisher ); | ||
| -$valid = $address->process( [ | ||
| - "city", "country", "postcode", "state", "street1", "phone", "name", "email" ] | ||
| -); | ||
| -$address->export( $session ); | ||
| +// Redirect if no address in session | ||
| +if( !$address ) { | ||
| + header( 'Location: index.html' ); | ||
| + exit; | ||
| +} | ||
| + | ||
| +function escape( $value ) { | ||
| + return htmlspecialchars( $value ?? '', ENT_QUOTES, 'UTF-8' ); | ||
| +} | ||
| ?> | ||
| <!DOCTYPE html> | ||
| -<html> | ||
| +<html lang="en"> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| - <title>autónoma – payment</title> | ||
| + <title>autónoma – payment</title> | ||
| <link rel="stylesheet" href="main.css"> | ||
| </head> | ||
| <body> | ||
| - <h1>autónoma – payment</h1> | ||
| - <div class="payment-content"> | ||
| - <?php | ||
| - if( $valid ) { | ||
| - $publisher->process( $address, $order ); | ||
| - $order->render(); | ||
| - } else { | ||
| - $address->render(); | ||
| - } | ||
| - ?> | ||
| - </div> | ||
| + <h1>autónoma – payment</h1> | ||
| + <form action="process_payment.php" method="post"> | ||
| + <p> | ||
| + Provide your credit card details to complete the purchase. Upon | ||
| + completing the purchase, a custom book will be generated within | ||
| + 24 hours, printed, and shipped. | ||
| + </p> | ||
| + <p> | ||
| + Shipping may take up to 15 business days. | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="card_number">Card number:</label> | ||
| + <input type="text" id="card_number" name="card_number" | ||
| + maxlength="19" required autofocus="autofocus" | ||
| + placeholder="1234 5678 9012 3456"> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="cardholder_name">Cardholder name:</label> | ||
| + <input type="text" id="cardholder_name" name="cardholder_name" | ||
| + maxlength="100" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="expiry_month">Expiry month:</label> | ||
| + <select id="expiry_month" name="expiry_month" required> | ||
| + <option value="">Month</option> | ||
| + <?php | ||
| + for( $month = 1; $month <= 12; $month++ ) { | ||
| + $mCode = str_pad( $month, 2, '0', STR_PAD_LEFT ); | ||
| + $mName = date( 'F', mktime( 0, 0, 0, $month, 1 ) ); | ||
| + echo "<option value=\"$mCode\">$mCode - $mName</option>\n"; | ||
| + } | ||
| + ?> | ||
| + </select> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="expiry_year">Expiry year:</label> | ||
| + <select id="expiry_year" name="expiry_year" required> | ||
| + <option value="">Year</option> | ||
| + <?php | ||
| + $current_year = date( 'Y' ); | ||
| + | ||
| + for( $i = 0; $i < 15; $i++ ) { | ||
| + $year = $current_year + $i; | ||
| + echo "<option value=\"$year\">$year</option>"; | ||
| + } | ||
| + ?> | ||
| + </select> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="cvv">CVV:</label> | ||
| + <input type="text" id="cvv" name="cvv" maxlength="4" | ||
| + required placeholder="123"> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="billing_postcode">Billing postal code:</label> | ||
| + <input type="text" id="billing_postcode" name="billing_postcode" | ||
| + maxlength="20" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <button type="submit">Complete purchase</button> | ||
| + </p> | ||
| + </form> | ||
| </body> | ||
| </html> | ||
| + | ||
| Delta | 159 lines added, 38 lines removed, 121-line increase |
|---|