$this->productNotFound; } } /** * Display invalid product page * @return void */ private function productNotFound { $this->registry->getObject'template'-> buildFromTemplates'he
Trang 1[ 83 ]
else
{
// If the product path wasn't valid, a product not found method
// is called
$this->productNotFound();
}
}
/**
* Display invalid product page
* @return void
*/
private function productNotFound()
{
$this->registry->getObject('template')->
buildFromTemplates('header.tpl.php',
'invalid-product.tpl.php', 'footer.tpl.php');
}
}
?>
The product data, which is represented within the model is taken and converted
into tags for use within the template system Metadata is extracted separately and
converted into tags individually; as the product tags were prefixed, we don't want
these tags to be prefixed, as they are common template tags throughout the site.
Categories
Our category model and controller will be similar in complexity to the products
model and controller, with some minor differences:
Not as many tables need to be referenced to get the details of a category
(as the content_versions table fulfills the data requirements of a category)
Categories also need to list products contained or referenced within them
One aspect that is important with categories, which we are not yet going to focus on,
is a structure for categories Categories may have parent or child categories, so we
may wish to implement a hierarchical structure for our categories However, we will
put some basic provisions for this into place for now.
The controller also needs to omit or extend the view depending on if the category has
any products within it, or if it has any child categories.
•
•
Trang 2The model for categories is a little more complicated than the products, as it needs
to lookup subcategories and products associated with it The first stage to doing
this is a simple subquery, which counts the number of products and number of
subcategories If these values are greater than zero, then additional queries are
performed These queries are then cached, and a reference to the query is passed
to the template engine This allows the template engine to easily replace the results
of the query within the view for the categories The second stage is adding some
additional functions to tell the controller about these cached queries, and if there
are any subcategories or products.
An example model for this is as follows:
<?php
class Category{
private $registry;
private $subcatsCache = 0;
private $productsCache = 0;
private $numSubcats=0;
private $isValid = false;
private $numProducts = 0;
private $name;
private $title;
private $content;
private $metakeywords;
private $metadescription;
private $metarobots;
private $active;
private $secure;
The constructor simply takes the registry and the path to the category as parameters,
and then calls the getCategory method.
public function construct( PHPEcommerceFrameworkRegistry
$registry, $catPath )
{
$this->urlPath = $catPath;
$this->getCategory();
}
Trang 3[ 85 ]
The "get category" method looks up the category in the database, and sets
appropriate variables depending on if a category was found.
private function getCategory()
{
$sql = "SELECT c.ID, c.active, c.secure, v.title, v.name,
v.heading, v.content, v.metakeywords,
v.metadescription, v.metarobots, ( SELECT COUNT(*)
FROM content cn, content_types ct
WHERE ct.ID=cn.type AND ct.reference='category'
AND cn.parent=c.ID )
AS num_subcats, ( SELECT COUNT(*) FROM content cn,
content_types_products_in_categories pic
WHERE cn.active=1 AND cn.ID=pic.product_id
AND pic.category_id=c.ID ) AS num_products
FROM content c, content_types t, content_versions v
WHERE c.type=t.ID AND t.reference='category'
AND c.path='{$this->urlPath}'
AND v.ID=c.current_revision LIMIT 1";
$this->registry->getObject('db')->executeQuery( $sql );
if( $this->registry->getObject('db')->numRows() == 1 )
{
$this->isValid = true;
$data = $this->registry->getObject('db')->getRows();
$this->numSubcats = $data['num_subcats'];
$this->numProducts = $data['num_products'];
// If the category has subcategories, these should be looked up
// and cached, as we may wish to generate a list or submenu
// based off these
if( $this->numSubcats != 0 )
{
$catid = $data['ID'];
$sql = "SELECT v.name AS category_name,
c.path AS category_path
FROM content c, content_versions v,
WHERE c.parent={$catid} AND v.ID=c.current_revision
AND c.active=1 ";
$cache = $this->registry->getObject('db')->
cacheQuery( $sql );
$this->subCats = $cache;
}
// If the category has products within it, we should cache these
// too, as we will want to display these products on the
// category view
if( $this->numProducts != 0 )
{
Trang 4$catid = $data['ID'];
$sql = "SELECT p.price AS product_price,
v.name AS product_name, c.path AS product_path,
FROM content c, content_versions v,
content_types_products p,
content_types_products_in_categories pic
WHERE pic.product_id=c.ID
AND pic.category_id={$catid}
AND p.current_id=v.ID AND v.ID=c.current_revision
AND c.active=1 ";
$cache = $this->registry->getObject('db')->
cacheQuery( $sql );
$this->productsCache = $cache;
}
$this->name = $data['name'];
$this->title = $data['title'];
$this->content = $data['content'];
$this->title = $data['title'];
$this->metakeywords = $data['metakeywords'];
$this->metadescription = $data['metadescription'];
$this->metarobots = $data['metarobots'];
$this->active = $data['active'];
$this->secure = $data['secure'];
$this->heading = $data['heading'];
}
}
Finally, we have some getter methods, which inform the controller about the various
values set.
public function isValid()
{
return $this->isValid;
}
public function isEmpty()
{
return ($this->numProducts == 0) ? true : false;
}
public function numSubcats()
{
return $this->numSubcats;
}
public function getProperties()
{
$tor = array();
Trang 5[ 87 ]
$tor['title'] = $this->title;
$tor['name'] = $this->name;
$tor['content'] = $this->content;
$tor['heading'] = $this->heading;
$tor['metakeywords'] = $this->metakeywords;
$tor['metadescription'] = $this->metadescription;
$tor['metarobots'] = $this->metarobots;
return $tor;
}
public function getSubCatsCache()
{
return $this->subcatsCache;
}
public function getProductsCache()
{
return $this->productsCache;
}
}
?>
View
A number of templates are needed to build the view for our product categories,
these include:
Category template
Subcategories template
Products template, containing products within the category (a separate
template, because if there are none, the template tag is simply nulled out)
Category template
The category template can be laid out as follows:
<h1>{category_heading}</h1>
{category_content}
{catproducts}
{subcats}
•
•
•