VbzCart/code/pages

Code
<?php /* FILE: store.php PURPOSE: VbzCart page-rendering classes HISTORY: 2012-05-08 split off from store.php

if (!defined('LIBMGR')) { require(KFP_LIB.'/libmgr.php'); }

clsLibMgr::Add('vbz.db',	KFP_LIB_VBZ.'/store.php',__FILE__,__LINE__); clsLibMgr::AddClass('clsVbzTable','vbz.db'); clsLibMgr::Add('rtext.html',	KFP_LIB.'/rtext-html.php',__FILE__,__LINE__); clsLibMgr::AddClass('clsRTDoc_HTML','rtext.html');

/*==== NOTES: 2011-02-02 This could use some rewriting. A lot of it is kind of pointless, and other parts duplicate RichText objects. class clsPageOutput_WHO_USES_THIS { public $out; private $isOdd; public $inTbl; private $fpTools; private $fsLogo;

static public function SectionHeader($iTitle) { return ''.$iTitle.' '; }

function __construct($ifpTools,$iLogoRel) { $this->out = ''; $this->isOdd = false; $this->inTbl = 0; $this->fpTools = $ifpTools; $this->fsLogo = $this->ImageSpec($iLogoRel); } /*   function Clear { $this->out = ''; }   function AddText($iText) { $this->out .= $iText; }   function SectionHdr($iTitle) {	// this is specifically duplicated (where?) $this->out .= ''.$iTitle.' '; return $this->out; }   // eventually there needs to be a non-MediaWiki clsRichText, and these can go there /*   public function TableOpen($iAttr=NULL) { }   public function TableShut { }   public function TblRowOpen($iAttr=NULL,$iHdr=FALSE) { }   public function TblRowShut { }   public function TblCell($iText,$iAttr=NULL) { } /* this duplicates RichText function StartTable($iTitle) { if ($iTitle) { $this->SectionHdr($iTitle); $this->out .= ' '; $this->inTbl--; }   return $this->out; } function ShowImgUnavail { $this->out .= ' '; return $this->out; } } /* =================== CLASS: clsVbzSkin PURPOSE: Abstract skin class Specifies all the bits that we'll want to have, but doesn't define them Provides some basic support services, but no actual content (text or formatting) abstract class clsVbzSkin { protected $objDoc; public function __construct { $this->objDoc = new clsRTDoc_HTML; }

public function Doc { return $this->objDoc; }

/*-     USAGE: Normal main entry point -- should be called from index.php */   public function DoPage { try { $this->DoPreContent; $this->DoContent; $this->DoPostContent; } catch(exception $e) { $this->DoEmailException($e); }   }    /*      HISTORY: 2011-03-31 added Page and Cookie to list of reported variables */   protected function DoEmailException(exception $e) { $msg = $e->getMessage;

$arErr = array(	 'descr'	=> $e->getMessage,	  'stack'	=> $e->getTraceAsString,	  'guest.addr'	=> $_SERVER['REMOTE_ADDR'],	  'guest.agent'	=> $_SERVER['HTTP_USER_AGENT'],	  'guest.ref'	=> NzArray($_SERVER,'HTTP_REFERER'),	  'guest.page'	=> $_SERVER['REQUEST_URI'],	  'guest.ckie'	=> NzArray($_SERVER,'HTTP_COOKIE'),	  );

$out = $this->Message_toEmail_forException($arErr);	// generate the message to email $subj = $this->Subject_toEmail_forException($arErr); $ok = mail(KS_TEXT_EMAIL_ADDR_ERROR,$subj,$out);	// email the message

echo $this->Message_toShow_forException($msg);		// display something for the guest

throw $e;

// FUTURE: log the error and whether the email was successful }   abstract protected function Message_toEmail_forException(array $arErr); abstract protected function Subject_toEmail_forException(array $arErr); abstract protected function Message_toShow_forException($iMsg); /*-     ACTION: Displays everything *before* the main page contents */   protected function DoPreContent { $this->ParseInput; $this->HandleInput; $this->RenderHdrBlocks; }   /*-      ACTION: Displays everything *after* the main page contents */   protected function DoPostContent { $this->RenderFtrBlocks; }

// ABSTRACT section // /*-     ACTION: Displays the main page contents */   protected abstract function DoContent; /*-     ACTION: Grab any expected input and interpret it    */ protected abstract function ParseInput; /*-     ACTION: Take the parsed input and do any needed processing (e.g. looking up data) */   protected abstract function HandleInput; /*-     ACTION: Render any output that appears *before* the main content */   protected abstract function RenderHdrBlocks; /*-     ACTION: Render any output that appears *after* the main content */   protected abstract function RenderFtrBlocks; /*-     ACTION: Start a new section */   public abstract function NewSection($iName); /*-     ACTION: Open a table, with appropriate CSS class etc.    */ public abstract function NewTable($iClass='content');

} /* =================== CLASS: clsVbzSkin_Standard PURPOSE: Standard skin class Will later be replaceable with other skins abstract class clsVbzSkin_Standard extends clsVbzSkin { private $objApp; private $fpTools; private $fsLogo;

public function __construct { parent::__construct; $this->fpTools = KWP_TOOLS; $this->fsLogo = KWP_LOGO_HEADER; }   public function App(clsVbzApp $iApp=NULL) { if (!is_null($iApp)) { $this->objApp = $iApp; }	return $this->objApp; }   protected function Data { return $this->App->Data; }   public function NewSection($iTitle) { $obj = $this->Doc->NewSection($iTitle,'hdr-sub'); }   public function NewTable($iClass='content') { $objDoc = $this->Doc; $obj = $objDoc->NewTable; $obj->ClassName($iClass); return $obj; }

protected function Message_toEmail_forException(array $arErr) { $guest_ip = $arErr['guest.addr']; $guest_br = $arErr['guest.agent']; $guest_pg = $arErr['guest.page']; $guest_rf = $arErr['guest.ref']; $guest_ck = $arErr['guest.ckie']; $out = 'Description: '.$arErr['descr']; $out .= "\nStack trace:\n".$arErr['stack']; $out .= <<<__END__

Client information: - IP Addr : $guest_ip - Browser : $guest_br - Cur Page: $guest_pg - Prv Page: $guest_rf - Cookie : $guest_ck __END__;

return $out; }   protected function Subject_toEmail_forException(array $arErr) { return 'error in VBZ from IP '.$arErr['guest.addr']; }   protected function Message_toShow_forException($iMsg) { $msg = $iMsg; $out = <<<__END__ Ack! We seem to have a small problem here. (If it was a large problem, you wouldn't be seeing this message.) The webmaster is being alerted about this. Meanwhile, you might try reloading the page -- a lot of errors are transient, which makes them hard to fix, which is why there are more of them than the other kind. We apologize for the nuisance. Error Message: $msg __END__; return $out; }

protected function RenderHdrBlocks { $this->RenderHtmlStart; $this->RenderContentHdr; $this->DoSidebar; }   protected function RenderFtrBlocks { $this->RenderContentFtr; $this->RenderHtmlStop; }   protected function RenderContentFtr { global $didPage,$fltStart;

echo ' '; $this->DoSepBar; echo ' '; echo ' '; $didPage = true; }   protected function RenderHtmlStop { echo "\n \n "; }

// NEW METHODS for this class // protected function DoSidebar { //	$objCache = $this->CacheMgr; // TO DO: these should be pulled from the [stats] table /* if ($objCache->dtNewest) { $timeSidebarBuild=$objCache->dtNewest; } else { $timeSidebarBuild = NULL; }   $timeSidebarBuild = NULL; $statsQtyTitlesAvail = 2245; $statsQtyStockPieces = 1395; $statsQtyStockItems = 753; $statsQtyArtists = 136; $statsQtyTopics = 1048; //-

echo ' '; echo ' '; /*  echo $this->lstTop->Output('',': ',''); // echo '  '; echo ''; if ($this->strSideXtra) { echo ''.$this->strSideXtra.''; }	echo ''; echo 'Search '.$statsQtyTitlesAvail.' items: '; ?>  advanced Indexes Suppliers'; /*	echo ' ...Stock</a> ('.$statsQtyStockPieces.')'; echo ' ...Stock</a>'; echo ' ...Topics</a>'; //	echo ' ...Artists</a> ('.$statsQtyArtists.')'; echo ' '; echo ' wiki</a> '; echo '-- Help</a>  '; echo '-- About</a>  '; echo '-- Contact</a>  '; echo '-- Comments</a>  '; echo ' '; echo 'email form</a> '; echo 'shopping cart</a> '; echo '      '; }   protected function DoSepBar { echo $this->Render_HLine; }   protected function ImageSpec($iFileName) { return $this->fpTools.'/img'.$iFileName; }   public function Render_HLine($iHeight=NULL) { $htHt = is_null($iHeight)?'':('height='.$iHeight); return '<img src="'.$this->ImageSpec('/bg/hlines/').'"'.$htHt.' alt="-" width="100%">'; }   private function ToolbarItem($iURL,$iIcon,$iTitle,$iAlt) { return '<img border=0 src="'.$this->ImageSpec('/icons/'.$iIcon.'.050pxh.png').'" title="'.$iTitle.'" alt="'.$iAlt.'"></a>'; }   protected function DoToolbar { global $fpPages,$fwpCart;

echo $this->ToolbarItem($fpPages.'/','home',KS_STORE_NAME.' home page','home page'); echo $this->ToolbarItem($fpPages.'/search/','search','search page','search page'); echo $this->ToolbarItem($fwpCart,'cart','shopping cart','shopping cart'); echo $this->ToolbarItem(KWP_HELP_HOME,'help','help!','help'); }

// NEW METHODS for this class // /*     PURPOSE: Renders HTML inside  section HISTORY: 2011-01-11 Created */   protected function RenderHtmlHeaderSection { $strTitle = KS_STORE_NAME.' - '.$this->strName; $out = "\n $strTitle ";

$arVars = array('sheet' => $this->strSheet); $objStrTplt = new clsStringTemplate_array(NULL,NULL,$arVars); $objStrTplt->MarkedValue(KHT_PAGE_STYLE); $out .= $objStrTplt->Replace; //$out .= KHT_PAGE_STYLE; if (!empty($this->strName)) { $ftName = ': '.htmlspecialchars($this->strName); } else { $ftName = ''; }	$strContent = KS_STORE_NAME_META.$ftName; $out .= "\n<meta name=description content=\"$strContent\">"; return $out; }   /*      PURPOSE: Renders HTML up to beginning of BODY. HISTORY: 2011-01-11 Extracted everything between and into RenderHtmlHeaderSection */   protected function RenderHtmlStart { //$this->strCalcTitle = KS_STORE_NAME.' - '.$this->strName; $out = KHT_PAGE_DOCTYPE; $out .= "\n \n "; $out .= $this->RenderHtmlHeaderSection; $out .= "\n "; $out .= KHT_PAGE_BODY_TAG; echo $out; }   protected function RenderContentHdr { //$strWikiPg = $this->strWikiPg;

// begin content header echo ' \n  ";    } }

/*%%%% CLASS: clsVbzApp PURPOSE: container for the chosen skin and database class clsVbzApp { private $objSkin; private $objData;

public function __constructor(clsVbzSkin $iSkin, clsVbzData $iData) { $this->objSkin = $iSkin; $this->objData = $iData; }   public function Skin { return $this->objSkin; }   public function Data { return $this->objData; } }

/* =================== CLASS: clsVbzPage_Cat PURPOSE: Handles display of catalog page types TO DO: These classes still need more tidying -- see clsPageCat -- and still need a bit of work to allow user-choosable skins. abstract class clsVbzPage_Cat extends clsVbzSkin_Standard { // helper objects protected $db;	// database - CHANGE TO PRIVATE // query protected $strReq;	// requested page // page definition protected $strName;	// short title: {item name} (goes into html title, prefixed with store name) protected $strTitle;	// longer, descriptive title: {"item name" by Supplier} (goes at top of page) protected $strSheet;	// name of style sheet to use (without the .css) protected $strWikiPg;	// name of wiki page to embed, if any (blank = suppress embedding) protected $strTitleContext;	// context of short title, in HTML: {Supplier: Department:} (goes above title, in small print) protected $strHdrXtra;	// any extra stuff (HTML) for the header protected $strSideXtra;	// any extra stuff for the sidebar protected $lstTop;	// stuff listed at the top of the sidebar // calculated fields //   protected $strCalcTitle; protected $strContText; // flags set by wiki contents protected $hideImgs;

public function __construct { parent::__construct; $this->lstTop = new clsNavList; }   protected function HandleInput { $this->strSheet	= 'browse';	// default }   /*-      IMPLEMENTATION: Retrieves request from URL and parses it	URL data identifies page, keyed to cat_pages data */   protected function ParseInput { if (isset($_SERVER['PATH_INFO'])) { $strReq = $_SERVER['PATH_INFO']; } else { $strReq = ''; }	$this->strReq = $strReq; if (strrpos($strReq,'/')+1 < strlen($strReq)) { $strRedir = KWP_CAT_REL.substr($strReq,1).'/'; header('Location: '.$strRedir); exit;	// retry with new URL }   } // DIFFERENT TYPES OF PAGES protected function DoNotFound { $this->strWikiPg	= ''; $this->strTitle	= 'Unknown Page'; $this->strName	= 'unknown title in catalog'; $this->strTitleContext	= 'Tomb of the...'; $this->strHdrXtra	= ''; $this->strSideXtra	= '<dt>Cat #: '.$this->strReq; } // UTILITY protected function AddText($iText) { $this->strContText .= $iText; }   private function DoWikiContent { if (KF_USE_WIKI) { $txtWiki = GetWikiPage($this->strWikiPg); if ($txtWiki) { if (strpos($txtWiki,'__NOIMG__') != -1) { $txtWiki = str_replace('__NOIMG__','',$txtWiki); $this->hideImgs = true; }	   }	    if ($txtWiki) { echo ' '; }	}   } }
 * 1) WIKI CONTENTS
 * 2) 	$txtPage = GetEmbedPage('cat');

/*%%%% TODO: * figure out why we need to have this as a separate class from clsVbzPage_Cat * give it a better name class clsPageCat extends clsVbzPage_Cat { private $objCatPage;	// object for identifying page to display

private function Suppliers($id=NULL) { $tbl = $this->Data->Suppliers; $tbl->Page($this); if (is_null($id)) { return $tbl; } else { $rc = $tbl->GetItem($id); return $rc; }   }

protected function RenderHdrBlocks { if ($this->useSkin) { parent::RenderHdrBlocks; }   }    protected function RenderFtrBlocks { if ($this->useSkin) { parent::RenderFtrBlocks; }   }    protected function HandleInput { parent::HandleInput; $strReq = $this->strReq; $this->objCatPage = $this->Data->Pages->GetItem_byKey($strReq); $objPage = $this->objCatPage; $this->useSkin = TRUE;

if ($this->strReq) { if (is_object($objPage)) { switch ($objPage->Type) { case 'S': $this->DoCatSupp; break; case 'D': $this->DoCatDept; break; case 'T': $this->DoCatTitle; break; case 'I': $this->useSkin = FALSE; $this->DoCatImage; break; }	   } else { $this->DoNotFound; }	} else { $this->DoCatHome; }   }    public function DoContent { echo $this->Doc->Render; } // SIDEBAR INFO for different types of pages private function DoCatIndicia { $this->lstTop->Add('Section','by supplier</a>'); } private function DoSuppIndicia($iSupp,$isFinal=true) { $this->DoCatIndicia; if ($isFinal) { $this->lstTop->Add('Supplier',$iSupp->Name); $this->lstTop->Add('Name.'">more info</a>'); } else { $this->lstTop->Add('Supplier',$iSupp->Link); } }  private function DoDeptIndicia($iDept,$isFinal=true) { $this->DoSuppIndicia($iDept->Supplier,false); if ($isFinal) { $this->lstTop->Add('Dept.',$iDept->Name); } else { $this->lstTop->Add('Dept.',$iDept->LinkName); } }  private function DoTitleIndicia($iTitle) { $this->DoDeptIndicia($iTitle->Dept,false); $this->lstTop->Add('Title',$iTitle->Name); $this->lstTop->Add(' - catalog #',$iTitle->CatNum); }

private function DoCatHome { $this->DoCatIndicia; $this->strWikiPg	= 'cat'; $this->strTitle	= 'Catalog Home'; $this->strName	= 'Catalog main page'; $this->strTitleContext	= 'hello and welcome to the...'; $this->Suppliers->DoHomePage; $this->AddText($this->Doc->Render); }   private function DoCatSupp { $idRow = $this->objCatPage->Value('ID_Row'); $rcSupp = $this->Suppliers($idRow); assert('is_object($rcSupp)'); $strSuppName = $rcSupp->Value('Name');

$this->DoSuppIndicia($rcSupp); $this->strWikiPg	= 'supp:'.strtoupper($rcSupp->Value('CatKey')); $this->strTitle	= $strSuppName; $this->strName	= 'listing for '.$strSuppName; $this->strTitleContext	= 'Suppliers</a>: '.$strSuppName.':'; $rcSupp->DoDeptsPage; $this->AddText($this->Doc->Render); } private function DoCatDept { CallEnter($this,__LINE__,'clsPage.DoCatDept');

//   $objDeptTbl = VbzClasses::Depts; $objDeptTbl = $this->Depts; $objDept = $objDeptTbl->GetItem($this->objCatPage->ID_Row); assert('is_object($objDept)'); $objSupp = $objDept->Supplier; assert('is_object($objSupp)'); $strDeptName = $objDept->Name; $strSuppName = $objSupp->Name; $strDeptLink = $objDept->LinkName; $strSuppLink = $objSupp->Link;

$this->DoDeptIndicia($objDept); $this->strWikiPg	= 'dept:'.strtoupper($objDept->PageKey);

$this->strTitle	= $strSuppName; $this->strName	= $strDeptName.' dept. of '.$strSuppName; $this->strTitleContext	= 'items supplied</a> by '.$strSuppLink.'\'s '.$strDeptName.' department:'; $this->AddText($objDept->DoPage); CallExit('clsPage.DoCatDept'); } private function DoCatTitle { CallEnter($this,__LINE__,'clsPage.DoCatTitle');

$strPageKey = $this->objCatPage->Path; //   $objTitleTbl = VbzClasses::Titles; $objTitleTbl = $this->Titles;

$idRow = $this->objCatPage->ID_Row; $objTitle = $objTitleTbl->GetItem($idRow); assert('is_object($objTitle)'); $objDept = $objTitle->Dept; assert('is_object($objDept)'); $objSupp = $objDept->Supplier; assert('is_object($objSupp)'); $strTitleName = $objTitle->Name;

$this->DoTitleIndicia($objTitle);

//   $this->strAbbr	= 'title:'.strtoupper($strCatNum); $this->strWikiPg	= 'title:'.$objTitle->CatNum; //print 'ABBR='.$this->strAbbr; $this->strTitle	= $strTitleName; $this->strName	= $strPageKey.' "'.$strTitleName.'" from '.$objSupp->Name; $this->strTitleContext 	= 'items <a href="'.KWP_CAT_REL.     '">supplied</a> by '.$objSupp->Link.'\'s '. $objDept->LinkName.' department:'; $objTitle->hideImgs = $this->hideImgs; $this->AddText($objTitle->DoPage); CallExit('clsPage.DoCatTitle'); } private function DoCatImage { CallEnter($this,__LINE__,'clsPage.DoCatImage'); //   $objImageTbl = VbzClasses::Images; $objImageTbl = $this->Images; $objImage = $objImageTbl->GetItem($this->objCatPage->ID_Row); $objImage->DoPage; CallExit('clsPage.DoCatImage'); } }