changeset 363:0b12af2c103a misc

Split prices.php configuration into a separate PHP file, do some cleanups in the code as well.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 30 Mar 2020 10:53:33 +0300
parents 06f3892d53e9
children 32a5a3a88f0a
files prices.config.php prices.php
diffstat 2 files changed, 424 insertions(+), 364 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/prices.config.php	Mon Mar 30 10:53:33 2020 +0300
@@ -0,0 +1,279 @@
+<?php
+/* Merchant/alchemist price calculator in PHP
+ * (C) Copyright 2009-2013,2020 Matti 'Ggr' Hamalainen <ccr@tnsp.org>
+ *
+ * Requires PHP 5.4 or later, primarily tested on PHP 5.6.x.
+ * Also tested on PHP 7.3.
+ *
+ * Notes:
+ * - Possibility for discount can be enabled per section, there is
+ *   no "global" discount for everything, however.
+ *
+ * - Services in $services1_prices have a threshold for quantity
+ *   discount, but services in $services2_prices do not. The total
+ *   service discount % applies to both, too.
+ *
+ * - If "extra" field is set (as it is for services that have some
+ *   additional material costs), the extra price DOES NOT get
+ *   the section discount % applied!!
+ *
+ * - Ammunition, potions and salves sections have a "base" price,
+ *   on top of which specials (more difficult to make, etc.) additional
+ *   price can be set.
+ *
+ */
+//
+// General settings
+//
+$pageTitle = "Ggr's Merchant Pricelist";
+$pageCharset = "UTF-8";
+//$pageCSS = "foobar.css";  // Uncomment and change this, if you want to use your own CSS stylesheet file
+
+
+//
+// Enable different service and product sections
+//
+$sections = [
+  "services1"  => true,
+  "services2"  => true,
+  "reagents"   => true,
+  "arrows"     => true,
+  "salves"     => true,
+  "potions"    => false,
+];
+
+
+//
+// Global additional description string, added to start of the page
+//
+$global_desc = '
+<div style="border: 1px solid #0f0; padding: 15px; color: #ff0; text-align: center; font-size: 8pt;">
+<span style="font-size: 20pt;">I do NOT make alchemist potions or rings*, or any SHIP stuff.</span><br />
+<br />
+(*) Well, actually I do make rings, but only for personal amusement. I do
+not wish to spend time trying to come up with some specific ring type.)
+</div>
+';
+
+
+//
+// Generic services section settings
+//
+$services = [
+  "name"     => "services",
+  "title"    => "Generic services",
+  "discount" => true,	// enable discounts for this section
+
+  "desc"     => "As one might expect, <b>I have most of the relevant
+skills/spells/masteries at 100%</b>.",
+];
+
+
+// Services with discount thresholds for prices
+$services1_prices = [
+  "fw" => [
+    "name"     => "Feather weight",
+    "subj"     => "cast",
+    "tresh"    => 20,		// threshold count for discount
+    "price1"   => 2500,		// price per item below discount threshold
+    "base"     => 10000,	// base price for discounted total
+    "price2"   => 1750		// price per item with discount
+  ],
+  "prot" => [
+    "name"     => "Protect armour/weapon/item",
+    "subj"     => "cast",
+    "tresh"    => 20,
+    "price1"   => 3000,
+    "base"     => 10000,
+    "price2"   => 2000
+  ],
+  "repair" => [
+    "name"     => "Repair armour/weapon/item",
+    "tresh"    => 6,
+    "subj"     => "item",
+    "price1"   => 10000,
+    "price2"   => 7500,
+    "extra"    => " + materials"
+  ],
+];
+
+
+// Services _without_ discount threshold
+$services2_prices = [
+  "labels" => [
+    "name"     => "Labelling",
+    "subj"     => "item",
+    "price"    => 3000
+  ],
+  "surg80" => [
+    "name"     => "Surgery to 80%",
+    "subj"     => "item",
+    "price"    => 10000,
+  ],
+  "surg100" => [
+    "name"     => "Surgery to 100",
+    "subj"     => "item",
+    "price"    => 15000,
+  ],
+  "mip" => [
+    "name"     => "Money is Power",
+    "subj"     => "cast",
+    "price"    => 10000,
+  ],
+  "makegear" => [
+    "name"     => "Make mount gear",
+    "subj"     => "item",
+    "price"    => 20000,
+    "extra"    => " + materials",
+  ],
+  "refitgear" => [
+    "name"     => "Refit mount gear",
+    "subj"     => "item",
+    "price"    => 10000,
+    "extra"    => " + materials"
+  ],
+
+  "createaw" => [
+    "name"     => "Create armour/weapon",
+    "subj"     => "item",
+    "price"    => 15000,
+    "extra"    => " + materials"
+  ],
+];
+
+
+//
+// Mage reagents
+//
+$reagents = [
+  "name"     => "reagent",
+  "title"    => "Power reagents",
+  "discount" => true,	// enable discounts for this section
+  "datafile" => "reagents.txt",
+
+  "desc"     => "Bulk orders may require time to complete, inquire.
+<b>Notice! Availability presented below may or may not reflect the current stock situation.</b>",
+
+  "prices" => [
+    "Blast reagents" => [
+      "acid1" => ["acid", "Acid Blast",           "handful of olivine powder",    125],
+      "acid2" => ["acid", "Acid Storm",           "pair of interlocked rings",    125],
+
+      "asph1" => ["asph", "Blast Vacuum",         "bronze marble",                150],
+      "asph2" => ["asph", "Vacuum Globe",         "small fan",                    150],
+
+      "elec1" => ["elec", "Electrocution",        "small piece of electrum wire", 125],
+      "elec2" => ["elec", "Lightning Storm",      "cluster of tungsten wires",    125],
+
+      "cold1" => ["cold", "Cold Ray",             "steel arrowhead",              150],
+      "cold2" => ["cold", "Hailstorm",            "handful of onyx gravel",       125],
+
+      "pois1" => ["pois", "Summon Carnal Spores", "silvery bark chip",            125],
+      "pois2" => ["pois", "Killing Cloud",        "ebony tube",                   100],
+
+      "fire1" => ["fire", "Lava Blast",           "granite sphere",               125],
+      "fire2" => ["fire", "Lava Storm",           "blue cobalt cup",              125],
+
+      "mana1" => ["mana", "Golden Arrow",         "copper rod",                   125],
+      "mana2" => ["mana", "Magic Eruption",       "tiny platinum hammer",         125],
+    ],
+
+    "Prot reagents" => [
+      "phys3" => ["phys", "Armour of Aether",         "small highsteel disc",     200],
+      "acid3" => ["acid", "Acid Shield",              "stone cube",               125],
+      "asph3" => ["asph", "Aura of Wind",             "tiny leather bag",         275],
+      "fire3" => ["fire", "Flame Shield",             "small glass cone",         150],
+      "cold3" => ["cold", "Frost Shield",             "grey fur triangle",        275],
+      "elec3" => ["elec", "Lightning Shield",         "small iron rod",           100],
+      "mana3" => ["mana", "Repulsor Aura",            "quartz prism",             125],
+      "pois3" => ["pois", "Shield of Detoxification", "tiny amethyst crystal",    125],
+    ],
+  ],
+];
+
+
+//
+// Ammunition
+//
+$arrows = [
+  "name" => "arrow",
+  "title" => "Ammunition",
+  "desc" => "Only advertised <b>damage types</b> are available. If you want
+other material combos for base ammunition, these may be negotiable. Feel
+free to inquire about other ammunition types (bullets, etc.).
+",
+
+  "base" => 300, // base price per arrow, the values below are added on top of this
+  "discount" => true, // enable discounts for this section
+
+  "i_fields" => 2,
+  "i_price" => 2,
+  "i_titles" => ["Type", "Materials", "Price / arrow", "#"],
+  "prices" => [
+    "phys" => ["Normal (phys)", "ebony, feathers, diamond",     0],
+    "psi"  => ["Psi",           "* + brain",                    100],
+    "acid" => ["Acid",          "* + stomach",                  100],
+    "elec" => ["Elec",          "* + tungsten",                 100],
+    "mana" => ["Mana",          "* + crystalline",              150],
+    "cold" => ["Cold",          "* + ice",                      150],
+    "fire" => ["Fire",          "* + fire",                     250],
+    "asph" => ["Asphyx",        "* + toadstool",                350],
+//    "pois" => ["Poison",        "* + h'cliz",                   300],
+  ],
+];
+
+
+//
+// Salves
+//
+$salves = [
+  "name" => "salve",
+  "title" => "Salves",
+  "desc" => "All salves sold by me are <b>+25 to stat</b> with <b>10 min</b>
+duration. Salves of same type do not stack, so you can't get +50 or such,
+but different types of salves can be used simultaneously (like int and wis).
+One salve has 4 portions (e.g. 4 uses) and weighs about 1kg.
+<br />
+<b>Salve orders will take some time to complete, I don't keep much stock on these currently.</b>
+",
+
+  "base" => 6000,
+  "discount" => false,
+
+  "i_fields" => 1,
+  "i_price" => 1,
+  "i_titles" => ["Salve", "Price / piece", "#"],
+  "prices" => [
+    "str"  => ["+str", 0],
+    "con"  => ["+con", 0],
+    "int"  => ["+int", 0],
+    "wis"  => ["+wis", 0],
+    "dex"  => ["+dex", 0],
+
+    "pack" => ["white cloth pack for holding salves [0/15]", 29000],
+  ],
+];
+
+
+//
+// Alchemist potions
+//
+$potions = [
+  "name" => "potion",
+  "title" => "Alchemist potions",
+  "desc" => "Potion orders have no guaranteed completion time! If you want
+potions sooner rather than later, ask someone else!
+",
+
+  "base" => 5500,
+  "discount" => false,
+
+  "i_fields" => 1,
+  "i_price" => 1,
+  "i_titles" => ["Potion", "Price / piece", "#"],
+  "prices" => [
+    "generic" => ["Generic potion",                   0],
+  ],
+];
+
+?>
\ No newline at end of file
--- a/prices.php	Wed Aug 21 17:26:04 2019 +0300
+++ b/prices.php	Mon Mar 30 10:53:33 2020 +0300
@@ -1,264 +1,25 @@
-<?
+<?php
 /* Merchant/alchemist price calculator in PHP
- * (C) Copyright 2009-2013 Matti 'Ggr' Hamalainen <ccr@tnsp.org>
- *
- * Requires PHP 4.3 or later, primarily tested on PHP 5.2.x.
- *
- * Notes:
- * - Possibility for discount can be enabled per section, there is
- *   no "global" discount for everything, however.
+ * (C) Copyright 2009-2013,2020 Matti 'Ggr' Hamalainen <ccr@tnsp.org>
  *
- * - Services in $services1_prices have a threshold for quantity
- *   discount, but services in $services2_prices do not. The total
- *   service discount % applies to both, too.
- *
- * - If "extra" field is set (as it is for services that have some
- *   additional material costs), the extra price DOES NOT get
- *   the section discount % applied!!
- *
- * - Ammunition, potions and salves sections have a "base" price,
- *   on top of which specials (more difficult to make, etc.) additional
- *   price can be set.
+ * Requires PHP 5.4 or later, primarily tested on PHP 5.6.x.
+ * Also tested on PHP 7.3.
  *
  */
-// General settings
-$pageIndex = "prices.php";
-$pageTitle = "Ggr's Merchant Pricelist";
-$pageCharset = "UTF-8";
-//$pageCSS = "foobar.css";  // Uncomment and change this, if you want to use your own CSS stylesheet file
-
-
-// Enable service and product sections
-$sections = array(
-  "services1"  => true,
-  "services2"  => true,
-  "reagents"   => true,
-  "arrows"     => true,
-  "salves"     => true,
-  "potions"    => false,
-);
-
-
-// Global additional desc, added to start of the page
-$global_desc = '
-<div style="border: 1px solid #0f0; padding: 15px; color: #ff0; text-align: center; font-size: 8pt;">
-<span style="font-size: 20pt;">I do NOT make alchemist potions or rings*, or any SHIP stuff.</span><br />
-<br />
-(*) Well, actually I do make rings, but only for personal amusement. I do
-not wish to spend time trying to come up with some specific ring type.)
-</div>
-';
-
-
-// Generic services section settings
-$services = array(
-  "name"     => "services",
-  "title"    => "Generic services",
-  "discount" => true,	// enable discounts for this section
-
-  "desc"     => "As one might expect, <b>I have most of the relevant
-skills/spells/masteries at 100%</b>.",
-);
-
-// Service prices with discount thresholds
-$services1_prices = array(
-  "fw" => array(
-    "name"     => "Feather weight",
-    "subj"     => "cast",
-    "tresh"    => 20,		// threshold for discount
-    "price1"   => 2500,		// price per item below discount threshold
-    "base"     => 10000,	// base price for discounted total
-    "price2"   => 1750		// price per item with discount
-  ),
-  "prot" => array(
-    "name"     => "Protect armour/weapon/item",
-    "subj"     => "cast",
-    "tresh"    => 20,
-    "price1"   => 3000,
-    "base"     => 10000,
-    "price2"   => 2000
-  ),
-  "repair" => array(
-    "name"     => "Repair armour/weapon/item",
-    "tresh"    => 6,
-    "subj"     => "item",
-    "price1"   => 10000,
-    "price2"   => 7500,
-    "extra"    => " + materials"
-  ),
-);
-
-
-// Services without discount threshold
-$services2_prices = array(
-  "labels" => array(
-    "name"     => "Labelling",
-    "subj"     => "item",
-    "price"    => 3000
-  ),
-  "surg80" => array(
-    "name"     => "Surgery to 80%",
-    "subj"     => "item",
-    "price"    => 10000,
-  ),
-  "surg100" => array(
-    "name"     => "Surgery to 100", 
-    "subj"     => "item",
-    "price"    => 15000,
-  ),
-  "mip" => array(
-    "name"     => "Money is Power",
-    "subj"     => "cast",
-    "price"    => 10000,
-  ),
-  "makegear" => array(
-    "name"     => "Make mount gear",
-    "subj"     => "item",
-    "price"    => 20000,
-    "extra"    => " + materials",
-  ),
-  "refitgear" => array(
-    "name"     => "Refit mount gear",
-    "subj"     => "item",
-    "price"    => 10000,
-    "extra"    => " + materials"
-  ),
-
-  "createaw" => array(
-    "name"     => "Create armour/weapon",
-    "subj"     => "item",
-    "price"    => 15000,
-    "extra"    => " + materials"
-  ),
-);
-
-
-// Mage reagents
-$reagents = array(
-  "name"     => "reagent",
-  "title"    => "Power reagents",
-  "discount" => true,	// enable discounts for this section
-  "datafile" => "reagents.txt",
+$pageConfig = "prices.config.php";
 
-  "desc"     => "Bulk orders may require time to complete, inquire.
-<b>Notice! Availability presented below may or may not reflect the current stock situation.</b>",
-
-  "prices" => array(
-    "Blast reagents" => array(
-      "acid1" => array("acid", "Acid Blast",           "handful of olivine powder",    125),
-      "acid2" => array("acid", "Acid Storm",           "pair of interlocked rings",    125),
-
-      "asph1" => array("asph", "Blast Vacuum",         "bronze marble",                150),
-      "asph2" => array("asph", "Vacuum Globe",         "small fan",                    150),
-
-      "elec1" => array("elec", "Electrocution",        "small piece of electrum wire", 125),
-      "elec2" => array("elec", "Lightning Storm",      "cluster of tungsten wires",    125),
-
-      "cold1" => array("cold", "Cold Ray",             "steel arrowhead",              150),
-      "cold2" => array("cold", "Hailstorm",            "handful of onyx gravel",       125),
-
-      "pois1" => array("pois", "Summon Carnal Spores", "silvery bark chip",            125),
-      "pois2" => array("pois", "Killing Cloud",        "ebony tube",                   100),
-
-      "fire1" => array("fire", "Lava Blast",           "granite sphere",               125),
-      "fire2" => array("fire", "Lava Storm",           "blue cobalt cup",              125),
-
-      "mana1" => array("mana", "Golden Arrow",         "copper rod",                   125),
-      "mana2" => array("mana", "Magic Eruption",       "tiny platinum hammer",         125),
-    ),
-  
-    "Prot reagents" => array(
-      "phys3" => array("phys", "Armour of Aether",         "small highsteel disc",     200),
-      "acid3" => array("acid", "Acid Shield",              "stone cube",               125),
-      "asph3" => array("asph", "Aura of Wind",             "tiny leather bag",         275),
-      "fire3" => array("fire", "Flame Shield",             "small glass cone",         150),
-      "cold3" => array("cold", "Frost Shield",             "grey fur triangle",        275),
-      "elec3" => array("elec", "Lightning Shield",         "small iron rod",           100),
-      "mana3" => array("mana", "Repulsor Aura",            "quartz prism",             125),
-      "pois3" => array("pois", "Shield of Detoxification", "tiny amethyst crystal",    125),
-    )
-  )
-);
-
-
-// Ammunition
-$arrows = array(
-  "name" => "arrow",
-  "title" => "Ammunition",
-  "desc" => "Only advertised <b>damage types</b> are available. If you want
-other material combos for base ammunition, these may be negotiable. Feel
-free to inquire about other ammunition types (bullets, etc.).
-",
-
-  "base" => 300, // base price per arrow, the values below are added on top of this
-  "discount" => true, // enable discounts for this section
+if (!file_exists($pageConfig))
+{
+  echo "ERROR: Configuration file '".$pageConfig."' not found!";
+  exit;
+}
 
-  "i_fields" => 2,
-  "i_price" => 2,
-  "i_titles" => array("Type", "Materials", "Price / arrow", "#"),
-  "prices" => array(
-    "phys" => array("Normal (phys)", "ebony, feathers, diamond",     0),
-    "psi"  => array("Psi",           "* + brain",                    100),
-    "acid" => array("Acid",          "* + stomach",                  100),
-    "elec" => array("Elec",          "* + tungsten",                 100),
-    "mana" => array("Mana",          "* + crystalline",              150),
-    "cold" => array("Cold",          "* + ice",                      150),
-    "fire" => array("Fire",          "* + fire",                     250),
-    "asph" => array("Asphyx",        "* + toadstool",                350),
-//    "pois" => array("Poison",        "* + h'cliz",                   300),
-  )
-);
-
-
-// Salves
-$salves = array(
-  "name" => "salve",
-  "title" => "Salves",
-  "desc" => "All salves sold by me are <b>+25 to stat</b> with <b>10 min</b>
-duration. Salves of same type do not stack, so you can't get +50 or such,
-but different types of salves can be used simultaneously (like int and wis).
-One salve has 4 portions (e.g. 4 uses) and weighs about 1kg.
-<br />
-<b>Salve orders will take some time to complete, I don't keep much stock on these currently.</b>
-",
-
-  "base" => 6000,
-  "discount" => false,
+require_once $pageConfig;
 
-  "i_fields" => 1,
-  "i_price" => 1,
-  "i_titles" => array("Salve", "Price / piece", "#"),
-  "prices" => array(
-    "str"  => array("+str", 0),
-    "con"  => array("+con", 0),
-    "int"  => array("+int", 0),
-    "wis"  => array("+wis", 0),
-    "dex"  => array("+dex", 0),
-
-    "pack" => array("white cloth pack for holding salves [0/15]", 29000),
-  )
-);
-
-
-// Alchemist potions
-$potions = array(
-  "name" => "potion",
-  "title" => "Alchemist potions",
-  "desc" => "Potion orders have no guaranteed completion time! If you want
-potions sooner rather than later, ask someone else!
-",
-
-  "base" => 5500,
-  "discount" => false,
-
-  "i_fields" => 1,
-  "i_price" => 1,
-  "i_titles" => array("Potion", "Price / piece", "#"),
-  "prices" => array(
-    "generic" => array("Generic potion",                   0),
-  ),
-);
-
+if (!isset($pageIndex))
+{
+  $pageIndex = "prices.php";
+}
 
 
 //============================================================================
@@ -275,13 +36,16 @@
 }
 
 
-function getVal($name, &$val) 
+function getVal($name, &$val)
 {
-  if (isset($_REQUEST["num_".$name]) && is_numeric($_REQUEST["num_".$name])) {
+  if (isset($_REQUEST["num_".$name]) &&
+      is_numeric($_REQUEST["num_".$name]))
+  {
     $val = $_REQUEST["num_".$name];
     if ($val != 0)
       return TRUE;
-  } else
+  }
+  else
     $val = -1;
 
   return FALSE;
@@ -304,13 +68,17 @@
   $dfactor = 1.0;
   $dstr = "";
 
-  if (getVal($dfield."_discount", $dval)) {
+  if (getVal($dfield."_discount", $dval))
+  {
     addVal($dfield."_discount", $dval);
 
-    if ($dval > 0 && $dval <= 100) {
+    if ($dval > 0 && $dval <= 100)
+    {
       $dfactor = $dval / 100.0;
       $dstr = " [".-(100 - $dval)."%]";
-    } elseif ($dval < 0 && $dval >= -100) {
+    }
+    elseif ($dval < 0 && $dval >= -100)
+    {
       $dfactor = (100 + $dval) / 100.0;
       $dstr = " [".$dval."%]";
     }
@@ -331,79 +99,74 @@
 
 function printSectionFooter($sec)
 {
-  echo "</table>\n<p>\n";
-  
-  if ($sec["discount"]) {
+  echo
+    "</table>\n".
+    "<p>\n";
+
+  if ($sec["discount"])
+  {
     echo $sec["title"]." total discount %: ".
-    getField($sec["name"]."_discount")."<br />\n".
-    "";
+      getField($sec["name"]."_discount")."<br />\n";
   }
 
-  echo "<input type=\"submit\" value=\" Calculate \" class=\"isubmit\" />\n".
-  "</p>\n\n";
+  echo
+    "<input type=\"submit\" value=\" Calculate \" class=\"isubmit\" />\n".
+    "</p>\n\n";
 }
 
 
 //============================================================================
 
-if (1)
-{
-  echo
-  "<?xml version=\"1.0\" encoding=\"".$pageCharset."\"?>\n".
-  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n".
-//  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n".
-  "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n";
-}
-else
-{
-  echo
+echo
   "<!DOCTYPE HTML>\n".
-  "<html>\n";
-}
-?>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=<? echo $pageCharset; ?>" />
- <title><? echo $pageTitle; ?></title>
-<?
+  "<html>\n".
+  "<head>\n".
+  "  <meta charset=\"".$pageCharset."\">\n".
+  "  <title>".htmlentities($pageTitle)."</title>\n";
+
 if (isset($pageCSS))
 {
- echo "<link rel=\"stylesheet\" title=\"Default\" href=\"".$pageCSS."\" type=\"text/css\" />\n";
+  echo "<link rel=\"stylesheet\" title=\"Default\" href=\"".$pageCSS."\" type=\"text/css\" />\n";
 }
 else
 {
 ?>
  <style type="text/css">
- <!--
- body { background: black; color: white; font-family: Arial, Verdana, sans-serif; font-size: 10pt; }
- th   { background: gray; }
+   <!--
+   body { background: black; color: white; font-family: Arial, Verdana, sans-serif; font-size: 10pt; }
+   th   { background: gray; }
 
- table.pritab { width: 70%; }
- table.pritab tr:hover td { background: green; }
- tr.a td { background: #333; }
- tr.b td { background: #444; }
- 
- h1,h2,h3,h4  { color: #f00; border-bottom: 1px solid #c00; }
+   table.pritab { width: 70%; }
+   table.pritab tr:hover td { background: green; }
+   tr.a td { background: #333; }
+   tr.b td { background: #444; }
 
- .hide { display: none; }
+   h1,h2,h3,h4  { color: #f00; border-bottom: 1px solid #c00; }
+
+   .hide { display: none; }
 
- .phys { color: #ddd; }
- .fire { color: #f00; }
- .cold { color: #00f; }
- .mana { color: #ff0; }
- .asph { color: #8ff; }
- .pois { color: #0f0; }
- .elec { color: #08f; }
- -->
+   .phys { color: #ddd; }
+   .fire { color: #f00; }
+   .cold { color: #00f; }
+   .mana { color: #ff0; }
+   .asph { color: #8ff; }
+   .pois { color: #0f0; }
+   .elec { color: #08f; }
+   -->
  </style>
-<? } ?>
-</head>
-<body>
-<?
+<?php
+} // if no defined user stylesheet
+
+echo
+  "</head>\n".
+  "<body>\n";
+
 //============================================================================
 // Data input mode
 //============================================================================
 if (!isset($_REQUEST["ok"]))
 {
+
 echo "<h1>".$pageTitle."</h1>\n";
 
 if (isset($global_desc))
@@ -422,28 +185,36 @@
     {
       $s = isset($item["extra"]) ? $item["extra"] : "";
       echo
-      " <tr>\n".
-      "  <th>".$item["name"]."</th>\n".
-      "  <th>Cost</th>\n".
-      "  <th>#</th>\n".
-      "  <th class=\"hide\"></th>\n".
-      " </tr>\n".
-      " <tr><td>1-".($item["tresh"]-1)." ".$item["subj"]."s</td>".
-      "<td>".convPrice($item["price1"])." / ".$item["subj"].$s."</td>".
-      "<td>-</td><td class=\"hide\"></td></tr>\n".
-      " <tr><td>".$item["tresh"]."+ ".$item["subj"]."s</td><td>";
+        " <tr>\n".
+        "  <th>".$item["name"]."</th>\n".
+        "  <th>Cost</th>\n".
+        "  <th>#</th>\n".
+        "  <th class=\"hide\"></th>\n".
+        " </tr>\n".
+        " <tr><td>1-".($item["tresh"]-1)." ".$item["subj"]."s</td>".
+        "<td>".convPrice($item["price1"])." / ".$item["subj"].$s."</td>".
+        "<td>-</td><td class=\"hide\"></td></tr>\n".
+        " <tr><td>".$item["tresh"]."+ ".$item["subj"]."s</td><td>";
 
       if (isset($item["base"]))
+      {
         echo convPrice($item["base"])." initial fee + ".convPrice($item["price2"])." / ".$item["subj"].$s;
+      }
       else
+      {
         echo convPrice($item["price2"])." / ".$item["subj"].$s;
+      }
 
       echo "</td><td>".getField($key)."</td>";
 
       if (isset($item["extra"]))
+      {
         echo "<td>+ ".getField($key."_extra")."</td>";
+      }
       else
+      {
         echo "<td class=\"hide\"></td>";
+      }
 
       echo "</tr>\n";
     }
@@ -453,24 +224,28 @@
   if ($sections["services2"])
   {
     echo
-    " <tr>\n".
-    "  <th>Service</th>\n".
-    "  <th>Cost</th>\n".
-    "  <th>#</th>\n".
-    "  <th class=\"hide\"></th>\n".
-    " </tr>\n";
-    
+      "  <tr>\n".
+      "    <th>Service</th>\n".
+      "    <th>Cost</th>\n".
+      "    <th>#</th>\n".
+      "    <th class=\"hide\"></th>\n".
+      "  </tr>\n";
+
     foreach ($services2_prices as $key => $item)
     {
-      echo 
-      " <tr><td>".$item["name"]."</td>".
-      "<td>".convPrice($item["price"])." / ".$item["subj"]."</td>".
-      "<td>".getField($key)."</td>";
+      echo
+        "  <tr><td>".$item["name"]."</td>".
+        "<td>".convPrice($item["price"])." / ".$item["subj"]."</td>".
+        "<td>".getField($key)."</td>";
 
       if (isset($item["extra"]))
+      {
         echo "<td>+ ".getField($key."_extra")."</td>";
+      }
       else
+      {
         echo "<td></td>\n";
+      }
 
       echo "</tr>\n";
     }
@@ -486,45 +261,50 @@
   $sec = $reagents;
 
   $showSupply = FALSE;
-  if (file_exists($sec["datafile"]) &&
-    ($data = @file_get_contents($sec["datafile"])) !== FALSE)
+  if (file_exists($sec["datafile"]))
   {
-    $supply = array();
-    $lines = explode("\n", strtolower($data));
-    foreach ($lines as $line)
+    if (($data = @file_get_contents($sec["datafile"])) !== FALSE)
     {
-      $tmp = explode("|", $line);
-      if (count($tmp) >= 2)
-        $supply[$tmp[1]] = $tmp[0];
+      $supply = [];
+      $lines = explode("\n", strtolower($data));
+      foreach ($lines as $line)
+      {
+        $tmp = explode("|", $line);
+        if (count($tmp) >= 2)
+          $supply[$tmp[1]] = $tmp[0];
+      }
+      $showSupply = TRUE;
     }
-    $showSupply = TRUE;
   }
 
   printSectionHeader($sec);
   foreach ($sec["prices"] as $fkey => $flist)
   {
-    echo "<tr><th colspan=\"".($showSupply ? 6 : 5)."\">".$fkey."</th></tr>\n".
-    " <tr>\n".
-    "  <th>Type</th>\n".
-    "  <th>Spell</th>\n".
-    "  <th>Reagent</th>\n".
-    "  <th>Price</th>\n".
-    "  <th>#</th>\n".
-    ($showSupply ? "  <th>Avail</th>\n" : "").
-    " </tr>";
-  
+    echo
+      "<tr><th colspan=\"".($showSupply ? 6 : 5)."\">".$fkey."</th></tr>\n".
+      "  <tr>\n".
+      "    <th>Type</th>\n".
+      "    <th>Spell</th>\n".
+      "    <th>Reagent</th>\n".
+      "    <th>Price</th>\n".
+      "    <th>#</th>\n".
+      ($showSupply ? "    <th>Avail</th>\n" : "").
+      "  </tr>";
+
     $row = 1;
     foreach ($flist as $key => $item)
     {
       $s = ($row % 2 == 1) ? "a" : "b";
+
       echo
-        " <tr class=\"".$s."\"><td class=\"".$item[0]."\">".$item[0].
+        "  <tr class=\"".$s."\"><td class=\"".$item[0]."\">".$item[0].
         "</td><td>".$item[1]."</td><td>".$item[2]."</td><td>".$item[3]."</td>".
         "<td>".getField($key)."</td>";
 
       $spell = strtolower($item[1]);
       if ($showSupply && isset($supply[$spell]))
         echo "<td>".$supply[$spell]."</td>";
+
       echo "</tr>\n";
       $row++;
     }
@@ -537,7 +317,7 @@
 function printSection($sec)
 {
   printSectionHeader($sec);
-  
+
   echo " <tr>\n";
   foreach ($sec["i_titles"] as $title)
     echo "  <th>".$title."</th>\n";
@@ -551,12 +331,12 @@
     $s = ($row % 2 == 1) ? "a" : "b";
 
     echo " <tr class=\"".$s."\">";
-    
+
     for ($i = 0; $i < $sec["i_fields"]; $i++)
       echo "<td>".$item[$i]."</td>";
-    
+
     $add = isset($sec["i_price"]) ? $item[$sec["i_price"]] : 0;
-    
+
     echo "<td><b>".($base + $add)."</b></td>".
     "<td>".getField($name."_".$key)."</td></tr>\n";
     $row++;
@@ -612,15 +392,15 @@
 //============================================================================
 // Services
 //============================================================================
-?>
-<h1>Totals</h1>
-<table class="pritab">
- <tr>
-  <th>Item</th>
-  <th>#</th>
-  <th>Total</th>
- </tr>
-<?
+echo
+  "<h1>Totals</h1>\n".
+  "<table class=\"pritab\">\n".
+  "  <tr>\n".
+  "    <th>Item</th>\n".
+  "    <th>#</th>\n".
+  "    <th>Total</th>\n".
+  "  </tr>\n";
+
 $subTotal = $totalPrice = 0;
 $billText = "";
 $formText = "";
@@ -634,7 +414,8 @@
   {
     addVal($key, $val);
 
-    if ($val >= $item["tresh"]) {
+    if ($val >= $item["tresh"])
+    {
       if (isset($item["base"]))
         $total = $item["base"] + ($val * $item["price2"]);
       else
@@ -718,7 +499,7 @@
     $str = "";
     $factor = 1;
   }
-  
+
   $base = isset($sec["base"]) ? $sec["base"] : 0;
   $numItems = 0;
   $subTotal = 0;