Files
harbour-core/harbour/examples/uhttpd2/tests/webapp.prg
Viktor Szakats afa82f20e1 2010-11-24 01:09 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
* examples/uhttpd2/uhttpd2.hbp
    * Converted uhttpd2 core to a lib.

  + examples/uhttpd2/uhttpd2.hbc
    + Added .hbc file.

  * examples/uhttpd2/umain.prg
  * examples/uhttpd2/uwidgets.prg
  * examples/uhttpd2/uhbext.prg
  * examples/uhttpd2/app.prg
    * Formatted (with hbformat for the most part)
    * Minor cleanups.
    ! Fixed all -w3 warnings.

  + examples/uhttpd2/tests
  + examples/uhttpd2/tests/hbmk.hbm
  - examples/uhttpd2/carts.dbf
  - examples/uhttpd2/items.dbf
  - examples/uhttpd2/users.dbf
  + examples/uhttpd2/tests/carts.dbf
  + examples/uhttpd2/tests/items.dbf
  + examples/uhttpd2/tests/users.dbf
  - examples/uhttpd2/files
  + examples/uhttpd2/tests/files
  - examples/uhttpd2/app.prg
  + examples/uhttpd2/tests/webapp.prg
    + Added tests dir and moved app specific files there.
2010-11-24 00:09:54 +00:00

432 lines
14 KiB
Plaintext

/*
* $Id$
*/
#include "hbclass.ch"
#include "common.ch"
#include "fileio.ch"
#define CR_LF (CHR(13)+CHR(10))
REQUEST DBFCDX
MEMVAR server, get, post, cookie, session
STATIC s_aMap
FIELD USER, NAME, PASSWORD, CODE, PRICE, TOTAL, TITLE
FUNCTION Main()
LOCAL oServer
IF HB_ARGCHECK( "help" )
? "Usage: app [options]"
? "Options:"
? " //help Print help"
? " //stop Stop running server"
RETURN 0
ENDIF
IF HB_ARGCHECK( "stop" )
HB_MEMOWRIT( ".uhttpd.stop", "" )
RETURN 0
ELSE
FErase( ".uhttpd.stop" )
ENDIF
rddSetDefault( "DBFCDX" )
SET( _SET_DATEFORMAT, "yyyy-mm-dd" )
IF ! HB_FILEEXISTS( "users.dbf" )
FErase( "users.cdx" )
dbCreate( "users", { { "USER", "C", 16, 0 }, { "PASSWORD", "C", 16, 0 }, { "NAME", "C", 50, 0 } }, , .T. , "user" )
OrdCreate( "users", "user", "USER" )
dbCloseArea()
ELSEIF ! HB_FILEEXISTS( "users.cdx" )
dbUseArea( .T. , , "users", , .F. , .F. )
OrdCreate( "users", "user", "USER" )
dbCloseArea()
ENDIF
IF ! HB_FILEEXISTS( "carts.dbf" )
FErase( "carts.cdx" )
dbCreate( "carts", { { "USER", "C", 16, 0 }, { "CODE", "C", 16, 0 }, { "AMOUNT", "N", 6, 0 }, { "TOTAL", "N", 9, 2 } }, , .T. , "cart" )
OrdCreate( "carts", "user", "USER+CODE" )
dbCloseArea()
ELSEIF ! HB_FILEEXISTS( "carts.cdx" )
dbUseArea( .T. , , "carts", , .F. , .F. )
OrdCreate( "carts", "user", "USER+CODE" )
dbCloseArea()
ENDIF
IF ! HB_FILEEXISTS( "items.dbf" )
FErase( "items.cdx" )
dbCreate( "items", { { "CODE", "C", 16, 0 }, { "TITLE", "C", 80, 0 }, { "PRICE", "N", 9, 2 } }, , .T. , "items" )
OrdCreate( "items", "code", "CODE" )
dbCloseArea()
ELSEIF ! HB_FILEEXISTS( "item.cdx" )
dbUseArea( .T. , , "items", , .F. , .F. )
OrdCreate( "items", "code", "CODE" )
dbCloseArea()
ENDIF
oServer := UHttpdNew()
oServer:nPort := 8002
oServer:bIdle := { |o| iif( HB_FILEEXISTS( ".uhttpd.stop" ), ( FErase(".uhttpd.stop" ), o:Stop() ), NIL ) }
s_aMap := {;
"login" => @proc_login(), ;
"logout" => @proc_logout(), ;
"register" => @proc_register(), ;
"account" => @proc_account(), ;
"account/edit" => @proc_account_edit(), ;
"main" => @proc_main(), ;
"shopping" => @proc_shopping(), ;
"cart" => @proc_cart() }
oServer:aMount := {;
"/hello" => { {|| UWrite( "Hello!")}, .F. }, ;
"/info" => { {|| UProcInfo() }, .F. }, ;
"/files/*" => { {|x| UProcFiles( hb_dirBase() + "files/" + x, .F. ) }, .F. }, ;
"/app/*" => { {|x| UProcWidgets( x, s_aMap ) }, .T. }, ;
"/*" => { {|| URedirect( "/app/login" ) }, .F. } }
? "Listening on port:", oServer:nPort
IF ! oServer:Run()
? "Server error:", oServer:cError
RETURN 1
ENDIF
RETURN 0
STATIC FUNCTION proc_login( cMethod )
LOCAL cUser, oM, oF, oG
? ProcName(), cMethod
IF cMethod == "INIT"
oM := UWMainNew()
oM:Add( UWLabelNew( "", "errtxt", "color:red; font-weight:bold;" ) )
oM:Add( oF := UWFormNew( "" ) )
oF:Add( oG := UWLayoutGridNew() )
oG:Add( UWHtmlNew( "User" ), 1, 1 )
oG:Add( UWInputNew( "user" ), 1, 2 )
oG:Add( UWHtmlNew( "Password" ), 2, 1 )
oG:Add( UWPasswordNew( "password" ), 2, 2 )
oG:Add( UWSubmitNew( "submit", "Login" ), 3, 2 )
oM:Add( UWHtmlNew( ULink("Register", "register" ) ) )
ELSEIF cMethod == "POST"
dbUseArea( .T. , , "users", "users", .T. , .T. )
OrdSetFocus( "user" )
cUser := PadR( hb_HGetDef( post, "user", "" ), 16 )
IF !Empty( cUser ) .AND. dbSeek( cUser, .F. ) .AND. ! Deleted() .AND. ;
PadR( hb_HGetDef( post, "password", "" ), 16 ) == FIELD->PASSWORD
session[ "loggedin" ] := cUser
URedirect( "main" )
ELSE
URedirect( "login?err" )
USessionDestroy()
ENDIF
dbCloseArea()
ELSEIF cMethod == "GET"
IF HB_HHasKey( get, "err" )
GetWidgetById( "errtxt" ):cText := "Invalid username or password!"
ENDIF
UWDefaultHandler( cMethod )
USessionDestroy()
ENDIF
RETURN .T.
STATIC FUNCTION proc_register( cMethod )
LOCAL cUser, cName, cPassword, cPassword2, oM, oF, oG
? ProcName(), cMethod
IF cMethod == "INIT"
oM := UWMainNew()
oM:Add( UWLabelNew( "", "errtxt", "color:red; font-weight:bold;" ) )
oM:Add( oF := UWFormNew( "" ) )
oF:Add( oG := UWLayoutGridNew() )
oG:Add( UWHtmlNew( "User name" ), 1, 1 )
oG:Add( UWInputNew( "user",, "user" ), 1, 2 )
oG:Add( UWHtmlNew( "Name" ), 2, 1 )
oG:Add( UWInputNew( "name",, "name" ), 2, 2 )
oG:Add( UWHtmlNew( "Password" ), 3, 1 )
oG:Add( UWPasswordNew( "password" ), 3, 2 )
oG:Add( UWHtmlNew( "Password again" ), 4, 1 )
oG:Add( UWPasswordNew( "password2" ), 4, 2 )
oG:Add( UWSubmitNew( "register", "Register" ), 5, 2 )
ELSEIF cMethod == "POST"
dbUseArea( .T. , , "users", "users", .T. , .F. )
OrdSetFocus( "user" )
cUser := hb_HGetDef( post, "user", "" )
cName := hb_HGetDef( post, "name", "" )
cPassword := hb_HGetDef( post, "password", "" )
cPassword2 := hb_HGetDef( post, "password2", "" )
GetWidgetById( "user" ):cValue := cUser
GetWidgetById( "name" ):cValue := cName
IF Empty( cUser ) .OR. Empty( cName ) .OR. Empty( cPassword ) .OR. Empty( cPassword2 )
URedirect( "?err=1" )
ELSEIF !( cPassword == cPassword2 )
URedirect( "?err=2" )
ELSEIF dbSeek( cUser, .F. )
URedirect( "?err=3" )
ELSE
FLock()
dbAppend()
USER := cUser
NAME := cName
PASSWORD := cPassword
dbUnlock()
session[ "loggedin" ] := cUser
URedirect( "main" )
ENDIF
dbCloseArea()
ELSEIF cMethod == "GET"
IF HB_HHasKey( get, "err" )
IF get[ "err" ] == "1"
GetWidgetById( "errtxt" ):cText := "All fields are required!"
ELSEIF get[ "err" ] == "2"
GetWidgetById( "errtxt" ):cText := "Passwords does not match!"
ELSEIF get[ "err" ] == "3"
GetWidgetById( "errtxt" ):cText := "This user already exists!"
ENDIF
ENDIF
UWDefaultHandler( cMethod )
ENDIF
RETURN .T.
STATIC FUNCTION proc_account( cMethod )
LOCAL oM, oG
? ProcName(), cMethod
IF cMethod == "INIT"
IF ! HB_HHasKey( session, "loggedin" ); URedirect( "/app/login" ); RETURN .F.
ENDIF
dbUseArea( .T. , , "users", "users", .T. , .F. )
OrdSetFocus( "user" )
ELSEIF cMethod == "GET"
dbSeek( session[ "loggedin" ], .F. )
/* Create object here because user name can be changed in account/edit */
oM := UWMainNew()
oM:Add( UWMenuNew():AddItem( "Shopping", "shopping" ):AddItem( "Cart", "cart" ):AddItem( "Logout", "logout" ) )
oM:Add( UWSeparatorNew() )
oM:Add( oG := UWLayoutGridNew() )
oG:Add( UWHtmlNew( "User name:" ), 1, 1 )
oG:Add( UWHtmlNew( session[ "loggedin" ] ), 1, 2 )
oG:Add( UWHtmlNew( "Name:" ), 2, 1 )
oG:Add( UWHtmlNew( NAME ), 2, 2 )
oM:Add( UWHtmlNew( ULink("Edit", "account/edit" ) ) )
UWDefaultHandler( cMethod )
ELSEIF cMethod == "EXIT"
users->( dbCloseArea() )
ENDIF
RETURN .T.
STATIC FUNCTION proc_account_edit( cMethod )
LOCAL cName, cPassword, cPassword2, oM, oG, oF
? ProcName(), cMethod
IF cMethod == "INIT"
IF ! HB_HHasKey( session, "loggedin" ); URedirect( "/app/login" ); RETURN .F.
ENDIF
dbSeek( session[ "loggedin" ], .F. )
oM := UWMainNew()
oM:Add( UWLabelNew( "", "errtxt", "color:red; font-weight:bold;" ) )
oM:Add( oF := UWFormNew( "" ) )
oF:Add( oG := UWLayoutGridNew() )
oG:Add( UWHtmlNew( "User name" ), 1, 1 )
oG:Add( UWHtmlNew( session[ "loggedin" ] ), 1, 2 )
oG:Add( UWHtmlNew( "Name" ), 2, 1 )
oG:Add( UWInputNew( "name", RTrim( NAME ), "name" ), 2, 2 )
oG:Add( UWHtmlNew( "Password" ), 3, 1 )
oG:Add( UWPasswordNew( "password" ), 3, 2 )
oG:Add( UWHtmlNew( "Password again" ), 4, 1 )
oG:Add( UWPasswordNew( "password2" ), 4, 2 )
oG:Add( UWSubmitNew( "save", "Save" ), 5, 2 )
ELSEIF cMethod == "POST"
dbSeek( session[ "loggedin" ], .F. )
cName := hb_HGetDef( post, "name", "" )
cPassword := hb_HGetDef( post, "password", "" )
cPassword2 := hb_HGetDef( post, "password2", "" )
GetWidgetById( "name" ):cValue := RTrim( cName )
IF Empty( cName )
URedirect( "?err=1" )
ELSEIF ( ! Empty( cPassword ) .OR. ! Empty( cPassword2 ) ) .AND. ! ( cPassword == cPassword2 )
URedirect( "?err=2" )
ELSE
FLock()
NAME := cName
QOut( "PO DBAPPEND", Alias(), RecNo(), cName )
IF ! Empty( cPassword )
PASSWORD := cPassword
ENDIF
dbUnlock()
URedirect( "../account" )
ENDIF
ELSEIF cMethod == "GET"
IF HB_HHasKey( get, "err" )
IF get[ "err" ] == "1"
GetWidgetById( "errtxt" ):cText := "All fields are required!"
ELSEIF get[ "err" ] == "2"
GetWidgetById( "errtxt" ):cText := "Passwords does not match!"
ENDIF
ENDIF
UWDefaultHandler( cMethod )
ELSEIF cMethod == "EXIT"
ENDIF
RETURN .T.
STATIC FUNCTION proc_main( cMethod )
LOCAL oM
? ProcName(), cMethod
IF cMethod == "INIT"
IF ! HB_HHasKey( session, "loggedin" ); URedirect( "/app/login" ); RETURN .F.
ENDIF
oM := UWMainNew()
oM:Add( UWMenuNew():AddItem( "Shopping", "shopping" );
:AddItem( "Cart", "cart" );
:AddItem( "My account", "account" );
:AddItem( "Logout", "logout" ) )
oM:Add( UWSeparatorNew() )
oM:Add( UWLabelNew( "You can do shopping, or edit your cart using menu links above" ) )
ELSEIF cMethod == "GET"
UWDefaultHandler( cMethod )
ENDIF
RETURN .T.
STATIC FUNCTION proc_shopping( cMethod )
LOCAL oM, oW, nT, cCode
? ProcName(), cMethod
IF cMethod == "INIT"
IF ! HB_HHasKey( session, "loggedin" ); URedirect( "/app/login" ); RETURN .F.
ENDIF
oM := UWMainNew()
oM:Add( UWMenuNew():AddItem( "Cart", "cart" ):AddItem( "My account", "account" ):AddItem( "Logout", "logout" ) )
oM:Add( UWSeparatorNew() )
oM:Add( UWLabelNew( "", "cartsum" ) )
dbUseArea( .T. , , "carts", "carts", .T. , .F. )
OrdSetFocus( "user" )
ORDSCOPE( 0, session[ "loggedin" ] )
ORDSCOPE( 1, session[ "loggedin" ] )
dbUseArea( .T. , , "items", "items", .T. , .T. )
OrdSetFocus( "code" )
oW := UWBrowseNew( "1" )
oW:AddColumn( 101, "Item No.", "CODE" )
oW:AddColumn( 102, "Title", "TITLE" )
oW:AddColumn( 103, "Price", "PRICE" )
oW:AddColumn( 104, "", {|| ULink( "Add to cart", "?add=" + RTrim( CODE ) ) }, .T. )
oM:Add( oW )
ELSEIF cMethod == "GET"
IF HB_HHasKey( get, "add" )
cCode := PadR( get[ "add" ], 16 )
IF items->( dbSeek( cCode ) ) .AND. carts->( FLock() )
IF ! carts->( dbSeek( session[ "loggedin" ] + cCode ) )
carts->( dbAppend() )
carts->USER := session[ "loggedin" ]
carts->CODE := cCode
ENDIF
carts->AMOUNT += 1
carts->TOTAL += items->PRICE
carts->( dbUnlock() )
ENDIF
URedirect( "shopping" )
RETURN .T.
ENDIF
nT := 0
carts->( dbEval( {|| nT += TOTAL } ) )
GetWidgetById( "cartsum" ):cText := "Your cart is worth: " + hb_ntos( nT )
UWDefaultHandler( cMethod )
ELSEIF cMethod == "EXIT"
items->( dbCloseArea() )
carts->( dbCloseArea() )
ENDIF
RETURN .T.
STATIC FUNCTION proc_cart( cMethod )
LOCAL oM, oW, nT, cCode
? ProcName(), cMethod
IF cMethod == "INIT"
IF ! HB_HHasKey( session, "loggedin" ); URedirect( "/app/login" ); RETURN .F.
ENDIF
oM := UWMainNew()
oM:Add( UWMenuNew():AddItem( "Shopping", "shopping" ):AddItem( "My account", "account" ):AddItem( "Logout", "logout" ) )
oM:Add( UWSeparatorNew() )
oM:Add( UWLabelNew( "", "cartsum" ) )
dbUseArea( .T. , , "items", "items", .T. , .T. )
OrdSetFocus( "code" )
dbUseArea( .T. , , "carts", "carts", .T. , .F. )
OrdSetFocus( "user" )
ORDSCOPE( 0, session[ "loggedin" ] )
ORDSCOPE( 1, session[ "loggedin" ] )
oW := UWBrowseNew( "1" )
oW:AddColumn( 101, "Item No.", "CODE" )
oW:AddColumn( 102, "Title", {|| items->( dbSeek(carts->CODE, .F. ), TITLE ) } )
oW:AddColumn( 103, "Amount", "AMOUNT" )
oW:AddColumn( 104, "Total", "TOTAL" )
oW:AddColumn( 104, "", {|| ULink( "Delete", "?del=" + RTrim( CODE ) ) }, .T. )
oM:Add( oW )
ELSEIF cMethod == "GET"
IF HB_HHasKey( get, "del" )
cCode := PadR( get[ "del" ], 16 )
IF items->( dbSeek( cCode ) ) .AND. carts->( FLock() )
IF carts->( dbSeek( session[ "loggedin" ] + cCode ) )
carts->( dbDelete() )
carts->USER := ""
carts->CODE := cCode
ENDIF
carts->( dbUnlock() )
ENDIF
URedirect( "cart" )
RETURN .T.
ENDIF
nT := 0
carts->( dbEval( {|| nT += TOTAL } ) )
GetWidgetById( "cartsum" ):cText := "Your cart is worth: " + hb_ntos( nT )
UWDefaultHandler( cMethod )
ELSEIF cMethod == "EXIT"
items->( dbCloseArea() )
carts->( dbCloseArea() )
ENDIF
RETURN .T.
STATIC FUNCTION proc_logout( cMethod )
LOCAL oM
? ProcName(), cMethod
IF cMethod == "INIT"
IF ! HB_HHasKey( session, "loggedin" ); URedirect( "/app/login" ); RETURN .F.
ENDIF
oM := UWMainNew()
oM:Add( UWMenuNew():AddItem( "Login", "login" ) )
oM:Add( UWSeparatorNew() )
oM:Add( UWLabelNew( "Your session is ended." ) )
ELSEIF cMethod == "GET"
UWDefaultHandler( cMethod )
USessionDestroy()
ENDIF
RETURN .T.