Difference between revisions of "VbzCart/archive/code/files/store.php"
(→Code - store.php: oops, wrong code (non-working dev code); this is the right one) |
(basically working... totally different: is an actual class library now) |
||
Line 8: | Line 8: | ||
==Code - store.php== | ==Code - store.php== | ||
<php><?php | <php><?php | ||
− | # PURPOSE: vbz page | + | /* |
− | # | + | FILE: store.php |
+ | PURPOSE: vbz class library - should eventually be subdivided | ||
+ | HISTORY: | ||
+ | 2009-07-11 (Wzl) Lots of cleanup; added types and methods needed for shopping cart page | ||
+ | */ | ||
+ | //define('kfpHostAcctRoot','/hsphere/local/home/hypertwi/'); | ||
+ | //define('kfpMediaWiki',kfpHostAcctRoot.'wiki.vbz.net/'); | ||
+ | define('kEmbeddedPagePrefix','embed:'); | ||
+ | |||
+ | if (defined( '__DIR__' )) { | ||
+ | $fpThis = __DIR__; | ||
+ | } else { | ||
+ | $fpThis = dirname(__FILE__); | ||
+ | } | ||
+ | if (!defined('LIBMGR')) { | ||
+ | require('libmgr.php'); | ||
+ | } | ||
+ | clsLibMgr::Add('datamgr',$fpThis.'/datamgr.php'); | ||
+ | clsLibMgr::Load('datamgr'); | ||
+ | |||
+ | define('EN_PGTYPE_NOTFND',-1); // requested item (supp/dept/title) not found | ||
+ | define('EN_PGTYPE_HOME',1); // catalog home page | ||
+ | define('EN_PGTYPE_SUPP',2); // supplier page | ||
+ | define('EN_PGTYPE_DEPT',3); // department page, or possibly title for keyless dept | ||
+ | define('EN_PGTYPE_TITLE',4); // title page | ||
+ | // table names | ||
+ | // - caching | ||
+ | define('ksTbl_cache_tables','data_tables'); | ||
+ | define('ksTbl_cache_procs','data_procs'); | ||
+ | define('ksTbl_cache_flow','data_flow'); | ||
+ | define('ksTbl_cache_log','data_log'); | ||
+ | // - stock | ||
+ | define('ksTbl_stock_places','stk_places'); | ||
+ | define('ksTbl_stock_bins','stk_bins'); | ||
+ | define('ksQry_stock_bins_wInfo','qryStk_Bins_w_info'); | ||
+ | define('ksTbl_stock_items','stk_items'); | ||
+ | define('ksTbl_stock_hist_items','stk_history'); | ||
+ | define('ksTbl_stock_hist_bins','stk_bin_history'); | ||
+ | |||
+ | $vbgImgSize = array( | ||
+ | 'th' => 'thumbnail', | ||
+ | 'sm' => 'small', | ||
+ | 'big' => 'large', | ||
+ | 'huge' => 'huge', | ||
+ | 'zoom' => 'detail'); | ||
+ | |||
+ | // shipping charge adjustment factors by destination zone: | ||
+ | $listShipListDesc['US'] = 'United States'; | ||
+ | $listShipListDesc['CA'] = 'Canada'; | ||
+ | $listShipListDesc['INT'] = 'International'; | ||
+ | $listPkgFactors['US'] = 1.0; | ||
+ | $listItmFactors['US'] = 1.0; | ||
+ | $listPkgFactors['CA'] = 2.0; | ||
+ | $listItmFactors['CA'] = 2.0; | ||
+ | $listPkgFactors['INT'] = 4.0; | ||
+ | $listItmFactors['INT'] = 4.0; | ||
+ | // The above is just until we have something more exact and dynamic | ||
+ | |||
+ | $intCallDepth = 0; | ||
+ | |||
+ | // CALCULATED GLOBALS | ||
+ | $fpTools = '/tools'; | ||
+ | $fpPages = ''; | ||
+ | $fwpAbsPages = 'http://'.KS_PAGE_SERVER.$fpPages; | ||
+ | $fwpAbsTools = 'http://'.KS_TOOLS_SERVER.$fpTools; | ||
+ | $fwpCart = $fwpAbsPages.'/cart/'; | ||
+ | $strCurServer = $_ENV['SERVER_NAME']; | ||
+ | |||
+ | // SET UP DEPENDENT VALUES | ||
+ | /* | ||
+ | if ($strCurServer != KS_TOOLS_SERVER) { | ||
+ | $fpTools = $fwpAbsTools; | ||
+ | $fpPages = $fwpAbsPages; | ||
+ | } | ||
+ | */ | ||
+ | $fwpLogo = $fpTools.'/img/logos/v/'; | ||
+ | |||
+ | class clsVbzData extends clsDatabase { | ||
+ | private $objPages; | ||
+ | |||
+ | public function __construct($iSpec) { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | parent::__construct($iSpec); | ||
+ | $objDataMgr = new clsDataMgr($this,ksTbl_cache_tables,ksTbl_cache_procs,ksTbl_cache_flow,ksTbl_cache_log); | ||
+ | $this->Open(); | ||
+ | } | ||
+ | // generic object-creation function | ||
+ | protected function Make($iName) { | ||
+ | if (!isset($this->$iName)) { | ||
+ | $this->$iName = new $iName($this); | ||
+ | } | ||
+ | return $this->$iName; | ||
+ | } | ||
+ | // table-specific functions | ||
+ | public function Pages() { | ||
+ | return $this->Make('clsCatPages'); | ||
+ | } | ||
+ | public function Suppliers() { | ||
+ | return $this->Make('clsSuppliers'); | ||
+ | } | ||
+ | public function Depts() { | ||
+ | return $this->Make('clsDepts'); | ||
+ | } | ||
+ | public function Titles() { | ||
+ | return $this->Make('clsTitles'); | ||
+ | } | ||
+ | public function TitlesExt() { | ||
+ | return $this->Make('clsTitlesExt'); | ||
+ | } | ||
+ | public function Items() { | ||
+ | return $this->Make('clsItems'); | ||
+ | } | ||
+ | public function Items_Stock() { | ||
+ | return $this->Make('clsItems_Stock'); | ||
+ | } | ||
+ | public function ItTyps() { | ||
+ | return $this->Make('clsItTyps'); | ||
+ | } | ||
+ | public function ItOpts() { | ||
+ | return $this->Make('clsItOpts'); | ||
+ | } | ||
+ | public function ShipCosts() { | ||
+ | return $this->Make('clsShipCosts'); | ||
+ | } | ||
+ | public function Images() { | ||
+ | return $this->Make('clsImages'); | ||
+ | } | ||
+ | public function StkItems() { | ||
+ | return $this->Make('clsStkItems'); | ||
+ | } | ||
+ | public function Topics() { | ||
+ | return $this->Make('clsTopics'); | ||
+ | } | ||
+ | public function Events() { | ||
+ | return $this->Make('clsEvents'); | ||
+ | } | ||
+ | public function LogEvent($iWhere,$iParams,$iDescr,$iCode,$iIsError,$iIsSevere) { | ||
+ | return $this->Events()->LogEvent($iWhere,$iParams,$iDescr,$iCode,$iIsError,$iIsSevere); | ||
+ | } | ||
+ | // Page output routines | ||
+ | public function SectionHdr($iTitle) { | ||
+ | $out = '<p class=main><big>'.$iTitle.'</big></p>'; | ||
+ | return $out; | ||
+ | } | ||
+ | public function ShowTitles($iHdrText,$iList,$objNoImgSect) { | ||
+ | $cntImgs = 0; | ||
+ | $outImgs = ''; | ||
+ | foreach ($iList as $i => $objTitleData) { | ||
+ | $objTitle = $this->Titles()->GetItem($objTitleData->ID); | ||
+ | $objImgs = $objTitle->ListImages('th'); | ||
+ | $currMinPrice = $objTitleData->currMinPrice; | ||
+ | $currMaxPrice = $objTitleData->currMaxPrice; | ||
+ | $strPrice = DataCurr($currMinPrice); | ||
+ | if ($currMinPrice != $currMaxPrice) { | ||
+ | $strPrice .= '-'.DataCurr($currMaxPrice); | ||
+ | } | ||
+ | assert('is_resource($objImgs->Res)'); | ||
+ | if ($objImgs->RowCount()) { | ||
+ | $cntImgs++; | ||
+ | $strCatNum = $objTitleData->CatNum; | ||
+ | $strTitleTag = '"'.$objTitle->Name.'" ('.$strCatNum.')'; | ||
+ | $strTitleLink = $objTitle->Link(); | ||
+ | while ($objImgs->NextRow()) { | ||
+ | $strImgTag = $strTitleTag.' - '.$strPrice; | ||
+ | $qtyStk = $objTitleData->qtyForSale; | ||
+ | if ($qtyStk) { | ||
+ | $strImgTag .= ' - '.$qtyStk.' in stock'; | ||
+ | } | ||
+ | $outImgs .= $strTitleLink.'<img class="thumb" src="'.KWP_IMG_MERCH.'/'.$objImgs->Spec.'" title="'.$strImgTag.'"></a>'; | ||
+ | } | ||
+ | } else { | ||
+ | if (!$objNoImgSect->inTbl) { | ||
+ | $objNoImgSect->StartTable('titles without images:'); | ||
+ | $objNoImgSect->AddText('<tr class=main><th>Cat. #</th><th>Title</th><th>Price<br>Range</th><th>to<br>order</th><th>status</th></tr>'); | ||
+ | } | ||
+ | $objNoImgSect->RowStart(); | ||
+ | $objNoImgSect->ColAdd('<b>'.$objTitleData->CatNum.'</b>'); | ||
+ | $objNoImgSect->ColAdd($objTitle->Name); | ||
+ | $objNoImgSect->ColAdd($strPrice); | ||
+ | $objNoImgSect->ColAdd('<b>[</b>'.$objTitle->Link().'order</a><b>]</b>'); | ||
+ | $qtyStk = $objTitleData->qtyForSale; | ||
+ | if ($qtyStk) { | ||
+ | $strStock = '<b>'.$qtyStk.'</b> in stock'; | ||
+ | $objNoImgSect->ColAdd($strStock); | ||
+ | if ($objTitleData->cntInPrint == 0) { | ||
+ | $objNoImgSect->ColAdd('OUT OF PRINT!'); | ||
+ | } | ||
+ | } else { | ||
+ | $objNoImgSect->ColAdd('<a title="explanation..." href="'.KWP_WIKI.'Available_but_not_in_stock">available, not in stock</a>'); | ||
+ | // Debugging: | ||
+ | // $objNoImgSect->ColAdd('ID_Title='.$objTitle->ID.' ID_ItTyp='.$objTitle->idItTyp); | ||
+ | } | ||
+ | $objNoImgSect->RowStop(); | ||
+ | } | ||
+ | } | ||
+ | $out = ''; | ||
+ | if ($cntImgs) { | ||
+ | $out .= $this->SectionHdr($iHdrText); | ||
+ | $out .= $outImgs; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsList { | ||
+ | public $List; | ||
+ | |||
+ | public function Add($iName, $iValue=NULL) { | ||
+ | $objItem = new clsListItem($iName,$iValue); | ||
+ | $this->List[] = $objItem; | ||
+ | return $objItem; | ||
+ | } | ||
+ | public function Output($iPfx, $iSep, $iSfx) { | ||
+ | $out = NULL; | ||
+ | if (is_array($this->List)) { | ||
+ | foreach ($this->List as $objItem) { | ||
+ | if (is_null($objItem->value)) { | ||
+ | $out .= $iPfx.$iSep.$objItem->name.$iSfx; | ||
+ | } else { | ||
+ | $out .= $iPfx.$objItem->name.$iSep.$objItem->value.$iSfx; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | class clsListItem { | ||
+ | public $name; | ||
+ | public $value; | ||
+ | |||
+ | public function __construct($iName, $iValue=NULL) { | ||
+ | $this->name = $iName; | ||
+ | $this->value = $iValue; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* =================== | ||
+ | CLASS: clsPage | ||
+ | PURPOSE: Handles display of different page types | ||
+ | */ | ||
+ | class clsPage extends clsVbzData { | ||
+ | // 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($iSpec) { | ||
+ | parent::__construct($iSpec); | ||
+ | $this->lstTop = new clsList(); | ||
+ | } | ||
+ | |||
+ | public function GetQuery() { | ||
+ | // ACTION: Retrieves request from URL and parses it | ||
+ | if (isset($_SERVER['PATH_INFO'])) { | ||
+ | $strReq = $_SERVER['PATH_INFO']; | ||
+ | } else { | ||
+ | $strReq = ''; | ||
+ | } | ||
+ | $this->strReq = $strReq; | ||
+ | // $pathinfo = $_SERVER['REQUEST_URI']; | ||
+ | if (strrpos($strReq,'/')+1 < strlen($strReq)) { | ||
+ | $strRedir = KWP_CAT_REL.substr($strReq,1).'/'; | ||
+ | header('Location: '.$strRedir); | ||
+ | exit; // retry with new URL | ||
+ | } | ||
+ | $this->ParseQuery(); | ||
+ | } | ||
+ | public function ParseQuery() { | ||
+ | // This is essentially an abstract function | ||
+ | // Define any additional parsing of the query (store member vars etc.) | ||
+ | |||
+ | // global $objFactory; | ||
+ | |||
+ | // $strReq = $this->strReq; | ||
+ | |||
+ | |||
+ | // $this->objCatPage = $objFactory->Pages()->GetItem_byKey($strReq); | ||
+ | //print 'REQ='.$strReq.' ABBR='.$this->objCatPage->AB; | ||
+ | } | ||
+ | // DIFFERENT TYPES OF PAGES | ||
+ | protected function DoNotFound() { | ||
+ | // $this->Setup('','Unknown Title','unknown title in catalog','browse','Tomb of the...'); | ||
+ | $this->strWikiPg = ''; | ||
+ | $this->strTitle = 'Unknown Page'; | ||
+ | $this->strName = 'unknown title in catalog'; | ||
+ | $this->strTitleContext = 'Tomb of the...'; | ||
+ | $this->strHdrXtra = ''; | ||
+ | $this->strSideXtra = '<dt><b>Cat #</b>: '.$this->strReq; | ||
+ | } | ||
+ | // UTILITY | ||
+ | protected function AddText($iText) { | ||
+ | $this->strContText .= $iText; | ||
+ | } | ||
+ | |||
+ | // PAGE COMPONENTS | ||
+ | // -- HEADER COMPONENTS | ||
+ | protected function DoPreamble() { | ||
+ | # Framework | ||
+ | $this->DoHeader(); | ||
+ | $this->DoSidebar(); | ||
+ | $this->DoWikiContent(); | ||
+ | } | ||
+ | protected function DoPostamble() { | ||
+ | global $didPage,$fltStart; | ||
+ | |||
+ | echo '<div style="clear: both;" align=right>'; | ||
+ | $this->DoSepBar(); | ||
+ | echo '<table width=100%><tr><td align=right><small><i>'; | ||
+ | $fltExecTime = microtime(true)-$fltStart; | ||
+ | $dat = getrusage(); | ||
+ | $fltUserTime = $dat["ru_utime.tv_usec"]/1000000; | ||
+ | $strServer = $_SERVER['SERVER_SOFTWARE']; | ||
+ | echo $strServer.' .. '; | ||
+ | echo 'PHP '.phpversion().' .. Generated in <b>'.$fltUserTime.'</b> seconds (script execution '.$fltExecTime.' sec.) .. '; | ||
+ | $strWikiPg = $this->strWikiPg; | ||
+ | if ($strWikiPg) { | ||
+ | echo 'wiki: <a href="'.KWP_WIKI.kEmbeddedPagePrefix.$this->strWikiPg.'">'.$strWikiPg.'</a> .. '; | ||
+ | } | ||
+ | echo date('Y-m-d H:i:s'); | ||
+ | echo '</i></small></td></tr></table>'; | ||
+ | echo '</div></body></html>'; | ||
+ | $didPage = true; | ||
+ | } | ||
+ | private function DoWikiContent() { | ||
+ | # WIKI CONTENTS | ||
+ | # $txtPage = GetEmbedPage('cat'); | ||
+ | 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) { | ||
+ | // print '<span class=main>'.$txtPage.'</span><br>'; | ||
+ | echo '<table class=main><tr><td>'.$txtWiki.'</td></tr></table>'; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | protected function DoSidebar() { | ||
+ | global $fpTools,$objDataMgr; | ||
+ | |||
+ | // TO DO: these should be pulled from the [stats] table | ||
+ | if ($objDataMgr->dtNewest) { | ||
+ | $timeSidebarBuild=$objDataMgr->dtNewest; | ||
+ | } else { | ||
+ | $timeSidebarBuild = NULL; | ||
+ | } | ||
+ | $statsQtyTitlesAvail = 2245; | ||
+ | $statsQtyStockPieces = 1395; | ||
+ | $statsQtyStockItems = 753; | ||
+ | $statsQtyArtists = 136; | ||
+ | $statsQtyTopics = 1048; | ||
+ | //--------- | ||
+ | |||
+ | echo '<table class=border align=left cellpadding=3 bgcolor="#000000"><tr><td>'; | ||
+ | ?> | ||
+ | <table class=sidebar bgcolor="#ffffff" cellpadding=5><tr><td> | ||
+ | <table border=0 class=menu-title width="100%"><tr><td class=menu-title><a href="/">Home</a></td></tr></table> | ||
+ | <span class=menu-text><dl> | ||
+ | <?php | ||
+ | /* | ||
+ | <span class=menu-text><p style="background: #eeeeee;"><dl> | ||
+ | */ | ||
+ | echo $this->lstTop->Output('<dt><b>','</b>: ',''); | ||
+ | // echo '</p></span></dl>'; | ||
+ | echo '</dl>'; | ||
+ | if ($this->strSideXtra) { | ||
+ | echo '<dl style="background: #eeeeee;">'.$this->strSideXtra.'</dl>'; | ||
+ | } | ||
+ | echo '<form action="/search/">'; | ||
+ | echo 'Search '.$statsQtyTitlesAvail.' items:<br>'; | ||
+ | ?> | ||
+ | <input size=10 name=search><input type=submit value="Go"><br> | ||
+ | <small><a href="/search/">advanced</a></small> | ||
+ | </form> | ||
+ | <b>Indexes</b> | ||
+ | <br> ...<a href="/cat/"><b>C</b>atalog <b>H</b>ome</a> | ||
+ | <?php | ||
+ | |||
+ | echo '<br> ...<a href="/stock/" title="'.$statsQtyStockPieces.' pieces, '.$statsQtyStockItems.'. items"><b>S</b>tock</a> ('.$statsQtyStockPieces.')'; | ||
+ | echo '<br> ...<a href="/artists/" title="'.$statsQtyArtists.'.artists"><b>A</b>rtists</a> ('.$statsQtyArtists.')'; | ||
+ | //print '<br> ...<a href="/topics/" title="'.$statsQtyTopics.'.topics"><b>T</b>opics</a> ('.$statsQtyTopics.')'; | ||
+ | echo '<p>'; | ||
+ | echo '[[ <a href="'.KWP_WIKI.'" title="vbz wiki homepage"><b>wiki</b></a> ]]<br>'; | ||
+ | echo '-- [[ <a href="'.KWP_WIKI.'help" title="help-related pages on the wiki"><b>Help</b></a> ]]<br>'; | ||
+ | echo '-- [[ <a href="'.KWP_WIKI.'about" title="about vbz.net (probably more than you want to know)"><b>About</b></a> ]]<br>'; | ||
+ | echo '-- [[ <a href="'.KWP_WIKI.'contact" title="contact vbz.net (several different methods)"><b>Contact</b></a> ]]<br>'; | ||
+ | echo '<p>'; | ||
+ | echo '<a href="/email/" title="web form for sending us email">email form</a><br>'; | ||
+ | echo '<a href="/cart/" title="your shopping cart">shopping cart</a><p>'; | ||
+ | # == END Sidebar B == | ||
+ | /* | ||
+ | print '<table class=border width="100%"><tr><td>'; | ||
+ | print '<table width="100%"><tr><td valign=top class=menu-status>Updated:</td><td>'; | ||
+ | print '<td align=right class=menu-status><b>'.$timeSidebarBuild.'</b>'; | ||
+ | print '</td></tr></table>'; | ||
+ | print '</td></tr></table>'; | ||
+ | */ | ||
+ | echo '</span></td></tr></table></td></tr></table>'; | ||
+ | } | ||
+ | private function DoSepBar() { | ||
+ | global $fpTools; | ||
+ | |||
+ | echo '<img src="'.$fpTools.'/img/bg/hlines/" alt="-----" width="100%">'; | ||
+ | } | ||
+ | private function ToolbarItem($iURL,$iIcon,$iTitle,$iAlt) { | ||
+ | global $fpTools; | ||
+ | return '<a href="'.$iURL.'"><img border=0 src="'.$fpTools.'/img/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_WIKI.'help','help','help!','help'); | ||
+ | } | ||
+ | // -- HEADER | ||
+ | protected function DoHeader() { | ||
+ | global $fpTools, $fwpLogo; | ||
+ | |||
+ | $strWikiPg = $this->strWikiPg; | ||
+ | $this->strCalcTitle = KS_STORE_NAME.' - '.$this->strName; | ||
+ | $htmlHead = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'; | ||
+ | $htmlHead .= '<html><head><title>'.$this->strCalcTitle.'</title>'; | ||
+ | if ($this->strSheet) { | ||
+ | $htmlHead .= '<link rel="StyleSheet" href="'.$fpTools.'/styles/'.$this->strSheet.'.css">'; | ||
+ | } | ||
+ | # remove any quotes from $pageName: | ||
+ | $htmlName = str_replace('"','"',$this->strName); | ||
+ | if ($htmlName) { | ||
+ | $htmlName = ': '.$htmlName; | ||
+ | } | ||
+ | $htmlHead .= '<meta name=description content="'.KS_STORE_NAME_META.$htmlName.'">'; | ||
+ | $htmlHead .= '</head>'; | ||
+ | echo $htmlHead; | ||
+ | ?><body | ||
+ | bgcolor=000044 | ||
+ | TEXT=CCFFFF | ||
+ | LINK=33FF33 | ||
+ | VLINK=33CCFF | ||
+ | ALINK=FFCC00 | ||
+ | TOPMARGIN=0 | ||
+ | LEFTMARGIN=0 | ||
+ | MARGINWIDTH=0 | ||
+ | MARGINHEIGHT=0 | ||
+ | > | ||
+ | <? | ||
+ | // begin content header | ||
+ | echo '<table width="100%" class=border cellpadding=5><tr><td>'; | ||
+ | echo '<table width="100%" class=hdr cellpadding=2><tr>'; | ||
+ | // === LEFT HEADER: Title === | ||
+ | echo '<td>'; | ||
+ | echo '<a href="'.KWP_HOME_ABS.'"><img align=left border=0 src="'.$fwpLogo.'" title="'.KS_STORE_NAME.' home" alt="'.KS_SMALL_LOGO_ALT.'"></a>'; | ||
+ | if ($this->strTitleContext) { | ||
+ | echo '<span class=pretitle><b><a href="/">'.KS_STORE_NAME.'</a></b>: '.$this->strTitleContext.'</span><br>'; | ||
+ | } | ||
+ | echo '<span class=page-title>'.$this->strTitle.'</span></td>'; | ||
+ | // === END LEFT HEADER === | ||
+ | |||
+ | // === RIGHT HEADER: nav icons === | ||
+ | echo '<td align=right>'; | ||
+ | $this->DoToolbar(); | ||
+ | echo '</td>'; | ||
+ | // === END RIGHT HEADER === | ||
+ | ?> | ||
+ | </tr></table> | ||
+ | </td></tr></table> | ||
+ | <!-- end html header --> | ||
+ | <? | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsPageCat extends clsPage { | ||
+ | private $objCatPage; // object for identifying page to display | ||
+ | |||
+ | public function ParseQuery() { | ||
+ | $strReq = $this->strReq; | ||
+ | $this->objCatPage = $this->Pages()->GetItem_byKey($strReq); | ||
+ | |||
+ | //print 'REQ='.$strReq.' ABBR='.$this->objCatPage->AB; | ||
+ | } | ||
+ | |||
+ | public function DoRequest() { | ||
+ | $doRawHTML = FALSE; | ||
+ | $this->strSheet = 'browse'; // default | ||
+ | if ($this->strReq) { | ||
+ | if (is_object($this->objCatPage)) { | ||
+ | switch ($this->objCatPage->Type) { | ||
+ | case 'S': | ||
+ | $this->DoCatSupp(); | ||
+ | break; | ||
+ | case 'D': | ||
+ | $this->DoCatDept(); | ||
+ | break; | ||
+ | case 'T': | ||
+ | $this->DoCatTitle(); | ||
+ | break; | ||
+ | case 'I': | ||
+ | $doRawHTML = TRUE; | ||
+ | $this->DoCatImage(); | ||
+ | break; | ||
+ | } | ||
+ | } else { | ||
+ | $this->DoNotFound(); | ||
+ | } | ||
+ | } else { | ||
+ | $this->DoCatHome(); | ||
+ | } | ||
+ | if ($doRawHTML) { | ||
+ | echo $this->strContText; | ||
+ | } else { | ||
+ | $this->DoPreamble(); // everything before the contents | ||
+ | echo $this->strContText; | ||
+ | $this->DoPostamble(); // everything after the contents | ||
+ | } | ||
+ | } | ||
+ | // SIDEBAR INFO for different types of pages | ||
+ | private function DoCatIndicia() { | ||
+ | $this->lstTop->Add('Section','<a href="'.KWP_CAT_REL.'">by supplier</a>'); | ||
+ | } | ||
+ | private function DoSuppIndicia($iSupp,$isFinal=true) { | ||
+ | $this->DoCatIndicia(); | ||
+ | if ($isFinal) { | ||
+ | $this->lstTop->Add('Supplier',$iSupp->Name); | ||
+ | $this->lstTop->Add('<a href="'.KWP_WIKI.$iSupp->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() { | ||
+ | // $objSuppTbl = VbzClasses::Suppliers(); | ||
+ | // $this->Setup('cat','Catalog Home','Catalog main page','browse','hello and welcome to the...'); | ||
+ | $this->DoCatIndicia(); | ||
+ | $this->strWikiPg = 'cat'; | ||
+ | $this->strTitle = 'Catalog Home'; | ||
+ | $this->strName = 'Catalog main page'; | ||
+ | $this->strTitleContext = 'hello and welcome to the...'; | ||
+ | $this->AddText($this->Suppliers()->DoHomePage()); | ||
+ | } | ||
+ | private function DoCatSupp() { | ||
+ | CallEnter($this,__LINE__,'clsPage.DoCatSupp()'); | ||
+ | |||
+ | // $objSuppTbl = VbzClasses::Suppliers(); | ||
+ | $objSuppTbl = $this->Suppliers(); | ||
+ | $objSupp = $objSuppTbl->GetItem($this->objCatPage->ID_Row); | ||
+ | assert('is_object($objSupp)'); | ||
+ | $strSuppName = $objSupp->Name; | ||
+ | |||
+ | $this->DoSuppIndicia($objSupp); | ||
+ | $this->strWikiPg = 'supp:'.strtoupper($objSupp->CatKey); | ||
+ | $this->strTitle = $strSuppName; | ||
+ | $this->strName = 'listing for '.$strSuppName; | ||
+ | $this->strTitleContext = '<a href="'.KWP_CAT_REL.'">Suppliers</a>: <b>'.$strSuppName.'</b>:'; | ||
+ | $this->AddText($objSupp->DoPage()); | ||
+ | |||
+ | CallExit('clsPage.DoCatSupp()'); | ||
+ | } | ||
+ | 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 <a href="'.KWP_CAT_REL.'">supplied</a> by '.$strSuppLink.'\'s <b>'.$strDeptName.'</b> 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(); | ||
+ | |||
+ | $objTitle = $objTitleTbl->GetItem($this->objCatPage->ID_Row); | ||
+ | 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()'); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsPageTopic extends clsPage { | ||
+ | public function DoRequest() { | ||
+ | $this->strSheet = 'browse'; // default | ||
+ | $strReq = $this->strReq; | ||
+ | if (is_numeric($strReq)) { | ||
+ | $idTopic = (int)$strReq; | ||
+ | $objTopic = $this->Topics()->GetItem($idTopic); | ||
+ | $this->strWikiPg = 'topic.'.$objTopic->WebName(); | ||
+ | $this->strTitle = 'Topic Index'; | ||
+ | $this->strName = 'catalog topic index'; | ||
+ | $this->AddText($objTopic->DoPage()); | ||
+ | } else { | ||
+ | $this->strWikiPg = 'topics'; | ||
+ | $this->strTitle = 'Topic Index'; | ||
+ | $this->strName = 'catalog topic index'; | ||
+ | $this->AddText($this->Topics()->DoIndex()); | ||
+ | } | ||
+ | $this->DoPreamble(); // everything before the contents | ||
+ | echo '<span class=main>'.$this->strContText.'</span>'; | ||
+ | $this->DoPostamble(); // everything after the contents | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsPageOutput { | ||
+ | public $out; | ||
+ | private $isOdd; | ||
+ | public $inTbl; | ||
+ | |||
+ | function __construct() { | ||
+ | $this->out = ''; | ||
+ | $this->isOdd = false; | ||
+ | $this->inTbl = 0; | ||
+ | } | ||
+ | function Clear() { | ||
+ | $this->out = ''; | ||
+ | } | ||
+ | function AddText($iText) { | ||
+ | $this->out .= $iText; | ||
+ | } | ||
+ | function SectionHdr($iTitle) { | ||
+ | $this->out .= '<p class=main><big>'.$iTitle.'</big></p>'; | ||
+ | return $this->out; | ||
+ | } | ||
+ | function StartTable($iTitle) { | ||
+ | if ($iTitle) { | ||
+ | $this->SectionHdr($iTitle); | ||
+ | $this->out .= '<table class=content>'; | ||
+ | $this->inTbl++; | ||
+ | } | ||
+ | } | ||
+ | function RowStart($iClass='') { | ||
+ | if ($iClass) { | ||
+ | $this->out .= '<tr class="'.$iClass.'">'; | ||
+ | } else { | ||
+ | $this->out .= '<tr>'; | ||
+ | } | ||
+ | } | ||
+ | function RowStop() { | ||
+ | $this->out .= '</tr>'; | ||
+ | $this->isOdd = !$this->isOdd; | ||
+ | } | ||
+ | function ColAdd($iText) { | ||
+ | if ($this->isOdd) { | ||
+ | $cellOpen = '<td class=catalog-stripe valign=top>'; | ||
+ | } else { | ||
+ | $cellOpen = '<td class=catalog valign=top>'; | ||
+ | } | ||
+ | $this->out .= $cellOpen.$iText.'</td>'; | ||
+ | } | ||
+ | function EndTable() { | ||
+ | if ($this->inTbl) { | ||
+ | $this->out .= '</table>'; | ||
+ | $this->inTbl--; | ||
+ | } | ||
+ | return $this->out; | ||
+ | } | ||
+ | function ShowImgUnavail() { | ||
+ | $this->out .= '<table class=border cellpadding="5"><tbody><tr><td><table class="hdr" cellpadding="2"><tbody><tr><td align="center"><span class="page-title">No Images<br>Available<br></span>for this item<br><b>:-(</b></td></tr></tbody></table></td></tr></tbody></table>'; | ||
+ | return $this->out; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* =========================== | ||
+ | *** CATALOG DATA CLASSES *** | ||
+ | */ | ||
+ | class clsVbzTable extends clsTable { | ||
+ | protected function Touch($iCaller) { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | $objDataMgr->Update_byName($this->Name(),$iCaller); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsCatPages extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_pages'); | ||
+ | $this->KeyName('AB'); | ||
+ | $this->ClassSng('clsCatPage'); | ||
+ | } | ||
+ | /* | ||
+ | protected function _newItem() { | ||
+ | return new clsCatPage($this); | ||
+ | } | ||
+ | */ | ||
+ | public function GetItem_byKey($iKey) { | ||
+ | |||
+ | CallEnter($this,__LINE__,__CLASS__.'.GetItem_byKey('.$iKey.')'); | ||
+ | $strKey = trim($iKey,'/'); | ||
+ | $strKey = str_replace('-','/',$strKey); | ||
+ | $sqlCatKey = $this->objDB->SafeParam($strKey); | ||
+ | $this->Touch('clsCatPages.GetItem_byKey('.$iKey.')'); | ||
+ | $objItem = $this->GetData('Path="'.$sqlCatKey.'"'); | ||
+ | // $objRec = $this->objDB->Query($sql); | ||
+ | assert('is_object($objItem)'); | ||
+ | if ($objItem->NextRow()) { | ||
+ | DumpValue('objItem NumRows',$objItem->hasRows()); | ||
+ | CallExit('clsCatPages.GetItem_byKey('.$iKey.') -> Page '.$objItem->AB); | ||
+ | } else { | ||
+ | CallExit('clsCatPages.GetItem_byKey('.$iKey.') -> no data'); | ||
+ | } | ||
+ | return $objItem; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsCatPage extends clsDataSet { | ||
+ | // == STATIC SECTION | ||
+ | // const cksTblName = 'cat_pages'; | ||
+ | // const cksIDName = 'AB'; | ||
+ | |||
+ | } | ||
+ | |||
+ | class clsSuppliers extends clsVbzTable { | ||
+ | // ==== STATIC SECTION | ||
+ | |||
+ | // ==== DYNAMIC SECTION | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_supp'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsSupplier'); | ||
+ | } | ||
+ | public function GetItem_byKey($iKey) { | ||
+ | CallEnter($this,__LINE__,__CLASS__.'.GetItem_byKey('.$iKey.')'); | ||
+ | $sqlCatKey = $this->objDB->SafeParam($iKey); | ||
+ | $objItem = $this->GetData('CatKey="'.$sqlCatKey.'"'); | ||
+ | CallExit(__CLASS__.'.GetItem_byKey('.$iKey.') -> new supplier'); | ||
+ | return $objItem; | ||
+ | } | ||
+ | public function DoHomePage() { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | $objDataMgr->Update_byName('_supplier_ittyps','clsSuppliers.DoHomePage()'); | ||
+ | $sql = 'SELECT * FROM _supplier_ittyps ORDER BY Name, ItemCount DESC'; | ||
+ | $objRec = $this->objDB->DataSet($sql); | ||
+ | $out = ''; | ||
+ | if ($objRec->hasRows()) { | ||
+ | $objTbl = new clsPageOutput; | ||
+ | $objTbl->StartTable('Suppliers'); | ||
+ | $strKeyLast = $outCell = ''; | ||
+ | while ($objRec->NextRow()) { | ||
+ | $strKey = $objRec->CatKey; | ||
+ | if ($strKey != $strKeyLast) { | ||
+ | $strKeyLast = $strKey; | ||
+ | $strKeyLink = strtolower($strKey).'/'; | ||
+ | if ($outCell) { | ||
+ | $objTbl->ColAdd($outCell); | ||
+ | $objTbl->RowStop(); | ||
+ | $outCell = ''; | ||
+ | } | ||
+ | $objTbl->RowStart(); | ||
+ | $objTbl->ColAdd('<b><a href="'.$strKeyLink.'">'.$objRec->Name.'</a></b>'); | ||
+ | $isFirst = true; | ||
+ | } | ||
+ | if ($isFirst) { | ||
+ | $isFirst = false; | ||
+ | } else { | ||
+ | $outCell .= ', '; | ||
+ | } | ||
+ | $strItType = $objRec->ItemType; | ||
+ | if ($strItType == '') { | ||
+ | $strItType = '?id'.$objRec->ID; | ||
+ | } | ||
+ | $outCell .= ' <b>'.$objRec->ItemCount.'</b> '.$strItType; | ||
+ | } | ||
+ | $objTbl->ColAdd($outCell); | ||
+ | $objTbl->RowStop(); | ||
+ | $out .= $objTbl->EndTable(); | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsSupplier extends clsDataSet { | ||
+ | public function DoPage() { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | CallEnter($this,__LINE__,'clsSupplier.DoPage()'); | ||
+ | $out = ''; | ||
+ | assert('$this->ID'); | ||
+ | // first, check how many departments supplier has: | ||
+ | $objDeptTbl = $this->objDB->Depts(); | ||
+ | $objDepts = $objDeptTbl->GetData('isActive AND (ID_Supplier='.$this->ID.')','clsDept','Sort'); | ||
+ | |||
+ | if ($objDepts->RowCount() == 1) { | ||
+ | // if there's only one department, display that instead of a department listing | ||
+ | $out = $objDepts->DoPage(); | ||
+ | } else { | ||
+ | $objDataMgr->Update_byName('_supplier_ittyps','clsSupplier.DoPage() for '.$this->CatKey); | ||
+ | $sql = 'SELECT * FROM _supplier_ittyps WHERE ID='.$this->ID.' ORDER BY Name, ItemCount DESC'; | ||
+ | $objItTyps = $this->objDB->DataSet($sql,'clsItTyp'); | ||
+ | $isFirst = true; | ||
+ | $out .= '<span class=catalog-summary>'; | ||
+ | while ($objItTyps->NextRow()) { | ||
+ | if ($isFirst) { | ||
+ | $isFirst = false; | ||
+ | } else { | ||
+ | $out .= ', '; | ||
+ | } | ||
+ | $out .= ' <b>'.$objItTyps->ItemCount.'</b> '.$objItTyps->ItemType; | ||
+ | } | ||
+ | $out .= '</span>'; | ||
+ | $out .= $objDeptTbl->DoListing_forSupp($this->ID); | ||
+ | } | ||
+ | |||
+ | CallExit('clsSupplier.DoPage()'); | ||
+ | return $out; | ||
+ | } | ||
+ | public function Link() { | ||
+ | $out = '<a href="'.$this->URL().'">'.$this->Name.'</a>'; | ||
+ | return $out; | ||
+ | } | ||
+ | public function URL() { | ||
+ | return KWP_CAT_REL.strtolower($this->CatKey).'/'; | ||
+ | } | ||
+ | } | ||
+ | class clsDepts extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_depts'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsDept'); | ||
+ | } | ||
+ | protected function _newItem() { | ||
+ | CallStep('clsDepts._newItem()'); | ||
+ | return new clsDept($this); | ||
+ | } | ||
+ | public function DoListing_forSupp($iSuppID) { | ||
+ | CallEnter($this,__LINE__,'clsDepts.DoListing_forSupp('.$iSuppID.')'); | ||
+ | |||
+ | $out = '<p class=main><big>Departments:</big></p><table class=depts>'; | ||
+ | $objDepts = $this->GetData('ID_Supplier='.$iSuppID,'clsDept'); | ||
+ | $isFirst = true; | ||
+ | |||
+ | $isOdd = FALSE; | ||
+ | while ($objDepts->NextRow()) { | ||
+ | $outDept = $objDepts->DoListing(); | ||
+ | if ($outDept) { // only show departments with something in them | ||
+ | if ($isOdd) { | ||
+ | $cellOpen = '<td class=catalog-stripe valign=top>'; | ||
+ | } else { | ||
+ | $cellOpen = '<td class=catalog valign=top>'; | ||
+ | } | ||
+ | $keyDept = $objDepts->PageKey(); | ||
+ | $out .= '<tr>'.$cellOpen.'<a href="'.strtolower($keyDept).'/">'.$objDepts->Name.'</a></td>'; | ||
+ | $isOdd = !$isOdd; | ||
+ | $out .= $cellOpen.$outDept.'</td></tr>'; | ||
+ | } | ||
+ | } | ||
+ | $out .= '</table>'; | ||
+ | CallExit('clsDepts.DoListing_forSupp()'); | ||
+ | return $out; | ||
+ | /**/ | ||
+ | } | ||
+ | } | ||
+ | class clsDept extends clsDataSet { | ||
+ | // object cache | ||
+ | private $objSupp; | ||
+ | |||
+ | public function Supplier() { | ||
+ | if (is_object($this->objSupp)) { | ||
+ | return $this->objSupp; | ||
+ | } else { | ||
+ | $idSupp = $this->ID_Supplier; | ||
+ | if ($idSupp) { | ||
+ | $this->objSupp = $this->objDB->Suppliers()->GetItem($idSupp); | ||
+ | return $this->objSupp; | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | public function PageKey() { | ||
+ | if ($this->PageKey) { | ||
+ | return $this->PageKey; | ||
+ | } else { | ||
+ | return $this->CatKey; | ||
+ | } | ||
+ | } | ||
+ | protected function GetDeptData() { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | $objDataMgr->Update_byName('_dept_ittyps','clsDept.DoListing() for ID='.$this->ID); | ||
+ | $sql = 'SELECT * FROM qryItTypsDepts_ItTyps WHERE (ID_Dept='.$this->ID.') ORDER BY cntInPrint DESC'; | ||
+ | $objItTyps = $this->objDB->DataSet($sql,'clsItTyp'); | ||
+ | return $objItTyps; | ||
+ | } | ||
+ | public function DoListing() { | ||
+ | // PURPOSE: Print this department's information as part of department list | ||
+ | |||
+ | assert('$this->ID'); | ||
+ | $objItTyps = $this->GetDeptData(); | ||
+ | $isFirst = true; | ||
+ | $out = ''; | ||
+ | while ($objItTyps->NextRow()) { | ||
+ | if ($isFirst) { | ||
+ | $isFirst = false; | ||
+ | } else { | ||
+ | $out .= ', '; | ||
+ | } | ||
+ | $cntInPrint = $objItTyps->cntInPrint; | ||
+ | $qtyInStock = $objItTyps->qtyForSale; | ||
+ | // TO FIX: This is wrong. Need cntForSale field | ||
+ | $cntAvail = $cntInPrint + $qtyInStock; | ||
+ | if ($cntAvail == 1) { | ||
+ | $strName = $objItTyps->ItTyp_Sng; | ||
+ | } else { | ||
+ | $strName = $objItTyps->ItTyp_Plr; | ||
+ | } | ||
+ | $out .= ' <b>'.$cntAvail.'</b> '.$strName; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | public function DoPage() { | ||
+ | // PURPOSE: Print page for current department | ||
+ | // ACTION: | ||
+ | // * Iterates through item types available for this department. | ||
+ | // * For each item type, prints header and then a list of titles. | ||
+ | global $objDataMgr; | ||
+ | |||
+ | assert('$this->ID'); | ||
+ | $out = ''; | ||
+ | $idDept = $this->ID; | ||
+ | $objSection = new clsPageOutput(); | ||
+ | $objItTyps = $this->GetDeptData(); | ||
+ | $objTitles = new clsTitleExt($this->objDB); | ||
+ | $objNoImgSect = new clsPageOutput(); | ||
+ | $cntSections = 0; | ||
+ | while ($objItTyps->NextRow()) { | ||
+ | $cntInPrint = $objItTyps->cntInPrint; | ||
+ | $qtyInStock = $objItTyps->qtyForSale; | ||
+ | // TO FIX: This is wrong. Need cntForSale field | ||
+ | $cntAvail = $cntInPrint + $qtyInStock; | ||
+ | if ($cntAvail) { | ||
+ | $cntSections++; | ||
+ | $idItTyp = $objItTyps->ID_ItTyp; | ||
+ | // $objSection->SectionHdr(); | ||
+ | // $sql = 'SELECT *, ID_Title AS ID, TitleName AS Name FROM _title_ittyps WHERE ((cntForSale) AND (ID_ItTyp='.$idItTyp.') AND (ID_Dept='.$idDept.'));'; | ||
+ | $sql = 'SELECT t.ID_Title AS ID, t.* FROM qryTitles_ItTyps_Titles AS t WHERE (ID_ItTyp='.$idItTyp.') AND (ID_Dept='.$idDept.');'; | ||
+ | // $objDataMgr->Update_byName('_title_ittyps','clsDept.DoPage() for ID_ItTyp='.$idItTyp.', ID_Dept='.$idDept); | ||
+ | $objTitles->Query($sql); | ||
+ | // $idTitle = $objTitles->GetValue('ID_Title'); | ||
+ | // $objTitles->ID = $idTitle; | ||
+ | |||
+ | if ($objTitles->hasRows()) { | ||
+ | while ($objTitles->NextRow()) { | ||
+ | // make a copy with current row's data | ||
+ | $objTitle = new clsDataSet(NULL,$objTitles->Res,$objTitles->Row); | ||
+ | //$objTitle = clone $objTitles; | ||
+ | $lstTitles[] = $objTitle; // save it in a list | ||
+ | } | ||
+ | assert('is_array($lstTitles)'); | ||
+ | |||
+ | // We've generated the list of titles for this section; now display the section header and titles: | ||
+ | |||
+ | // $out .= $objSection->ShowTitles($objItTyps->ItTypNamePlr.':',$lstTitles,$objNoImgSect); | ||
+ | // $out .= $objSection->ShowTitles($objItTyps->ItTyp_Plr.':',$lstTitles,$objNoImgSect); | ||
+ | $out .= $this->objDB->ShowTitles($objItTyps->ItTyp_Plr.':',$lstTitles,$objNoImgSect); | ||
+ | } else { | ||
+ | echo 'ERROR: No titles found! SQL='.$sql; | ||
+ | } | ||
+ | unset($lstTitles); | ||
+ | $objSection->Clear(); | ||
+ | } else { | ||
+ | $out .= '<span class=main>Small coding error: this line should never happen.</span>'; // TO DO: log an error | ||
+ | } | ||
+ | } | ||
+ | if (!$cntSections) { | ||
+ | $out .= '<span class=main>This department appears to have been emptied of all leftover stock. (Eventually there will be a way to see what items used to be here.)</span>'; | ||
+ | } | ||
+ | if ($objNoImgSect->inTbl) { | ||
+ | $objNoImgSect->EndTable(); | ||
+ | $objSection->AddText($objNoImgSect->out); | ||
+ | $objSection->EndTable(); | ||
+ | $out .= $objSection->out; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | public function LinkName() { | ||
+ | $strURL = $this->Supplier()->URL(); | ||
+ | if ($this->PageKey) { | ||
+ | $strURL .= strtolower($this->PageKey).'/'; | ||
+ | } | ||
+ | // return '<a href="'.KWP_CAT_REL.$strURL.'">'.$this->Name.'</a>'; | ||
+ | return '<a href="'.$strURL.'">'.$this->Name.'</a>'; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsTitles extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_titles'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsTitle'); | ||
+ | } | ||
+ | /* | ||
+ | ACTION: Finds a Title from a CatNum and returns an object for it | ||
+ | TO DO: Rename to Get_byCatNum() | ||
+ | */ | ||
+ | public function GetItem_byCatNum($iCatNum) { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | CallEnter($this,__LINE__,__CLASS__.'.GetItem_byCatNum('.$iCatNum.')'); | ||
+ | assert('is_object($this->objDB)'); | ||
+ | $sqlCatNum = strtoupper(str_replace('.','-',$iCatNum)); | ||
+ | $sqlCatNum = $this->objDB->SafeParam($sqlCatNum); | ||
+ | $sql = 'SELECT * FROM v_titles WHERE CatNum="'.$sqlCatNum.'"'; | ||
+ | $objTitle = new clsTitleExt($this); | ||
+ | // make sure _titles (part of v_titles) is up-to-date | ||
+ | //$objDataMgr->Update_byName('_titles','GetItem_byCatNum('.$iCatNum.')'); | ||
+ | $objDataMgr->Update_byName('_depts','GetItem_byCatNum('.$iCatNum.')'); | ||
+ | // get data from v_titles | ||
+ | $objTitle->Query($sql); | ||
+ | $idTitle = $objTitle->ID; | ||
+ | assert('is_resource($objTitle->Res)'); | ||
+ | if ($objTitle->RowCount()) { | ||
+ | assert('$idTitle'); | ||
+ | $sql = 'SELECT * FROM titles WHERE ID='.$idTitle; | ||
+ | $objTitle->dontLoadBasic = true; | ||
+ | $objTitle->Query($sql); | ||
+ | CallExit('clsTitles.GetItem_byCatNum() -> ok'); | ||
+ | return $objTitle; | ||
+ | } else { | ||
+ | CallExit('clsTitles.GetItem_byCatNum() -> NULL'); | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | class clsTitle extends clsDataSet { | ||
+ | // == STATIC SECTION == | ||
+ | const cksTblName = 'cat_titles'; | ||
+ | const cksIDName = 'ID'; | ||
+ | |||
+ | public static function GetItem($iID) { | ||
+ | $sql = 'SELECT * FROM '.self::cksTblName.' WHERE '.self::cksIDName.'="'.$iID.'"'; | ||
+ | $objItem = new self; | ||
+ | $objItem->Query($sql); | ||
+ | return $objItem; | ||
+ | } | ||
+ | |||
+ | // == DYNAMIC SECTION == | ||
+ | // object cache | ||
+ | private $objDept; | ||
+ | // options | ||
+ | public $hideImgs; | ||
+ | |||
+ | public function Dept() { | ||
+ | if (is_object($this->objDept)) { | ||
+ | return $this->objDept; | ||
+ | } else { | ||
+ | $idDept = $this->ID_Dept; | ||
+ | if ($idDept) { | ||
+ | $objDept = $this->objDB->Depts()->GetItem($idDept); | ||
+ | $this->objDept = $objDept; | ||
+ | assert('is_object($objDept)'); | ||
+ | return $objDept; | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | public function IsActive() { | ||
+ | if (is_null($this->DateUnavail)) { | ||
+ | $out = TRUE; | ||
+ | } else { | ||
+ | $out = ($this->DateUnavail > time()); | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | public function DoPage() { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | $idTitle = $this->ID; | ||
+ | assert('$idTitle'); | ||
+ | $objSection = new clsPageOutput(); | ||
+ | |||
+ | // show small-size images | ||
+ | if (!$this->hideImgs) { | ||
+ | $objImgs = $this->ListImages('sm'); | ||
+ | if ($objImgs->hasRows()) { | ||
+ | while ($objImgs->NextRow()) { | ||
+ | $strImgTag = $objImgs->AttrDispl; | ||
+ | $urlRel = $objImgs->Spec; | ||
+ | $idImg = $objImgs->ID; | ||
+ | $strImg = '<img src="'.KWP_IMG_MERCH.$urlRel.'"'; | ||
+ | if ($strImgTag) { | ||
+ | $strImg .= ' title="'.$strImgTag.'"'; | ||
+ | } | ||
+ | $strImg .= '>'; | ||
+ | $objImgBig = $objImgs->ImgForSize('big'); | ||
+ | if (is_object($objImgBig)) { | ||
+ | if ($objImgBig->hasRow()) { | ||
+ | $strImg = $objImgBig->Href().$strImg.'</a>'; | ||
+ | } | ||
+ | } | ||
+ | $objSection->AddText($strImg); | ||
+ | } | ||
+ | } else { | ||
+ | $objSection->ShowImgUnavail(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // now list available items as table | ||
+ | $sql = 'SELECT * FROM qryTitles_ItTyps_ItTyps WHERE (ID_Title='.$idTitle.') ORDER BY ItTyp_Sort IS NULL, ItTyp_Sort;'; | ||
+ | $objTypes = $this->objDB->DataSet($sql); | ||
+ | if ($objTypes->hasRows()) { | ||
+ | if (KF_CART_ABSOLUTE) { | ||
+ | $urlCart = KWP_CART_ABS; | ||
+ | } else { | ||
+ | $urlCart = KWP_CART_REL; | ||
+ | } | ||
+ | $objSection->AddText('<form method=post action="'.$urlCart.'"><input type=hidden name=from value=browse-multi>'); | ||
+ | |||
+ | $flagDisplayTogether = false; // hard-coded for now | ||
+ | |||
+ | while ($objTypes->NextRow()) { | ||
+ | $idItTyp = $objTypes->ID_ItTyp; | ||
+ | assert('$idItTyp'); | ||
+ | $sqlFilt = '(ID_Title='.$idTitle.') AND (ID_ItTyp='.$idItTyp.')'; | ||
+ | $sqlSort = 'GrpSort,GrpDescr,ItOpt_Sort'; | ||
+ | $objStk = $this->objDB->Items_Stock(); | ||
+ | $objItems = $objStk->GetData($sqlFilt,'clsItem',$sqlSort); | ||
+ | $idItType = 0; | ||
+ | |||
+ | $txtLine = '<tr class=typeHdr><td colspan=3><b>'.$objTypes->ItTyp_Plr.'</b>:</td></tr>'; | ||
+ | |||
+ | if ($flagDisplayTogether) { | ||
+ | // displaying all items in a single listing | ||
+ | $txtBoth .= $txtLine; | ||
+ | } else { | ||
+ | // set flags to determine which stock-status sections to show | ||
+ | $cntInStock = $objTypes->cntStkForSale; | ||
+ | $cntForSale = $objTypes->cntForSale; | ||
+ | $cntOutStock = $cntForSale - $cntInStock; | ||
+ | |||
+ | $txtInStock = $txtOutStock = ''; | ||
+ | if ($cntInStock > 0) { | ||
+ | $txtInStock .= $txtLine; | ||
+ | } | ||
+ | if ($cntOutStock > 0) { | ||
+ | $txtOutStock .= $txtLine; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // iterate through items for this type: | ||
+ | $strGrpLast = ''; | ||
+ | while ($objItems->NextRow()) { | ||
+ | $strGrp = $objItems->GrpDescr; | ||
+ | $qtyStk = $objItems->qtyForSale; | ||
+ | if ($strGrp != $strGrpLast) { | ||
+ | $strGrpLast = $strGrp; | ||
+ | $strGrpCode = $objItems->GrpCode; | ||
+ | $out = '<tr class="group">'; | ||
+ | $out .= '<td colspan=5> — '.$strGrp; | ||
+ | if ($strGrpCode) { | ||
+ | $out .= ' <font color=#666666>(<font color=#666699>'.$strGrpCode.'</font>)</font>'; | ||
+ | } | ||
+ | $out .= '</td>'; | ||
+ | $out .= '</tr>'; | ||
+ | // this should probably be a subroutine... | ||
+ | if ($flagDisplayTogether) { | ||
+ | $txtBoth .= $out; | ||
+ | } else { | ||
+ | if ($qtyStk > 0) { | ||
+ | $txtInStock .= $out; | ||
+ | } else { | ||
+ | $txtOutStock .= $out; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | if ($objItems->isForSale) { | ||
+ | $txtLine = $objItems->Print_TableRow(); | ||
+ | |||
+ | if ($flagDisplayTogether) { | ||
+ | $txtBoth .= $txtLine; | ||
+ | } else { | ||
+ | if ($qtyStk > 0) { | ||
+ | $txtInStock .= $txtLine; | ||
+ | } else { | ||
+ | $txtOutStock .= $txtLine; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // DO the actual display of the accumulated text | ||
+ | |||
+ | $txtTblOpen = '<table class=main><tbody>'; | ||
+ | $txtTblHdr = '<tr><th align=left>Option</th><th>Status</th><th align=right class=title-price>Price</th><th align=center class=orderQty>Order<br>Qty.</th><th><i>list<br>price</th></tr>'; | ||
+ | $txtTblFtr = '<tr><td colspan="4" align="right"><input value="Add to Cart" type="submit"></td></tr>'; | ||
+ | $txtTblShut = '</tbody></table>'; | ||
− | + | if ($flagDisplayTogether) { | |
− | // -- | + | // Display in-stock and backordered items together |
− | + | $objSection->AddText($txtTblOpen); | |
− | + | $objSection->AddText($txtTblHdr); | |
− | // -- | + | $objSection->AddText($txtBoth); |
− | + | $objSection->AddText($txtTblFtr); | |
− | $ | + | $objSection->AddText($txtTblShut); |
− | // | + | } else { |
− | + | if ($txtInStock != '') { | |
− | + | $txtClause = Pluralize($cntInStock,'This item is','These items are'); | |
− | // | + | $objSection->AddText($txtTblOpen); |
− | + | $objSection->AddText('<tr class=inStock><td colspan=5>'.$txtClause.' in stock:</td></tr>'); | |
− | + | $objSection->AddText($txtTblHdr); | |
− | + | $objSection->AddText($txtInStock); | |
− | + | $objSection->AddText($txtTblFtr); | |
− | // | + | $objSection->AddText($txtTblShut); |
− | + | } | |
+ | |||
+ | if ($txtOutStock != '') { | ||
+ | if ($txtInStock != '') { | ||
+ | $objSection->AddText('<p>'); | ||
+ | } | ||
+ | $txtClause = Pluralize($cntOutStock,'This item is','These items are'); | ||
+ | $objSection->AddText($txtTblOpen); | ||
+ | $objSection->AddText('<tr><td colspan=5>'.$txtClause.' <a href="http://wiki.vbz.net/Available_but_not_in_stock"><b>not in stock</b></a>'); | ||
+ | $txtClause = Pluralize($cntOutStock,'it','them'); | ||
+ | $objSection->AddText(', but we can (probably) <a href="http://wiki.vbz.net/Shipping_Policies">get '.$txtClause.'</a>:</td></tr>'); | ||
+ | $objSection->AddText($txtTblHdr); | ||
+ | $objSection->AddText($txtOutStock); | ||
+ | $objSection->AddText($txtTblFtr); | ||
+ | $objSection->AddText($txtTblShut); | ||
+ | } /**/ | ||
+ | } | ||
+ | // $objSection->AddText('<tr><td colspan="4" align="right"><input value="Add to Cart" type="submit"></td></tr></tbody></table></form>'); | ||
+ | $objSection->AddText('</form>'); | ||
+ | } else { | ||
+ | $objSection->SectionHdr('This title is currently unavailable'); | ||
+ | } | ||
+ | return $objSection->out; | ||
+ | } | ||
+ | public function ListImages($iSize) { | ||
+ | $sqlFilt = '(ID_Title='.$this->ID.') AND (Ab_Size="'.$iSize.'")'; | ||
+ | $objImgs = $this->objDB->Images()->GetData($sqlFilt,'clsImage','AttrSort'); | ||
+ | return $objImgs; | ||
+ | } | ||
+ | public function CatNum($iSep='-') { | ||
+ | $objDept = $this->Dept(); | ||
+ | $objSupp = $objDept->Supplier(); | ||
+ | $strDeptKey = $objDept->CatKey; | ||
+ | $strOut = $objSupp->CatKey; | ||
+ | if ($strDeptKey) { | ||
+ | $strOut .= $iSep.$strDeptKey; | ||
+ | } | ||
+ | $strOut .= $iSep.$this->CatKey; | ||
+ | return strtoupper($strOut); | ||
+ | } | ||
+ | public function URL_part() { | ||
+ | return strtolower($this->CatNum('/')); | ||
+ | } | ||
+ | public function URL() { | ||
+ | return KWP_CAT_REL.$this->URL_part(); | ||
+ | } | ||
+ | public function Link() { | ||
+ | $strURL = $this->URL(); | ||
+ | return '<a href="'.$strURL.'">'; | ||
+ | } | ||
+ | public function LinkName() { | ||
+ | return $this->Link().$this->Name.'</a>'; | ||
+ | } | ||
+ | public function LinkName_wt() { | ||
+ | // TO DO: make this more configurable | ||
+ | $out = '[[vbznet:cat/'.$this->URL_part().'|'.$this->Name.']]'; | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | // extended Title data from v_titles | ||
+ | class clsTitlesExt extends clsTitles { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('v_titles'); | ||
+ | $this->KeyName('ID'); | ||
+ | } | ||
+ | protected function _newItem() { | ||
+ | CallStep('clsTitlesExt._newItem()'); | ||
+ | return new clsTitleExt($this); | ||
+ | } | ||
+ | } | ||
+ | // this encapsulates [_titles] instead of [titles] | ||
+ | class clsTitleExt extends clsTitle { | ||
/* | /* | ||
− | + | public $CatNum; | |
+ | public $CatWeb; | ||
+ | public $curMinPrice; | ||
+ | public $curMaxPrice; | ||
+ | public $idItTyp; | ||
+ | public $qtyInStock; | ||
*/ | */ | ||
+ | // action flags | ||
+ | public $dontLoadBasic; | ||
+ | /* | ||
+ | protected function LoadResults() { | ||
+ | CallEnter($this,__LINE__,'clsTitleExt.LoadResults()'); | ||
+ | if (!$this->dontLoadBasic) { | ||
+ | parent::LoadResults(); | ||
+ | } | ||
− | + | $this->CatNum = $this->GetValue('CatNum'); | |
− | + | $this->CatWeb = $this->GetValue('CatWeb'); | |
− | $ | + | $this->currMinPrice = $this->GetValue('currMinPrice'); |
− | + | $this->currMaxPrice = $this->GetValue('currMaxPrice'); | |
− | + | $this->idItTyp = $this->GetValue('ID_ItTyp'); | |
+ | $this->qtyInStock = $this->GetValue('qtyInStock'); | ||
− | + | CallExit('clsTitle.LoadResults()'); | |
− | + | } | |
− | / | + | */ |
− | + | public function Link() { | |
− | + | $out = '<a class="thumb" href="'.$this->URL().'">'; | |
− | // | + | return $out; |
− | // | + | } |
+ | public function URL() { | ||
+ | return KWP_CAT_REL.$this->CatWeb.'/'; | ||
+ | } | ||
+ | } | ||
+ | /* -------------------- *\ | ||
+ | TITLE/ITTYP hybrid | ||
+ | \* -------------------- */ | ||
+ | class clsTitleIttyp extends clsDataSet { | ||
+ | /* | ||
+ | public $ID_ItTyp; | ||
+ | //public $ID_Dept; | ||
+ | public $cntForSale; | ||
+ | public $cntInPrint; | ||
+ | public $cntInStock; | ||
+ | public $qtyInStock; | ||
+ | public $ItTypSng; | ||
+ | public $ItTypPlr; | ||
+ | */ | ||
+ | // object cache | ||
+ | private $objIttyp; | ||
− | // | + | /* |
− | $ | + | protected function LoadResults() { |
− | $ | + | CallEnter($this,__LINE__,'clsTitleIttyp.LoadResults()'); |
− | $ | + | $idItTyp = $this->GetValue('ID_ItTyp'); |
+ | if ($idItTyp != $this->ID_ItTyp) { | ||
+ | $this->ID_ItTyp = $this->GetValue('ID_ItTyp'); | ||
+ | $this->objIttyp = NULL; | ||
+ | } | ||
+ | $this->ID_Title = $this->GetValue('ID_Title'); | ||
+ | //$this->ID_Dept = $this->GetValue('ID_Dept'); | ||
+ | $this->cntForSale = $this->GetValue('cntForSale'); | ||
+ | $this->cntInPrint = $this->GetValue('cntInPrint'); | ||
+ | $this->cntInStock = $this->GetValue('cntInStock'); | ||
+ | $this->qtyInStock = $this->GetValue('qtyInStock'); | ||
+ | $this->ItTypSng = $this->GetValue('ItTyp_Sng'); | ||
+ | $this->ItTypPlr = $this->GetValue('ItTyp_Plr'); | ||
+ | if ($this->ID_ItTyp) { } else { | ||
+ | echo 'ERROR: ID_ItTyp has no value! data = '; | ||
+ | DumpArray($this->Row,TRUE); | ||
+ | } | ||
+ | CallExit('clsTitleIttyp.LoadResults()'); | ||
+ | } | ||
+ | */ | ||
+ | public function Ittyp() { | ||
+ | if (is_null($this->objIttyp)) { | ||
+ | $this->objIttyp = VbzClasses::ItTyps()->GetItem($this->ID_ItTyp); | ||
+ | } | ||
+ | return $this->objIttyp; | ||
+ | } | ||
+ | } | ||
+ | /* -------------------- *\ | ||
+ | ITEM classes | ||
+ | \* -------------------- */ | ||
+ | class clsItems extends clsVbzTable { | ||
− | + | public function __construct($iDB) { | |
− | + | parent::__construct($iDB); | |
− | + | $this->Name('cat_items'); | |
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsItem'); | ||
+ | } | ||
+ | /* | ||
+ | ACTION: Finds the Item with the given CatNum, and returns a clsItem object | ||
+ | */ | ||
+ | public function Get_byCatNum($iCatNum) { | ||
+ | $sqlCatNum = $this->objDB->SafeParam($iCatNum); | ||
+ | $objItem = $this->GetData('CatNum="'.$sqlCatNum.'"'); | ||
+ | if ($objItem->HasRows()) { | ||
+ | $objItem->NextRow(); | ||
+ | return $objItem; | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
} | } | ||
− | if ( | + | /* =============== |
− | + | CLASS: clsItem | |
+ | NOTE: "in stock" always refers to stock for sale, not stock which has already been purchased | ||
+ | */ | ||
+ | class clsItem extends clsDataSet { | ||
+ | // object cache | ||
+ | private $objTitle; | ||
+ | |||
+ | public function Print_TableRow() { | ||
+ | /* | ||
+ | ASSUMES: | ||
+ | This item is ForSale, so isForSale = true and (qtyForSale>0 || isInPrint) = true | ||
+ | This item's data was generated by clsItems_Stock | ||
+ | TO DO: create a separate clsItem_Stock class and move this method there. | ||
+ | */ | ||
+ | $qtyInStock = $this->qtyForSale; | ||
+ | if ($qtyInStock) { | ||
+ | $strClass = 'inStock'; | ||
+ | $strStock = $qtyInStock.' in stock'; | ||
+ | } else { | ||
+ | $strClass = 'noStock'; | ||
+ | } | ||
+ | $out = '<tr class='.$strClass.'><!-- ID='.$this->ID.' -->'; | ||
+ | $out .= '<td> '.$this->ItOpt_Descr; | ||
+ | if ($this->isInPrint) { | ||
+ | if ($qtyInStock) { | ||
+ | $strStatus = $strStock.'; more available'; | ||
+ | } else { | ||
+ | $strStatus = '<a title="explanation..." href="'.KWP_WIKI.'Available_but_not_in_stock">available, not in stock</a>'; | ||
+ | } | ||
+ | } else { | ||
+ | $strStatus = '<b>'.$strStock.'</b> - <i>out of print!</i>'; | ||
+ | } | ||
+ | $out .= '<td>'.$strStatus.'</td>'; | ||
+ | $out .= '<td>'.DataCurr($this->PriceSell).'</td>'; | ||
+ | $out .= '<td>'.'<input size=3 name="qty-'.$this->CatNum.'"></td>'; | ||
+ | if ($this->PriceList) { | ||
+ | $out .= '<td><i>'.DataCurr($this->PriceList).'</i></td>'; | ||
+ | } | ||
+ | $out .= '</tr>'; | ||
+ | return $out; | ||
+ | } | ||
+ | public function Title() { | ||
+ | $doLoad = TRUE; | ||
+ | if (is_object($this->objTitle)) { | ||
+ | if ($this->objTitle->ID == $this->ID_Title) { | ||
+ | $doLoad = FALSE; | ||
+ | } | ||
+ | } | ||
+ | if ($doLoad) { | ||
+ | $this->objTitle = $this->objDB->Titles()->GetItem($this->ID_Title); | ||
+ | } | ||
+ | return $this->objTitle; | ||
+ | } | ||
+ | public function ItTyp() { | ||
+ | $doLoad = TRUE; | ||
+ | if (is_object($this->objItTyp)) { | ||
+ | if ($this->objItTyp->ID == $this->ID_ItTyp) { | ||
+ | $doLoad = FALSE; | ||
+ | } | ||
+ | } | ||
+ | if ($doLoad) { | ||
+ | $this->objItTyp = $this->objDB->ItTyps()->GetItem($this->ID_ItTyp); | ||
+ | } | ||
+ | return $this->objItTyp; | ||
+ | } | ||
+ | public function ItOpt() { | ||
+ | $doLoad = TRUE; | ||
+ | if (is_object($this->objItOpt)) { | ||
+ | if ($this->objItOpt->ID == $this->ID_ItOpt) { | ||
+ | $doLoad = FALSE; | ||
+ | } | ||
+ | } | ||
+ | if ($doLoad) { | ||
+ | $this->objItOpt = $this->objDB->ItOpts()->GetItem($this->ID_ItOpt); | ||
+ | } | ||
+ | return $this->objItOpt; | ||
+ | } | ||
+ | public function ShCost() { | ||
+ | $doLoad = TRUE; | ||
+ | if (is_object($this->objShCost)) { | ||
+ | if ($this->objShCost->ID == $this->ID_ShipCost) { | ||
+ | $doLoad = FALSE; | ||
+ | } | ||
+ | } | ||
+ | if ($doLoad) { | ||
+ | $this->objShCost = $this->objDB->ShipCosts()->GetItem($this->ID_ShipCost); | ||
+ | } | ||
+ | return $this->objShCost; | ||
+ | } | ||
+ | public function ShipPriceItem($iZone) { | ||
+ | global $listItmFactors; | ||
+ | $this->ShCost(); // get the shipping cost object | ||
+ | $fltZoneFactor = $listItmFactors[$iZone]; | ||
+ | return $this->objShCost->PerItem * $fltZoneFactor; | ||
+ | } | ||
+ | public function ShipPricePkg($iZone) { | ||
+ | global $listPkgFactors; | ||
+ | $this->ShCost(); // get the shipping cost object | ||
+ | $fltZoneFactor = $listPkgFactors[$iZone]; | ||
+ | return $this->objShCost->PerPkg * $fltZoneFactor; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* -------------------- *\ | ||
+ | ITEM TYPE classes | ||
+ | \* -------------------- */ | ||
+ | class clsItTyps extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_ittyps'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsItTyp'); | ||
+ | } | ||
+ | } | ||
+ | class clsItTyp extends clsDataSet { | ||
+ | public function Name($iCount=-1) { | ||
+ | if ($iCount == -1) { | ||
+ | $iCount = $this->cntInPrint; | ||
+ | } | ||
+ | if ($iCount == 1) { | ||
+ | return $this->NameSng; | ||
+ | } else { | ||
+ | return $this->NamePlr; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | /* -------------------- *\ | ||
+ | ITEM OPTION classes | ||
+ | \* -------------------- */ | ||
+ | class clsItOpts extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_ioptns'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsItOpt'); | ||
+ | } | ||
+ | } | ||
+ | class clsItOpt extends clsDataSet { | ||
+ | } | ||
+ | /* -------------------- *\ | ||
+ | SHIP COST classes | ||
+ | \* -------------------- */ | ||
+ | class clsShipCosts extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_ship_cost'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsShipCost'); | ||
+ | } | ||
+ | } | ||
+ | class clsShipCost extends clsDataSet { | ||
+ | } | ||
+ | /* -------------------- *\ | ||
+ | STOCK ITEM classes | ||
+ | \* -------------------- */ | ||
+ | // TO DO: explain the difference between clsItems_Stock and clsStkItems | ||
+ | class clsItems_Stock extends clsItems { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('qryCat_Items_Stock'); | ||
+ | $this->KeyName('ID'); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class clsStkItems extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('stk_items'); | ||
+ | $this->KeyName('ID'); | ||
+ | } | ||
+ | public function QtyInStock_forItem($iItemID) { | ||
+ | $sql = 'SELECT SUM(s.Qty) AS Qty FROM stk_items AS s LEFT JOIN stk_bins AS sb ON s.ID_Bin=sb.ID WHERE (s.ID_Item='.$iItemID.') AND (s.WhenRemoved IS NULL) AND (sb.WhenVoided IS NULL) AND (sb.isForSale) GROUP BY s.ID_Item'; | ||
+ | // ** TO DO: maybe this can use a view or one of the calculated tables now? | ||
+ | |||
+ | $objStock = new clsDataItem($this); | ||
+ | $objStock->Query($sql); | ||
+ | if ($objStock->NextRow()) { | ||
+ | assert('is_resource($objStock->Res)'); | ||
+ | if ($objStock->RowCount()) { | ||
+ | assert('$objStock->RowCount() == 1'); | ||
+ | return $objStock->Qty; | ||
+ | } | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | /* -------------------- *\ | ||
+ | IMAGE classes | ||
+ | \* -------------------- */ | ||
+ | class clsImages extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('cat_images'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsImage'); | ||
+ | } | ||
+ | } | ||
+ | class clsImage extends clsDataSet { | ||
+ | // == STATIC SECTION == | ||
+ | const cksTblName = 'cat_images'; | ||
+ | |||
+ | // == DYNAMIC SECTION == | ||
+ | // object cache | ||
+ | private $objTitle; | ||
+ | |||
+ | public function ImgForSize($iSize) { | ||
+ | // ACTION: Get the image with the same title and attribute but with the given size | ||
+ | if ($this->AttrFldr) { | ||
+ | $sqlAttr = '="'.$this->AttrFldr.'"'; | ||
+ | } else { | ||
+ | $sqlAttr = ' IS NULL'; | ||
+ | } | ||
+ | $sqlFilt = '(ID_Title='.$this->ID_Title.') AND (AttrFldr'.$sqlAttr.') AND (Ab_Size="'.$iSize.'")'; | ||
+ | $objImgOut = $this->objDB->Images()->GetData($sqlFilt); | ||
+ | return $objImgOut; | ||
+ | } | ||
+ | public function Title() { | ||
+ | if (!is_object($this->objTitle)) { | ||
+ | $this->objTitle = $this->objDB->Titles()->GetItem($this->ID_Title); | ||
+ | } | ||
+ | return $this->objTitle; | ||
+ | } | ||
+ | public function DoPage() { | ||
+ | global $vbgImgSize; | ||
+ | |||
+ | $objTitle = $this->Title(); | ||
+ | $strCatNum = $objTitle->CatNum(); | ||
+ | $strTitle = $objTitle->Name; | ||
+ | $htmlTitle = KS_STORE_NAME.' - '.$strCatNum.' “'.$strTitle.'”'; | ||
+ | echo '<html><head><title>'.$htmlTitle.'</title></head>'; | ||
+ | echo '<body | ||
+ | bgcolor=000044 | ||
+ | TEXT=CCFFFF | ||
+ | LINK=33FF33 | ||
+ | VLINK=33CCFF | ||
+ | ALINK=FFCC00 | ||
+ | TOPMARGIN=0 | ||
+ | LEFTMARGIN=0 | ||
+ | MARGINWIDTH=0 | ||
+ | MARGINHEIGHT=0 | ||
+ | >'; | ||
+ | echo '<center>'; | ||
+ | echo '<big>'.$strTitle.'</big><br><small>'.$strCatNum.' - title ID #'.$this->ID_Title.'</small>'; | ||
+ | echo '<table border=1><tr><td><table>'; | ||
+ | // show list of available image sizes (except th and sm) | ||
+ | |||
+ | $objImgs = $this->ListImages_sameAttr(); | ||
+ | $strOut = NULL; | ||
+ | if ($objImgs->hasRows()) { | ||
+ | $strImgCount = 0; | ||
+ | while ($objImgs->NextRow()) { | ||
+ | $strImgType = $objImgs->Ab_Size; | ||
+ | if (($strImgType != 'th') && ($strImgType != 'sm')) { | ||
+ | $strImgCount++; | ||
+ | $strDesc = $vbgImgSize[$strImgType]; | ||
+ | if ($objImgs->ID == $this->ID) { | ||
+ | $strImgTag = '<b>'.$strDesc.'</b>'; | ||
+ | } else { | ||
+ | $strImgTag = $objImgs->Href(TRUE).$strDesc.'</a>'; | ||
+ | } | ||
+ | if ($strOut) { | ||
+ | $strOut .= ' .. '; | ||
+ | } | ||
+ | $strOut .= $strImgTag; | ||
+ | } | ||
+ | } | ||
+ | if ($strImgCount > 1) { | ||
+ | echo '<tr><td><font color=#aaaaaa>sizes</font> :</td><td align=center>'.$strOut.'</td><td>: <font color=#aaaaaa>sizes</font></td></tr>'; | ||
+ | } | ||
+ | } | ||
+ | $strOut = NULL; | ||
+ | |||
+ | // show list of available images for this title at this size | ||
+ | $objImgs = $this->ListImages_sameSize(); | ||
+ | if ($objImgs->NextRow()) { | ||
+ | $strImgCount = 0; | ||
+ | $strOut .= ''; | ||
+ | if ($objImgs->hasRows()) { | ||
+ | while ($objImgs->NextRow()) { | ||
+ | $strImgFldr = $objImgs->AttrFldr; | ||
+ | $strImgDescr = $objImgs->AttrDispl; | ||
+ | $strImgCount++; | ||
+ | if ($strOut) { | ||
+ | $strOut .= ' .. '; | ||
+ | } | ||
+ | if ($objImgs->ID == $this->ID) { | ||
+ | $strOut .= '<b>'.$strImgDescr.'</b>'; | ||
+ | } else { | ||
+ | $strOut .= $objImgs->Href(TRUE).$strImgDescr.'</a>'; | ||
+ | } | ||
+ | } | ||
+ | if ($strImgCount > 1) { | ||
+ | echo '<tr><td><font color=#aaaaaa>views</font> :</td><td align=center>'.$strOut.'</td><td>: <font color=#aaaaaa>views</font></td></tr>'; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | echo '</table></td></tr></table>'; | ||
+ | echo $objTitle->Link().'ordering page</a><br>'; | ||
+ | echo $this->ImgSrc(); | ||
+ | echo '</body></html>'; | ||
+ | } | ||
+ | public function ListImages_sameAttr() { | ||
+ | if ($this->AttrFldr) { | ||
+ | $sqlFilt = '(ID_Title='.$this->ID_Title.') AND (AttrFldr="'.$this->AttrFldr.'")'; | ||
+ | } else { | ||
+ | $sqlFilt = '(ID_Title='.$this->ID_Title.')'; | ||
+ | } | ||
+ | $objImgOut = $this->objDB->Images()->GetData($sqlFilt); | ||
+ | |||
+ | return $objImgOut; | ||
+ | } | ||
+ | public function ListImages_sameSize() { | ||
+ | $sqlFilt = '(ID_Title='.$this->ID_Title.') AND (Ab_Size="'.$this->Ab_Size.'")'; | ||
+ | $objImgOut = $this->objDB->Images()->GetData($sqlFilt); | ||
+ | return $objImgOut; | ||
+ | } | ||
+ | public function Href($iAbs=false) { | ||
+ | $strFldrRel = $this->AttrFldr; | ||
+ | if ($strFldrRel) { | ||
+ | $strFldrRel .= '-'; | ||
+ | } | ||
+ | $strFldrRel .= $this->Ab_Size; | ||
+ | |||
+ | if ($iAbs) { | ||
+ | $strFldr = $this->Title()->URL().'/'.$strFldrRel; | ||
+ | } else { | ||
+ | $strFldr = $strFldrRel; | ||
+ | } | ||
+ | |||
+ | return '<a href="'.$strFldr.'/">'; | ||
+ | } | ||
+ | public function ImgSrc() { | ||
+ | return '<img src="'.KWP_IMG_MERCH.$this->Spec.'">'; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* ------------------ *\ | ||
+ | CATALOG BROWSING | ||
+ | \* ------------------ */ | ||
+ | class clsTopics extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('brs_topics'); | ||
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsTopic'); | ||
+ | } | ||
+ | public function DoIndex() { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | CallEnter($this,__LINE__,'clsTopics.DoIndex()'); | ||
+ | $objSection = new clsPageOutput(); | ||
+ | |||
+ | $objTopics = $this->GetData('ID_Parent IS NULL',NULL,'Sort,Name,NameTree'); | ||
+ | while ($objTopics->NextRow()) { | ||
+ | if ($isFirst) { | ||
+ | $isFirst = false; | ||
+ | $objSection->SectionHdr('Root Topics'); | ||
+ | } else { | ||
+ | $objSection->AddText($objTopics->Name.'<br>'); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | CallExit('clsTopic.DoIndex()'); | ||
+ | return $objSection->out; | ||
+ | } | ||
+ | } | ||
+ | class clsTopic extends clsDataSet { | ||
+ | /* | ||
+ | public $ID_Parent; | ||
+ | public $Name; | ||
+ | public $NameTree; | ||
+ | public $NameFull; | ||
+ | public $Variants; | ||
+ | public $Mispeled; | ||
+ | |||
+ | protected function LoadResults() { | ||
+ | CallEnter($this,__LINE__,'clsTopic.LoadResults()'); | ||
+ | $this->ID = $this->GetValue('ID'); | ||
+ | $this->ID_Parent = $this->GetValue('ID_Parent'); | ||
+ | $this->Name = $this->GetValue('Name'); | ||
+ | $this->NameTree = $this->GetValue('NameTree'); | ||
+ | $this->NameFull = $this->GetValue('NameFull'); | ||
+ | $this->Variants = $this->GetValue('Variants'); | ||
+ | $this->Mispeled = $this->GetValue('Mispeled'); | ||
+ | assert('$this->ID'); | ||
+ | CallExit('clsTopic.LoadResults()'); | ||
+ | } | ||
+ | */ | ||
+ | |||
+ | public function DoPage() { | ||
+ | global $objDataMgr; | ||
+ | |||
+ | CallEnter($this,__LINE__,'clsTopic.DoPage()'); | ||
+ | assert('$this->ID'); | ||
+ | $objSection = new clsPageOutput(); | ||
+ | |||
+ | $objTitles = $this->objDB->DataSet('SELECT * FROM brs_titles_x_topics WHERE ID_Topic='.$this->ID); | ||
+ | while ($objTitles->NextRow()) { | ||
+ | if ($isFirst) { | ||
+ | $isFirst = false; | ||
+ | $objSection->SectionHdr('Titles'); | ||
+ | } else { | ||
+ | $objSection->AddText($objTitles->Name.'<br>'); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | CallExit('clsTopic.DoPage()'); | ||
+ | return $out; | ||
+ | } | ||
+ | public function WebName() { | ||
+ | return sprintf(KS_FMT_TOPICID,$this->ID); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* ------------------ *\ | ||
+ | EVENT LOGGING | ||
+ | \* ------------------ */ | ||
+ | class clsEvents extends clsVbzTable { | ||
+ | public function __construct($iDB) { | ||
+ | assert('is_object($iDB)'); | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('event_log'); | ||
+ | $this->KeyName('ID'); | ||
+ | } | ||
+ | |||
+ | public function LogEvent($iWhere,$iParams,$iDescr,$iCode,$iIsError,$iIsSevere) { | ||
+ | global $sql, $vgUserName; | ||
+ | |||
+ | $sql = 'INSERT INTO `'.$this->Name().'` (EvWhen,EvWhere,Params,Descr,Code,VbzUser,SysUser,Machine,isError,isSevere)'. | ||
+ | 'VALUES(NOW(),"'.$iWhere.'","'.$iParams.'","'.$iDescr.'",'.SQLValue($iCode).','.SQLValue($vgUserName). | ||
+ | ',NULL,"'. | ||
+ | $_ENV['REMOTE_ADDR'].'",'. | ||
+ | ($iIsError?'TRUE':'FALSE').','. | ||
+ | ($iIsSevere?'TRUE':'FALSE').');'; | ||
+ | $this->objDB->Exec($sql); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* ==================== *\ | ||
+ | UTILITY FUNCTIONS | ||
+ | \* ==================== */ | ||
+ | |||
+ | function DataCents($iCents,$iPfx='$') { | ||
+ | $out = $iPfx.sprintf("%01.2f",$iCents/100); | ||
+ | return $out; | ||
+ | } | ||
+ | function DataCurr($iCurr,$iPfx='$') { | ||
+ | $out = $iPfx.sprintf("%01.2f",$iCurr); | ||
+ | return $out; | ||
+ | } | ||
+ | function DataDate($iDate) { | ||
+ | if (is_string($iDate)) { | ||
+ | $objDate = new DateTime($iDate); | ||
+ | // if ($iDate == 0) { | ||
+ | // $out = ''; | ||
+ | // } else { | ||
+ | // $out = date('Y-m-d',$iDate); | ||
+ | $out = $objDate->format('Y-m-d'); | ||
+ | } else { | ||
+ | $out = ''; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | function DataDateTime($iDate) { | ||
+ | if (is_string($iDate)) { | ||
+ | if ($iDate == '') { | ||
+ | $out = '-'; | ||
+ | } else { | ||
+ | $objDate = new DateTime($iDate); | ||
+ | $out = $objDate->format('Y-m-d H:i'); | ||
+ | } | ||
+ | } else { | ||
+ | $out = ''; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | function IsEmail($iAddr) { | ||
+ | $ok = preg_match('/.{1}.*[\@].{1}.*[\.][a-z]{2}.*/i', $iAddr ); | ||
+ | return $ok; | ||
+ | } | ||
+ | |||
+ | /* ==================== *\ | ||
+ | MISSING FUNCTIONS | ||
+ | \* ==================== */ | ||
+ | if (!function_exists('http_redirect')) { | ||
+ | function http_redirect($iURL) { | ||
+ | header('Status: 301 Moved Permanently',TRUE); | ||
+ | header('Location: '.$iURL,TRUE); | ||
+ | } | ||
} | } | ||
</php> | </php> |
Revision as of 12:21, 6 October 2009
About
- Purpose: Classes for displaying different types of catalog display pages
- History:
- 2009-03-07 Transcribed from working code at vbz.net
- To Do:
- should be split up into auto-loadable class files, e.g. vbz.title.php, vbz.dept.php, etc.
- "clsFactory" should be eliminated in favor of static functions for each class
Code - store.php
<php><?php /*
FILE: store.php PURPOSE: vbz class library - should eventually be subdivided HISTORY: 2009-07-11 (Wzl) Lots of cleanup; added types and methods needed for shopping cart page
- /
//define('kfpHostAcctRoot','/hsphere/local/home/hypertwi/'); //define('kfpMediaWiki',kfpHostAcctRoot.'wiki.vbz.net/'); define('kEmbeddedPagePrefix','embed:');
if (defined( '__DIR__' )) {
$fpThis = __DIR__;
} else {
$fpThis = dirname(__FILE__);
} if (!defined('LIBMGR')) {
require('libmgr.php');
} clsLibMgr::Add('datamgr',$fpThis.'/datamgr.php'); clsLibMgr::Load('datamgr');
define('EN_PGTYPE_NOTFND',-1); // requested item (supp/dept/title) not found define('EN_PGTYPE_HOME',1); // catalog home page define('EN_PGTYPE_SUPP',2); // supplier page define('EN_PGTYPE_DEPT',3); // department page, or possibly title for keyless dept define('EN_PGTYPE_TITLE',4); // title page // table names // - caching define('ksTbl_cache_tables','data_tables'); define('ksTbl_cache_procs','data_procs'); define('ksTbl_cache_flow','data_flow'); define('ksTbl_cache_log','data_log'); // - stock define('ksTbl_stock_places','stk_places'); define('ksTbl_stock_bins','stk_bins'); define('ksQry_stock_bins_wInfo','qryStk_Bins_w_info'); define('ksTbl_stock_items','stk_items'); define('ksTbl_stock_hist_items','stk_history'); define('ksTbl_stock_hist_bins','stk_bin_history');
$vbgImgSize = array(
'th' => 'thumbnail', 'sm' => 'small', 'big' => 'large', 'huge' => 'huge', 'zoom' => 'detail');
// shipping charge adjustment factors by destination zone: $listShipListDesc['US'] = 'United States'; $listShipListDesc['CA'] = 'Canada'; $listShipListDesc['INT'] = 'International'; $listPkgFactors['US'] = 1.0; $listItmFactors['US'] = 1.0; $listPkgFactors['CA'] = 2.0; $listItmFactors['CA'] = 2.0; $listPkgFactors['INT'] = 4.0; $listItmFactors['INT'] = 4.0; // The above is just until we have something more exact and dynamic
$intCallDepth = 0;
// CALCULATED GLOBALS $fpTools = '/tools'; $fpPages = ; $fwpAbsPages = 'http://'.KS_PAGE_SERVER.$fpPages; $fwpAbsTools = 'http://'.KS_TOOLS_SERVER.$fpTools; $fwpCart = $fwpAbsPages.'/cart/'; $strCurServer = $_ENV['SERVER_NAME'];
// SET UP DEPENDENT VALUES /* if ($strCurServer != KS_TOOLS_SERVER) {
$fpTools = $fwpAbsTools; $fpPages = $fwpAbsPages;
}
- /
$fwpLogo = $fpTools.'/img/logos/v/';
class clsVbzData extends clsDatabase {
private $objPages;
public function __construct($iSpec) { global $objDataMgr;
parent::__construct($iSpec); $objDataMgr = new clsDataMgr($this,ksTbl_cache_tables,ksTbl_cache_procs,ksTbl_cache_flow,ksTbl_cache_log); $this->Open(); }
// generic object-creation function
protected function Make($iName) { if (!isset($this->$iName)) { $this->$iName = new $iName($this); } return $this->$iName; }
// table-specific functions
public function Pages() { return $this->Make('clsCatPages'); } public function Suppliers() { return $this->Make('clsSuppliers'); } public function Depts() { return $this->Make('clsDepts'); } public function Titles() { return $this->Make('clsTitles'); } public function TitlesExt() { return $this->Make('clsTitlesExt'); } public function Items() { return $this->Make('clsItems'); } public function Items_Stock() { return $this->Make('clsItems_Stock'); } public function ItTyps() { return $this->Make('clsItTyps'); } public function ItOpts() { return $this->Make('clsItOpts'); } public function ShipCosts() { return $this->Make('clsShipCosts'); } public function Images() { return $this->Make('clsImages'); } public function StkItems() { return $this->Make('clsStkItems'); } public function Topics() { return $this->Make('clsTopics'); } public function Events() { return $this->Make('clsEvents'); } public function LogEvent($iWhere,$iParams,$iDescr,$iCode,$iIsError,$iIsSevere) { return $this->Events()->LogEvent($iWhere,$iParams,$iDescr,$iCode,$iIsError,$iIsSevere); }
// Page output routines
public function SectionHdr($iTitle) {
$out = '
'.$iTitle.'
';
return $out; } public function ShowTitles($iHdrText,$iList,$objNoImgSect) { $cntImgs = 0; $outImgs = ; foreach ($iList as $i => $objTitleData) { $objTitle = $this->Titles()->GetItem($objTitleData->ID); $objImgs = $objTitle->ListImages('th'); $currMinPrice = $objTitleData->currMinPrice; $currMaxPrice = $objTitleData->currMaxPrice; $strPrice = DataCurr($currMinPrice); if ($currMinPrice != $currMaxPrice) { $strPrice .= '-'.DataCurr($currMaxPrice); } assert('is_resource($objImgs->Res)'); if ($objImgs->RowCount()) { $cntImgs++;
$strCatNum = $objTitleData->CatNum;
$strTitleTag = '"'.$objTitle->Name.'" ('.$strCatNum.')'; $strTitleLink = $objTitle->Link(); while ($objImgs->NextRow()) { $strImgTag = $strTitleTag.' - '.$strPrice;
$qtyStk = $objTitleData->qtyForSale;
if ($qtyStk) { $strImgTag .= ' - '.$qtyStk.' in stock'; } $outImgs .= $strTitleLink.'<img class="thumb" src="'.KWP_IMG_MERCH.'/'.$objImgs->Spec.'" title="'.$strImgTag.'"></a>'; } } else { if (!$objNoImgSect->inTbl) { $objNoImgSect->StartTable('titles without images:');
$objNoImgSect->AddText('Cat. #TitlePrice
Rangeto
orderstatus');
} $objNoImgSect->RowStart(); $objNoImgSect->ColAdd(''.$objTitleData->CatNum.''); $objNoImgSect->ColAdd($objTitle->Name); $objNoImgSect->ColAdd($strPrice); $objNoImgSect->ColAdd('['.$objTitle->Link().'order</a>]'); $qtyStk = $objTitleData->qtyForSale; if ($qtyStk) { $strStock = ''.$qtyStk.' in stock'; $objNoImgSect->ColAdd($strStock); if ($objTitleData->cntInPrint == 0) { $objNoImgSect->ColAdd('OUT OF PRINT!'); } } else { $objNoImgSect->ColAdd('<a title="explanation..." href="'.KWP_WIKI.'Available_but_not_in_stock">available, not in stock</a>');
// Debugging: // $objNoImgSect->ColAdd('ID_Title='.$objTitle->ID.' ID_ItTyp='.$objTitle->idItTyp);
} $objNoImgSect->RowStop(); } } $out = ; if ($cntImgs) { $out .= $this->SectionHdr($iHdrText); $out .= $outImgs; } return $out; }
}
class clsList {
public $List;
public function Add($iName, $iValue=NULL) { $objItem = new clsListItem($iName,$iValue); $this->List[] = $objItem; return $objItem; } public function Output($iPfx, $iSep, $iSfx) { $out = NULL; if (is_array($this->List)) { foreach ($this->List as $objItem) { if (is_null($objItem->value)) { $out .= $iPfx.$iSep.$objItem->name.$iSfx; } else { $out .= $iPfx.$objItem->name.$iSep.$objItem->value.$iSfx; } } } return $out; }
} class clsListItem {
public $name; public $value;
public function __construct($iName, $iValue=NULL) { $this->name = $iName; $this->value = $iValue; }
}
/* ===================
CLASS: clsPage PURPOSE: Handles display of different page types
- /
class clsPage extends clsVbzData { // 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($iSpec) { parent::__construct($iSpec); $this->lstTop = new clsList(); }
public function GetQuery() {
// ACTION: Retrieves request from URL and parses it
if (isset($_SERVER['PATH_INFO'])) {
$strReq = $_SERVER['PATH_INFO'];
} else {
$strReq = ;
} $this->strReq = $strReq;
// $pathinfo = $_SERVER['REQUEST_URI'];
if (strrpos($strReq,'/')+1 < strlen($strReq)) { $strRedir = KWP_CAT_REL.substr($strReq,1).'/'; header('Location: '.$strRedir); exit; // retry with new URL } $this->ParseQuery(); } public function ParseQuery() {
// This is essentially an abstract function // Define any additional parsing of the query (store member vars etc.)
// global $objFactory;
// $strReq = $this->strReq;
// $this->objCatPage = $objFactory->Pages()->GetItem_byKey($strReq);
//print 'REQ='.$strReq.' ABBR='.$this->objCatPage->AB;
}
// DIFFERENT TYPES OF PAGES
protected function DoNotFound() {
// $this->Setup(,'Unknown Title','unknown title in catalog','browse','Tomb of the...');
$this->strWikiPg = ; $this->strTitle = 'Unknown Page'; $this->strName = 'unknown title in catalog'; $this->strTitleContext = 'Tomb of the...'; $this->strHdrXtra = ;
$this->strSideXtra = '
- Framework
$this->DoSepBar();echo '
';
$fltExecTime = microtime(true)-$fltStart; $dat = getrusage(); $fltUserTime = $dat["ru_utime.tv_usec"]/1000000; $strServer = $_SERVER['SERVER_SOFTWARE']; echo $strServer.' .. '; echo 'PHP '.phpversion().' .. Generated in '.$fltUserTime.' seconds (script execution '.$fltExecTime.' sec.) .. '; $strWikiPg = $this->strWikiPg; if ($strWikiPg) { echo 'wiki: <a href="'.KWP_WIKI.kEmbeddedPagePrefix.$this->strWikiPg.'">'.$strWikiPg.'</a> .. '; } echo date('Y-m-d H:i:s');echo ' |
$didPage = true; } private function DoWikiContent() {
- WIKI CONTENTS
- $txtPage = GetEmbedPage('cat');
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) {
// print ''.$txtPage.'
';
'.$txtWiki.' |
} } } protected function DoSidebar() { global $fpTools,$objDataMgr;
// TO DO: these should be pulled from the [stats] table if ($objDataMgr->dtNewest) {
$timeSidebarBuild=$objDataMgr->dtNewest;
} else {
$timeSidebarBuild = NULL;
} $statsQtyTitlesAvail = 2245; $statsQtyStockPieces = 1395; $statsQtyStockItems = 753; $statsQtyArtists = 136; $statsQtyTopics = 1048; //---------
echo '';
?>
|
} private function DoSepBar() { global $fpTools;
echo '<img src="'.$fpTools.'/img/bg/hlines/" alt="-----" width="100%">'; } private function ToolbarItem($iURL,$iIcon,$iTitle,$iAlt) { global $fpTools; return '<a href="'.$iURL.'"><img border=0 src="'.$fpTools.'/img/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_WIKI.'help','help','help!','help'); }
// -- HEADER
protected function DoHeader() { global $fpTools, $fwpLogo;
$strWikiPg = $this->strWikiPg; $this->strCalcTitle = KS_STORE_NAME.' - '.$this->strName; $htmlHead = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'; $htmlHead .= ''.$this->strCalcTitle.' '; if ($this->strSheet) { $htmlHead .= ''; } # remove any quotes from $pageName: $htmlName = str_replace('"','"',$this->strName); if ($htmlName) { $htmlName = ': '.$htmlName; } $htmlHead .= ''; $htmlHead .= ''; echo $htmlHead; ?> '; echo ''; // === LEFT HEADER: Title === echo ''; // === END LEFT HEADER === // === RIGHT HEADER: nav icons === echo ''; // === END RIGHT HEADER === ?>
';
echo '';
if ($this->strTitleContext) {
echo ''.KS_STORE_NAME.': '.$this->strTitleContext.' '; } echo ''.$this->strTitle.' | '; $this->DoToolbar(); echo ' |
'.$iTitle.'
'; return $this->out; } function StartTable($iTitle) { if ($iTitle) { $this->SectionHdr($iTitle); $this->out .= ''; $this->inTbl++; } } function RowStart($iClass='') { if ($iClass) { $this->out .= ''; } else { $this->out .= ''; } } function RowStop() { $this->out .= ''; $this->isOdd = !$this->isOdd; } function ColAdd($iText) { if ($this->isOdd) { $cellOpen = ''; } function EndTable() { if ($this->inTbl) { $this->out .= ''; } else { $cellOpen = ' | '; } $this->out .= $cellOpen.$iText.' |
|
Departments:
'; $objDepts = $this->GetData('ID_Supplier='.$iSuppID,'clsDept'); $isFirst = true; $isOdd = FALSE; while ($objDepts->NextRow()) { $outDept = $objDepts->DoListing(); if ($outDept) { // only show departments with something in them if ($isOdd) { $cellOpen = ''.$cellOpen.''.$objDepts->Name.''; $isOdd = !$isOdd; $out .= $cellOpen.$outDept.''; } } $out .= ''; } else { $cellOpen = ' | '; } $keyDept = $objDepts->PageKey(); $out .= ' |
'.$strCatNum.' - title ID #'.$this->ID_Title.''; echo '
';
// show list of available image sizes (except th and sm)
$objImgs = $this->ListImages_sameAttr();
$strOut = NULL;
if ($objImgs->hasRows()) {
$strImgCount = 0;
while ($objImgs->NextRow()) {
$strImgType = $objImgs->Ab_Size;
if (($strImgType != 'th') && ($strImgType != 'sm')) {
$strImgCount++;
$strDesc = $vbgImgSize[$strImgType];
if ($objImgs->ID == $this->ID) {
$strImgTag = ''.$strDesc.'';
} else {
$strImgTag = $objImgs->Href(TRUE).$strDesc.'';
}
if ($strOut) {
$strOut .= ' .. ';
}
$strOut .= $strImgTag;
}
}
if ($strImgCount > 1) {
echo '';
}
}
$strOut = NULL;
// show list of available images for this title at this size
$objImgs = $this->ListImages_sameSize();
if ($objImgs->NextRow()) {
$strImgCount = 0;
$strOut .= '';
if ($objImgs->hasRows()) {
while ($objImgs->NextRow()) {
$strImgFldr = $objImgs->AttrFldr;
$strImgDescr = $objImgs->AttrDispl;
$strImgCount++;
if ($strOut) {
$strOut .= ' .. ';
}
if ($objImgs->ID == $this->ID) {
$strOut .= ''.$strImgDescr.'';
} else {
$strOut .= $objImgs->Href(TRUE).$strImgDescr.'';
}
}
if ($strImgCount > 1) {
echo '';
}
}
}
echo '
|
'; echo $this->ImgSrc(); echo ''; } public function ListImages_sameAttr() { if ($this->AttrFldr) { $sqlFilt = '(ID_Title='.$this->ID_Title.') AND (AttrFldr="'.$this->AttrFldr.'")'; } else { $sqlFilt = '(ID_Title='.$this->ID_Title.')'; } $objImgOut = $this->objDB->Images()->GetData($sqlFilt);
return $objImgOut; } public function ListImages_sameSize() { $sqlFilt = '(ID_Title='.$this->ID_Title.') AND (Ab_Size="'.$this->Ab_Size.'")'; $objImgOut = $this->objDB->Images()->GetData($sqlFilt); return $objImgOut; } public function Href($iAbs=false) { $strFldrRel = $this->AttrFldr; if ($strFldrRel) { $strFldrRel .= '-'; } $strFldrRel .= $this->Ab_Size;
if ($iAbs) { $strFldr = $this->Title()->URL().'/'.$strFldrRel; } else { $strFldr = $strFldrRel; }
return '<a href="'.$strFldr.'/">'; } public function ImgSrc() { return '<img src="'.KWP_IMG_MERCH.$this->Spec.'">'; }
}
/* ------------------ *\
CATALOG BROWSING
\* ------------------ */ class clsTopics extends clsVbzTable {
public function __construct($iDB) { parent::__construct($iDB); $this->Name('brs_topics'); $this->KeyName('ID'); $this->ClassSng('clsTopic'); } public function DoIndex() { global $objDataMgr;
CallEnter($this,__LINE__,'clsTopics.DoIndex()'); $objSection = new clsPageOutput();
$objTopics = $this->GetData('ID_Parent IS NULL',NULL,'Sort,Name,NameTree'); while ($objTopics->NextRow()) { if ($isFirst) { $isFirst = false; $objSection->SectionHdr('Root Topics'); } else { $objSection->AddText($objTopics->Name.'
'); } }
CallExit('clsTopic.DoIndex()'); return $objSection->out; }
} class clsTopic extends clsDataSet { /*
public $ID_Parent; public $Name; public $NameTree; public $NameFull; public $Variants; public $Mispeled;
protected function LoadResults() { CallEnter($this,__LINE__,'clsTopic.LoadResults()'); $this->ID = $this->GetValue('ID'); $this->ID_Parent = $this->GetValue('ID_Parent'); $this->Name = $this->GetValue('Name'); $this->NameTree = $this->GetValue('NameTree'); $this->NameFull = $this->GetValue('NameFull'); $this->Variants = $this->GetValue('Variants'); $this->Mispeled = $this->GetValue('Mispeled'); assert('$this->ID'); CallExit('clsTopic.LoadResults()'); }
- /
public function DoPage() { global $objDataMgr;
CallEnter($this,__LINE__,'clsTopic.DoPage()'); assert('$this->ID'); $objSection = new clsPageOutput();
$objTitles = $this->objDB->DataSet('SELECT * FROM brs_titles_x_topics WHERE ID_Topic='.$this->ID); while ($objTitles->NextRow()) { if ($isFirst) { $isFirst = false; $objSection->SectionHdr('Titles'); } else { $objSection->AddText($objTitles->Name.'
'); } }
CallExit('clsTopic.DoPage()'); return $out; } public function WebName() { return sprintf(KS_FMT_TOPICID,$this->ID); }
}
/* ------------------ *\
EVENT LOGGING
\* ------------------ */ class clsEvents extends clsVbzTable {
public function __construct($iDB) { assert('is_object($iDB)'); parent::__construct($iDB); $this->Name('event_log'); $this->KeyName('ID'); }
public function LogEvent($iWhere,$iParams,$iDescr,$iCode,$iIsError,$iIsSevere) { global $sql, $vgUserName;
$sql = 'INSERT INTO `'.$this->Name().'` (EvWhen,EvWhere,Params,Descr,Code,VbzUser,SysUser,Machine,isError,isSevere)'.
'VALUES(NOW(),"'.$iWhere.'","'.$iParams.'","'.$iDescr.'",'.SQLValue($iCode).','.SQLValue($vgUserName). ',NULL,"'. $_ENV['REMOTE_ADDR'].'",'. ($iIsError?'TRUE':'FALSE').','. ($iIsSevere?'TRUE':'FALSE').');';
$this->objDB->Exec($sql); }
}
/* ==================== *\
UTILITY FUNCTIONS
\* ==================== */
function DataCents($iCents,$iPfx='$') {
$out = $iPfx.sprintf("%01.2f",$iCents/100); return $out;
} function DataCurr($iCurr,$iPfx='$') {
$out = $iPfx.sprintf("%01.2f",$iCurr); return $out;
} function DataDate($iDate) {
if (is_string($iDate)) { $objDate = new DateTime($iDate);
// if ($iDate == 0) { // $out = ; // } else { // $out = date('Y-m-d',$iDate);
$out = $objDate->format('Y-m-d'); } else { $out = ; } return $out;
} function DataDateTime($iDate) {
if (is_string($iDate)) {
if ($iDate == ) { $out = '-'; } else { $objDate = new DateTime($iDate); $out = $objDate->format('Y-m-d H:i'); }
} else { $out = ; } return $out;
} function IsEmail($iAddr) {
$ok = preg_match('/.{1}.*[\@].{1}.*[\.][a-z]{2}.*/i', $iAddr ); return $ok;
}
/* ==================== *\
MISSING FUNCTIONS
\* ==================== */ if (!function_exists('http_redirect')) {
function http_redirect($iURL) {
header('Status: 301 Moved Permanently',TRUE); header('Location: '.$iURL,TRUE);
}
} </php>