| Author | Dave Jarvis <email> |
|---|---|
| Date | 2026-01-18 00:08:16 GMT-0800 |
| Commit | 9c9677f534a3aa6210eed01320a2617bb30e8a9a |
| Parent | 8648b58 |
| +<?php | ||
| +class Address { | ||
| + private $fields = []; | ||
| + private $missing = []; | ||
| + private const KEEP = false; | ||
| + private const UPPER = true; | ||
| + | ||
| + public function __construct( array $input ) { | ||
| + $this->fields = $input; | ||
| + } | ||
| + | ||
| + private function escape( $value ) { | ||
| + return htmlspecialchars( $value ?? '', ENT_QUOTES, 'UTF-8' ); | ||
| + } | ||
| + | ||
| + public function process( array $required ) { | ||
| + foreach( $required as $field ) { | ||
| + if( empty( $this->fields[ $field ] ) ) { | ||
| + $this->missing[] = $field; | ||
| + } | ||
| + } | ||
| + | ||
| + $rules = [ | ||
| + 'name' => [ 100, self::KEEP ], | ||
| + 'street1' => [ 100, self::UPPER ], | ||
| + 'street2' => [ 100, self::UPPER ], | ||
| + 'city' => [ 50, self::UPPER ], | ||
| + 'state' => [ 50, self::UPPER ], | ||
| + 'postcode' => [ 20, self::UPPER ], | ||
| + 'country' => [ 2, self::UPPER ], | ||
| + 'phone' => [ 20, self::KEEP ], | ||
| + 'email' => [ 254, self::KEEP ], | ||
| + 'gifted' => [ 100, self::KEEP ] | ||
| + ]; | ||
| + | ||
| + $clean = []; | ||
| + foreach( $rules as $field => $config ) { | ||
| + $value = mb_substr( trim( $this->fields[ $field ] ?? '' ), 0, | ||
| + $config[ 0 ], 'UTF-8' ); | ||
| + | ||
| + $transform = [ | ||
| + self::KEEP => $value, | ||
| + self::UPPER => mb_strtoupper( $value, 'UTF-8' ) | ||
| + ]; | ||
| + | ||
| + $clean[ $field ] = $transform[ $config[ 1 ] ]; | ||
| + } | ||
| + $this->fields = $clean; | ||
| + | ||
| + return empty( $this->missing ); | ||
| + } | ||
| + | ||
| + public function export( Session $session ) { | ||
| + if( empty( $this->missing ) ) { | ||
| + $session->write( 'user_address', $this->fields ); | ||
| + } | ||
| + } | ||
| + | ||
| + public function configure( array &$payload ) { | ||
| + $payload[ 'shipping_address' ] = [ | ||
| + 'phone_number' => $this->fields[ 'phone' ] ?? '', | ||
| + 'name' => $this->fields[ 'name' ] ?? '', | ||
| + 'email' => $this->fields[ 'email' ] ?? '', | ||
| + 'city' => $this->fields[ 'city' ] ?? '', | ||
| + 'country_code' => $this->fields[ 'country' ] ?? '', | ||
| + 'postcode' => $this->fields[ 'postcode' ] ?? '', | ||
| + 'state_code' => $this->fields[ 'state' ] ?? '', | ||
| + 'street1' => $this->fields[ 'street1' ] ?? '', | ||
| + 'street2' => $this->fields[ 'street2' ] ?? '' | ||
| + ]; | ||
| + return $this->fields[ 'country' ] ?? ''; | ||
| + } | ||
| + | ||
| + public function render() { | ||
| + if( !empty( $this->missing ) ) { | ||
| + echo "<h2>Missing fields</h2><ul>"; | ||
| + foreach( $this->missing as $field ) { | ||
| + echo "<li>" . $this->escape( $field ) . "</li>"; | ||
| + } | ||
| + echo "</ul>"; | ||
| + } | ||
| + } | ||
| +} | ||
| +<?php | ||
| +class Configuration { | ||
| + private $settings = []; | ||
| + | ||
| + public function load() { | ||
| + $path = $this->homeDirectory() . '/.keys/lulu.config'; | ||
| + if( file_exists( $path ) ) { | ||
| + $this->settings = json_decode( file_get_contents( $path ), true ); | ||
| + } | ||
| + } | ||
| + | ||
| + private function homeDirectory() { | ||
| + $result = ''; | ||
| + | ||
| + if( function_exists( 'posix_getpwnam' ) ) { | ||
| + $homedir = posix_getpwnam( get_current_user() ); | ||
| + | ||
| + if( !empty( $homedir[ 'dir' ] ) ) { | ||
| + $result = $homedir[ 'dir' ]; | ||
| + } | ||
| + } | ||
| + | ||
| + if( empty( $result ) ) { | ||
| + if( !empty( $_SERVER[ 'HOME' ] ) ) { | ||
| + $result = $_SERVER[ 'HOME' ]; | ||
| + } | ||
| + elseif( !empty( getenv( 'HOME' ) ) ) { | ||
| + $result = getenv( 'HOME' ); | ||
| + } | ||
| + elseif( function_exists( 'posix_getpwuid' ) && | ||
| + function_exists( 'posix_getuid' ) ) { | ||
| + $userInfo = posix_getpwuid( posix_getuid() ); | ||
| + | ||
| + if( !empty( $userInfo[ 'dir' ] ) ) { | ||
| + $result = $userInfo[ 'dir' ]; | ||
| + } | ||
| + } | ||
| + } | ||
| + | ||
| + return $result; | ||
| + } | ||
| + | ||
| + public function configure( Publisher $publisher ) { | ||
| + $publisher->initialize( | ||
| + $this->settings[ 'CLIENT_KEY' ] ?? '', | ||
| + $this->settings[ 'URL_BASE' ] ?? '', | ||
| + [ | ||
| + 'package' => $this->settings[ 'ORDER_PACKAGE' ] ?? '', | ||
| + 'pages' => $this->settings[ 'ORDER_PAGE_COUNT' ] ?? 0, | ||
| + 'quantity' => $this->settings[ 'ORDER_QUANTITY' ] ?? 1, | ||
| + 'shipping' => $this->settings[ 'ORDER_SHIPPING' ] ?? '' | ||
| + ] | ||
| + ); | ||
| + } | ||
| +} | ||
| +<?php | ||
| +class Order { | ||
| + private $summary = []; | ||
| + private $errorMessage = ''; | ||
| + private $statusCode = 0; | ||
| + | ||
| + private function escape( $value ) { | ||
| + return htmlspecialchars( $value ?? '', ENT_QUOTES, 'UTF-8' ); | ||
| + } | ||
| + | ||
| + public function process( array $apiResponse, int $statusCode ) { | ||
| + $this->statusCode = $statusCode; | ||
| + if( $statusCode === 201 ) { | ||
| + $this->summary = $apiResponse; | ||
| + } else { | ||
| + $this->errorMessage = $apiResponse[ 'shipping_address' ][ 'detail' ] | ||
| + [ 'errors' ][ 0 ][ 'message' ] ?? $apiResponse[ 'detail' ] ?? | ||
| + "An unexpected error occurred (HTTP $statusCode)."; | ||
| + } | ||
| + } | ||
| + | ||
| + public function render() { | ||
| + if( $this->statusCode === 201 ) { | ||
| + $this->renderSummary(); | ||
| + } else { | ||
| + $this->renderError(); | ||
| + } | ||
| + } | ||
| + | ||
| + private function renderSummary() { | ||
| + $address = $this->summary[ 'shipping_address' ]; | ||
| + $currency = $this->escape( $this->summary[ 'currency' ] ); | ||
| + ?> | ||
| + <h2>Order summary</h2> | ||
| + <section> | ||
| + <p class="address"> | ||
| + <strong><?= $this->escape( $address[ 'name' ] ) ?></strong><br> | ||
| + <?= $this->escape( $address[ 'street1' ] ) ?><br> | ||
| + <?php if( !empty( $address[ 'street2' ] ) ) { ?> | ||
| + <?= $this->escape( $address[ 'street2' ] ) ?><br> | ||
| + <?php } ?> | ||
| + <?= $this->escape( $address[ 'city' ] ) ?> | ||
| + <?= $this->escape( $address[ 'state_code' ] ) ?> | ||
| + <?= $this->escape( $address[ 'postcode' ] ) ?><br> | ||
| + <?= $this->escape( $address[ 'country_code' ] ) ?> | ||
| + </p> | ||
| + <table> | ||
| + <tr> | ||
| + <td>Book price</td> | ||
| + <td><?= $this->escape( $this->summary[ 'line_item_costs' ][ 0 ] | ||
| + [ 'total_cost_excl_tax' ] ) ?> <?= $currency ?></td> | ||
| + </tr> | ||
| + <tr> | ||
| + <td>Shipping</td> | ||
| + <td><?= $this->escape( $this->summary[ 'shipping_cost' ] | ||
| + [ 'total_cost_excl_tax' ] ) ?> <?= $currency ?></td> | ||
| + </tr> | ||
| + <tr> | ||
| + <td>Taxes</td> | ||
| + <td><?= $this->escape( $this->summary[ 'total_tax' ] ) ?> | ||
| + <?= $currency ?></td> | ||
| + </tr> | ||
| + <tr> | ||
| + <td><strong>Amount due</strong></td> | ||
| + <td><strong><?= $this->escape( | ||
| + $this->summary[ 'total_cost_incl_tax' ] ) ?> | ||
| + <?= $currency ?></strong></td> | ||
| + </tr> | ||
| + </table> | ||
| + </section> | ||
| + <?php | ||
| + } | ||
| + | ||
| + private function renderError() { | ||
| + ?> | ||
| + <h2>Shipping calculation error</h2> | ||
| + <p><?= $this->escape( $this->errorMessage ) ?></p> | ||
| + <form action='.'> | ||
| + <button type='submit' onclick='history.back(); return false;'> | ||
| + Try again | ||
| + </button> | ||
| + </form> | ||
| + <?php | ||
| + } | ||
| +} | ||
| +<?php | ||
| +class Publisher { | ||
| + private $key; | ||
| + private $base; | ||
| + private $specs; | ||
| + | ||
| + private const PATH_AUTH = "auth/realms/glasstree/protocol/openid-connect/token"; | ||
| + private const PATH_COST = "print-job-cost-calculations/"; | ||
| + | ||
| + private const CURRENCY_MAP = [ | ||
| + 'AU'=>'AUD','CA'=>'CAD','GB'=>'GBP','AT'=>'EUR','BE'=>'EUR','CY'=>'EUR', | ||
| + 'EE'=>'EUR','FI'=>'EUR','FR'=>'EUR','DE'=>'EUR','GR'=>'EUR','IE'=>'EUR', | ||
| + 'IT'=>'EUR','LV'=>'EUR','LT'=>'EUR','LU'=>'EUR','MT'=>'EUR','NL'=>'EUR', | ||
| + 'PT'=>'EUR','SK'=>'EUR','SI'=>'EUR','ES'=>'EUR' | ||
| + ]; | ||
| + | ||
| + public function initialize( string $key, string $base, array $specs ) { | ||
| + $this->key = $key; | ||
| + $this->base = $base; | ||
| + $this->specs = $specs; | ||
| + } | ||
| + | ||
| + public function process( Address $address, Order $order ) { | ||
| + $token = $this->authenticate(); | ||
| + | ||
| + if( !$token ) { | ||
| + $order->process( [ 'detail' => 'Authentication failed.' ], 401 ); | ||
| + return; | ||
| + } | ||
| + | ||
| + $payload = [ | ||
| + 'line_items' => [ [ | ||
| + 'page_count' => $this->specs[ 'pages' ], | ||
| + 'quantity' => $this->specs[ 'quantity' ], | ||
| + 'pod_package_id' => $this->specs[ 'package' ] | ||
| + ] ], | ||
| + 'shipping_option' => $this->specs[ 'shipping' ] | ||
| + ]; | ||
| + | ||
| + $country = $address->configure( $payload ); | ||
| + $payload[ 'currency' ] = self::CURRENCY_MAP[ $country ] ?? 'USD'; | ||
| + | ||
| + $context = stream_context_create( [ 'http' => [ | ||
| + 'method' => 'POST', | ||
| + 'header' => "Authorization: Bearer $token\r\nContent-Type: " . | ||
| + "application/json\r\n", | ||
| + 'content' => json_encode( $payload ), | ||
| + 'ignore_errors' => true | ||
| + ] ] ); | ||
| + | ||
| + $raw = @file_get_contents( $this->base . self::PATH_COST, false, $context ); | ||
| + $body = json_decode( $raw, true ) ?? []; | ||
| + | ||
| + $code = 0; | ||
| + | ||
| + if( !empty( $http_response_header ) ) { | ||
| + preg_match( "/\d{3}/", $http_response_header[ 0 ], $matches ); | ||
| + $code = intval( $matches[ 0 ] ); | ||
| + } | ||
| + | ||
| + // Preserve the name and country code for the order summary. | ||
| + if( $code === 201 && isset( $body[ 'shipping_address' ] ) ) { | ||
| + $sentName = $payload[ 'shipping_address' ][ 'name' ]; | ||
| + $sentCountry = $payload[ 'shipping_address' ][ 'country_code' ]; | ||
| + | ||
| + if( empty( $body[ 'shipping_address' ][ 'name' ] ) ) { | ||
| + $body[ 'shipping_address' ][ 'name' ] = $sentName; | ||
| + } | ||
| + if( empty( $body[ 'shipping_address' ][ 'country_code' ] ) ) { | ||
| + $body[ 'shipping_address' ][ 'country_code' ] = $sentCountry; | ||
| + } | ||
| + } | ||
| + | ||
| + $order->process( $body, $code ); | ||
| + } | ||
| + | ||
| + private function authenticate() { | ||
| + $context = stream_context_create( [ 'http' => [ | ||
| + 'method' => 'POST', | ||
| + 'header' => "Authorization: Basic " . base64_encode( $this->key ) . | ||
| + "\r\nContent-Type: application/x-www-form-urlencoded\r\n", | ||
| + 'content' => http_build_query( [ 'grant_type' => 'client_credentials' ] ) | ||
| + ] ] ); | ||
| + $response = @file_get_contents( | ||
| + $this->base . self::PATH_AUTH, false, $context | ||
| + ); | ||
| + | ||
| + return $response | ||
| + ? ( json_decode( $response, true )[ 'access_token' ] ?? null ) | ||
| + : null; | ||
| + } | ||
| +} | ||
| +<?php | ||
| +class Session { | ||
| + public function __construct() { | ||
| + if( session_status() === PHP_SESSION_NONE ) { | ||
| + session_start(); | ||
| + } | ||
| + } | ||
| + | ||
| + public function write( $key, $value ) { | ||
| + $_SESSION[ $key ] = $value; | ||
| + } | ||
| +} | ||
| <?php | ||
| -function getHomeDirectory() { | ||
| - $result = ''; | ||
| - | ||
| - if( function_exists( 'posix_getpwnam' ) ) { | ||
| - $homedir = posix_getpwnam( get_current_user() ); | ||
| - | ||
| - if( !empty( $homedir[ 'dir' ] ) ) { | ||
| - $result = $homedir[ 'dir' ]; | ||
| - } | ||
| - } | ||
| - | ||
| - if( empty( $result ) ) { | ||
| - if( !empty( $_SERVER[ 'HOME' ] ) ) { | ||
| - $result = $_SERVER[ 'HOME' ]; | ||
| - } | ||
| - elseif( !empty( getenv( 'HOME' ) ) ) { | ||
| - $result = getenv( 'HOME' ); | ||
| - } | ||
| - elseif( function_exists( 'posix_getpwuid' ) && | ||
| - function_exists( 'posix_getuid' ) ) { | ||
| - $userInfo = posix_getpwuid( posix_getuid() ); | ||
| - | ||
| - if( !empty( $userInfo[ 'dir' ] ) ) { | ||
| - $result = $userInfo[ 'dir' ]; | ||
| - } | ||
| - } | ||
| - } | ||
| - return $result; | ||
| -} | ||
| - | ||
| -$configPath = getHomeDirectory() . '/.keys/lulu.config'; | ||
| -$config = json_decode( file_get_contents( $configPath ), true ); | ||
| - | ||
| -define( 'CLIENT_KEY', $config[ 'CLIENT_KEY' ] ); | ||
| -define( 'URL_BASE', $config[ 'URL_BASE' ] ); | ||
| -define( 'ORDER_PAGE_COUNT', $config[ 'ORDER_PAGE_COUNT' ] ); | ||
| -define( 'ORDER_PACKAGE', $config[ 'ORDER_PACKAGE' ] ); | ||
| -define( 'ORDER_QUANTITY', $config[ 'ORDER_QUANTITY' ] ); | ||
| -define( 'ORDER_SHIPPING', $config[ 'ORDER_SHIPPING' ] ); | ||
| - | ||
| -const URL_AUTH = URL_BASE . "auth/realms/glasstree/protocol/openid-connect/token"; | ||
| -const URL_COST = URL_BASE . "print-job-cost-calculations/"; | ||
| - | ||
| -const CURRENCY_MAP = [ | ||
| - 'AU'=>'AUD','CA'=>'CAD','GB'=>'GBP', | ||
| - 'AT'=>'EUR','BE'=>'EUR','CY'=>'EUR','EE'=>'EUR','FI'=>'EUR','FR'=>'EUR', | ||
| - 'DE'=>'EUR','GR'=>'EUR','IE'=>'EUR','IT'=>'EUR','LV'=>'EUR','LT'=>'EUR', | ||
| - 'LU'=>'EUR','MT'=>'EUR','NL'=>'EUR','PT'=>'EUR','SK'=>'EUR','SI'=>'EUR', | ||
| - 'ES'=>'EUR' | ||
| -]; | ||
| - | ||
| -$required = [ | ||
| - "city", "country", "postcode", "state", "street1", "phone", "name", "email" | ||
| -]; | ||
| -$missing = []; | ||
| - | ||
| -foreach( $required as $f ) { | ||
| - if( empty( $_POST[ $f ] ) ) { | ||
| - $missing[] = $f; | ||
| - } | ||
| -} | ||
| - | ||
| -$code = 0; | ||
| -$raw_response = ""; | ||
| -$error_message = ""; | ||
| - | ||
| -if( empty( $missing ) ) { | ||
| - define( 'KEEP', false ); | ||
| - define( 'UPPER', true ); | ||
| - | ||
| - $fields = [ | ||
| - 'name' => [ 100, KEEP ], | ||
| - 'street1' => [ 100, UPPER ], | ||
| - 'street2' => [ 100, UPPER ], | ||
| - 'city' => [ 50, UPPER ], | ||
| - 'state' => [ 50, UPPER ], | ||
| - 'postcode' => [ 20, UPPER ], | ||
| - 'phone' => [ 20, KEEP ], | ||
| - 'email' => [ 254, KEEP ], | ||
| - 'gifted' => [ 100, KEEP ] | ||
| - ]; | ||
| - | ||
| - $clean = []; | ||
| - | ||
| - foreach( $fields as $f => $cfg ) { | ||
| - $val = mb_substr( trim( $_POST[ $f ] ?? '' ), 0, $cfg[ 0 ], 'UTF-8' ); | ||
| - $transform = [ | ||
| - KEEP => $val, | ||
| - UPPER => mb_strtoupper( $val, 'UTF-8' ) | ||
| - ]; | ||
| - $clean[ $f ] = $transform[ $cfg[ 1 ] ]; | ||
| - } | ||
| - | ||
| - $selected_currency = CURRENCY_MAP[ $_POST[ "country" ] ] ?? 'USD'; | ||
| - | ||
| - $auth_context = stream_context_create( [ | ||
| - "http" => [ | ||
| - "method" => "POST", | ||
| - "header" => "Authorization: Basic " . | ||
| - base64_encode( CLIENT_KEY ) . | ||
| - "\r\nContent-Type: application/x-www-form-urlencoded\r\n", | ||
| - "content" => http_build_query( [ "grant_type" => "client_credentials" ] ), | ||
| - ], | ||
| - ] ); | ||
| - | ||
| - $auth_json = file_get_contents( URL_AUTH, false, $auth_context ); | ||
| - $auth_response = json_decode( $auth_json, 1 ); | ||
| - $token = $auth_response[ "access_token" ] ?? null; | ||
| - | ||
| - if( $token ) { | ||
| - $cost_data = [ | ||
| - "line_items" => [ [ | ||
| - "page_count" => ORDER_PAGE_COUNT, | ||
| - "quantity" => ORDER_QUANTITY, | ||
| - "pod_package_id" => ORDER_PACKAGE | ||
| - ] ], | ||
| - "shipping_address" => [ | ||
| - "phone_number" => $clean[ "phone" ], | ||
| - "name" => $clean[ "name" ], | ||
| - "email" => $clean[ "email" ], | ||
| - "city" => $clean[ "city" ], | ||
| - "country_code" => $_POST[ "country" ], | ||
| - "postcode" => $clean[ "postcode" ], | ||
| - "state_code" => $clean[ "state" ], | ||
| - "street1" => $clean[ "street1" ], | ||
| - "street2" => $clean[ "street2" ], | ||
| - ], | ||
| - "shipping_option" => ORDER_SHIPPING, | ||
| - "currency" => $selected_currency, | ||
| - ]; | ||
| - | ||
| - $cost_context = stream_context_create( [ | ||
| - "http" => [ | ||
| - "method" => "POST", | ||
| - "header" => "Authorization: Bearer $token\r\n" . | ||
| - "Content-Type: application/json\r\n", | ||
| - "content" => json_encode( $cost_data ), | ||
| - "ignore_errors" => true, | ||
| - ], | ||
| - ] ); | ||
| - | ||
| - $raw_response = file_get_contents( URL_COST, false, $cost_context ); | ||
| - | ||
| - if( !empty( $http_response_header ) ) { | ||
| - preg_match( "/\d{3}/", $http_response_header[ 0 ], $m ); | ||
| - $code = intval( $m[ 0 ] ); | ||
| - } | ||
| - | ||
| - $api_data = json_decode( $raw_response, 1 ) ?? []; | ||
| - | ||
| - if( $code !== 201 ) { | ||
| - $error_message = | ||
| - $api_data[ 'shipping_address' ][ 'detail' ][ 'errors' ][ 0 ][ 'message' ] | ||
| - ?? $api_data[ 'detail' ] | ||
| - ?? "An unexpected error occurred (HTTP $code)."; | ||
| - } | ||
| - } else { | ||
| - $error_message = "Authentication failed."; | ||
| - } | ||
| -} | ||
| - | ||
| -function escape( $data ) { | ||
| - if( is_array( $data ) ) { | ||
| - return array_map( 'escape', $data ); | ||
| - } | ||
| +require_once 'Configuration.php'; | ||
| +require_once 'Address.php'; | ||
| +require_once 'Order.php'; | ||
| +require_once 'Publisher.php'; | ||
| +require_once 'Session.php'; | ||
| - return htmlspecialchars( $data ?? '', ENT_QUOTES, 'UTF-8' ); | ||
| -} | ||
| +$config = new Configuration(); | ||
| +$address = new Address( $_POST ); | ||
| +$order = new Order(); | ||
| +$publisher = new Publisher(); | ||
| +$session = new Session(); | ||
| -$response = escape( array_merge( | ||
| - [ 'form' => $_POST, 'missing' => $missing, 'api_error' => $error_message ], | ||
| - $api_data[ 'shipping_address' ] ?? [], | ||
| - $api_data ?? [] | ||
| -) ); | ||
| +$config->load(); | ||
| +$config->configure( $publisher ); | ||
| +$valid = $address->process( [ | ||
| + "city", "country", "postcode", "state", "street1", "phone", "name", "email" ] | ||
| +); | ||
| +$address->export( $session ); | ||
| ?> | ||
| <!DOCTYPE html> | ||
| <h1>autónoma – payment</h1> | ||
| <div class="payment-content"> | ||
| - <?php if( !empty( $response[ 'missing' ] ) ) { ?> | ||
| - <h2>Missing fields</h2> | ||
| - <ul> | ||
| - <?php foreach( $response[ 'missing' ] as $m ) { ?> | ||
| - <li><?= $m ?></li> | ||
| - <?php } ?> | ||
| - </ul> | ||
| - <?php } else { ?> | ||
| - <?php if( $code == 201 ) { ?> | ||
| - <h2>Order summary</h2> | ||
| - <section> | ||
| - <p class="address"> | ||
| - <strong><?= $_POST[ 'name' ] ?></strong><br> | ||
| - <?= $response[ 'street1' ] ?><br> | ||
| - <?php if( !empty( $response[ 'street2' ] ) ) { ?> | ||
| - <?= $response[ 'street2' ] ?><br> | ||
| - <?php } ?> | ||
| - <?= $response[ 'city' ] ?> | ||
| - <?= $response[ 'state' ] ?> | ||
| - <?= $response[ 'postcode' ] ?><br> | ||
| - <?= $response[ 'country' ] ?><br> | ||
| - </p> | ||
| - <table> | ||
| - <tr> | ||
| - <td>Book price</td> | ||
| - <td><?= $response[ 'line_item_costs' ][0][ 'total_cost_excl_tax' ] ?> <?= $response[ 'currency' ] ?></td> | ||
| - </tr> | ||
| - <tr> | ||
| - <td>Shipping</td> | ||
| - <td><?= $response[ 'shipping_cost' ][ 'total_cost_excl_tax' ] ?> <?= $response[ 'currency' ] ?></td> | ||
| - </tr> | ||
| - <tr> | ||
| - <td>Taxes</td> | ||
| - <td><?= $response[ 'total_tax' ] ?> <?= $response[ 'currency' ] ?></td> | ||
| - </tr> | ||
| - <tr> | ||
| - <td><strong>Amount due</strong></td> | ||
| - <td><strong><?= $response[ 'total_cost_incl_tax' ] ?> <?= $response[ 'currency' ] ?></strong></td> | ||
| - </tr> | ||
| - </table> | ||
| - </section> | ||
| - <?php } else { ?> | ||
| - <h2>Shipping calculation error</h2> | ||
| - <p><?= $response[ 'api_error' ] ?></p> | ||
| - <form action="."> | ||
| - <button type="submit" onclick="history.back(); return false;"> | ||
| - Try again | ||
| - </button> | ||
| - </form> | ||
| - <?php } ?> | ||
| - <?php } ?> | ||
| + <?php | ||
| + if( $valid ) { | ||
| + $publisher->process( $address, $order ); | ||
| + $order->render(); | ||
| + } else { | ||
| + $address->render(); | ||
| + } | ||
| + ?> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| - | ||
| Delta | 351 lines added, 224 lines removed, 127-line increase |
|---|