docu for templates
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Mon, 5 Jul 2010 19:53:59 +0000 (19:53 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Mon, 5 Jul 2010 19:53:59 +0000 (19:53 +0000)
make eventOrder more robust
make cart table defs more robust

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

wob/cart.wolf
wob/user.wolf
www/inc/rendering/autoload.php
www/inc/rendering/cart_listing.php
www/inc/rendering/twig_extensions.php
www/inc/wext/event.php
www/index.php
www/template/en/cart.html
www/template/en/eventdetails.html
www/template/en/index.html
www/template/en/layout.html

index aae1f75..ca8afb4 100644 (file)
@@ -7,7 +7,7 @@
    - see COPYING.AGPL for details
    -->
 <Wolf>
-       <Table name="cart">
+       <Table name="cart" backup="no">
                <Column name="cartid" type="string:32" primarykey="yes">
                        the cookie for this cart
                        <Call lang="php" method="WebCart::getNewCartId()"/>
@@ -28,7 +28,7 @@
                pointer to shipping type (none per default, programmatic default is in config)
                </Column>
        </Table>
-       <Table name="cartticket">
+       <Table name="cartticket" backup="no">
                <Column name="cartid" type="string:32" notnull="yes" foreignkey="cart:cartid" primarykey="yes"/>
                <!--tickets in the cart-->
                <Column name="eventid" type="int32" notnull="yes" foreignkey="event:eventid" primarykey="yes"/>
                <Column name="amount" type="int32" notnull="yes"/>
                <!-- Column name="seating" type="string:32" null="yes"/ -->
        </Table>
-       <Table name="cartvoucher">
+       <Table name="cartvoucher" backup="no">
                <Column name="cvid" type="seq64" primarykey="yes"/>
                <Column name="cartid" type="string:32" notnull="yes" foreignkey="cart:cartid"/>
                <Column name="value" type="int32" notnull="yes">voucher value in cents</Column>
        </Table>
-       <Table name="cartitem">
+       <Table name="cartitem" backup="no">
                <Column name="ciid" type="seq64" primarykey="yes"/>
                <Column name="cartid" type="string:32" notnull="yes" foreignkey="cart:cartid"/>
                <Column name="productid" type="int32" foreignkey="product:productid" notnull="yes"/>
                <Column name="amount" type="int32" notnull="yes"/>
        </Table>
        
-       <Table name="websession">
+       <Table name="websession" backup="no">
                <Column name="sessionid" type="string:64" primarykey="yes"/>
                <!--/customer-->
                <Column name="customerid" type="int32" notnull="yes" foreignkey="customer:customerid"/>
                <Abstract lang="php"/>
                <Doc>The cart as used by the web user interface, this maps into the cart tables. This class is never used by the </Doc>
                <Property name="cartid" type="astring">The cart ID of this session</Property>
+               <Property name="timeout" type="int">When the cart will be automatically deleted</Property>
                <Property name="customerid" type="int32">The customer of this cart</Property>
                <Property name="deliveryaddressid" type="int64">The address to deliver to (mandatory)</Property>
                <Property name="invoiceaddressid" type="int64">The address to send the invoice to if different from the delivery address (optional)</Property>
                
                <Mapping table="cart">
                        <Map property="cartid"/>
+                       <Map property="timeout"/>
                        <Map property="customerid"/>
                        <Map property="deliveryaddressid" column="deliveryaddress"/>
                        <Map property="invoiceaddressid" column="invoiceaddress"/>
index 8320696..5f0971d 100644 (file)
@@ -58,7 +58,7 @@
                <Column name="host" type="string:64" notnull="yes" foreignkey="host:hostname" primarykey="yes"/>
        </Table>
        
-       <Table name="session">
+       <Table name="session" backup="no">
                <Column name="sessionid" type="string:64" primarykey="yes"/>
                <Column name="uname" type="string:64" notnull="yes" foreignkey="user:uname"/>
                <!-- unix timestamp at which to delete this session -->
index 256c4e4..f42aed8 100644 (file)
@@ -11,6 +11,8 @@
 $d=dirname(__FILE__);
 wob_autoclass("EventRender",$d.'/event_listing.php');
 wob_autoclass("WebCart",$d.'/cart_listing.php');
+
 wob_autoclass("LangFilterExtension",$d.'/twig_extensions.php');
+wob_autoclass("SmokeFilterExtension",$d.'/twig_extensions.php');
 
 ?>
index 7610d96..2dde2a2 100644 (file)
@@ -25,16 +25,21 @@ static public function addTickets(){
        //get the cart
        $cartid=self::getOrCreateCart();
        //find event
-       if(!isset($HTTPARGS['event']) || !isset($HTTPARGS[self::TicketAmountField]))
+       if(!isset($HTTPARGS[self::TicketAmountField]))
                redirectHome();
-       $evid=$HTTPARGS['event']+0;
        //find price categories
        $pcs=$HTTPARGS[self::TicketAmountField];
        if(!is_array($pcs) || count($pcs)==0)
                redirectHome();
        //go through them
        foreach($pcs as $pcid => $amount){
-               $pcid=$pcid+0;$amount=$amount+0;
+               //extract event ID from pcid
+               $evid=WOEventPrice::getEventIdFromAmountIndex($pcid);
+               //convert pcid to int
+               $pcid=WOEventPrice::getCategoryIdFromAmountIndex($pcid);
+               //convert amount to int
+               $amount=$amount+0;
+               //actually add
                WTrWebCartAddTicket::execute($cartid,$evid,$pcid,$amount);
        }
        //go to the cart
@@ -126,7 +131,7 @@ static public function getNewCartId(){
 /** creates the cart overview */
 static public function createCartOverview()
 {
-       global $twig,$basevars;
+       global $twig,$basevars,$WebForceShipping;
        
        //get cart id and check it
        $cartid=self::getCart();
@@ -135,19 +140,26 @@ static public function createCartOverview()
                return $p->render($basevars);
        }
        
-       //cart is ok, now display it
+       //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);
        }
-
-       $p = $twig->loadTemplate("cart.html");
        $list=$basevars;
        $list["cart"]=$cart;
        
-       // create page
+       //additional info: available shipping types
+       $list["shipping"]=array();
+       $list["forceshipping"]=$WebForceShipping;
+       $sl=WOShipping::fromTableArrayshipping(WTshipping::selectFromDB());
+       foreach($sl as $s)
+               if($s->getcanuse())
+                       $list["shipping"][]=$s;
+
+       //display
+       $p = $twig->loadTemplate("cart.html");
        return $p->render($list);
 }
 
index d10644b..acfb95f 100644 (file)
@@ -31,11 +31,32 @@ class LangFilterExtension extends Twig_Extension
        public function getTime($i){return $this->lang->getTime($i);}
        public function getDateTime($i){return $this->lang->getDateTime($i);}
        
+       public function formatDate($i,$f){return $this->lang->formatDate($i,$f);}
+       
        public function getName()
        {
                return 'LangFilter';
        }
+}
 
+class SmokeFilterExtension extends Twig_Extension
+{
+       public function getFilters()
+       {
+               $this->lang=LanguageManager::singleton();
+               return array(
+                       'isObject' => new Twig_Filter_Method($this, 'isObject'),
+                       'isFalse'  => new Twig_Filter_Method($this, 'isFalse'),
+               );
+       }
+       
+       public function isObject($i){return is_a($i,"WObject");}
+       public function isFalse($i){return $i===false || $i === null;}
+       
+       public function getName()
+       {
+               return 'SmokeFilter';
+       }
 }
 
 ?>
\ No newline at end of file
index 92688a7..746ea17 100644 (file)
@@ -34,10 +34,26 @@ class WOEventPrice extends WOEventPriceAbstract
                return $cnt;
        }
        
-       /**helper for web UI: returns the name of the field for this event price*/
+       /**helper for web UI: returns the name of the field for this event price, always the configured amount field from WebCart plus an index indicating category and event IDs*/
        public function getAmountinputfield()
        {
-               return WebCart::TicketAmountField."[".$this->prop_pricecategoryid."]";
+               return WebCart::TicketAmountField."[".$this->prop_pricecategoryid.":".$this->prop_eventid."]";
+       }
+       
+       /**helper function for web UI: returns the event ID from an amount field index */
+       static public function getEventIdFromAmountIndex($idx)
+       {
+               $sl=explode(":",$idx);
+               if(count($sl==2))return $sl[1]+0;
+               else return null;
+       }
+       
+       /**helper function for web UI: returns the event ID from an amount field index */
+       static public function getCategoryIdFromAmountIndex($idx)
+       {
+               $sl=explode(":",$idx);
+               if(count($sl==2))return $sl[0]+0;
+               else return null;
        }
 };
 
index f072ca9..a025efd 100644 (file)
@@ -32,6 +32,7 @@ foreach($twigextensions as $te){
        $twig->addExtension(new $t());
 }
 $twig->addExtension(new LangFilterExtension);
+$twig->addExtension(new SmokeFilterExtension);
 
 //basic variables shared by all templates
 // script URLs
@@ -39,7 +40,7 @@ $basevars['script']['root']=$_SERVER['SCRIPT_NAME'];
 $basevars['script']['this']=$_SERVER['REQUEST_URI'];
 $basevars['script']['index']=$_SERVER['SCRIPT_NAME']."?mode=index";
 $basevars['script']['eventDetails']=$_SERVER['SCRIPT_NAME']."?mode=eventDetails&event=";
-$basevars['script']['eventOrder']=$_SERVER['SCRIPT_NAME']."?mode=eventOrder&event=";
+$basevars['script']['eventOrder']=$_SERVER['SCRIPT_NAME']."?mode=eventOrder";
 $basevars['script']['cart']=$_SERVER['SCRIPT_NAME']."?mode=cart";
 $basevars['script']['mycart']=$_SERVER['SCRIPT_NAME']."?mode=mycart";
 $basevars['script']['checkout']=$_SERVER['SCRIPT_NAME']."?mode=checkout";
index 8934ac4..70abf5c 100644 (file)
@@ -2,33 +2,62 @@
    ================================
    this one is called to show the cart
 #}
-
 {% extends 'layout.html' %}
 
 {% block title %}Cart{% endblock %}
 
 {% block page %}
- <p style="font-size:40%;">This is cart {{cart.cartid}}</p>
+ {# 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>
 
+ {# the isempty flag tells us whether we need to bother with the rest... #}
  {% if cart.isempty %}
   This cart is empty.
  {% else %}
+  {# 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}}</td><td align="right">{{ticket.price|asMoney}}</td><td align="right">{{ticket.amount}}</td><td align="right">{{pricesum|asMoney}}</td></tr>
+    {% set pricesum=ticket.price * ticket.amount %}
+    <tr><td>Ticket: {{ticket.event.title}}</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}}</td><td align="right">1</td><td align="right">{{voucher.value}}</td></tr>
   {% endfor %}
   
-  <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>
-  <tr><td colspan="3" align="right"><b>Sum:</b></td><td>{{cart.totalsum|asMoney}}</td></tr>
+  {# 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.checkout}}">Checkout</a></p>
+  
+  {# end of the non-empty cart... #}
  {% endif %}
 
+ {# in any case: allow the user to shop some more... #}
  <p><a href="{{script.root}}">Continue Shopping</a></p>
 
-{% endblock %}
+{% endblock page %}
index 8bec38f..0d5a6bd 100644 (file)
@@ -2,31 +2,40 @@
    ================================
    this one is called to create the event detail/order page
 #}
-
 {% extends 'layout.html' %}
 
 {% block title %}{{event.title}}{% endblock %}
 
 {% block page %}
-
+  {# show basic information about the event #}
   {{event.start|asDateTime}}, {{event.room|e}}<br/>
   Artist: {{event.artist.name|e}}<br/>
   {{event.description}}<br/>
-  <form action="{{script.eventOrder|safe}}{{event.ID|safe}}" method="POST">
-  <table>
-  <tr><td>Price:</td><td>Amount:</td></tr>
-  {% for price in event.price %}
-   {% if price.canuse %}
-   <tr><td>{{price.price|asMoney}} ({{price.pricecategory.name}})</td>
-   <td><select name="{{price.amountinputfield}}">
-    {% set ticketsavailable=price.maxavailable - price.amountticketsblock %}
-    {% for i in 0 .. ticketsavailable %}
-      <option>{{i}}</option>
-    {% endfor %}
-    </select></td></tr>
-   {% endif %}
-  {% endfor %}</table><br/>
-  <input type="submit" value="add to cart" />
+  
+  {# start the form that allows users to order for an event, the |safe filter tells the Twig parser that the URL should not be mangled #}
+  <form action="{{script.eventOrder|safe}}" method="POST">
+   <table>
+   {# listing pricing options... #}
+   <tr><td>Price:</td><td>Amount:</td></tr>
+   {% for price in event.price %}
+     {# the objects handed over from MagicSmoke are not filtered, so it is important to check whether it makes sense to offer a specific price category #}
+     {% if price.canuse %}
+       {# if usable: show the details of the price category #}
+       <tr><td>{{price.price|asMoney}} ({{price.pricecategory.name}})</td>
+       {# the amountinputfield property of the price contains the name for the form element to be used for each options amount - please use this property instead of hard coded values! #}
+       <td><select name="{{price.amountinputfield}}">
+         {# the following example shows how to make the selection of tickets more fool-proof by using a select and a few inline calculations #}
+         {% set ticketsavailable=price.maxavailable - price.amountticketsblock %}
+         {% for i in 0 .. ticketsavailable %}
+           <option>{{i}}</option>
+         {% endfor %}
+       </select></td></tr>
+     {% endif %}
+   {% endfor %}
+   </table><br/>
+   
+   {# end of the form... just add a button... #}
+   <input type="submit" value="add to cart" />
   </form>
 
-{% endblock %}
+{% endblock page %}
index f699354..4ab49e5 100644 (file)
@@ -9,16 +9,48 @@
 
 {% block page %}
 
- {% for event in events %}
-  <h2>{{event.name}}</h2>
-  {{event.start|asDate}} {{event.start|asTime}}, {{event.room}}<br/>
-  Artist: {{event.artist.name}}<br/>
-  {{event.description}}<br/>
-  Price: 
-  {% for price in event.price %}
-   {{price.price|asMoney}} ({{price.pricecategory.name}})
-  {% endfor %}<br/>
-  <a href="{{script.eventDetails}}{{event.ID}}">details/order tickets</a>
- {% endfor %}
+  {# 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.name}}</h2>
+      {{event.start|asDateTime}}, {{event.room}}<br/>
+      Artist: {{event.artist.name}}<br/>
+      {{event.description}}<br/>
+      
+      {# show pricing options #}
+      Price: 
+      {% for price in event.price %}
+        {% if loop.index > 1 %},{% endif %}
+        {{price.price|asMoney}} ({{price.pricecategory.name}})
+      {% 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 %}
+{% endblock page %}
index be1e036..bd38368 100644 (file)
@@ -2,7 +2,7 @@
 
 <head>
 <title>{% block title %}{% endblock %} - Magic Smoke Example Layout</title>
-<link rel="stylesheet" type="text/css" href="styles/style.css">
+<link rel="stylesheet" type="text/css" href="styles/style.css"/>
 </head>
 
 <body>