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 ' '; } 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>