21492 Posts in 5783 Topics by 2621 members
| Go to End | Next > | |
| Author | Topic: | 1641 Views |
-
Method Calls from Templates Fail

14 January 2010 at 3:59pm Last edited: 14 January 2010 4:17pm
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?
-
Re: Method Calls from Templates Fail

14 January 2010 at 4:35pm
Might be helpful if you post the affected code
-
Re: Method Calls from Templates Fail

14 January 2010 at 4:41pm Last edited: 14 January 2010 4:44pm
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 %> -
Re: Method Calls from Templates Fail

14 January 2010 at 6:59pm Last edited: 14 January 2010 7:01pm
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
-
Re: Method Calls from Templates Fail

15 January 2010 at 5:09am Last edited: 15 January 2010 5:27am
_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?
-
Re: Method Calls from Templates Fail

15 January 2010 at 11:41am Last edited: 15 January 2010 11:50am
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"> </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"> </td>
<td colspan="2" align="right" class="noborder">Sub Total</td>
<td align="right" nowrap="nowrap" class="borderleft">$SubTotal</td>
<td align="right"> </td>
</tr>
<tr>
<td align="left" valign="bottom" class="noborder"> </td>
<td colspan="2" align="right" class="noborder">GST</td>
<td align="right" class="borderleft">$GST</td>
<td align="right"> </td>
</tr>
<% end_if %>
<tr>
<td align="left" valign="bottom" class="noborder"> </td>
<td colspan="2" align="right" class="noborder"><strong>Total</strong></td>
<td align="right" class="borderleft"><strong>$$GrandTotal</strong></td>
<td align="right"> </td>
</tr>
<% end_if %>
</table>This seems to work well enough is probally a more pure SS way though hope this helps.
-
Re: Method Calls from Templates Fail

15 January 2010 at 2:38pm Last edited: 15 January 2010 2:42pm
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 %> -
Re: Method Calls from Templates Fail

15 January 2010 at 2:52pm Last edited: 15 January 2010 2:52pm
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()
| 1641 Views | ||
| Go to Top | Next > |



