Jump to:

22976 Posts in 11620 Topics by 2826 members

General Questions

SilverStripe Forums » General Questions » Method Calls from Templates Fail

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2
Go to End
Author Topic: 2057 Views
  • arsenic
    Avatar
    Community Member
    9 Posts

    Method Calls from Templates Fail Link to this post

    In one of my controllers, a method returns a DataObjectSet of plain objects. Lets say the objects' class has a method called objectMethod that returns a value. In the template, I loop through the DSO with with <% control %> and print the value of objectMethod with $objectMethod. However it doesn't print. The template documentation says that $obj->objectMethod() should have been called. Fields work fine. What's happening?

  • Willr
    Avatar
    Forum Moderator
    5462 Posts

    Re: Method Calls from Templates Fail Link to this post

    Might be helpful if you post the affected code

  • arsenic
    Avatar
    Community Member
    9 Posts

    Re: Method Calls from Templates Fail Link to this post

    Cart.php:

    class Cart {
    var $_items = array(); // array of Cart_Items

    ...

    function getItems() {
    return new DataObjectSet($this->_items);
    }
    }

    class Cart_Item {
    var $_id;

    function getSubtotal() {
    return 0; // for testing
    }
    }

    class Cart_Controller extends Controller {

    ...

    function getItems() {
    return $this->_cart->getItems(); // $this->_cart is an instance of Cart
    }

    }

    Cart.ss:

    <% control getItems %>
    $getSubtotal // doesn't work
    $_id // works
    <% end_control %>

  • CodeGuerrilla
    Avatar
    Community Member
    105 Posts

    Re: Method Calls from Templates Fail Link to this post

    I think it is because you are inside a control getSubtotal is another control try using $Top to break out of the controls varibles to the controllers top level functions, also it looks like getSubtotal should be in the Cart_Controller and retrieve the value from Cart_Items?

    <% control getItems %>
    $Top.getSubtotal // should work
    $_id // must be a property of getItems ?
    <% end_control %>

    This is a common confusion with SilverStripe has got me once or twice

  • arsenic
    Avatar
    Community Member
    9 Posts

    Re: Method Calls from Templates Fail Link to this post

    _id and getSubtotal are in Cart_Item. getSubtotal multiplies the price of an item with its quantity. getItems returns an array of Cart_Items. Shouldn't <% control getItems %> loop through the array of Cart_Items, in which I can call the properties and methods of each Cart_Item?

  • CodeGuerrilla
    Avatar
    Community Member
    105 Posts

    Re: Method Calls from Templates Fail Link to this post

    Hmm I guess you can do that the Cart I have wrote for SilverStripe uses the SessionID in the Cart table and you call the getSubTotal from the Cart object (you could also do this with SQL and have a field to store it in the Cart DataObject)

    Cart.php (dataobject)

    ...

    public function getSubTotal()
       {
          $items = self::getBySessionID(session_id());
          $out = array();
          if($items) {
             foreach($items as $item) {
                array_push($out, ($item->Price * $item->Quantity));
             }
             return array_sum($out);
          }
       }

    public function getBySessionID($SessionID)
       {
          return DataObject::get("Cart", sprintf("SessionID = '%s'", $SessionID));
       }
    ...

    page.php (want these functions global)
    Page_Controller

    ...

    public function CartItems()
    {
          $items = Cart::getBySessionID(session_id());
          return $items;
    }

    public function SubTotal()
    {
          return number_format(Cart::getSubTotal(), 2);
    }

    ...

    Cart.ss (template include)

    <table width="213" cellpadding="2" cellspacing="0">
    <% if CartItems %>
    <tr>
    <th align="left" class="borderleft">Product</th>
    <th align="left">Price</th>
    <th align="center">Qty</th>
    <th align="right">Total</th>
    <th align="right">&nbsp;</th>
    </tr>
    <% end_if %>
    <% if CartItems %>
    <% control CartItems %>
    <tr>
    <td class="borderleft"><a href="$Product.URLSegment/">$Product.Title</a></td>
    <td>$Product.Price</td>
    <td align="center"><form action="$Top.URLSegment/update" method="post"><div><input name="Quantity" class="quantity" value="$Quantity" size="1" maxlength="2" /><input type="hidden" name="CartID" value="$ID" /></div></form></td>
       <td align="right">$Total</td>
    <td align="center"><a href="$Top.URLSegment/remove/$ID">x</a></td>
    </tr>
    <% end_control %>
    <% else %>
          <tr class="empty"><td class="noborder" colspan="5">Your cart is currently empty.</td></tr>
    <% end_if %>
    <% if CartItems %>
    <% if UseGST %>
    <tr>
    <td align="left" valign="bottom" class="noborder">&nbsp;</td>
    <td colspan="2" align="right" class="noborder">Sub Total</td>
    <td align="right" nowrap="nowrap" class="borderleft">$SubTotal</td>
    <td align="right">&nbsp;</td>
    </tr>
    <tr>
    <td align="left" valign="bottom" class="noborder">&nbsp;</td>
    <td colspan="2" align="right" class="noborder">GST</td>
    <td align="right" class="borderleft">$GST</td>
    <td align="right">&nbsp;</td>
    </tr>
    <% end_if %>
    <tr>
    <td align="left" valign="bottom" class="noborder">&nbsp;</td>
    <td colspan="2" align="right" class="noborder"><strong>Total</strong></td>
    <td align="right" class="borderleft"><strong>$$GrandTotal</strong></td>
    <td align="right">&nbsp;</td>
    </tr>
    <% end_if %>
    </table>

    This seems to work well enough is probally a more pure SS way though hope this helps.

  • arsenic
    Avatar
    Community Member
    9 Posts

    Re: Method Calls from Templates Fail Link to this post

    Thanks for the code, but I think there is a larger, more serious, problem.

    The following test case does not work:

    Test.php

    class Apple {

       var $_color;

       function __construct($color) {
          $this->_color = $color;
       }

       function getColor() {
          return $this->_color;
       }
    }

    class Test_Controller extends Controller {
       function init() {
          parent::init();
       }

       function getApples() {
          $a = array();
          $a[] = new Apple('red');
          $a[] = new Apple('green');

          return new DataObjectSet($a);
       }
    }

    Test.ss:

    <% control getApples %>
    $_color // prints red and green
    $getColor // does not print anything
    <% end_control %>

  • CodeGuerrilla
    Avatar
    Community Member
    105 Posts

    Re: Method Calls from Templates Fail Link to this post

    You might have to use them statically depends on the way SilverStripe initializes the functions if it is statically then __construct may not be called you would have to do the new Apple('red') as this calls the constructor. So I am guessing SS is calling it like Apple::getColor()

    2057 Views
Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.