<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://htyp.org/mw/index.php?action=history&amp;feed=atom&amp;title=VbzCart%2Farchive%2Fcode%2Ffiles%2Fcart.php</id>
	<title>VbzCart/archive/code/files/cart.php - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://htyp.org/mw/index.php?action=history&amp;feed=atom&amp;title=VbzCart%2Farchive%2Fcode%2Ffiles%2Fcart.php"/>
	<link rel="alternate" type="text/html" href="https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;action=history"/>
	<updated>2026-09-25T10:45:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=20392&amp;oldid=prev</id>
		<title>Woozle: Woozle moved page VbzCart/code/files/cart.php to VbzCart/archive/code/files/cart.php</title>
		<link rel="alternate" type="text/html" href="https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=20392&amp;oldid=prev"/>
		<updated>2014-12-19T02:09:15Z</updated>

		<summary type="html">&lt;p&gt;Woozle moved page &lt;a href=&quot;/mw/index.php?title=VbzCart/code/files/cart.php&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;VbzCart/code/files/cart.php (page does not exist)&quot;&gt;VbzCart/code/files/cart.php&lt;/a&gt; to &lt;a href=&quot;/VbzCart/archive/code/files/cart.php&quot; title=&quot;VbzCart/archive/code/files/cart.php&quot;&gt;VbzCart/archive/code/files/cart.php&lt;/a&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:09, 19 December 2014&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Woozle</name></author>
	</entry>
	<entry>
		<id>https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=19075&amp;oldid=prev</id>
		<title>Woozle: Woozle moved page VbzCart/files/cart.php to VbzCart/code/files/cart.php: oops</title>
		<link rel="alternate" type="text/html" href="https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=19075&amp;oldid=prev"/>
		<updated>2012-12-20T16:18:33Z</updated>

		<summary type="html">&lt;p&gt;Woozle moved page &lt;a href=&quot;/mw/index.php?title=VbzCart/files/cart.php&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;VbzCart/files/cart.php (page does not exist)&quot;&gt;VbzCart/files/cart.php&lt;/a&gt; to &lt;a href=&quot;/mw/index.php?title=VbzCart/code/files/cart.php&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;VbzCart/code/files/cart.php (page does not exist)&quot;&gt;VbzCart/code/files/cart.php&lt;/a&gt;: oops&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:18, 20 December 2012&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Woozle</name></author>
	</entry>
	<entry>
		<id>https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=19069&amp;oldid=prev</id>
		<title>Woozle: Woozle moved page VbzCart/code/lib/cart to VbzCart/files/cart.php: reorganizing</title>
		<link rel="alternate" type="text/html" href="https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=19069&amp;oldid=prev"/>
		<updated>2012-12-20T16:17:18Z</updated>

		<summary type="html">&lt;p&gt;Woozle moved page &lt;a href=&quot;/mw/index.php?title=VbzCart/code/lib/cart&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;VbzCart/code/lib/cart (page does not exist)&quot;&gt;VbzCart/code/lib/cart&lt;/a&gt; to &lt;a href=&quot;/mw/index.php?title=VbzCart/files/cart.php&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;VbzCart/files/cart.php (page does not exist)&quot;&gt;VbzCart/files/cart.php&lt;/a&gt;: reorganizing&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:17, 20 December 2012&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Woozle</name></author>
	</entry>
	<entry>
		<id>https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=17884&amp;oldid=prev</id>
		<title>Woozle: saving current version for archival purposes, so I can hack out large chunks without losing them permanently</title>
		<link rel="alternate" type="text/html" href="https://htyp.org/mw/index.php?title=VbzCart/archive/code/files/cart.php&amp;diff=17884&amp;oldid=prev"/>
		<updated>2012-05-13T12:40:49Z</updated>

		<summary type="html">&lt;p&gt;saving current version for archival purposes, so I can hack out large chunks without losing them permanently&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Notes==&lt;br /&gt;
2012-05-13 This version is being revised, and probably does not function as currently written.&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php&lt;br /&gt;
/*&lt;br /&gt;
  PURPOSE: shopping cart stuff -- base&lt;br /&gt;
  HISTORY:&lt;br /&gt;
    2012-04-17 extracted from shop.php&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
clsLibMgr::Add(&amp;#039;vbz.cart-data&amp;#039;,	KFP_LIB_VBZ.&amp;#039;/cart-data.php&amp;#039;,__FILE__,__LINE__);&lt;br /&gt;
  clsLibMgr::AddClass(&amp;#039;clsCartVars&amp;#039;, &amp;#039;vbz.cart-data&amp;#039;);&lt;br /&gt;
clsLibMgr::Add(&amp;#039;vbz.pages&amp;#039;,	KFP_LIB_VBZ.&amp;#039;/pages.php&amp;#039;,__FILE__,__LINE__);&lt;br /&gt;
  clsLibMgr::AddClass(&amp;#039;clsVbzSkin_Standard&amp;#039;,&amp;#039;vbz.pages&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
class clsPageCart extends clsVbzSkin_Standard {&lt;br /&gt;
    protected $objSess;&lt;br /&gt;
    protected $objCart;&lt;br /&gt;
&lt;br /&gt;
    /*----&lt;br /&gt;
      ACTION: Cart does not use URL data; all info passed via POST.&lt;br /&gt;
	So this implementation does nothing (but must be defined&lt;br /&gt;
	so class is not abstract).&lt;br /&gt;
    */&lt;br /&gt;
    protected function ParseInput() {}&lt;br /&gt;
&lt;br /&gt;
// process functions&lt;br /&gt;
    public function DoPreContent() {&lt;br /&gt;
	$this-&amp;gt;inCkout = FALSE;	// (2011-04-01) not sure why this is sometimes not getting set&lt;br /&gt;
	parent::DoPreContent();&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
      INPUT: $iCaller is for debugging and is discarded; caller should pass __METHOD__ as the argument.&lt;br /&gt;
    */&lt;br /&gt;
    public function GetObjects($iCaller) {&lt;br /&gt;
	$objSessions = $this-&amp;gt;Sessions();&lt;br /&gt;
	$this-&amp;gt;objSess = $objSessions-&amp;gt;GetCurrent();	// get whatever session is currently applicable (existing or new)&lt;br /&gt;
	$this-&amp;gt;objCart = $this-&amp;gt;objSess-&amp;gt;CartObj();&lt;br /&gt;
	$this-&amp;gt;objCart-&amp;gt;objSess = $this-&amp;gt;objSess;	// used for logging&lt;br /&gt;
    }&lt;br /&gt;
    public function Cart($iObj=NULL) {&lt;br /&gt;
	if (!is_null($iObj)) {&lt;br /&gt;
	    $this-&amp;gt;objCart = $iObj;&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objCart;&lt;br /&gt;
    }&lt;br /&gt;
    protected function HandleInput() {&lt;br /&gt;
	$this-&amp;gt;GetObjects(__METHOD__);&lt;br /&gt;
	$this-&amp;gt;objCart-&amp;gt;CheckData();	// check for any form data (added items, recalculations, etc.)&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;strSheet	= &amp;#039;cart&amp;#039;;	// cart stylesheet has a few different things in it&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;strWikiPg	= &amp;#039;&amp;#039;;&lt;br /&gt;
	$this-&amp;gt;strTitle	= &amp;#039;Shopping Cart&amp;#039;;	// Displayed title (page header)&lt;br /&gt;
	$this-&amp;gt;strName	= &amp;#039;shopping cart&amp;#039;;	// HTML title&lt;br /&gt;
	$this-&amp;gt;strTitleContext	= &amp;#039;this is your&amp;#039;; // &amp;#039;Tomb of the...&amp;#039;;&lt;br /&gt;
	$this-&amp;gt;strHdrXtra	= &amp;#039;&amp;#039;;&lt;br /&gt;
	$this-&amp;gt;strSideXtra	= &amp;#039;&amp;#039;; //&amp;#039;&amp;lt;dt&amp;gt;&amp;lt;b&amp;gt;Cat #&amp;lt;/b&amp;gt;: &amp;#039;.$this-&amp;gt;strReq;&lt;br /&gt;
	$this-&amp;gt;strSheet	= KSQ_PAGE_CART;	// default&lt;br /&gt;
    }&lt;br /&gt;
    protected function DoContent() {&lt;br /&gt;
	echo $this-&amp;gt;objCart-&amp;gt;Render();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
// ShopCart&lt;br /&gt;
class clsShopCarts extends clsTable {&lt;br /&gt;
    const TableName=&amp;#039;shop_cart&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    public function __construct($iDB) {&lt;br /&gt;
	parent::__construct($iDB);&lt;br /&gt;
	  $this-&amp;gt;Name(self::TableName);&lt;br /&gt;
	  $this-&amp;gt;KeyName(&amp;#039;ID&amp;#039;);&lt;br /&gt;
	  $this-&amp;gt;ClassSng(&amp;#039;clsShopCart&amp;#039;);&lt;br /&gt;
	  $this-&amp;gt;ActionKey(&amp;#039;cart&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
class clsShopCart extends clsDataSet {&lt;br /&gt;
    protected $objShipZone;&lt;br /&gt;
    protected $objCartData;&lt;br /&gt;
    private $arDataItem;&lt;br /&gt;
    protected $objOrder;&lt;br /&gt;
&lt;br /&gt;
    protected $hasDetails;	// customer details have been loaded?&lt;br /&gt;
/*&lt;br /&gt;
    protected $objDataTree;&lt;br /&gt;
    protected $objAddrShip;&lt;br /&gt;
    protected $objAddrCard;&lt;br /&gt;
    protected $objContDest;&lt;br /&gt;
    protected $objContCust;&lt;br /&gt;
    protected $objShip;&lt;br /&gt;
    protected $objCust;&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
    public function __construct(clsDatabase $iDB=NULL, $iRes=NULL, array $iRow=NULL) {&lt;br /&gt;
	parent::__construct($iDB,$iRes,$iRow);&lt;br /&gt;
	$this-&amp;gt;objShipZone = new clsShipZone();&lt;br /&gt;
	$this-&amp;gt;objCartData = NULL;&lt;br /&gt;
	$this-&amp;gt;hasDetails = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    public function InitNew($iSess) {&lt;br /&gt;
	$this-&amp;gt;ID = 0;&lt;br /&gt;
	$this-&amp;gt;WhenCreated = NULL;	// not created until saved&lt;br /&gt;
	$this-&amp;gt;WhenViewed = NULL;&lt;br /&gt;
	$this-&amp;gt;WhenUpdated = NULL;&lt;br /&gt;
	$this-&amp;gt;WhenOrdered = NULL;&lt;br /&gt;
	$this-&amp;gt;ID_Sess = $iSess;&lt;br /&gt;
	$this-&amp;gt;ID_Order = NULL;&lt;br /&gt;
	$this-&amp;gt;ID_Cust = NULL;&lt;br /&gt;
    }&lt;br /&gt;
    /*====&lt;br /&gt;
      BLOCK: EVENT HANDLING&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-03-27 copied from VbzAdminCustCard to VbzAdminCart&lt;br /&gt;
	  Then moved from VbzAdminCart to clsShopCart&lt;br /&gt;
    */&lt;br /&gt;
    protected function Log() {&lt;br /&gt;
	if (!is_object($this-&amp;gt;logger)) {&lt;br /&gt;
	    $this-&amp;gt;logger = new clsLogger_DataSet($this,$this-&amp;gt;objDB-&amp;gt;Events());&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;logger;&lt;br /&gt;
    }&lt;br /&gt;
    public function StartEvent(array $iArgs) {&lt;br /&gt;
	return $this-&amp;gt;Log()-&amp;gt;StartEvent($iArgs);&lt;br /&gt;
    }&lt;br /&gt;
    public function FinishEvent(array $iArgs=NULL) {&lt;br /&gt;
	return $this-&amp;gt;Log()-&amp;gt;FinishEvent($iArgs);&lt;br /&gt;
    }&lt;br /&gt;
    public function EventListing() {&lt;br /&gt;
	return $this-&amp;gt;Log()-&amp;gt;EventListing();&lt;br /&gt;
    }&lt;br /&gt;
    // specialized event logging (deprecated)&lt;br /&gt;
    public function LogEvent($iCode,$iDescr,$iUser=NULL) {&lt;br /&gt;
	global $vgUserName;&lt;br /&gt;
&lt;br /&gt;
	$strUser = is_null($iUser)?$vgUserName:$iUser;&lt;br /&gt;
	$this-&amp;gt;objDB-&amp;gt;CartLog()-&amp;gt;Add($this,$iCode,$iDescr,$strUser);&lt;br /&gt;
    }&lt;br /&gt;
    //====&lt;br /&gt;
    /*----&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2010-12-31 Created so placed orders do not get &amp;quot;stuck&amp;quot; in user&amp;#039;s browser&lt;br /&gt;
	2011-02-07 Doesn&amp;#039;t work; same cart still comes up (though at least it generates a new order...&lt;br /&gt;
	  but it pulls up all the same contact info)&lt;br /&gt;
	2011-03-27 Changed flag from ID_Order to WhenOrdered OR WhenVoided, because we don&amp;#039;t want to have to clear&lt;br /&gt;
	  ID_Order anymore. Carts should retain their order ID.&lt;br /&gt;
    */&lt;br /&gt;
    public function IsLocked() {&lt;br /&gt;
	return $this-&amp;gt;IsOrdered() || $this-&amp;gt;IsVoided();&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
      RETURNS: TRUE if the cart has been converted to an order&lt;br /&gt;
      USED BY: $this-&amp;gt;IsLocked() and (something)-&amp;gt;IsUsable()&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-03-27 written for improved handling of cart status at checkout&lt;br /&gt;
    */&lt;br /&gt;
    public function IsOrdered() {&lt;br /&gt;
	return !(is_null($this-&amp;gt;WhenOrdered));&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
      RETURNS: TRUE if the cart has been discarded (voided)&lt;br /&gt;
      USED BY: $this-&amp;gt;IsLocked() and (something)-&amp;gt;IsUsable()&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-03-27 written for improved handling of cart status at checkout&lt;br /&gt;
    */&lt;br /&gt;
    public function IsVoided() {&lt;br /&gt;
	return !(is_null($this-&amp;gt;WhenVoided));&lt;br /&gt;
    }&lt;br /&gt;
    public function CartData() {&lt;br /&gt;
	if (is_null($this-&amp;gt;objCartData)) {&lt;br /&gt;
	    $this-&amp;gt;objCartData = new clsCartVars($this-&amp;gt;Engine());&lt;br /&gt;
	    $this-&amp;gt;objCartData-&amp;gt;LoadCart($this-&amp;gt;KeyValue());&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objCartData;&lt;br /&gt;
    }&lt;br /&gt;
/*&lt;br /&gt;
// == GENERAL DATA UTILITY FUNCTIONS&lt;br /&gt;
    public function GetDataItem($iType) {&lt;br /&gt;
	global $sql;	// for debugging&lt;br /&gt;
&lt;br /&gt;
	if (isset($this-&amp;gt;arDataItem[$iType])) {&lt;br /&gt;
	    return $this-&amp;gt;arDataItem[$iType];&lt;br /&gt;
	} else {&lt;br /&gt;
	    $sqlType = $this-&amp;gt;objDB-&amp;gt;SafeParam($iType);&lt;br /&gt;
	    $sql = &amp;#039;SELECT Val FROM &amp;#039;.KST_CART_DATA.&amp;#039; WHERE (ID_Cart=&amp;#039;.$this-&amp;gt;ID.&amp;#039;) AND (Type=&amp;quot;&amp;#039;.$sqlType.&amp;#039;&amp;quot;);&amp;#039;;&lt;br /&gt;
	    $objItem = $this-&amp;gt;objDB-&amp;gt;DataSet($sql);&lt;br /&gt;
	    if ($objItem-&amp;gt;HasRows()) {&lt;br /&gt;
		$objItem-&amp;gt;FirstRow();&lt;br /&gt;
		return $objItem-&amp;gt;Val;&lt;br /&gt;
	    } else {&lt;br /&gt;
		return NULL;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
    public function PutDataItem($iType,$iVal,$iForce=FALSE) {&lt;br /&gt;
	  global $sql;	// for debugging&lt;br /&gt;
&lt;br /&gt;
	  $sqlType = $this-&amp;gt;objDB-&amp;gt;SafeParam($iType);&lt;br /&gt;
	  $sqlFilt = &amp;#039;(ID_Cart=&amp;#039;.$this-&amp;gt;ID.&amp;#039;) AND (Type=&amp;quot;&amp;#039;.$iType.&amp;#039;&amp;quot;)&amp;#039;;&lt;br /&gt;
	  if ($iVal == &amp;#039;&amp;#039;) {&lt;br /&gt;
	      if ($iForce) {&lt;br /&gt;
		  // delete the entry&lt;br /&gt;
		  $sql = &amp;#039;DELETE FROM &amp;#039;.KST_CART_DATA.&amp;#039; WHERE &amp;#039;.$sqlFilt;&lt;br /&gt;
		  $ok = $this-&amp;gt;objDB-&amp;gt;Exec($sql);&lt;br /&gt;
		  return $ok;&lt;br /&gt;
	      } else {&lt;br /&gt;
		  return FALSE;&lt;br /&gt;
	      }&lt;br /&gt;
	  } else {&lt;br /&gt;
	      $sqlVal = $this-&amp;gt;objDB-&amp;gt;SafeParam($iVal);&lt;br /&gt;
	      // check to see if item exists (UPDATE) or not (INSERT):&lt;br /&gt;
	      $objRows = $this-&amp;gt;objDB-&amp;gt;DataSet(&amp;#039;SELECT Val FROM &amp;#039;.KST_CART_DATA.&amp;#039; WHERE &amp;#039;.$sqlFilt);&lt;br /&gt;
	      $qrows = $objRows-&amp;gt;RowCount();&lt;br /&gt;
	      if ($qrows == 0) {&lt;br /&gt;
		  $sql = &amp;#039;INSERT INTO &amp;#039;.KST_CART_DATA.&amp;#039; (ID_Cart,Type,Val) VALUES(&amp;#039;.$this-&amp;gt;ID.&amp;#039;,&amp;#039;.$iType.&amp;#039;,&amp;quot;&amp;#039;.$sqlVal.&amp;#039;&amp;quot;);&amp;#039;;&lt;br /&gt;
		  $ok = $this-&amp;gt;objDB-&amp;gt;Exec($sql);&lt;br /&gt;
	      } elseif ($qrows == 1) {&lt;br /&gt;
		  $sql = &amp;#039;UPDATE &amp;#039;.KST_CART_DATA.&amp;#039; SET Val=&amp;quot;&amp;#039;.$sqlVal.&amp;#039;&amp;quot; WHERE &amp;#039;.$sqlFilt.&amp;#039;;&amp;#039;;&lt;br /&gt;
		  $ok = $this-&amp;gt;objDB-&amp;gt;Exec($sql);&lt;br /&gt;
	      } else {&lt;br /&gt;
		  // the db should never let this happen since ID_Cart+Type is the primary key, but leaving in as a sanity check for now.&lt;br /&gt;
		  $this-&amp;gt;objDB-&amp;gt;LogEvent(&amp;#039;cart.data.write&amp;#039;,&amp;#039;type=&amp;#039;.$iType.&amp;#039; val=&amp;#039;.$sqlVal,$qrows.&amp;#039; rows match: too many&amp;#039;,&amp;#039;DUP&amp;#039;,TRUE,TRUE);&lt;br /&gt;
		  $ok = FALSE;&lt;br /&gt;
	      }&lt;br /&gt;
	      return $ok;&lt;br /&gt;
	  }&lt;br /&gt;
    }&lt;br /&gt;
    public function DataItem($iType,$iVal=NULL,$iForce=FALSE) {&lt;br /&gt;
	if ($this-&amp;gt;HasCart()) {&lt;br /&gt;
	    if (is_null($iVal)) {&lt;br /&gt;
		return $this-&amp;gt;GetDataItem($iType);&lt;br /&gt;
	    } else {&lt;br /&gt;
		return $this-&amp;gt;PutDataItem($iType,$iVal,$iForce);&lt;br /&gt;
	    }&lt;br /&gt;
	} else {&lt;br /&gt;
	    return NULL;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
// == STATUS&lt;br /&gt;
    public function HasCart() {&lt;br /&gt;
	return $this-&amp;gt;IsCreated();	// may use different criteria later on&lt;br /&gt;
    }&lt;br /&gt;
    public function HasSession() {&lt;br /&gt;
	$ok = FALSE;&lt;br /&gt;
	if ($this-&amp;gt;HasField(&amp;#039;ID_Sess&amp;#039;)) {&lt;br /&gt;
	    if ($this-&amp;gt;ID_Sess&amp;gt;0) {&lt;br /&gt;
		$ok = TRUE;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
	return $ok;&lt;br /&gt;
    }&lt;br /&gt;
    public function Session() {&lt;br /&gt;
	if ($this-&amp;gt;HasSession()) {&lt;br /&gt;
	    $objSessions = $this-&amp;gt;objDB-&amp;gt;Sessions();&lt;br /&gt;
	    $objSess = $objSessions-&amp;gt;GetItem($this-&amp;gt;ID_Sess);&lt;br /&gt;
	    return $objSess;&lt;br /&gt;
	} else {&lt;br /&gt;
	    return NULL;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
    // DEPRECATED - use OrderObj()&lt;br /&gt;
    public function Order() {&lt;br /&gt;
	return $this-&amp;gt;OrderObj();&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
      RETURNS: Order object&lt;br /&gt;
    */&lt;br /&gt;
    public function OrderObj() {&lt;br /&gt;
	$doGet = TRUE;&lt;br /&gt;
	if (isset($this-&amp;gt;objOrder)) {&lt;br /&gt;
	    if ($this-&amp;gt;objOrder-&amp;gt;ID == $this-&amp;gt;ID_Order) {&lt;br /&gt;
		$doGet = FALSE;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
	if ($doGet) {&lt;br /&gt;
	    $this-&amp;gt;objOrder = $this-&amp;gt;objDB-&amp;gt;Orders()-&amp;gt;GetItem($this-&amp;gt;ID_Order);&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objOrder;&lt;br /&gt;
    }&lt;br /&gt;
    public function HasLines() {&lt;br /&gt;
	$objLines = $this-&amp;gt;GetLines();&lt;br /&gt;
	if (is_null($objLines)) {&lt;br /&gt;
	    return FALSE;&lt;br /&gt;
	} else {&lt;br /&gt;
	    return $objLines-&amp;gt;hasRows();&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
    public function LineCount() {&lt;br /&gt;
	if ($this-&amp;gt;HasLines()) {&lt;br /&gt;
	    return $this-&amp;gt;objLines-&amp;gt;RowCount();&lt;br /&gt;
	} else {&lt;br /&gt;
	    return 0;&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
    public function GetLines($iRefresh=TRUE) {&lt;br /&gt;
	if ($iRefresh || (!isset($this-&amp;gt;objLines))) {&lt;br /&gt;
	    if ($this-&amp;gt;IsCreated()) {&lt;br /&gt;
		//$this-&amp;gt;objLines = $this-&amp;gt;objDB-&amp;gt;CartLines()-&amp;gt;GetData(&amp;#039;(ID_Cart=&amp;#039;.$this-&amp;gt;ID.&amp;#039;) AND (Qty&amp;gt;0)&amp;#039;,&amp;#039;clsShopCartLine&amp;#039;);&lt;br /&gt;
		$this-&amp;gt;objLines = $this-&amp;gt;objDB-&amp;gt;CartLines()-&amp;gt;GetData(&amp;#039;(ID_Cart=&amp;#039;.$this-&amp;gt;ID.&amp;#039;) AND (Qty&amp;gt;0)&amp;#039;);&lt;br /&gt;
	    } else {&lt;br /&gt;
		$this-&amp;gt;objLines = NULL;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objLines;&lt;br /&gt;
    }&lt;br /&gt;
    public function IsCreated() {&lt;br /&gt;
	return ($this-&amp;gt;ID &amp;gt; 0);&lt;br /&gt;
	//return !is_null($this-&amp;gt;ID);&lt;br /&gt;
	//return $this-&amp;gt;hasField(&amp;#039;ID&amp;#039;) || isset($this-&amp;gt;ID)&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
      RETURNS: TRUE iff customer has any known email addresses&lt;br /&gt;
    public function HasEmail() {&lt;br /&gt;
	$isShipCard = $this-&amp;gt;DataItem(KSI_SHIP_IS_CARD);&lt;br /&gt;
	$isShipSelf = $this-&amp;gt;DataItem(KSI_SHIP_TO_SELF);&lt;br /&gt;
	// $objCart-&amp;gt;ContCustObj()-&amp;gt;Email()-&amp;gt;Value()&lt;br /&gt;
	if ($isShipSelf) {&lt;br /&gt;
	return $this-&amp;gt;ContCustObj()-&amp;gt;HasEmail();&lt;br /&gt;
    }&lt;br /&gt;
    public function EmailObj() {&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
// == FORM HANDLING STUFF&lt;br /&gt;
    public function CheckData() {&lt;br /&gt;
// check for buttons&lt;br /&gt;
	$doCheckout = isset($_POST[&amp;#039;finish&amp;#039;]);&lt;br /&gt;
	$isCart = (isset($_POST[&amp;#039;recalc&amp;#039;]) || $doCheckout);&lt;br /&gt;
	$isZoneSet = FALSE;&lt;br /&gt;
// check for specific actions&lt;br /&gt;
	if (isset($_GET[&amp;#039;action&amp;#039;])) {&lt;br /&gt;
	    $strDo = $_GET[&amp;#039;action&amp;#039;];&lt;br /&gt;
	    switch ($strDo) {&lt;br /&gt;
	      case &amp;#039;del&amp;#039;:&lt;br /&gt;
		$intItem = 0+$_GET[&amp;#039;item&amp;#039;];&lt;br /&gt;
		$this-&amp;gt;GetLines();&lt;br /&gt;
		$this-&amp;gt;objLines-&amp;gt;Update(array(&amp;#039;Qty&amp;#039;=&amp;gt;0),&amp;#039;ID_Item=&amp;#039;.$intItem);&lt;br /&gt;
		$this-&amp;gt;LogEvent(&amp;#039;del&amp;#039;,&amp;#039;deleting from cart: ID &amp;#039;.$intItem);&lt;br /&gt;
		break;&lt;br /&gt;
	      case &amp;#039;delcart&amp;#039;;&lt;br /&gt;
		$this-&amp;gt;LogEvent(&amp;#039;clr&amp;#039;,&amp;#039;voiding cart&amp;#039;);&lt;br /&gt;
		$this-&amp;gt;ID = -1;&lt;br /&gt;
		$this-&amp;gt;objSess-&amp;gt;DropCart();&lt;br /&gt;
		break;&lt;br /&gt;
	    }&lt;br /&gt;
	} else {&lt;br /&gt;
	    foreach ($_POST as $key =&amp;gt; $val) {&lt;br /&gt;
    // check for added items:&lt;br /&gt;
		if (substr($key,0,4) == &amp;#039;qty-&amp;#039;) {&lt;br /&gt;
		    if (($val != &amp;#039;&amp;#039;) &amp;amp;&amp;amp; ($val != 0)) {&lt;br /&gt;
			$sqlCatNum = $this-&amp;gt;objDB-&amp;gt;SafeParam(substr($key,4));&lt;br /&gt;
			if ($isCart) {&lt;br /&gt;
			    // zero out all items, so only items in visible cart will be retained:&lt;br /&gt;
			    $this-&amp;gt;ZeroAll();&lt;br /&gt;
			}&lt;br /&gt;
			$this-&amp;gt;AddItem($sqlCatNum,$val);&lt;br /&gt;
		    }&lt;br /&gt;
		} elseif ($key == KSF_SHIP_ZONE) {&lt;br /&gt;
//		    $custShipZone	= $this-&amp;gt;GetFormItem(KSF_SHIP_ZONE);&lt;br /&gt;
		    $custShipZone	= $val;&lt;br /&gt;
		    $this-&amp;gt;DataItem(KSI_SHIP_ZONE,$custShipZone);&lt;br /&gt;
		    $this-&amp;gt;objShipZone-&amp;gt;Abbr($custShipZone);&lt;br /&gt;
		    $isZoneSet = TRUE;&lt;br /&gt;
		}&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
	if (!$isZoneSet) {&lt;br /&gt;
	    // reload the shipping zone if we don&amp;#039;t already know it&lt;br /&gt;
	    $this-&amp;gt;objShipZone-&amp;gt;Abbr($this-&amp;gt;CartData()-&amp;gt;ShipZone());&lt;br /&gt;
	}&lt;br /&gt;
	if ($doCheckout) {&lt;br /&gt;
	    $this-&amp;gt;LogEvent(&amp;#039;ck1&amp;#039;,&amp;#039;going to checkout&amp;#039;);&lt;br /&gt;
	    $objSess = $this-&amp;gt;Session();&lt;br /&gt;
	    //http_redirect(KWP_CHKOUT,array(KS_VBZCART_SESSION_KEY =&amp;gt; $objSess-&amp;gt;SessKey()));&lt;br /&gt;
	    //http_redirect(KWP_CHKOUT.&amp;#039;?&amp;#039;.KS_VBZCART_SESSION_KEY.&amp;#039;=&amp;#039;.$objSess-&amp;gt;SessKey());&lt;br /&gt;
	    http_redirect(KWP_CHKOUT);&lt;br /&gt;
//	    http_redirect(&amp;#039;https://ssl.vbz.net/phpinfo.php&amp;#039;);&lt;br /&gt;
	    $this-&amp;gt;LogEvent(&amp;#039;ck2&amp;#039;,&amp;#039;sent redirect to checkout&amp;#039;);&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
    public function ZeroAll() {&lt;br /&gt;
	$this-&amp;gt;Update(array(&amp;#039;Qty&amp;#039;=&amp;gt;0),&amp;#039;ID_Cart=&amp;#039;.$this-&amp;gt;ID);&lt;br /&gt;
    }&lt;br /&gt;
    public function AddItem($iCatNum,$iQty) {&lt;br /&gt;
	$this-&amp;gt;Build();	// make sure there&amp;#039;s a record for the cart, get ID&lt;br /&gt;
	$objCartLines = $this-&amp;gt;objDB-&amp;gt;CartLines();&lt;br /&gt;
	$objCartLines-&amp;gt;Add($this-&amp;gt;ID,$iCatNum,$iQty);&lt;br /&gt;
	$this-&amp;gt;LogEvent(&amp;#039;add&amp;#039;,&amp;#039;adding to cart: cat# &amp;#039;.$iCatNum.&amp;#039; qty &amp;#039;.$iQty);&lt;br /&gt;
    }&lt;br /&gt;
    /*-----&lt;br /&gt;
      ACTION:&lt;br /&gt;
	* make sure there is a cart record&lt;br /&gt;
	* update the quantity, if there is one&lt;br /&gt;
    */&lt;br /&gt;
    public function Build() {&lt;br /&gt;
	$id = $this-&amp;gt;ID;&lt;br /&gt;
	if (empty($id)) {&lt;br /&gt;
	    $this-&amp;gt;Create();&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
    public function Create() {&lt;br /&gt;
	$sql =&lt;br /&gt;
	  &amp;#039;INSERT INTO `&amp;#039;.clsShopCarts::TableName.&amp;#039;` (WhenCreated,ID_Sess)&amp;#039;.&lt;br /&gt;
	  &amp;#039;VALUES(NOW(),&amp;#039;.$this-&amp;gt;ID_Sess.&amp;#039;);&amp;#039;;&lt;br /&gt;
	$this-&amp;gt;objDB-&amp;gt;Exec($sql);&lt;br /&gt;
	$this-&amp;gt;ID = $this-&amp;gt;objDB-&amp;gt;NewID(&amp;#039;carts.create&amp;#039;);&lt;br /&gt;
	$objSess = $this-&amp;gt;objDB-&amp;gt;Sessions()-&amp;gt;GetCurrent();&lt;br /&gt;
	if (!is_object($objSess-&amp;gt;Table)) {&lt;br /&gt;
	    throw new exception(&amp;#039;Session object has no table for Cart ID=&amp;#039;.$this-&amp;gt;Value(&amp;#039;ID&amp;#039;));&lt;br /&gt;
	}&lt;br /&gt;
	$objSess-&amp;gt;SetCart($this-&amp;gt;ID);&lt;br /&gt;
    }&lt;br /&gt;
    public function RenderHdr() {&lt;br /&gt;
	$out = &amp;quot;\n&amp;quot;.&amp;#039;&amp;lt;!-- Cart ID=&amp;#039;.$this-&amp;gt;KeyValue().&amp;#039; | Session ID=&amp;#039;.$this-&amp;gt;ID_Sess.&amp;#039; --&amp;gt;&amp;#039;;&lt;br /&gt;
	$out .= &amp;quot;\n&amp;lt;center&amp;gt;&amp;lt;table class=border&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;table class=cart&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td align=center valign=middle&amp;gt;&amp;quot;;&lt;br /&gt;
	$out .= &amp;quot;\n&amp;lt;form method=post action=&amp;#039;./&amp;#039;&amp;gt;&amp;quot;;&lt;br /&gt;
	$out .= &amp;quot;\n&amp;lt;table class=cart-data&amp;gt;\n&amp;quot;;&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
    public function RenderFtr() {&lt;br /&gt;
	return KHT_CART_FTR;&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
      ACTION: Render the receipt in HTML&lt;br /&gt;
	Shows the order as generated from *cart* data, not what&amp;#039;s in the order record.&lt;br /&gt;
	...except for the order number.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-03-27 adapting this from clsOrder::RenderReceipt()&lt;br /&gt;
    */&lt;br /&gt;
    public function RenderReceipt() {&lt;br /&gt;
	$out = NULL;&lt;br /&gt;
&lt;br /&gt;
	$objCart = $this;&lt;br /&gt;
	$objOrd = $this-&amp;gt;OrderObj();&lt;br /&gt;
&lt;br /&gt;
	// load contact data&lt;br /&gt;
	assert(&amp;#039;is_object($objOrd);&amp;#039;);&lt;br /&gt;
	if (($objOrd-&amp;gt;ID == 0) || ($objCart-&amp;gt;ID == 0)) {&lt;br /&gt;
	    throw new exception(&amp;#039;Receipt has missing object: Order ID=&amp;#039;.$this-&amp;gt;Value(&amp;#039;ID_Order&amp;#039;).&amp;#039;, Cart ID=&amp;#039;.$objCart-&amp;gt;KeyValue());&lt;br /&gt;
	}&lt;br /&gt;
	$objCart-&amp;gt;GetDetailObjs();&lt;br /&gt;
	$objPay = $objCart-&amp;gt;PersonCustObj()-&amp;gt;Payment();&lt;br /&gt;
	$objAddrCard = $objCart-&amp;gt;AddrCardObj();&lt;br /&gt;
	// the next line is a kluge which only works as long as payment is always ccard&lt;br /&gt;
	// it&amp;#039;s also not clear why GetDetailObjs() isn&amp;#039;t loading it properly&lt;br /&gt;
	$objPay-&amp;gt;Node(&amp;#039;addr&amp;#039;, $objAddrCard);&lt;br /&gt;
&lt;br /&gt;
	$arVars = array(&lt;br /&gt;
	  &amp;#039;ord.num&amp;#039;	=&amp;gt; $objOrd-&amp;gt;Number,&lt;br /&gt;
	  &amp;#039;timestamp&amp;#039;	=&amp;gt; date(KF_RCPT_TIMESTAMP),&lt;br /&gt;
	  &amp;#039;cart.id&amp;#039;	=&amp;gt; $objCart-&amp;gt;ID,&lt;br /&gt;
	  &amp;#039;cart.detail&amp;#039;	=&amp;gt; $objCart-&amp;gt;RenderConfirm(),&lt;br /&gt;
	  &amp;#039;ship.name&amp;#039;	=&amp;gt; $objCart-&amp;gt;AddrShipObj()-&amp;gt;Name()-&amp;gt;Value(),&lt;br /&gt;
	  &amp;#039;ship.addr&amp;#039;	=&amp;gt; $objCart-&amp;gt;AddrShipObj()-&amp;gt;AsText(&amp;quot;\n&amp;lt;br&amp;gt;&amp;quot;),&lt;br /&gt;
	  &amp;#039;pay.name&amp;#039;	=&amp;gt; $objPay-&amp;gt;Addr()-&amp;gt;Name()-&amp;gt;Value(),&lt;br /&gt;
	  &amp;#039;pay.spec&amp;#039;	=&amp;gt; $objPay-&amp;gt;SafeDisplay(),&lt;br /&gt;
	  &amp;#039;email.short&amp;#039;	=&amp;gt; &amp;#039;orders-&amp;#039;.date(&amp;#039;Y&amp;#039;).&amp;#039;@vbz.net&amp;#039;&lt;br /&gt;
	  );&lt;br /&gt;
	$objStrTplt = new clsStringTemplate_array(NULL,NULL,$arVars);&lt;br /&gt;
	$objStrTplt-&amp;gt;MarkedValue(KHT_RCPT_TPLT);&lt;br /&gt;
	$out = &amp;#039;&amp;lt;!-- ORDER ID: &amp;#039;.$objOrd-&amp;gt;ID.&amp;#039; / CART ID from order: &amp;#039;.$objCart-&amp;gt;ID.&amp;#039; --&amp;gt;&amp;#039;;&lt;br /&gt;
	$out .= $objStrTplt-&amp;gt;Replace();&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
    /*-----&lt;br /&gt;
      ACTION: Renders the order contents as plaintext, suitable for emailing&lt;br /&gt;
    */&lt;br /&gt;
    public function RenderOrder_Text() {&lt;br /&gt;
/* NOT USED HERE&lt;br /&gt;
	$isShipCard = $this-&amp;gt;DataItem(KSI_SHIP_IS_CARD);&lt;br /&gt;
	$isShipSelf = $this-&amp;gt;DataItem(KSI_SHIP_TO_SELF);&lt;br /&gt;
*/&lt;br /&gt;
// copy any needed constants over to variables for parsing:&lt;br /&gt;
	$ksShipMsg	= KSF_SHIP_MESSAGE;&lt;br /&gt;
	$ksfCustCardNum = KSF_CUST_CARD_NUM;&lt;br /&gt;
	$ksfCustCardExp = KSF_CUST_CARD_EXP;&lt;br /&gt;
&lt;br /&gt;
// get non-address field data:&lt;br /&gt;
	$strCardNum = $this-&amp;gt;DataItem(KSI_CUST_CARD_NUM);&lt;br /&gt;
	$strCardExp = $this-&amp;gt;DataItem(KSI_CUST_CARD_EXP);&lt;br /&gt;
	$strCustShipMsg = $this-&amp;gt;DataItem(KSI_SHIP_MESSAGE);&lt;br /&gt;
	$ftCustShipMsg = wordwrap($strCustShipMsg);&lt;br /&gt;
&lt;br /&gt;
	$out = &amp;#039;&amp;#039;;&lt;br /&gt;
	$out .= &amp;quot;ITEMS ORDERED:\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	$out .= $this-&amp;gt;RenderCore_Text();&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;doFixedCard = TRUE;&lt;br /&gt;
	$this-&amp;gt;doFixedSelf = TRUE;&lt;br /&gt;
	$this-&amp;gt;doFixedName = TRUE;&lt;br /&gt;
	$this-&amp;gt;htmlBeforeAddress = &amp;#039;&amp;#039;;&lt;br /&gt;
	$this-&amp;gt;htmlBeforeContact = &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	$out .= &amp;quot;\n\nSHIP TO:\n&amp;quot;;&lt;br /&gt;
	$out .= &amp;#039;  &amp;#039;.$this-&amp;gt;AddrShipObj()-&amp;gt;Name()-&amp;gt;Value().&amp;quot;\n&amp;quot;;&lt;br /&gt;
	$out .= &amp;#039;  &amp;#039;.$this-&amp;gt;AddrShipObj()-&amp;gt;AsText(&amp;quot;\n  &amp;quot;);&lt;br /&gt;
	$out .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
	$out .= &amp;quot;\n  Email: &amp;quot;.$this-&amp;gt;ContDestObj()-&amp;gt;Email()-&amp;gt;Value();&lt;br /&gt;
	$out .= &amp;quot;\n  Phone: &amp;quot;.$this-&amp;gt;ContDestObj()-&amp;gt;Phone()-&amp;gt;Value();&lt;br /&gt;
	&lt;br /&gt;
	$out .= &amp;quot;\n\n  &amp;quot;;&lt;br /&gt;
	if (empty($strCustShipMsg)) {&lt;br /&gt;
	    $out .= &amp;quot;(No special instructions)&amp;quot;;&lt;br /&gt;
	} else {&lt;br /&gt;
	    $out .= &amp;quot;Special Instructions:\n$ftCustShipMsg&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	$out .= &amp;quot;\n\nPAYMENT:\n  &amp;quot;.clsCustCards::SafeDescr_Long($strCardNum,$strCardExp).&amp;quot;\n&amp;quot;;&lt;br /&gt;
	$out .= &amp;#039;  &amp;#039;.$this-&amp;gt;AddrCardObj()-&amp;gt;Name()-&amp;gt;Value().&amp;quot;\n&amp;quot;;&lt;br /&gt;
	$out .= &amp;#039;  &amp;#039;.$this-&amp;gt;AddrCardObj()-&amp;gt;AsText(&amp;quot;\n  &amp;quot;);&lt;br /&gt;
	$out .= &amp;quot;\n&amp;quot;;&lt;br /&gt;
	$out .= &amp;quot;\n  Email: &amp;quot;.$this-&amp;gt;ContCustObj()-&amp;gt;Email()-&amp;gt;Value();&lt;br /&gt;
	$out .= &amp;quot;\n  Phone: &amp;quot;.$this-&amp;gt;ContCustObj()-&amp;gt;Phone()-&amp;gt;Value();&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
    public function RenderCore($iAsForm) {&lt;br /&gt;
	$strZone = $this-&amp;gt;objShipZone-&amp;gt;Abbr();&lt;br /&gt;
	$shipMinCost = 0;&lt;br /&gt;
&lt;br /&gt;
	$out = &amp;#039;&amp;lt;tr&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;&amp;lt;big&amp;gt;cat #&amp;lt;/big&amp;gt;&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;&amp;lt;big&amp;gt;description&amp;lt;/big&amp;gt;&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;price&amp;lt;br&amp;gt;each&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;&amp;lt;small&amp;gt;per-item&amp;lt;br&amp;gt;s/h ea.&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;qty.&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;&amp;lt;small&amp;gt;purchase&amp;lt;br&amp;gt;line total&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;&amp;lt;small&amp;gt;per-item&amp;lt;br&amp;gt;s/h line total&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;totals&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;th&amp;gt;&amp;lt;small&amp;gt;pkg s/h&amp;lt;br&amp;gt;min.&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;&amp;#039;&lt;br /&gt;
	  .&amp;#039;&amp;lt;/tr&amp;gt;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	$rsLine = $this-&amp;gt;objLines;&lt;br /&gt;
	while ($rsLine-&amp;gt;NextRow()) {&lt;br /&gt;
	    if ($iAsForm) {&lt;br /&gt;
		$out .= $rsLine-&amp;gt;RenderForm($this);&lt;br /&gt;
	    } else {&lt;br /&gt;
		$out .= $rsLine-&amp;gt;RenderHtml($this);&lt;br /&gt;
	    }&lt;br /&gt;
	    if ($shipMinCost &amp;lt; $rsLine-&amp;gt;ShipPkgDest) {&lt;br /&gt;
		    $shipMinCost = $rsLine-&amp;gt;ShipPkgDest;&lt;br /&gt;
	    }&lt;br /&gt;
	    $intQty = $rsLine-&amp;gt;Qty;&lt;br /&gt;
	    $this-&amp;gt;CostTotalItem += $rsLine-&amp;gt;CostItemQty;&lt;br /&gt;
	    $this-&amp;gt;CostTotalShip += $rsLine-&amp;gt;CostShipQty;&lt;br /&gt;
	}&lt;br /&gt;
// save official totals for order creation:&lt;br /&gt;
// TO DO: are CostTotalItem and CostTotalShip referenced anywhere else? Make them local if not.&lt;br /&gt;
//	But if they are, then why isn&amp;#039;t shipMinCost also a field?&lt;br /&gt;
	$this-&amp;gt;DataItem(KSI_ITEM_TOTAL,$this-&amp;gt;CostTotalItem);&lt;br /&gt;
	$this-&amp;gt;DataItem(KSI_PER_ITEM_TOTAL,$this-&amp;gt;CostTotalShip);&lt;br /&gt;
	$this-&amp;gt;DataItem(KSI_PER_PKG_TOTAL,$shipMinCost);&lt;br /&gt;
&lt;br /&gt;
	$strTotalMerch = FormatMoney($this-&amp;gt;CostTotalItem);&lt;br /&gt;
	$strItemsShip = FormatMoney($this-&amp;gt;CostTotalShip);&lt;br /&gt;
	$strTotalItems = FormatMoney($this-&amp;gt;CostTotalItem + $this-&amp;gt;CostTotalShip);&lt;br /&gt;
	$strShipZone = $this-&amp;gt;objShipZone-&amp;gt;Text();&lt;br /&gt;
	$strShipDesc = $strShipZone.&amp;#039; s/h package cost:&amp;#039;;&lt;br /&gt;
	$strShipPkg = FormatMoney($shipMinCost);&lt;br /&gt;
	$strTotalDesc = &amp;#039;order total if shipping to &amp;#039;.$strShipZone.&amp;#039;:&amp;#039;;&lt;br /&gt;
	$strOrdTotal = FormatMoney($this-&amp;gt;CostTotalItem + $this-&amp;gt;CostTotalShip + $shipMinCost);&lt;br /&gt;
&lt;br /&gt;
	$objSess = $this-&amp;gt;Session();&lt;br /&gt;
	&lt;br /&gt;
	if ($iAsForm) {&lt;br /&gt;
	    $htDelAll = &amp;#039;&amp;lt;span class=text-btn&amp;gt;[&amp;lt;a href=&amp;quot;?action=delcart&amp;quot; title=&amp;quot;remove all items from cart&amp;quot;&amp;gt;remove all&amp;lt;/a&amp;gt;]&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
	    $htFirstTot = &amp;quot;&amp;lt;td align=left&amp;gt;$htDelAll&amp;lt;/td&amp;gt;&amp;lt;td align=right class=total-desc colspan=4&amp;gt;totals:&amp;lt;/td&amp;gt;&amp;quot;;&lt;br /&gt;
	    $htZoneCombo = &amp;#039;Shipping destination: &amp;#039;.$this-&amp;gt;objShipZone-&amp;gt;ComboBox();&lt;br /&gt;
	} else {&lt;br /&gt;
	    $htFirstTot = &amp;#039;&amp;lt;td align=right class=total-desc colspan=5&amp;gt;totals:&amp;lt;/td&amp;gt;&amp;#039;;&lt;br /&gt;
	    $htZoneCombo = &amp;#039;Shipping costs shown assume shipment to &amp;lt;b&amp;gt;&amp;#039;.$this-&amp;gt;objShipZone-&amp;gt;Text().&amp;#039;&amp;lt;/b&amp;gt; address.&amp;#039;;&lt;br /&gt;
	}&lt;br /&gt;
	$out .= &amp;lt;&amp;lt;&amp;lt;__END__&lt;br /&gt;
&amp;lt;tr&amp;gt;$htFirstTot&lt;br /&gt;
&amp;lt;td align=right class=total-amount&amp;gt;$strTotalMerch&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=right class=total-amount&amp;gt;$strItemsShip&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=right class=total-amount&amp;gt;$strTotalItems&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=right&amp;gt;&amp;amp;dArr;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=right  class=total-desc colspan=7&amp;gt;$strShipDesc&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=right  class=total-amount&amp;gt;$strShipPkg&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=right&amp;gt;&amp;amp;crarr;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=right  class=total-desc colspan=7&amp;gt;$strTotalDesc&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=right  class=total-final&amp;gt;$strOrdTotal&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td colspan=6&amp;gt;$htZoneCombo&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
__END__;&lt;br /&gt;
	$this-&amp;gt;LogEvent(&amp;#039;disp&amp;#039;,&amp;#039;displaying cart, zone &amp;#039;.$this-&amp;gt;objShipZone-&amp;gt;Abbr().&amp;#039; total $&amp;#039;.$strOrdTotal);&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
    /*-----&lt;br /&gt;
      RETURNS: The contents of the cart as text. Includes column headers and totals.&lt;br /&gt;
      USED BY: does anything actually use this, or was it intended for the email confirmation?&lt;br /&gt;
    */&lt;br /&gt;
    public function RenderCore_Text() {&lt;br /&gt;
	$abbrShipZone = $this-&amp;gt;DataItem(KSI_SHIP_ZONE);&lt;br /&gt;
	$this-&amp;gt;objShipZone-&amp;gt;Abbr($abbrShipZone);	&lt;br /&gt;
&lt;br /&gt;
	$shipMinCost = 0;&lt;br /&gt;
&lt;br /&gt;
	$strLineFmt = &amp;#039;%-16s |%6.2f |%6.2f |%4d |%7.2f |%10.2f |%13.2f&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	if ($this-&amp;gt;HasRows()) {&lt;br /&gt;
	    $hdr = &amp;quot;\n&amp;quot;.sprintf(&amp;#039;%-17s|%6s|%5s|%5s|%7s|%10s|%13s&amp;#039;&lt;br /&gt;
	      ,&amp;#039;cat #&amp;#039;&lt;br /&gt;
	      ,&amp;#039; $ ea. &amp;#039;&lt;br /&gt;
	      ,&amp;#039; $ s/h &amp;#039;&lt;br /&gt;
	      ,&amp;#039; qty &amp;#039;&lt;br /&gt;
	      ,&amp;#039; $ sale &amp;#039;&lt;br /&gt;
	      ,&amp;#039; $ s/h tot &amp;#039;&lt;br /&gt;
	      ,&amp;#039; $ LINE TOTAL&amp;#039;);&lt;br /&gt;
	    $out = $hdr;&lt;br /&gt;
	    $out .= &amp;quot;\n&amp;quot;.str_repeat(&amp;#039;-&amp;#039;,strlen($hdr));&lt;br /&gt;
	    $objLines = $this-&amp;gt;GetLines();&lt;br /&gt;
	    $dlrSaleTot = 0;	// total sale before shipping&lt;br /&gt;
	    $dlrPItmTot = 0;	// per-item shipping total&lt;br /&gt;
	    $dlrPPkgMax = 0;	// per-pkg shipping total&lt;br /&gt;
	    while ($objLines-&amp;gt;NextRow()) {&lt;br /&gt;
		$objItem = $objLines-&amp;gt;Item();&lt;br /&gt;
		$dlrShipItm = $objItem-&amp;gt;ShipPriceItem($abbrShipZone);&lt;br /&gt;
		$dlrShipPkg = $objItem-&amp;gt;ShipPricePkg($abbrShipZone);&lt;br /&gt;
&lt;br /&gt;
		$out .= $objLines-&amp;gt;RenderText($this,$strLineFmt);&lt;br /&gt;
		if ($dlrPPkgMax &amp;lt; $dlrShipPkg) {&lt;br /&gt;
		    $dlrPPkgMax = $dlrShipPkg;&lt;br /&gt;
		}&lt;br /&gt;
		$intQty = $objLines-&amp;gt;Qty;&lt;br /&gt;
		$dlrSaleTot += $objLines-&amp;gt;PriceItem;&lt;br /&gt;
		$dlrPItmTot += $dlrShipItm*$intQty;&lt;br /&gt;
	    }&lt;br /&gt;
	    $out .= &amp;quot;\n&amp;quot;.str_repeat(&amp;#039;=&amp;#039;,strlen($hdr));&lt;br /&gt;
&lt;br /&gt;
	    $ftTotalMerch = sprintf(&amp;#039;%6.2f&amp;#039;,FormatMoney($dlrSaleTot));&lt;br /&gt;
	    $ftItemsShip = sprintf(&amp;#039;%6.2f&amp;#039;,FormatMoney($dlrPItmTot));&lt;br /&gt;
	    $ftTotalItems = sprintf(&amp;#039;%6.2f&amp;#039;,FormatMoney($dlrSaleTot + $dlrPItmTot));&lt;br /&gt;
	    $ftShipPkg = sprintf(&amp;#039;%6.2f&amp;#039;,FormatMoney($dlrPPkgMax));&lt;br /&gt;
	    //$ftTotalDesc = &amp;#039;order total for shipping to &amp;#039;.$ftShipZone.&amp;#039;:&amp;#039;;&lt;br /&gt;
	    $ftOrdTotal = sprintf(&amp;#039;%6.2f&amp;#039;,FormatMoney($dlrSaleTot + $dlrPItmTot + $dlrPPkgMax));&lt;br /&gt;
&lt;br /&gt;
// these items don&amp;#039;t depend on cart contents, but there&amp;#039;s no point in calculating them if the cart is empty:&lt;br /&gt;
	$ftShipZone = $this-&amp;gt;objShipZone-&amp;gt;Text();&lt;br /&gt;
	$ftShipDesc = $ftShipZone.&amp;#039; s/h package cost:&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	//$objSess = $this-&amp;gt;Session();&lt;br /&gt;
&lt;br /&gt;
	$ftZone = $this-&amp;gt;objShipZone-&amp;gt;Text();&lt;br /&gt;
	//$ftZone = $this-&amp;gt;objShipZone-&amp;gt;Abbr();&lt;br /&gt;
	//$ftZone = $abbrShipZone;&lt;br /&gt;
&lt;br /&gt;
	$out .= &amp;quot;\n&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n *          Sale: $ftTotalMerch&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n * S/H -&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n  * per item sum: $ftItemsShip&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n  * per  package: $ftShipPkg&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n========================&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n==== FINAL TOTAL: $ftOrdTotal&amp;quot;&lt;br /&gt;
	  .&amp;quot;\n\nShipping Zone: $ftZone&amp;quot;;&lt;br /&gt;
	} else {&lt;br /&gt;
	    $out = &amp;quot;\nSorry, we seem to have goofed: this cart appears to have no items in it.&amp;quot;;&lt;br /&gt;
	    $out .= &amp;quot;\nThe webmaster is being alerted to the problem.&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
    public function Render() {&lt;br /&gt;
// return rendering of current contents of cart&lt;br /&gt;
	$ok = FALSE;&lt;br /&gt;
	if ($this-&amp;gt;ID) {&lt;br /&gt;
	    if ($this-&amp;gt;HasLines()) {&lt;br /&gt;
		$ok = TRUE;&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if ($ok) {&lt;br /&gt;
# get information for that destination type:&lt;br /&gt;
	    $out = $this-&amp;gt;RenderHdr();&lt;br /&gt;
	    $out .= $this-&amp;gt;RenderCore(TRUE);&lt;br /&gt;
	    $out .= $this-&amp;gt;RenderFtr();&lt;br /&gt;
	} else {&lt;br /&gt;
	    if ($this-&amp;gt;IsCreated()) {&lt;br /&gt;
		if (is_null($this-&amp;gt;objLines)) {&lt;br /&gt;
		    $out = &amp;quot;&amp;lt;font size=4&amp;gt;Internal error - cart data not available!&amp;lt;/font&amp;gt;&amp;quot;;&lt;br /&gt;
		    $this-&amp;gt;LogEvent(&amp;#039;disp&amp;#039;,&amp;quot;can&amp;#039;t display cart - no data!&amp;quot;);&lt;br /&gt;
		    $this-&amp;gt;objDB-&amp;gt;Events()-&amp;gt;LogEvent(&amp;#039;cart.render&amp;#039;,&amp;#039;&amp;#039;,&amp;#039;cart data unavailable&amp;#039;,&amp;#039;cdna&amp;#039;,TRUE,TRUE);&lt;br /&gt;
		} else {&lt;br /&gt;
		    $out = &amp;quot;&amp;lt;font size=4&amp;gt;Your cart is empty.&amp;lt;/font&amp;gt;&amp;quot;;&lt;br /&gt;
		    $this-&amp;gt;LogEvent(&amp;#039;disp&amp;#039;,&amp;#039;displaying cart - empty; zone &amp;#039;.$this-&amp;gt;objShipZone-&amp;gt;Abbr());&lt;br /&gt;
		}&lt;br /&gt;
	    } else {&lt;br /&gt;
		$out = &amp;quot;&amp;lt;font size=4&amp;gt;You have not put anything in your cart yet.&amp;lt;/font&amp;gt;&amp;quot;;&lt;br /&gt;
		$this-&amp;gt;LogEvent(&amp;#039;disp&amp;#039;,&amp;#039;displaying cart - nothing yet; zone &amp;#039;.$this-&amp;gt;objShipZone-&amp;gt;Abbr());&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
    /*----&lt;br /&gt;
    PURPOSE: Render cart for order confirmation page (read-only, no form controls)&lt;br /&gt;
    */&lt;br /&gt;
    public function RenderConfirm() {&lt;br /&gt;
	if ($this-&amp;gt;HasLines()) {&lt;br /&gt;
	    $out = $this-&amp;gt;RenderCore(FALSE);&lt;br /&gt;
	} else {&lt;br /&gt;
	    // log error - you shouldn&amp;#039;t be able to get to this point with an empty cart&lt;br /&gt;
	    $txtParams = &amp;#039;Cart ID=&amp;#039;.$this-&amp;gt;ID.&amp;#039; Order ID=&amp;#039;.$this-&amp;gt;ID_Order;&lt;br /&gt;
	    $this-&amp;gt;objDB-&amp;gt;LogEvent(&amp;#039;cart.renderconf&amp;#039;,$txtParams,&amp;#039;cart empty at confirmation&amp;#039;,&amp;#039;cec&amp;#039;,TRUE,TRUE);	// also sends email alert&lt;br /&gt;
	    $out = &amp;#039;&amp;lt;font color=red&amp;gt;INTERNAL ERROR&amp;lt;/font&amp;gt;: cart data has become separated from browser. The webmaster has been notified.&amp;#039;;&lt;br /&gt;
	}&lt;br /&gt;
	return $out;&lt;br /&gt;
    }&lt;br /&gt;
/*==========&lt;br /&gt;
  CUSTOMER DATA AMALGAMATION&lt;br /&gt;
*/&lt;br /&gt;
/*&lt;br /&gt;
    public function AddrShipObj() {&lt;br /&gt;
	if (empty($this-&amp;gt;objAddrShip)) {&lt;br /&gt;
	    $arFields = array(&lt;br /&gt;
	      &amp;#039;name&amp;#039;	=&amp;gt; $this-&amp;gt;SpawnName(KSI_ADDR_SHIP_NAME	,KSF_ADDR_SHIP_NAME),&lt;br /&gt;
	      &amp;#039;street&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_SHIP_STREET, KSF_ADDR_SHIP_STREET),&lt;br /&gt;
	      &amp;#039;city&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_SHIP_CITY	,KSF_ADDR_SHIP_CITY),&lt;br /&gt;
	      &amp;#039;state&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_SHIP_STATE	,KSF_ADDR_SHIP_STATE),&lt;br /&gt;
	      &amp;#039;zip&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_SHIP_ZIP	,KSF_ADDR_SHIP_ZIP),&lt;br /&gt;
	      &amp;#039;country&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_SHIP_COUNTRY,KSF_ADDR_SHIP_COUNTRY),&lt;br /&gt;
	      &amp;#039;instruc&amp;#039;	=&amp;gt; new clsCartField($this, KSI_SHIP_MESSAGE	,KSF_SHIP_MESSAGE)&lt;br /&gt;
	      );&lt;br /&gt;
	    $this-&amp;gt;objAddrShip = $this-&amp;gt;SpawnAddress($arFields);&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objAddrShip;&lt;br /&gt;
    }&lt;br /&gt;
    public function AddrCardObj() {&lt;br /&gt;
	if (empty($this-&amp;gt;objAddrCard)) {&lt;br /&gt;
	    $arFields = array(&lt;br /&gt;
	      &amp;#039;name&amp;#039;	=&amp;gt; $this-&amp;gt;SpawnName(KSI_ADDR_CARD_NAME	,KSF_CUST_CARD_NAME),&lt;br /&gt;
	      &amp;#039;street&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_CARD_STREET	,KSF_CUST_CARD_STREET),&lt;br /&gt;
	      &amp;#039;city&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_CARD_CITY	,KSF_CUST_CARD_CITY),&lt;br /&gt;
	      &amp;#039;state&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_CARD_STATE	,KSF_CUST_CARD_STATE),&lt;br /&gt;
	      &amp;#039;zip&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_CARD_ZIP	,KSF_CUST_CARD_ZIP),&lt;br /&gt;
	      &amp;#039;country&amp;#039;	=&amp;gt; new clsCartField($this, KSI_ADDR_CARD_COUNTRY,KSF_CUST_CARD_COUNTRY),&lt;br /&gt;
	      &amp;#039;instruc&amp;#039;	=&amp;gt; new clsCartField($this, NULL			,NULL)&lt;br /&gt;
	      );&lt;br /&gt;
	    $this-&amp;gt;objAddrCard = $this-&amp;gt;SpawnAddress($arFields);&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objAddrCard;&lt;br /&gt;
    }&lt;br /&gt;
    public function ContDestObj() {&lt;br /&gt;
	if (empty($this-&amp;gt;objContDest)) {&lt;br /&gt;
	    $arFields = array(&lt;br /&gt;
	      &amp;#039;email&amp;#039;	=&amp;gt; $this-&amp;gt;SpawnEmail(KSI_CUST_SHIP_EMAIL	,KSF_CUST_SHIP_EMAIL),&lt;br /&gt;
	      &amp;#039;phone&amp;#039;	=&amp;gt; $this-&amp;gt;SpawnPhone(KSI_CUST_SHIP_PHONE	,KSF_CUST_SHIP_PHONE)&lt;br /&gt;
	      );&lt;br /&gt;
	    $this-&amp;gt;objContDest = $this-&amp;gt;SpawnContact($arFields);	// blank object for rendering&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objContDest;&lt;br /&gt;
    }&lt;br /&gt;
    public function ContCustObj_raw() {&lt;br /&gt;
	if (empty($this-&amp;gt;objContCust)) {&lt;br /&gt;
	    $arFields = array(&lt;br /&gt;
	      &amp;#039;email&amp;#039;	=&amp;gt; $this-&amp;gt;SpawnEmail(KSI_CUST_PAY_EMAIL	,KSF_CUST_PAY_EMAIL),&lt;br /&gt;
	      &amp;#039;phone&amp;#039;	=&amp;gt; $this-&amp;gt;SpawnPhone(KSI_CUST_PAY_PHONE	,KSF_CUST_PAY_PHONE)&lt;br /&gt;
	      );&lt;br /&gt;
	    $this-&amp;gt;objContCust = $this-&amp;gt;SpawnContact($arFields);&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objContCust;&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      RETURNS: Contact information for the customer. If the &amp;quot;shipping to myself&amp;quot; box was checked,&lt;br /&gt;
	then it returns the shipping contact information instead, since this is presumed to be the&lt;br /&gt;
	customer&amp;#039;s contact information as well.&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function ContCustObj() {&lt;br /&gt;
	//$isShipCard = $this-&amp;gt;DataItem(KSI_SHIP_IS_CARD);&lt;br /&gt;
	$isShipSelf = $this-&amp;gt;DataItem(KSI_SHIP_TO_SELF);&lt;br /&gt;
	if ($isShipSelf) {&lt;br /&gt;
	    return $this-&amp;gt;ContDestObj();&lt;br /&gt;
	} else {&lt;br /&gt;
	    return $this-&amp;gt;ContCustObj_raw();&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnPerson()&lt;br /&gt;
      ACTION: creates clsPerson object or descendant&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-29 created&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function SpawnPerson($iName,$iDescr) {&lt;br /&gt;
	return new clsPerson($iName,$iDescr);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnPayment()&lt;br /&gt;
      ACTION: creates clsPayment object or descendant&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-29 created&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function SpawnPayment($iNodes=NULL) {&lt;br /&gt;
	return new clsPayment($iNodes);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnAddress()&lt;br /&gt;
      ACTION: creates clsCartAddr object or descendant&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-29 created&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function SpawnAddress($iNodes=NULL) {&lt;br /&gt;
	return new clsCartAddr($iNodes);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnContact()&lt;br /&gt;
      ACTION: creates clsCartContact object or descendant&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
	The extra functionality may not actually be needed for this, but I went and created it anyway.&lt;br /&gt;
	  (2011-12-15: yes, it was needed.)&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-29 created&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function SpawnContact($iNodes=NULL) {&lt;br /&gt;
	return new clsCartContact($iNodes);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnEmail()&lt;br /&gt;
      ACTION: creates object for handling cart email address data&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-29 created&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function SpawnEmail($iIndex, $iCtrlName) {&lt;br /&gt;
	return new clsCartField($this, $iIndex, $iCtrlName);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnPhone()&lt;br /&gt;
      ACTION: creates object for handling cart phone number data&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-29 created&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function SpawnPhone($iIndex, $iCtrlName) {&lt;br /&gt;
	return new clsCartField($this, $iIndex, $iCtrlName);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
/*&lt;br /&gt;
	    $objDataTree-&amp;gt;Node(&amp;#039;person.ship&amp;#039;,$this-&amp;gt;objShip);&lt;br /&gt;
	    $objDataTree-&amp;gt;Node(&amp;#039;person.cust&amp;#039;,$this-&amp;gt;objCust);&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: SpawnName()&lt;br /&gt;
      ACTION: creates object for handling person-name data&lt;br /&gt;
	This lets us stub off admin functionality here and extend it later.&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2011-11-30 created&lt;br /&gt;
    */&lt;br /&gt;
/*    public function SpawnName($iIndex, $iCtrlName) {&lt;br /&gt;
	return new clsCartField($this, $iIndex, $iCtrlName);&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      METHOD: clsShopCart-&amp;gt;PersonCustObj()&lt;br /&gt;
      USED BY: clsShopCart-&amp;gt;GetDetailObjs(), clsOrder-&amp;gt;RenderReceipt()&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2010-09-12 Extracted from clsShopCart-&amp;gt;GetDetailObjs() so it can be used by clsOrder-&amp;gt;RenderReceipt()&lt;br /&gt;
	2011-11-29 Now using SpawnPayment() and SpawnPerson() instead of creating directly with &amp;quot;new&amp;quot;&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function PersonCustObj() {&lt;br /&gt;
	if (empty($this-&amp;gt;objCust)) {&lt;br /&gt;
	    $arFields = array(&lt;br /&gt;
	      &amp;#039;num&amp;#039;		=&amp;gt; new clsCartField($this, KSI_CUST_CARD_NUM,	KSF_CUST_CARD_NUM),&lt;br /&gt;
	      &amp;#039;exp&amp;#039;		=&amp;gt; new clsCartField($this, KSI_CUST_CARD_EXP,	KSF_CUST_CARD_EXP)&lt;br /&gt;
	      );&lt;br /&gt;
	    $objPayment = $this-&amp;gt;SpawnPayment($arFields);&lt;br /&gt;
	    $this-&amp;gt;objCust = $this-&amp;gt;SpawnPerson(&amp;#039;person.cust&amp;#039;,&amp;#039;buyer&amp;#039;);&lt;br /&gt;
	    $this-&amp;gt;objCust-&amp;gt;Node(&amp;#039;payment&amp;#039;, $objPayment);	// the buyer always has the credit card&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objCust;&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*-----&lt;br /&gt;
      METHOD: clsShopCart-&amp;gt;GetDetailObjs()&lt;br /&gt;
      FUTURE: rename to GetDataTree()&lt;br /&gt;
      HISTORY:&lt;br /&gt;
	2010-09-12 borrowed (to be moved?) from clsPageCkout&lt;br /&gt;
	2011-11-27 the version in clsPageCkout has now been commented out&lt;br /&gt;
	2011-11-29 using SpawnPerson() instead of new clsPerson()&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function GetDetailObjs() {&lt;br /&gt;
	if (!$this-&amp;gt;hasDetails) {&lt;br /&gt;
	    $objAddrShip = $this-&amp;gt;AddrShipObj();&lt;br /&gt;
	    $objAddrCard = $this-&amp;gt;AddrCardObj();&lt;br /&gt;
	    $objContDest = $this-&amp;gt;ContDestObj();&lt;br /&gt;
	    $objContCust = $this-&amp;gt;ContCustObj();&lt;br /&gt;
&lt;br /&gt;
	    $objDataTree = new clsContactRoot($this-&amp;gt;Engine());&lt;br /&gt;
&lt;br /&gt;
	    $this-&amp;gt;objShip = $this-&amp;gt;SpawnPerson(&amp;#039;person.ship&amp;#039;,&amp;#039;recipient&amp;#039;);&lt;br /&gt;
	    $this-&amp;gt;objCust = $this-&amp;gt;PersonCustObj();&lt;br /&gt;
&lt;br /&gt;
	    $objDataTree-&amp;gt;NodeAdd($this-&amp;gt;objShip);&lt;br /&gt;
	    $objDataTree-&amp;gt;NodeAdd($this-&amp;gt;objCust);&lt;br /&gt;
//echo $objDataTree-&amp;gt;DumpHTML(); die();&lt;br /&gt;
	    $this-&amp;gt;objDataTree = $objDataTree;&lt;br /&gt;
&lt;br /&gt;
	    $objPayment = $this-&amp;gt;objCust-&amp;gt;Payment();&lt;br /&gt;
	    if (is_null($objPayment)) {&lt;br /&gt;
		echo &amp;#039;objCust is class &amp;#039;.get_class($this-&amp;gt;objCust).&amp;#039;&amp;lt;br&amp;gt;&amp;#039;;&lt;br /&gt;
		echo $this-&amp;gt;objCust-&amp;gt;DumpHTML();&lt;br /&gt;
		throw new exception(&amp;#039;coding error&amp;#039;);&lt;br /&gt;
	    }&lt;br /&gt;
&lt;br /&gt;
	    $this-&amp;gt;objShip-&amp;gt;Node(&amp;#039;contact&amp;#039;, $objContDest);	// shipping information is always specified&lt;br /&gt;
&lt;br /&gt;
	    $objContDest-&amp;gt;Addr = $objAddrShip;	// shipping address&lt;br /&gt;
&lt;br /&gt;
	    $this-&amp;gt;custShipIsCard	= $this-&amp;gt;DataItem(KSI_SHIP_IS_CARD);&lt;br /&gt;
	    $this-&amp;gt;custShipToSelf	= $this-&amp;gt;DataItem(KSI_SHIP_TO_SELF);&lt;br /&gt;
&lt;br /&gt;
	    if ($this-&amp;gt;custShipIsCard) {&lt;br /&gt;
		$objPayment-&amp;gt;Node(&amp;#039;addr&amp;#039;, $objAddrShip);	// use shipping address for card&lt;br /&gt;
	    } else {&lt;br /&gt;
		$objPayment-&amp;gt;Node(&amp;#039;addr&amp;#039;, $objAddrCard);	// use separate address for card&lt;br /&gt;
	    }&lt;br /&gt;
&lt;br /&gt;
	    $this-&amp;gt;objShip-&amp;gt;Node(&amp;#039;name&amp;#039;, $objAddrShip-&amp;gt;NameNode());&lt;br /&gt;
&lt;br /&gt;
// (2011-12-25) this section is tricky... it puts some of the key branches into the tree:&lt;br /&gt;
	    if ($this-&amp;gt;custShipToSelf) {&lt;br /&gt;
		// don&amp;#039;t use separate person data; re-use buyer contact info plus shipping address&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;objShip-&amp;gt;Node(&amp;#039;payment&amp;#039;, $objPayment);	// the only buyer field the recipient doesn&amp;#039;t have&lt;br /&gt;
		//$objContDest-&amp;gt;Node(&amp;#039;addr&amp;#039;, $objAddrShip);			// shipping address&lt;br /&gt;
		$this-&amp;gt;objShip-&amp;gt;Node(&amp;#039;contact&amp;#039;, $objContDest);&lt;br /&gt;
		  $objContDest-&amp;gt;Node(&amp;#039;addr&amp;#039;, $objAddrShip);&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;objCust = $this-&amp;gt;objShip;&lt;br /&gt;
	    } else {&lt;br /&gt;
		// buyer and recipient are different&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;objShip-&amp;gt;Node(&amp;#039;contact&amp;#039;, $objContDest);&lt;br /&gt;
		  $objContDest-&amp;gt;Node(&amp;#039;addr&amp;#039;, $objAddrShip);&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;objCust-&amp;gt;Node(&amp;#039;contact&amp;#039;, $objContCust);&lt;br /&gt;
		$this-&amp;gt;objCust-&amp;gt;Node(&amp;#039;name&amp;#039;, $objAddrCard-&amp;gt;NameNode());&lt;br /&gt;
	    }&lt;br /&gt;
	    $this-&amp;gt;hasDetails = TRUE;&lt;br /&gt;
	}&lt;br /&gt;
	return $this-&amp;gt;objDataTree;&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      ASSUMES: GetDetailObjs() has been called&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function WhoCust() {&lt;br /&gt;
	return $this-&amp;gt;objCust;&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
    /*----&lt;br /&gt;
      ASSUMES: GetDetailObjs() has been called&lt;br /&gt;
    */&lt;br /&gt;
/*&lt;br /&gt;
    public function WhoShip() {&lt;br /&gt;
	return $this-&amp;gt;objShip;&lt;br /&gt;
    }&lt;br /&gt;
*/&lt;br /&gt;
}&amp;lt;/php&amp;gt;&lt;/div&gt;</summary>
		<author><name>Woozle</name></author>
	</entry>
</feed>