Nice ZF, jQuery and Smarty combo

Today I noticed a nice, short example of the Zend Framework, jQuery and Smarty stack I’m using. It’s got a lot of niceties from each component in a very small space, perfect for showcasing each and how they can be integrated!

The result is an interface where an administrator can settle money transfers. It will start with displaying a list of all requested transfers, when the administrator has manually finished transferring cash to each recipient’s account he can use this interface to update the database.

{config_load file="$config_file"}
<script type="text/javascript">
var baseUrl = "{$baseUrl}/withdrawals/settle"
{literal}
$(document).ready(function(){
	$(".cmp_btn").click(function(){
		var w_id = $(this).attr('id').split('-').pop();
		$("#div-"+w_id).hide("slow");
		$.post(baseUrl, {w_id: w_id}); 
	});
});
</script>
{/literal}
{foreach from=$ws item=w}
	<div id="div-{$w.id}">
		<b>{#amount#}:</b> {$w.amount} <br>
		<b>{#by#}:</b> {$w.user.firstname} {$w.user.lastname}<br>
		<b>{#to_acc#}:</b> {$w.user.account_nbr} <br>
		<b>{#bank#}:</b> {$w.user.bank} <br>
		<b>{#acc_holder#}:</b> {$w.user.account_holder} <br>
		<b>{#date#}:</b> {$w.date|date_format:"%Y-%m-%d"} <br>
		<button id="btn-{$w.id}" class="cmp_btn">{#settle#}</button>
	</div>
{/foreach}

When the admin presses the settle button an ajax call ($.post…) will be made to the WithdrawalsController with the id of the withdrawal request in question. At the same time we slowly hide the div containing the withdrawal info. Everything is playing nicely here except for maybe the {literals} that we need to escape the javascript with.

Note that the html above is a skeleton template, a designer will have to fix it with proper stylesheets before it can be released.

function settleAction(){
  $this->aclOrExit(1000);
  $post 		    = $this->_request->getParams();
  $w 			    = $this->obj->fetchOne($post['w_id']);
  $user 		    = $w->findParentRow('users');
  $user->assets 	-= $w->amount;
  $user->save();
  echo $w->delete();
}

A nice example of how the Zend Table Row works, first we get the withdrawal info ($w) with fetchOne() that is described in the Extending Zend DB Table tutorial. With findParentRow we then fetch the user that made the request. We deduct the withdrawal amount from the user’s assets, save the user and delete the withdrawal request. Almost beautiful!

Almost forgot the view code that will display everything:

function view(){
  $this->aclOrExit(1000);
  $ws = $this->obj->fetchAll()->toArray();
  foreach($ws as &$w)
    $w['user'] = $this->loadModel('users')->fetchOne($w['user_id'])->toArray();
  $this->assign('ws', $ws);
  return $this->fetch('list_all.tpl');
}

Another more complex, and messier example:

{config_load file="$config_file"}
<script type="text/javascript"> 
var baseUrl = "{$baseUrl}/campaigns/rewardAffiliate"
var noMoney = "{#nomoney#}";
{literal}
$(document).ready(function(){ 
    $(".cmp_btn").click(function(){ 
        var arr = $(this).attr('id').split('-');
		var a_id = arr[1]; var a_status = arr[2];
        $.post(baseUrl, {a_id: a_id, status: a_status}, function(result){
			if(result == "nomoney_err")
				alert(noMoney);
			else
				$("#div-"+a_id).hide("slow");
		});  
    }); 
});
</script>
{/literal}
<table>
	{foreach from=$camps item=c}
	<tr>
		<td>
			<b>{$c.camp_name}:</b><br>
			<b>{#leads#}:</b><br>
			{foreach from=$c.actions item=a}
				<div id="div-{$a.id}">
					<b>{#ref_id#}:</b> {$a.ref_id} <br>
			        <b>{#amount#}:</b> {$a.amount} <br> 
			        <b>{#date#}:</b> {$a.stamp|date_format:"%Y-%m-%d"} <br> 
			        <button id="btn-2-{$a.id}" class="cmp_btn">{#cancel#}</button>
				<button id="btn-1-{$a.id}" class="cmp_btn">{#approve#}</button>
			    </div>
			{foreachelse}
				{#no_leads#}
			{/foreach}
		</td>
	</tr>
	{/foreach}
</table>

In the controller:

function rewardAffiliateAction(){
  $a = $this->loadModel('actions')->fetchOne($this->p['a_id']);
  $this->myCampOrDie(array('id' => $a->camp_id));
  $a->status = $this->p['status'];
  if($a->status == 1){
    if($this->checkAccount($a->amount)){
      $user = $this->loadModel('users');
      $user->updateOne(array('assets' => $this->gs->usr_info['assets'] - $a->amount), $this->usr_id);
      $aff = $user->fetchOne($this->loadModel('rotators')->fetchOne($a->rot_id)->aff_id);
      $aff->assets += $a->amount;
      $aff->save();
    }else{
      echo "nomoney_err";
      exit;
    }
  }
  echo $a->save();
}


Related Posts

Tags: , ,