The following are some snippets of code that should hopefully illustrate how single pages, controllers and models can interact to produce clean code, and let you build just about any type of functionality inside a concrete5 site, without forking the core concrete5 installation.
The following code snippets are NOT a functional shopping cart, but they should help you as a developer understand how you might continue them to finish our development.
Step 1, the model
Let's create a CartModel class in models/cart.php, named CartModel. Within that class, some common shopping cart methods should be defined:
<?
class CartModel {
/**
* Returns the total number of items in the
user's cart
*/
public function getTotal() {
return count($_SESSION['cart']);
}
/**
* Gets the contents of our cart, in a list of IDs
*/
public function get() {
return $_SESSION['cart'];
}
/**
* Adds a product ID to the cart
*/
public function add($productID) {
$_SESSION['cart'][] = $productID;
}
/**
* Removes a particular product ID from
the cart.
*/
public function remove($productID) {
foreach($_SESSION['cart'] as
$key => $_productID) {
if ($productID == $_productID) {
unset($_SESSION[$key]);
}
}
}
}
See, we separate all these items out into the cart model so that they can easily be changed, if, in the future, we need to switch from using a session-based cart to one based on the database, etc...
Step 2, the controller
Now that we have a basic shopping cart model with the ability to add, retrieve, and remove product IDs from our cart, we can code our controller to take advantage of this information
<?
// the concrete5 way to load a model
Loader::model('cart');
class CartController extends Controller {
private $cart;
public function on_start() {
$this->cart = new CartModel();
$this->set('items', $this->cart->get());
}
public function add() {
$productID = $this->post('productID');
$this->cart->add($productID);
$this->set('message',
'Product added successfully.');
}
public function remove($productID) {
$this->cart->remove($productID);
$this->set('message',
'Product removed successfully.');
}
}
This should be pretty obvious code. We've setup controller methods for adding products and removing products. Regardless of whether we're running the add or remove functions, the $items variable will always be set to our cart's items, since it's running in the on_start_ function.
Save this file as controllers/cart.php.
Step 3: The view
<?
if (isset($message)) {
print $message . '<br><br>';
}
<? foreach($items as $it) { ?>
Product ID <?=$it?> in the cart.
<a href="<?=$this->action('remove', $it)?>">
Remove product</a>.
<? } ?>
<h2>Add a Product</h2>
<form method="post"
action="<?=$this->action('add')?>">
Enter the product ID:
<input type="text" name="productID" value="" />
<input type="submit" value="Submit" />
</form>
Save this file as single_pages/cart.php and add it through the dashboard, and the three pieces of the puzzle should start talking to each other. Now you've got a single communicating to its controller in two ways - one is through GET, using the remove function, and one is through POST, adding a product ID to the cart. Those methods in the controller are responsible for setting the message variable, and actually saving the data to the cart (using the CartModel methods.)