# shop.ws3 - Example shop application for websh3
# nca-073-9
#
# Copyright (C) 2000 by Netcetera AG.
# Copyright (C) 2001 by the Apache Software Foundation.
# All rights reserved.
#
# @(#) $Id$
#
#
# ------------------------------------------------------------------------------
# util proc and HTML abstractions
# ------------------------------------------------------------------------------
# create a form tag
proc createForm {action code} {
web::put "
"
}
# creates a table tag
proc table {width attributes code} {
web::put "
tag plus a put command
proc tdPut {text} {
tdtd { web::put "$text"}
}
# create a font tag and put
proc fontPut {size str} {
font $size {web::put "$str"}
}
# create a table data tag, font tag and put command
proc tdFontPut {size str} {
tdtd { fontPut $size $str}
}
# create a table data, font, input form and put
proc tdFontPutInputfield {size type name value {inputsize ""} {text ""}} {
tdtd { font $size {
inputfield $type $name $value $inputsize
web::put "$text"
}}
}
# create a input form
proc inputfield {type name value {size -1}} {
web::put " 0} {
web::put " SIZE=\"$size\""
}
web::put ">"
}
# create a form submit button
proc inputSubmit {name value} {
inputfield submit $name $value
}
# sets the font class name
proc setFontClass {size} {
switch $size {
5 {set css "ShopStyleXLarge"}
3 {set css "ShopStyleLarge" }
error {set css "ShopStyleError" }
white {set css "ShopStyleWhite" }
default {set css "ShopStyle" }
}
}
proc createCSS {styleName fontFamily fontSize {color {black}} {fontWeight {standard}}} {
web::put "
\.$styleName \{
font-family\: $fontFamily\;
font-size\: $fontSize\;
color\: $color\;
font-weight\: $fontWeight\;
\}
"
}
# create a font tag
proc font {size code} {
web::put "\n"
uplevel $code
web::put "\n"
}
# create a link tag
proc linkIt {url val} {
return "$val"
}
# creates a tag
proc br {{max 1}} {
set count 0
while {$count < $max} {
web::put " "
incr count
}
}
proc space {{max 1}} {
set count 0
while {$count < $max} {
web::put "\ \;"
incr count
}
}
proc hr {} {
web::put ""
}
# changes the row color
proc rowColorChanger {rowColor} {
if {[string equal $rowColor [cget firstRowColor]]} {
set rowColor [cget secondRowColor]
} else {
set rowColor [cget firstRowColor]
}
return $rowColor
}
# calculate the total price of the shop bag
proc getTotalPrice {} {
uplevel {set totPrice [expr $totPrice + [proddata::cget price] * \
[shopbag::cget prod($prodID) 0]]}
}
# gets the image from the product
proc getImage {imageFile} {
set imageFile "[file join [cget pimagesDir] $imageFile].gif"
if {[catch {set fh [open "$imageFile" r]
fconfigure $fh -translation binary
set imageData [read $fh]
close $fh} errMsg]} {
putErrorMessage $errMsg
}
web::response -set header Content-Type image/gif
fconfigure [web::response] -translation binary
web::put $imageData
web::log debug "getImage: got done"
}
# is doing a glob in the entered directory
proc getFileList {typ} {
set var [glob -nocomplain [file join [cget catalogueDir] $typ*.dat]]
return $var
}
# gets the session id from a file
proc getSessionIdFromFileName {tag filename} {
set fn [file tail $filename]
if {[string equal [string index $fn 0] $tag]} {
set id [scan $fn $tag%d.dat]
} else {
error "not found"
}
return $id
}
proc displayProductList {from} {
table 600 "ALIGN=\"left\" CELLPADDING=\"0\" CELLSPACING=\"0\"" {
set prodfile [getFileList p]
set rowColor "[cget firstRowColor]"
trtrAttr "bgcolor=\"\#000000\"" {
tdFontPut white "\ \;\ \;Product name"
tdFontPut white "description"
tdFontPut white "price"
tdFontPut white "add to bag"
}
foreach item $prodfile {
set p_id [getSessionIdFromFileName p $item]
proddata::init $p_id
# check if the product is
# assigned to the root category
if {[string equal [proddata::cget category] $from]} {
trtrAttr "bgcolor=\"$rowColor\"" {
tdFontPut 2 " \
[linkIt "[web::cmdurl showDetail [list pid $p_id]]" \
"[web::htmlify [proddata::cget name]]"]"
tdFontPut 2 "[web::htmlify [proddata::cget sdesc]]"
tdFontPut 2 "[web::htmlify [proddata::cget price]]"
tdFontPut 2 "[linkIt " \
[web::cmdurl addShopBag [list pid $p_id]]" \
"" ]"
# change the row color
set rowColor [rowColorChanger $rowColor]
}
}
}
}
}
proc fileCounter {counterName fileName} {
web::filecounter $counterName \
-filename [file join [cget shopdata] $fileName]
}
proc fileContext {contextName path idgen attachto {logMessage {created shopbag path: [file join [cget shopdata] $path]}}} {
web::filecontext $contextName\
-path [file join [cget shopdata] $path] \
-idgen "$idgen nextval" \
-attachto $attachto
web::log *.-debug "$logMessage"
}
proc imgSrc {fileName {attributes {}}} {
web::put ""
}
# -----------------------------------------------------------------------
# application part
# -----------------------------------------------------------------------
# default procedure - displays the welcome screen
proc welcomeForm {} {
page "Welcome" {
table "600" "ALIGN=\"left\" CELLPADDING=\"0\" CELLSPACING=\"0\"" {
trtr {
tdtd {
br
imgSrc "[file join [cget imagePath]content_t.gif]" "ALIGN=\"right\""
br 4
web::log *.-debug "catalogue Dir: [file join [cget catalogueDir] c*]"
set catfiles [getFileList c]
# list categories
foreach item $catfiles {
set c_id [lindex [getSessionIdFromFileName c $item] 0]
prodcat::init $c_id
fontPut 5 "[linkIt "[web::cmdurl showCategory [list cid $c_id]]" "[web::htmlify [prodcat::cget name]]"]"
fontPut 5 "[br]
[web::htmlify [prodcat::cget desc]]"
br 2
}
# list products of root category
displayProductList "root"
}
}
}
}
}
# display a category
proc showCategory {} {
page "Category" {
prodcat::init [web::param cid]
table "600" "" {
trtr {
tdtd {
br
imgSrc "[file join [cget imagePath] content_t.gif]" "ALIGN=\"right\""
br 3
fontPut 5 "[web::htmlify [prodcat::cget name]]"
br 2
set prodfile [getFileList p]
set rowColor "[cget firstRowColor]"
# displays the product list of the category
displayProductList [web::param cid]
trtr {
tdFontPut 2 "[linkIt "[web::cmdurl default]" "back"]"
}
}
}
}
}
}
# display the product details
proc showProdDetail {} {
page "Product detail" {
table 600 "" {
trtr {
tdtd {
br
imgSrc "[file join [cget imagePath] content_t.gif]" "ALIGN=\"right\""
br 3
proddata::init [web::formvar pid]
set p_id [proddata::init [web::formvar pid]]
table 500 "" {
trtr {
tdtdAttr "COLSPAN=\"3\" WIDTH=\"500\"" {
imgSrc "[web::cmdurl getImage [list imageFile \
[proddata::cget pictname]]]"
}
}
trtr {
tdtdAttr "WIDTH=\"100\"" {
fontPut 2 "Product name:"
}
tdtdAttr "WIDTH=\"400\"" {
fontPut 2 "[web::htmlify [proddata::cget name]]"
}
tdtdAttr "ALIGN=\"right\"" {
web::put "[linkIt "[web::cmdurl addShopBag [list pid $p_id]]" \
"[imgSrc "[file join [cget imagePath] \
[bagImage::cget picture]]" "BORDER=\"0\""]"]"
}
}
trtr {
tdtdAttr "WIDTH=\"500\" COLSPAN=\"3\"" {
fontPut 2 "[web::htmlify [proddata::cget sdesc]]"
br 2
fontPut 2 "[web::htmlify [proddata::cget desc]]"
br
fontPut 2 "Price [web::htmlify [proddata::cget price]]
[cget currency] - TAX [web::htmlify [proddata::cget tax]]%"
}
}
trtr {
tdtdAttr "WIDTH=\"500\" COLSPAN=\"3\"" {
fontPut 2 "
[linkIt "[web::cmdurl default]" "back"]"
}
}
}
}
}
}
}
}
# display a form for enteringn the order informations
proc checkOutOrder {error} {
page "Order form" {
createForm [web::cmdurl submit] {
table 600 "" {
br 3
font 2 {web::putx {
Name:
{
# if "error" flag is set, show the red
# error message asking for input
if {[string equal $error 1]} {
fontPut "error" "Please enter your name \n"
}
}
E-Mail:
{
# if "error" flag is set, show the red
# error message asking for input
if {[string equal $error 2]} {
fontPut "error" "Please enter a valid email \n"
}
}
{inputSubmit "ok" "Send"}
}
}
}
}
}
}
# checks the enterd values in a form
proc checkFormData {} {
# check if a value is in the name field
if { [string length [web::formvar name]] < 0} {
# return error code
return 1
}
set email [string trim [web::formvar email]]
if {![regexp {^[^@]+@[^@][^@]+\.[^@][^@]+$} $email] || [regexp "\[ \t\r\n,;\]" $email]} {
# the email has an invalid format
return 2
}
# log (facility: emailform, level: debug)
web::log ckeckFormData.info {name [web::formvar name] is valid}
# looks good: no error
return 0
}
# generates a email and send it
proc sendEmail {} {
# sets the email body text
set emailtxt "Websh DemoShop \n"
append emailtxt "\nName:\n[web::formvar name]\n"
append emailtxt "Address:\n"
append emailtxt "[web::formvar addr]\n"
append emailtxt "[web::formvar email]\n"
shopbag::init
set p_id [shopbag::carray names prod]
set totPrice 0
set orderId [orderIdGenerator nextval]
append emailtxt "This is a order from Websh DemoShop\n \
Order ID: $orderId\n\nOrderd Products:\n"
# generates the order list included product name, - price, amount
if {[string length $p_id] > 0} {
foreach prodID $p_id {
proddata::init $prodID
append emailtxt "[shopbag::cget prod($prodID) 0] x \
[proddata::cget name] for [proddata::cget price]\n"
getTotalPrice
}
}
append emailtxt "Total price: $totPrice"
append emailtxt {
The Websh DemoShop.
}
# open pipe for e-mail
if {[catch {set fh [open "| /usr/lib/sendmail [cget email]" w]} msg]} {
putErrorMessage $msg }
# set email header information
puts $fh "From: info@websh.com"
puts $fh "Subject: $orderId - Order from Websh DemoShop"
puts $fh ""
puts $fh $emailtxt
# close pipe
if {[catch {close $fh} msg]} {
putErrorMessage $msg
}
web::log sendOrder.info {order sendt}
orderSuccess $orderId
}
# display a confirmation and order ID
proc orderSuccess {orderId} {
page "succsefully orderd" {
table 600 "" {
br 3
font 2 {
web::putx {
{br 2}
Thank you for using Websh DemoShop
{br}
Your order ID: {web::put $orderId}
You'll receive your \
orderd items in a few days.{br 2}
{web::put [linkIt "[web::cmdurl cleanBag]" "back"]}
}
}
}
}
}
# display the admin screen (add/edit product and categories)
proc adminform {error} {
page "welcome to the admin-screen" {
createForm [web::cmdurl addEditProduct] {
fontPut 4 "Insert a new Product to the DemoShop
"
table 400 "" {
web::putx {
{tdFontPut 2 "Category"}
{
# if "error" flag is set, show the red
# error message asking for input
if {[string equal $error 1]} {
{trtr {tdFontPut "error" "Please enter a product name"}}
}
}
{trtr {
tdFontPut 2 "Product Name:"
tdFontPutInputfield "2" "text" "p_name" \
"[web::formvar p_name]" "30"
}}
{trtr {
tdFontPut 2 "Short Description:"
tdFontPutInputfield "2" "text" "p_sdesc" \
"[web::formvar p_sdesc]" "50"
}}
{trtr {
tdFontPut 2 "Product Description:"
tdFontPut 2 ""
}}
{
# if "error" flag is set, show the red
# error message asking for input
if {[string equal $error 2]} {
trtr {
tdtdAttr "COLSPAN=\"2\"" {
fontPut error "Please enter a valid product price"
}
}
}
}
{trtr {
tdFontPut 2 "Product Price:"
tdFontPutInputfield "2" "text" "p_price" \
"[web::formvar p_price]" "4" "[cget currency]"
}}
{trtr {
tdFontPut 2 "TAX:"
tdFontPutInputfield "2" "text" "p_tax" \
"[web::formvar p_tax]" "2" "%"
}}
{
# if "error" flag is set, show the red
# error message asking for input
if {[string equal $error 3]} {
trtr {
tdtdAttr "COLSPAN=\"2\"" {
fontPut error "Please upload a valid picture"
}
}
}
}
{trtr {
tdFontPut 2 "Image:"
tdFontPutInputfield "2" "file" "upload" \
"[web::formvar upload]" "30"
}}
{trtr {
tdtd {space}
tdtd {inputSubmit "AddEditProduct" "Insert"}
}}
}
}
}
br
hr
br
createForm [web::cmdurl addCategory] {
fontPut 4 "Insert a new Category to the DemoShop"
br 2
table 400 "" {
trtr {
tdFontPut 2 "Category Name:"
tdFontPutInputfield "2" "text" \
"c_name" "" "30"
}
trtr {
tdFontPut 2 "Description:"
tdFontPutInputfield "2" "text" \
"c_desc" "" "50"
}
trtr {
tdtd {space}
tdtd {inputSubmit "ok" "Add"}
}
}
}
# display the available products in the shop
br
hr
br
fontPut 2 "The following products are available in the DemoShop"
br
table 400 "" {
trtr {
tdtdAttr "WIDTH=\"50\"" {
fontPut 2 "Product"
}
tdtdAttr "WIDTH=\"300\"" {
fontPut 2 "Product Description"
}
tdtdAttr "WIDTH=\"50\"" {
fontPut 2 "Price"
}
tdtd {
space
}
}
set prodfile [getFileList p]
foreach item $prodfile {
set p_id [lindex [getSessionIdFromFileName p $item] 0]
proddata::init $p_id
trtr {
tdFontPut 2 "[linkIt "[web::cmdurl showDetail [list pid $p_id]]" \
"[web::htmlify [proddata::cget name]]"]"
tdFontPut 2 "[web::htmlify [proddata::cget sdesc]]"
tdFontPut 2 "[web::htmlify [proddata::cget price]]"
tdFontPut 2 "[linkIt "[web::cmdurl delProduct [list pid $p_id]]" "delete"] |
[linkIt "[web::cmdurl editProduct [list pid $p_id]]" "edit"]"
}
}
}
# display the available categories in the shop
fontPut 2 "The following Categories are in the DemoShop"
br
table 400 "" {
trtr {
tdtdAttr "WIDTH=\"50\"" {
fontPut 2 "Category"
}
tdtdAttr "WIDTH=\"300\"" {
fontPut 2 "Category Description"
}
tdtd {space}
}
set catfile [getFileList c]
foreach item $catfile {
set c_id [lindex [getSessionIdFromFileName c $item] 0]
prodcat::init $c_id
trtr {
tdFontPut 2 "[web::htmlify [prodcat::cget name]]"
tdFontPut 2 "[web::htmlify [prodcat::cget desc]]"
tdFontPut 2 "[linkIt "[web::cmdurl delCategory [list cid $c_id]]" \
"delete"] | [linkIt "[web::cmdurl editCategory [list cid $c_id]]" "edit"]"
}
}
}
web::put "