separate index from ticket shop;
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 6 Feb 2011 21:50:22 +0000 (21:50 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 6 Feb 2011 21:50:22 +0000 (21:50 +0000)
implement customer login, checkout and address selection

git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@720 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

16 files changed:
www/config.php.template
www/inc/classes/basevars.php
www/inc/machine/session.php
www/inc/rendering/cart_listing.php
www/inc/rendering/event_listing.php
www/inc/rendering/twig_extensions.php
www/inc/wext/customer.php
www/index.php
www/template/en/changeaddress.html [new file with mode: 0644]
www/template/en/checkout.html [new file with mode: 0644]
www/template/en/index.html
www/template/en/layout.html
www/template/en/login.html [moved from www/template/en/orderlogin.html with 95% similarity]
www/template/en/reseterror.html [new file with mode: 0644]
www/template/en/resetlogin.html [new file with mode: 0644]
www/template/en/tickets.html [new file with mode: 0644]

index 80c17bc..a9f6a21 100644 (file)
@@ -27,9 +27,8 @@ $db->setCharacterSet("utf8");
 */
 
 ////
-//PGSQL
+//PostgreSQL
 
-/*
 //create engine: connection string, the sub-parameters are:
 // dbname - name of the database
 // user - DB user that is used to log in to the DB server
@@ -44,23 +43,23 @@ $db = new PGsqlEngine("dbname='smoke' user='smoke'");
 $db->setPrefix("smoke2_");
 //set this only if you want debug messages on error (developers only):
 //$db->setDebugMode();
-*/
+
 
 ////////////
 // DB Administration
 
-//use this for DB creation and upgrading, comment it out otherwise.
+//use this for DB creation and upgrading, comment it out otherwise
 //change the passcode before using this on a production system!!!
 $db->setAdminPassCode("Admin","SmokeInMyEye");
 
 //use this if you want to upgrade data from an old (MagicSmoke 1.x) DB instance
-/*
+// /*
 $olddb = new MysqlEngine("localhost","smoke","");
 $olddb->setDbName("smoke");
 $olddb->setPrefix("smoke_");
 $olddb->setStorageEngine("InnoDB");
 $olddb->setCharacterSet("utf8");
-*/
+// */
 
 
 ////////////
@@ -128,9 +127,12 @@ $WebDefaultShipping=1;
 $WebCustomerFlags="newsletter reminder";
 
 //order flags
-// you can add arbitrary input fields to the checkout pagem this array defines
+// you can add arbitrary input fields to the checkout page, this array defines
 // what values they must have, this can be used for acknowledging standard
-// form contract (German: AGB) clauses
+// form contract (German: AGB) clauses or other formalities that you need to
+// present at EVERY check out
+$WebOrderFields=array();
+//example: standard form contract
 $WebOrderFields['sfc_ack']='on';
 
 //customer password reset
index 3c4155b..8ee5014 100644 (file)
@@ -85,6 +85,7 @@ public static function initPriv(){
        $basevars['script']['index']=$BaseUrl."?mode=index";
        $basevars['script']['eventDetails']=$BaseUrl."?mode=eventDetails&event=";
        $basevars['script']['eventOrder']=$BaseUrl."?mode=eventOrder";
+       $basevars['script']['tickets']=$BaseUrl."?mode=tickets";
        $basevars['script']['vouchers']=$BaseUrl."?mode=vouchers";
        $basevars['script']['voucherOrder']=$BaseUrl."?mode=voucherOrder";
        $basevars['script']['shop']=$BaseUrl."?mode=shop";
@@ -93,8 +94,11 @@ public static function initPriv(){
        $basevars['script']['checkout']=$BaseUrl."?mode=checkout";
        $basevars['script']['removeItem']=$BaseUrl."?mode=removeItem";
        $basevars['script']['orderLogin']=$BaseUrl."?mode=orderLogin";
-       $basevars['script']['customerLogin']=$BaseUrl."?mode=customerLogin";
-       $basevars['script']['customerRegistration']=$BaseUrl."?mode=customerRegistration";
+       $basevars['script']['placeOrder']=$BaseUrl."?mode=placeOrder";
+       $basevars['script']['customerLoginOrder']=$BaseUrl."?mode=customerLoginOrder";
+       $basevars['script']['customerRegistrationOrder']=$BaseUrl."?mode=customerRegistrationOrder";
+       $basevars['script']['changeInvoiceAddress']=$BaseUrl."?mode=changeInvoiceAddress";
+       $basevars['script']['changeDeliveryAddress']=$BaseUrl."?mode=changeDeliveryAddress";
        $basevars['script']['customerResetLogin']=$BaseUrl."?mode=customerResetLogin";
        //$basevars['script']['orderOverview']=$BaseUrl."?mode=orderOverview";
        //$basevars['script']['editShippingAddress']=$BaseUrl."?mode=editShippingAddress";
@@ -112,6 +116,14 @@ public static function initPriv(){
        $basevars['inputnames']['login']['name']='customer_name';
        $basevars['inputnames']['login']['firstname']='customer_firstname';
        $basevars['inputnames']['login']['title']='customer_title';
+       $basevars['inputnames']['address']['setaddress']='setaddr';
+       $basevars['inputnames']['address']['createaddress']='createaddr';
+       $basevars['inputnames']['address']['name']='name';
+       $basevars['inputnames']['address']['addr1']='addr1';
+       $basevars['inputnames']['address']['addr2']='addr2';
+       $basevars['inputnames']['address']['city']='city';
+       $basevars['inputnames']['address']['state']='state';
+       $basevars['inputnames']['address']['country']='country';
        //end of basevars
 }
 
index d1215e5..11480b1 100644 (file)
@@ -118,12 +118,7 @@ class Session
                }
                
                //validate host
-               $splt=explode(" ",$hres[0]["hostkey"]);
-               if(count($splt)!=2){
-                       $trans->abortWithError(translate("Session","Host authentication failed"),"auth");
-               }
-               $cmp=strtolower(sha1($splt[0].$trans->gethostkey()));
-               if($cmp != strtolower($splt[1])){
+               if(!self::passwdVerify($trans->gethostkey(),$hres[0]["hostkey"])){
                        $trans->abortWithError(translate("Session","Host authentication failed"),"auth");
                }
                
@@ -133,12 +128,7 @@ class Session
                        $trans->abortWithError(translate("Session","User Authentication failed"),"auth");
                }
                //validate user
-               $splt=explode(" ",$ures[0]["passwd"]);
-               if(count($splt)!=2){
-                       $trans->abortWithError(translate("Session","User Authentication failed"),"auth");
-               }
-               $cmp=strtolower(sha1($splt[0].$trans->getpassword()));
-               if($cmp!=strtolower($splt[1])){
+               if(!self::passwdVerify($trans->getpassword(),$ures[0]["passwd"])){
                        $trans->abortWithError(translate("Session","User Authentication failed"),"auth");
                }
                
@@ -200,17 +190,12 @@ class Session
                $res=$db->select("user","passwd","uname=".$db->escapeString($this->user));
                if(count($res)!=1)
                        $trans->abortWithError(tr("Ooops. Unable to find user. You have been deleted."));
-               $splt=explode(" ",$res[0]["passwd"]);
-               if(count($splt)!=2)
-                       $trans->abortWithError(tr("Ooops. Internal storage error - cannot verify old password."));
-               $vrfy=sha1($splt[0].$old);
-               if($vrfy!=$splt[1]){
+               if(!self::passwdVerify($old,$res[0]["passwd"])){
                        $trans->abortWithError(tr("Wrong password. Request denied."));
                }
                //set new password
-               $salt=getSalt();
-               $pwh=sha1($salt.$nwp);
-               $db->update("user",array("passwd"=>($salt." ".$pwh)),"uname=".$db->escapeString($this->user));
+               $pwh=self::passwdHash($nwp);
+               $db->update("user",array("passwd"=>($pwh)),"uname=".$db->escapeString($this->user));
        }
        
        /**checks whether user can execute this transaction, returns true on success; it always returns true for admins*/
@@ -249,6 +234,32 @@ class Session
                //no matches, must be ok then
                return true;
        }
+       
+       ///helper function to generate salted user or customer password hash
+       /// \param $passwd unhashed password
+       /// \returns the salted password hash
+       public static function passwdHash($passwd)
+       {
+               $salt=getSalt();
+               return $salt." ".sha1($salt.$passwd);
+       }
+       
+       ///helper function to verify user or customer login
+       /// \param $passwd unhashed password
+       /// \param $hash salted password hash
+       /// \returns true on success, false on error or if the password does not match
+       public static function passwdVerify($passwd,$hash)
+       {
+               //separate salt and hash
+               $splt=explode(" ",$hash);
+               if(count($splt)!=2){
+                       return false;
+               }
+               //redo calculation
+               $cmp=sha1($splt[0].$passwd);
+               //compare (tolower since we use string compare on a hex number)
+               return strtolower($cmp)==strtolower($splt[1]);
+       }
 };
 
 /**dummy class used by browsed pages to represent the virtual web user*/
index f319c71..74b5784 100644 (file)
@@ -51,7 +51,7 @@ static public function addVoucher()
        //get the cart
        $cartid=self::getOrCreateCart();
        //find event
-       echo "checking";
+//     echo "checking";
        $vi=$basevars['inputnames']['voucher'];
        if(!isset($HTTPARGS[$vi])){
                redirectHome();
@@ -60,7 +60,7 @@ static public function addVoucher()
        //price
        $prc=$HTTPARGS[$vi];
        //add
-       echo "adding";
+//     echo "adding";
        WTrWebCartAddVoucher::execute($cartid,$prc);
        //go to the cart
        redirectHome(array("mode"=>"cart","cartid"=>$cartid));
@@ -276,15 +276,23 @@ static public function createVoucherOverview()
        return $p->render($list);
 }
 
-/** creates an overview of known good voucher types
+/** \page templates Templates
+\section tpl_cout Checkout Variables
 
-For templating info see \ref tpl_cart Cart Variables
-and \ref tpl_base Base Variables
-, however only the 'cart' variable itself is available from the Cart Variables.
+The checkout.html template is used to render the current cart of the customer.
+
+\param cart an object of the web type <a href="../wob/class-WebCart.html">WebCart</a> (PHP: WOWebCart) that represents the entire cart of the user.
 */
-static public function orderLoginPage()
+
+/**renders the checkout page
+
+see the \ref tpl_cout Checkout Template
+page for details */
+static public function checkout()
 {
-       global $twig,$basevars,$HTTPARGS;
+       global $twig,$basevars,$db;
+       //populate list
+       $list=$basevars;
        //get cart id and check it
        $cartid=self::getCart();
        if($cartid==""){
@@ -299,81 +307,98 @@ static public function orderLoginPage()
                $p=$twig->loadTemplate("carterror.html");
                return $p->render($basevars);
        }
-       $list=$basevars;
-       $list["cart"]=$cart;
-       $list["customer_name"]="";
-       if(isset($HTTPARGS["customer_name"]))
-               $list["customer_name"]=$HTTPARGS["customer_name"];
-       else{
-               $cust=$cart->getcustomer();
-               if(is_a($cust,"WOCustomer"))
-                       $list["customer_name"]=$cust->getemail();
+       //if empty: abort
+       if($cart->getisempty()){
+               redirectHome(array("mode"=>"cart"));
+               return;
        }
-       //display
-       $p=$twig->loadTemplate("orderlogin.html");
-       return $p->render($list);
+       //add cart object
+       $list["cart"]=$cart;
+       //render
+       return $twig->loadTemplate("checkout.html")->render($list);
 }
 
-
-/** \page templates Templates
-\section tpl_logerr Login Error
-
-The loginerror.html template is used to render customer login and registering errors.
-
-\param errorType the type of error: "login" - the login failed (wrong mail or password), "exist" - an account with the same mail already exists, "mismatch" - the new passwords do no match
-\param backUrl the URL to call back to the login page
-*/
-
-///renders a login error page, see \ref tpl_logerr Login Error Template
-static private function loginError($errorType)
+static public function changeAddressPage($mode)
 {
-       global $basevars,$HTTPARGS,$SERVER,$twig;
-       //find some basics
-       $vars=$basevars;
-       $vars["errorType"]=$errorType;
-       //construct URL back to login page
-       if(isset($_SERVER["HTTP_REFERER"])){
-               $vars["backUrl"]=$_SERVER["HTTP_REFERER"];
-       }else{
-               $vars["backUrl"]=$basevars['script']['orderLogin'];
+       global $twig,$HTTPARGS,$db,$basevars;
+       //get customer
+       $cartid=self::getCart();
+       if($cartid==""){
+               redirectHome();
+               return;
        }
-       if(strstr($vars["backUrl"],"?")===false)
-               $vars["backUrl"].="?";
-       else
-               $vars["backUrl"].="&";
-       $idx=$basevars['inputnames']['login']['name'];
-       $vars["backUrl"].=$idx."=";
-       if(isset($HTTPARGS[$idx]))$vars["backUrl"].=$HTTPARGS[$idx];
-       //render page
-       $p=$twig->loadTemplate("loginerror.html");
-       return $p->render($vars);
-}
-
-///check the login of the customer, either forwards to the checkout page or shows the loginerror page
-static public function checkOrderLogin()
-{
-       global $HTTPARGS,$db,$basevars;
-       //find customer
-       $nameidx=$basevars['inputnames']['login']['name'];
-       $passidx=$basevars['inputnames']['login']['passwd'];
-       if(!isset($HTTPARGS[$nameidx]) || !isset($HTTPARGS[$passidx])){
-               return self::loginError("param");
+       $ct=WTcart::getFromDB($cartid);
+       $cart=WOWebCart::fromTablecart($ct);
+       $cust=$cart->getcustomer();
+       if(!is_a($cust,"WOCustomer")){
+               //no customer: return to cart, something is very wrong
+               redirectHome(array("mode"=>"cart"));
+               return;
        }
-       $ct=WTcustomer::selectFromDB("email=".$db->escapeString($HTTPARGS[$nameidx]));
-       if(count($ct)<1){
-               return self::loginError("login");
+       //check whether we have arguments for setting
+       $setaddr=$basevars['inputnames']['address']['setaddress'];
+       if(isset($HTTPARGS[$setaddr])){
+               $at=WTaddress::getFromDB($HTTPARGS['setaddr']);
+               if(!is_a($at,"WTaddress")){
+                       redirectHome();
+                       return;
+               }
+               //check it is part of the customer
+               $found=false;
+               foreach($cust->getaddresses() as $adr){
+                       if($adr->getaddressid() == $at->addressid){
+                               $found=true;
+                               break;
+                       }
+               }
+               if(!$found){
+                       redirectHome();
+                       return;
+               }
+               //set it
+               if($mode=='changeInvoiceAddress'){
+                       $ct->invoiceaddress=$at->addressid;
+               }else{
+                       $ct->deliveryaddress=$at->addressid;
+               }
+               $ct->update();
+               redirectHome(array("mode"=>"checkout"));
+               return;
        }
-       //check password
-       $cust=WOCustomer::fromTablecustomer($ct[0]);
-       if(!$cust->checkPassword($HTTPARGS[$passidx])){
-               return self::loginError("login");
+       //check whether we have arguments for creating
+       $creat=$basevars['inputnames']['address']['createaddress'];
+       if(isset($HTTPARGS[$creat])){
+               //create address
+               $at=WTaddress::newrow();
+               $at->customerid=$cust->getid();
+               $at->name=getHttpArg($basevars['inputnames']['address']['name']);
+               $at->addr1=getHttpArg($basevars['inputnames']['address']['addr1']);
+               $at->addr2=getHttpArg($basevars['inputnames']['address']['addr2']);
+               $at->city=getHttpArg($basevars['inputnames']['address']['city']);
+               $at->state=getHttpArg($basevars['inputnames']['address']['state']);
+               $at->countryid=getHttpArg($basevars['inputnames']['address']['country']);
+               $at->insert();
+               //set it
+               if($mode=='changeInvoiceAddress'){
+                       $ct->invoiceaddress=$at->addressid;
+               }else{
+                       $ct->deliveryaddress=$at->addressid;
+               }
+               $ct->update();
+               redirectHome(array("mode"=>"checkout"));
+               return;
        }
+       //render addresses
+       $list=$basevars;
+       $list['customer']=$cust;
+       $list['cart']=$cart;
+       $list['countries']=WOCountry::fromTableArraycountry(WTcountry::selectFromDB(""));
+       return $twig->loadTemplate('changeaddress.html')->render($list);
 }
 
-static public function registerCustomer()
+static public function placeOrder()
 {
-       global $HTTPARGS;
-       
+       die ("not implemented");
 }
 
 //end of WebCart
index 91dc774..64122b4 100644 (file)
@@ -29,7 +29,7 @@ public static function createEventList()
        global $twig,$basevars,$session;
        
        //pass 1: get layout of single event
-       $p=$twig->loadTemplate("index.html");
+       $p=$twig->loadTemplate("tickets.html");
        $list=$basevars;
        $trn=WTrGetAllEvents::execute();
        $events = $trn->resultevents();
index 3133d04..5bc9a66 100644 (file)
@@ -47,13 +47,25 @@ class SmokeFilterExtension extends Twig_Extension
        public function getFilters()
        {
                return array(
-                       'isObject' => new Twig_Filter_Method($this, 'isObject'),
+                       'isObject' => new Twig_Filter_Method($this, 'isObjectTest'),
                        'isFalse'  => new Twig_Filter_Method($this, 'isFalse'),
+                       'getClass' => new Twig_Filter_Method($this, 'getClass'),
                );
        }
        
-       public function isObject($i){return is_a($i,"WObject");}
+       public function isObjectTest($i)
+       {
+               if(!is_object($i))return false;
+               return is_subclass_of($i,"WObject");
+       }
        public function isFalse($i){return $i===false || $i === null;}
+       public function getClass($o)
+       {
+               if(is_object($o))
+                       return get_class($o);
+               else
+                       return "basic:".gettype($o);
+       }
        
        public function getName()
        {
index 8ac2d02..48e7cda 100644 (file)
@@ -291,5 +291,200 @@ class WOCustomer extends WOCustomerAbstract
                //send mail
                mb_send_mail($ct->email,$subject,$mailtext,$mailheader);
        }
+       
+       /**page shown to the customer after clicking the password reset link above*/
+       static public function resetLoginPage()
+       {
+               global $HTTPARGS,$twig,$basevars,$db;
+               $vars=$basevars;
+               //get customer and reset code
+               if(!isset($HTTPARGS['customer']) || !isset($HTTPARGS['passcode'])){
+                       $p=$twig->loadTemplate('reseterror.html');
+                       $vars['errorText']=tr("There is a problem with your mail client or your browser: please copy the URL into the browser manually and try again.");
+                       return $p->render($vars);
+               }
+               //get customer
+               $cts=WTcustomer::selectFromDB("email=".$db->escapeString($HTTPARGS['customer']));
+               if(count($cts)<1){
+                       $p=$twig->loadTemplate('reseterror.html');
+                       $vars['errorText']=tr("This user does not exist.");
+                       return $p->render($vars);
+               }
+               $ct=$cts[0];
+               //check passcode validity
+               if($db->isNull($ct->rsttill) || $db->isNull($ct->rstcode) ||
+                  $ct->rstcode!=$HTTPARGS['passcode'] || $ct->rsttill < time()){
+                       $p=$twig->loadTemplate('reseterror.html');
+                       $vars['errorText']=tr("The passcode supplied by your browser is either invalid or expired.");
+                       return $p->render($vars);
+               }
+               //check for change request
+               $p1=$basevars['inputnames']['login']['passwd'];
+               $p2=$basevars['inputnames']['login']['passwdrepeat'];
+               if(isset($HTTPARGS[$p1]) && isset($HTTPARGS[$p2])){
+                       if($HTTPARGS[$p1] != $HTTPARGS[$p2] || $HTTPARGS[$p1] == ""){
+                               $p=$twig->loadTemplate('reseterror.html');
+                               $vars['errorText']=tr("The password does not match or is empty, please use the back button of your browser and try again.");
+                               return $p->render($vars);
+                       }
+                       //set password
+                       $ct->passwd=Session::passwdHash($HTTPARGS[$p1]);
+                       $ct->rsttill=null;
+                       $ct->rstcode=null;
+                       $ct->update();
+                       $vars['passwdchanged']=true;
+               }else $vars['passwdchanged']=false;
+               //render page
+               $p=$twig->loadTemplate('resetlogin.html');
+               $vars['customer']=WOCustomer::fromTablecustomer($ct);
+               $vars['customer_name']=$HTTPARGS['customer'];
+               $vars['passcode']=$HTTPARGS['passcode'];
+               return $p->render($vars);
+       }
+       
+       /** \page templates Templates
+       \section tpl_login Login Page
+
+       The login.html template is used to render the customer login and registration page.
+
+       \param script.customerLogin the page to call for logging in
+       \param script.customerRegistration the page to call for registering a new customer
+       \param customer_name the name of the customer (or an empty string if unknown)
+       */
+
+       /** creates a login page
+
+       For templating info see \ref tpl_login Login Variables
+       and \ref tpl_base Base Variables.
+       */
+       static public function loginPage($extension)
+       {
+               global $twig,$basevars,$HTTPARGS,$db;
+               //get cart id and check it
+               $cartid=WebCart::getCart();
+               if($cartid==""){
+                       $p=$twig->loadTemplate("carterror.html");
+                       return $p->render($basevars);
+               }
+               
+               //cart is ok, now get the object
+               $cart = WOWebCart::fromTablecart(WTcart::getFromDB($cartid));
+               if(!is_a($cart,"WOWebCart")){
+                       //ooops. internal problem
+                       $p=$twig->loadTemplate("carterror.html");
+                       return $p->render($basevars);
+               }
+               $list=$basevars;
+               $list["cart"]=$cart;
+               $list["customer_name"]="";
+               $list['script']['customerLogin']=$basevars['script']['customerLogin'.$extension];
+               $list['script']['customerRegistration']=$basevars['script']['customerRegistration'.$extension];
+               $list["customer_name"]="";
+               if(isset($HTTPARGS["customer_name"]))
+                       $list["customer_name"]=$HTTPARGS["customer_name"];
+               else{
+                       //get cart id and check it
+                       $cartid=WebCart::getCart();
+                       if($cartid!=""){
+                               //cart is ok, now get the object
+                               $cart = WTcart::getFromDB($cartid);
+                               $custid=$cart->customerid;
+                               if(!$db->isNull($custid)){
+                                       $cust=WTcustomer::getFromDB($custid);
+                                       $list["customer_name"]=$cust->email;
+                               }
+                       }else{
+                               //get session and check it
+                               $sess=WOWebSession::getOrCreateWebSession();
+                               $cust=$sess->getcustomer();
+                               if(is_a("WOCustomer",$cust))
+                                       $list["customer_name"]=$cust->getemail();
+                       }
+               }
+               //display
+               $p=$twig->loadTemplate("login.html");
+               return $p->render($list);
+       }
+
+
+       /** \page templates Templates
+       \section tpl_logerr Login Error
+
+       The loginerror.html template is used to render customer login and registering errors.
+
+       \param errorType the type of error: "login" - the login failed (wrong mail or password), "exist" - an account with the same mail already exists, "mismatch" - the new passwords do no match
+       \param backUrl the URL to call back to the login page
+       */
+
+       ///renders a login error page, see \ref tpl_logerr Login Error Template
+       static private function loginError($errorType)
+       {
+               global $basevars,$HTTPARGS,$SERVER,$twig;
+               //find some basics
+               $vars=$basevars;
+               $vars["errorType"]=$errorType;
+               //construct URL back to login page
+               if(isset($_SERVER["HTTP_REFERER"])){
+                       $vars["backUrl"]=$_SERVER["HTTP_REFERER"];
+               }else{
+                       //not really helpful, but nice for a fallback
+                       $vars["backUrl"]=$basevars['script']['root'];
+               }
+               if(strstr($vars["backUrl"],"?")===false)
+                       $vars["backUrl"].="?";
+               else
+                       $vars["backUrl"].="&";
+               $idx=$basevars['inputnames']['login']['name'];
+               $vars["backUrl"].=$idx."=";
+               if(isset($HTTPARGS[$idx]))$vars["backUrl"].=$HTTPARGS[$idx];
+               //render page
+               $p=$twig->loadTemplate("loginerror.html");
+               return $p->render($vars);
+       }
+
+       ///check the login of the customer, either forwards to the checkout page or shows the loginerror page
+       static public function checkLogin($next,$storeincart)
+       {
+               global $HTTPARGS,$db,$basevars;
+               //find customer
+               $nameidx=$basevars['inputnames']['login']['name'];
+               $passidx=$basevars['inputnames']['login']['passwd'];
+               if(!isset($HTTPARGS[$nameidx]) || !isset($HTTPARGS[$passidx])){
+                       return self::loginError("param");
+               }
+               $ct=WTcustomer::selectFromDB("email=".$db->escapeString($HTTPARGS[$nameidx]));
+               if(count($ct)<1){
+                       return self::loginError("login");
+               }
+               //check password
+               $ct=$ct[0];
+               if(!Session::passwdVerify($HTTPARGS[$passidx],$ct->passwd)){
+                       return self::loginError("login");
+               }
+               //store in cart
+               if($storeincart){
+                       $cartid=WebCart::getCart();
+                       if($cartid==""){
+                               $p=$twig->loadTemplate("carterror.html");
+                               return $p->render($basevars);
+                       }
+                       $cart=WTcart::getFromDB($cartid);
+                       $cart->customerid=$ct->customerid;
+                       $cart->update();
+               }
+               //store in session
+               $sess=WOWebSession::getOrCreateWebSession();
+               $st=WTwebsession::getFromDB($sess->getsessionid());
+               $st->customerid=$ct->customerid;
+               $st->update();
+               //go to checkout page
+               redirectHome(array("mode"=>$next));
+       }
+
+       static public function registerCustomer()
+       {
+               global $HTTPARGS,$db,$basevars;
+               die ("not implemented");
+       }
 };
 ?>
\ No newline at end of file
index 61b84c3..5a76b70 100644 (file)
@@ -12,6 +12,13 @@ include('inc/loader_nonadmin.php');
 $HTTPARGS=$_GET;
 foreach($_POST as $a=>$p)$HTTPARGS[$a]=$p;
 
+function getHttpArg($name,$default=null)
+{
+       global $HTTPARGS;
+       if(isset($HTTPARGS[$name]))return $HTTPARGS[$name];
+       return $default;
+}
+
 //set common basics
 $mode="index";
 if(isset($_GET["mode"])){
@@ -68,13 +75,23 @@ try{
                        $page=WebCart::checkout();
                        break;
                case "orderLogin":
-                       $page=WebCart::orderLoginPage();
+                       $page=WOCustomer::loginPage("Order");
+                       break;
+               case "customerLoginOrder":
+                       $page=WOCustomer::checkLogin("checkout",true);
                        break;
-               case "customerLogin":
-                       $page=WebCart::checkOrderLogin();
+               case "customerRegistrationOrder":
+                       $page=WOCustomer::registerCustomer("checkout",true);
                        break;
-               case "customerRegistration":
-                       $page=WebCart::registerCustomer();
+               case "changeDeliveryAddress":
+               case "changeInvoiceAddress":
+                       $page=WebCart::changeAddressPage($mode);
+                       break;
+               case 'placeOrder':
+                       $page=WebCart::placeOrder();
+                       break;
+               case "customerResetLogin":
+                       $page=WOCustomer::resetLoginPage();
                        break;
 /*             case "orderOverview":
                        orderTickets();
@@ -94,18 +111,24 @@ try{
                case "compile":
                        TemplateCompiler::execute();
                        break;
+               case "index":
+                       $page=$twig->loadTemplate("index.html")->render($basevars);
+                       break;
                default:
                        $page=EventRender::createEventList();
                        break;
        }
 }catch(Exception $ex){
+       //log to (Apache) log file
        error_log($ex->getMessage());
+       //get error template (or fallback for it)
        try{
                $p=$twig->loadTemplate("error.html");
        }catch(Exception $ex2){
                $twig->setLoader(new Twig_Loader_String);
                $p=$twig->loadTemplate("<font color=\"red\">{{ErrorText}}</font><p/><pre>\n{{ErrorTrace}}\n</pre>");
        }
+       //show error or some excuse for not showing one
        $e=$basevars;
        if($WebShowErrors){
                $e["ErrorText"]=$ex->getMessage();
diff --git a/www/template/en/changeaddress.html b/www/template/en/changeaddress.html
new file mode 100644 (file)
index 0000000..9747ecb
--- /dev/null
@@ -0,0 +1,43 @@
+{# Example Template for MagicSmoke
+   ================================
+   this one is called to select an address
+#}
+{% extends 'layout.html' %}
+
+{% block title %}Address Selection{% endblock %}
+
+{% block page %}
+<a href="{{script.checkout}}">Cancel Address Selection</a>
+
+<h2>Select Existing Address</h2>
+
+<form action="{{script.this}}" method="POST">
+{% for addr in customer.addresses %}
+ {{addr.name}}<br/>
+ {{addr.addr1}}<br/>
+ {{addr.addr2}}<br/>
+ {{addr.zipcode}} {{addr.city}}, {{addr.state}}<br/>
+ {{addr.country.name}}<br/>
+ <button type="submit" name="{{inputnames.address.setaddress}}" value="{{addr.addressid}}">Select</button><p>
+{% endfor %}
+</form>
+
+<h2>Create New Address</h2>
+
+<form action="{{script.this}}" method="POST">
+ <table>
+ <tr><td>Name:</td><td><input type="text" name="{{inputnames.address.name}}" value="{{customer.title}} {{customer.name}}, {{customer.firstname}}" size="60"/></td></tr>
+ <tr><td>Address Line 1:</td><td><input type="text" name="{{inputnames.address.addr1}}" size="60"/></td></tr>
+ <tr><td>Address Line 2:</td><td><input type="text" name="{{inputnames.address.addr2}}" size="60"/></td></tr>
+ <tr><td>City:</td><td><input type="text" name="{{inputnames.address.city}}" size="60"/></td></tr>
+ <tr><td>State:</td><td><input type="text" name="{{inputnames.address.state}}" size="60"/></td></tr>
+ <tr><td>Country:</td><td><select name="{{inputnames.address.country}}">
+  {% for ctry in countries %}
+   <option value="{{ctry.id}}">{{ctry.name}}</option>
+  {% endfor %}
+ </select></td></tr>
+ </table>
+ <input type="submit" name="{{inputnames.address.createaddress}}" value="Create and Select"/>
+</form>
+
+{% endblock page %}
diff --git a/www/template/en/checkout.html b/www/template/en/checkout.html
new file mode 100644 (file)
index 0000000..7653a60
--- /dev/null
@@ -0,0 +1,96 @@
+{# Example Template for MagicSmoke
+   ================================
+   this one is called to show the cart of a customer
+#}
+{% extends 'layout.html' %}
+
+{% block title %}Cart{% endblock %}
+
+{% block page %}
+ {# this just shows what is possible, we do not actually need to tell the user how secury it is...#}
+ <p style="font-size:40%;">This is cart {{cart.cartid}}. It will expire {{cart.timeout|asDateTime}}.</p>
+
+ <h2>Customer</h2>
+ {{cart.customer.title}} {{cart.customer.name}}, {{cart.customer.firstname}}
+ <h3>Invoice Address</h3>
+ {% if cart.invoiceaddress|isObject %}
+ {{cart.invoiceaddress.name}}<br/>
+ {{cart.invoiceaddress.addr1}}<br/>
+ {{cart.invoiceaddress.addr2}}<br/>
+ {{cart.invoiceaddress.zipcode}} {{cart.invoiceaddress.city}}, {{cart.invoiceaddress.state}}<br/>
+ {{cart.invoiceaddress.country.name}}
+ {% else %}
+ No invoice address.
+ {% endif %}
+ <a href="{{script.changeInvoiceAddress}}">Change Address</a>
+ <h3>Delivery Address</h3>
+ {% if cart.deliveryaddress|isObject %}
+ {{cart.deliveryaddress.name}}<br/>
+ {{cart.deliveryaddress.addr1}}<br/>
+ {{cart.deliveryaddress.addr2}}<br/>
+ {{cart.deliveryaddress.zipcode}} {{cart.deliveryaddress.city}}, {{cart.deliveryaddress.state}}<br/>
+ {{cart.deliveryaddress.country.name}}
+ {% else %}
+ Same as invoice address.
+ {% endif %}
+
+ <a href="{{script.changeDeliveryAddress}}">Change Address</a>
+ <h2>Cart Items</h2>
+ {# build a table with all the items of this shopping cart:
+ this is the headline: #}
+ <table frame="1" border="1">
+ <tr><td><b>Item</b></td><td><b>Item Price</b></td><td><b>Amount</b></td><td><b>Sum</b></td></tr>
+ {# go through tickets and render them #}
+ {% for ticket in cart.tickets %}
+   {% set pricesum=ticket.price * ticket.amount %}
+   <tr>
+   <td>Ticket: {{ticket.event.title}} ({{ticket.eventprice.pricecategory.name}})</td>
+   <td align="right">{{ticket.price|asMoney}}</td>
+   <td align="right">{{ticket.amount}}</td>
+   <td align="right">{{pricesum|asMoney}}</td>
+   </tr>
+ {% endfor %}
+ {# now go through vouchers #}
+ {% for voucher in cart.vouchers %}
+ <tr>
+ <td>Voucher</td>
+ <td align="right">{{voucher.value|asMoney}}</td>
+ <td align="right">1</td>
+ <td align="right">{{voucher.value|asMoney}}</td>
+ </tr>
+ {% endfor %}
+ {# TODO: go through product items #}
+ {# render the shipping option #}
+ {% if cart.shipping|isObject %}
+   <tr><td>Shipping: {{cart.shipping.description}}</td>
+   <td align="right">{{cart.shipping.cost|asMoney}}</td>
+   <td align="right">1</td>
+   <td align="right">{{cart.shipping.cost|asMoney}}</td></tr>
+ {% else %}
+   <tr><td colspan="3">No Shipping</td><td align="right">{{0|asMoney}}</td></tr>
+ {% endif %}
+
+ {# the overall sum of the above items... #}
+ <tr><td colspan="3" align="right"><b>Sum:</b></td><td><b>{{cart.totalsum|asMoney}}</b></td></tr>
+ {# end of the table #}
+ </table>
+ {# actions the user may want to take #}
+ <p><a href="{{script.placeOrder}}">Place Order</a></p>
+ {# in any case: allow the user to shop some more... #}
+ <p><a href="{{script.root}}">Continue Shopping</a></p>
+
+{% endblock page %}
index 1b32945..95a058f 100644 (file)
@@ -1,60 +1,20 @@
 {# Example Template for MagicSmoke
    ================================
-   this one is called to create the event list
+   this one is called to create the main index
 #}
 
 {% extends 'layout.html' %}
 
-{% block title %}Overview{% endblock %}
+{% block title %}Index{% endblock %}
 
 {% block page %}
 
-  {# we use this to show monthly date lines #}
-  {% set olddate = '00' %}
-  
-  {# go through all events that MagicSmoke gave us #}
-  {% for event in events %}
-    {# check whether it actually makes sense to show this event, we do not show any events that the user cannot get tickets for (however, we do show those which are sold out) #}
-    {% if event.canuse %}
-      {# show the monthly date line #}
-      {% set newdate = event.start|date('Y.m') %}
-      {% if newdate != olddate %}
-        <table width="80%"><td><td width="10%"><hr/></td>
-        <td width="125px">{{ event.start|date('F - Y') }}</td>
-        <td width="*"><hr/></td></tr></table>
-      {% endif %}
-      {% set olddate = newdate %}
-      
-      {# show basic data about the event #}
-      <h2>{{event.title}}</h2>
-      {{event.start|asDateTime}}, {{event.room}}<br/>
-      Artist: {{event.artist.name}}<br/>
-      {# uncomment to show the full description
-      {{event.description}}<br/>
-      #}
-      
-      {# show pricing options #}
-      Price: 
-      {% for price in event.price %}
-       {% if price.canuse %}
-        {% if loop.index > 1 %},{% endif %}
-        {{price.price|asMoney}} ({{price.pricecategory.name}})
-       {% endif %}
-      {% endfor %}<br/>
-      
-      {# is it sold out? #}
-      {% if event.amountFree == 0 %}
-        <font color="#ff0000">Event sold out.</font><br/>
-      {% else %}
-        {# only very few tickets left? #}
-        {% if event.amountFree <= 5 %}
-          <font color="#ff0000">Event almost sold out.</font><br/>
-        {% endif %}
-        <a href="{{script.eventDetails}}{{event.ID}}">details/order tickets</a>
-      {% endif %}
-      
-    {# end of event... #}
-    {% endif %}
-  {% endfor %}
+<ul>
+<li><a href="{{script.root|raw}}">Main Page</a></li>
+<li><a href="{{script.tickets|raw}}">Ticket Shop</a></li>
+<li><a href="{{script.vouchers|raw}}">Voucher Shop</a></li>
+<li><a href="{{script.shop|raw}}">Merchandising</a></li>
+<li><a href="{{script.mycart|raw}}">My Shoping Cart</a></li>
+</ul>
 
 {% endblock page %}
index 28e3839..0c59936 100644 (file)
@@ -8,7 +8,8 @@
 <body>
 <!-- Begin Menu -->
 <p align="right">
-<a href="{{script.root|raw}}">Ticket Shop</a> |
+<a href="{{script.root|raw}}">Main Page</a> |
+<a href="{{script.tickets|raw}}">Ticket Shop</a> |
 <a href="{{script.vouchers|raw}}">Voucher Shop</a> |
 <a href="{{script.shop|raw}}">Merchandising</a> |
 <a href="{{script.mycart|raw}}">My Shoping Cart</a>
similarity index 95%
rename from www/template/en/orderlogin.html
rename to www/template/en/login.html
index 33c126f..8d2e21c 100644 (file)
@@ -11,7 +11,7 @@
 
 {# the login dialog #}
 <div id="usediv">
-  <form action="{{script.customerLogin}}&next=checkout" method="POST">
+  <form action="{{script.customerLogin}}" method="POST">
     <table>
     <tr><td>E-mail address:</td><td><input type="text" name="{{inputnames.login.name}}" value="{{customer_name}}" /></td></tr>
     <tr><td>Password:</td><td><input type="password" name="{{inputnames.login.passwd}}"/></td></tr>
@@ -24,7 +24,7 @@
 
 {# the create account dialog #}
 <div id="creatediv">
-  <form action="{{script.customerRegistration}}&next=checkout" method="POST">
+  <form action="{{script.customerRegistration}}" method="POST">
     <table>
     <tr><td>E-mail address:</td><td><input type="text" name="{{inputnames.login.name}}" value="{{customer_name}}" /></td></tr>
     <tr><td>Select a Password:</td><td><input type="password" name="{{inputnames.login.passwd}}"/></td></tr>
diff --git a/www/template/en/reseterror.html b/www/template/en/reseterror.html
new file mode 100644 (file)
index 0000000..5b51263
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<title>Password Reset Error</title>
+<body>
+<h1>Password Reset Error</h1>
+
+{{errorText}}<p/>
+
+<hr/>
+<a href="{{script.root}}">Back to Index</a>
+</html>
\ No newline at end of file
diff --git a/www/template/en/resetlogin.html b/www/template/en/resetlogin.html
new file mode 100644 (file)
index 0000000..eff7543
--- /dev/null
@@ -0,0 +1,30 @@
+{# Example Template for MagicSmoke
+   ================================
+   this one is called to show the reset password page for a customer
+#}
+{% extends 'layout.html' %}
+
+{% block title %}Reset Password{% endblock %}
+
+{% block page %}
+<b>Hello {{customer.firstname}} {{customer.name}},</b><br/>
+
+{% if passwdchanged %}
+you have successfully changed your password.<p>
+
+<a href="{{script.root}}">Continue shopping</a>
+{% else %}
+please enter a new password for yourself below:<p>
+<form action="{{script.customerResetLogin}}" method="POST">
+  <input type="hidden" name="passcode" value="{{passcode}}" />
+  <input type="hidden" name="customer" value="{{customer_name}}" />
+  <table>
+  <tr><td>E-mail address:</td><td>{{customer_name}}</td></tr>
+  <tr><td>New Password:</td><td><input type="password" name="{{inputnames.login.passwd}}"/></td></tr>
+  <tr><td>Repeat Password:</td><td><input type="password" name="{{inputnames.login.passwdrepeat}}"/></td></tr>
+  </table><p/>
+  <input type="submit" value="Reset Password"/>
+</form><p/>
+{% endif %}
+
+{% endblock page %}
diff --git a/www/template/en/tickets.html b/www/template/en/tickets.html
new file mode 100644 (file)
index 0000000..1b32945
--- /dev/null
@@ -0,0 +1,60 @@
+{# Example Template for MagicSmoke
+   ================================
+   this one is called to create the event list
+#}
+
+{% extends 'layout.html' %}
+
+{% block title %}Overview{% endblock %}
+
+{% block page %}
+
+  {# we use this to show monthly date lines #}
+  {% set olddate = '00' %}
+  
+  {# go through all events that MagicSmoke gave us #}
+  {% for event in events %}
+    {# check whether it actually makes sense to show this event, we do not show any events that the user cannot get tickets for (however, we do show those which are sold out) #}
+    {% if event.canuse %}
+      {# show the monthly date line #}
+      {% set newdate = event.start|date('Y.m') %}
+      {% if newdate != olddate %}
+        <table width="80%"><td><td width="10%"><hr/></td>
+        <td width="125px">{{ event.start|date('F - Y') }}</td>
+        <td width="*"><hr/></td></tr></table>
+      {% endif %}
+      {% set olddate = newdate %}
+      
+      {# show basic data about the event #}
+      <h2>{{event.title}}</h2>
+      {{event.start|asDateTime}}, {{event.room}}<br/>
+      Artist: {{event.artist.name}}<br/>
+      {# uncomment to show the full description
+      {{event.description}}<br/>
+      #}
+      
+      {# show pricing options #}
+      Price: 
+      {% for price in event.price %}
+       {% if price.canuse %}
+        {% if loop.index > 1 %},{% endif %}
+        {{price.price|asMoney}} ({{price.pricecategory.name}})
+       {% endif %}
+      {% endfor %}<br/>
+      
+      {# is it sold out? #}
+      {% if event.amountFree == 0 %}
+        <font color="#ff0000">Event sold out.</font><br/>
+      {% else %}
+        {# only very few tickets left? #}
+        {% if event.amountFree <= 5 %}
+          <font color="#ff0000">Event almost sold out.</font><br/>
+        {% endif %}
+        <a href="{{script.eventDetails}}{{event.ID}}">details/order tickets</a>
+      {% endif %}
+      
+    {# end of event... #}
+    {% endif %}
+  {% endfor %}
+
+{% endblock page %}