The examples on this site are currently tested to work on Phalcon V3.4 and Phalcon Devtools V3.2 Some issues may arise when using later versions.

Please get in touch or post a comment below the post if you encounter a problem.

In this step we need to review the contents of the cart before supplying additional information and placing the order.

The following action can be added to app/controllers/ScorderController.php. It will pull each item from the cart into an array called $lineItems. The cart only contains a productid and quantity for each line item of the order. For the order to be reviewed we need to display more details about each of the products. With this in mind we will get a full product object using Product::findById($productid) and append it to the array. This will allow us to access the Product details from the view.

public function checkOutAction()
{
	if ($this->session->has('cart')) {
		$cart = $this->session->get('cart');
		$lineitems = array();
		foreach ($cart as $productid => $qty) {
			$lineitem['product'] = Product::findFirstByid($productid);
			$lineitem['qty'] = $qty;
			$lineitems[] = $lineitem;
		}
		$this->view->lineitems = $lineitems;
	}
	else {
		$this->flash->error("There are no items in your cart");
		$this->dispatcher->forward(['controller' => "product",'action' => 'displayGrid']);
	}
}

Next to create the view which will display the contents of the order. Add the following code to a view file corresponding to the action above called app/views/scorder/checkOut.phtml

<?php echo $this->getContent(); ?>
<?php
    echo $this->tag->form(["scorder/placeOrder","autocomplete" => "off", "class" => "form-horizontal"]);
?>
<H2>Place Order</h2>
<table class="table table-condensed table-bordered">
	<thead>
		<tr><th>Id</th><th>Name</th><th>Description</th><th>Colour</th><th>Price</th><th>Quantity</th></tr></thead>
	<tbody>
	<?php $ttlCost=0; $ttlQty=0;?>
	<?php foreach ($lineitems as $lineitem): ?>
		<?php $product=$lineitem['product']; ?>	 
		<tr>
			<td><input size="3" style="border:none" type="text" name="productid[]" readonly value="<?php echo $product->getId()?>"></td>
			<td><?php echo $product->getName() ?></td>
			<td><?php echo $product->getDescription() ?></td>
			<td><?php echo $product->getColour() ?></td>
			<td><div class="price"><?php echo $product->getPrice() ?></div></td>
			<td>
				<input size="3" style="border:none" class="qty" type="text" name="quantity[]" readonly value="<?php echo $lineitem['qty'] ?>">
			</td>
			<td>
				<button type="button" class="btn btn-default add"><span class="glyphicon glyphicon-plus"/></button>
				<button type="button" class="btn btn-default subtract"><span class="glyphicon glyphicon-minus"/></button>
				<button type="button" class="btn btn-default value="remove" onClick="$(this).closest('tr').remove();"><span class="glyphicon glyphicon-remove"/></button>
			</td>
			<?php
				$ttlQty = $ttlQty + $lineitem['qty'];
				$ttlCost = $ttlCost + ($product->getPrice()*$lineitem['qty']);	
			?>
		</tr>
	<?php endforeach; ?>
	
	</tbody>
</table>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

This is an order form and the data from the form will ultimately be submitted to an action called placeOrderAction() in ScorderController.php. Although there is a lot of information displayed on the order form (including the total quantity of items in the order and the total cost of the order overall) all that is actually required to process the order is the productid and quantity for each lineitem. Both of these are actually in input boxes but these inputs are styled so there will be no border and they are readonly. The input boxes will not be apparent to the user but they allow the final data to be submitted. 

As there can be any number of rows and therefore any number of productid and quantity input boxes they need to be processed as arrarys. This is done by naming the fields name="productid[ ]" and name="quantity[ ]". The square brackets in the name allow the information to be submitted and processed as arrays.

The final column in the table contains three buttons styled with glyphicons. These buttons will allow the user to increase or reduce the quantity of the item on that line, or remove the line altogether.

Now we need an action which will process the order form once it is submitted. The following function, when added to app/controllers/ScorderController.php, will create a new order record in the database. Once this order has been saved the orderID which was generated in the database is retrieved and can be used as a foreign key in the order detail line item table. The loop processes the arrays of productids and quantities and adds a new order detail line item for each row of the order detail.


public function placeOrderAction()
{
	$thisOrder = new Scorder();
	$thisOrder->setOrderDate((new DateTime())->format("Y-m-d H:i:s"));
	$thisOrder->save();
	$orderID = $thisOrder->getId();
	
	$productids = $this->request->getPost("productid");
	$quantities = $this->request->getPost("quantity");
	for($i=0;$i<sizeof($productids);$i++) {
		$thisOrderDetail = new OrderDetail();
		$thisOrderDetail->setOrderid($orderID);
		$thisOrderDetail->setProductid($productids[$i]);
		$thisOrderDetail->setQuantity($quantities[$i]);
		$thisOrderDetail->save();
	}
	$this->session->remove('cart');
	$this->flash->success("The Order has been placed");
	$this->dispatcher->forward(["controller" => "product", "action" => "displayGrid"]);
}
To make this checkout order form viist /scorder/checkout and click on the submit button. The order and order detail line items will be added to the database.