Products and Categories [ 88 ] Subcategories template And here is the subcategories template: <h2>Subcategories</h2> <p>This category has the following subcategories</p> <ul> <! START subcatslist > <li> <a href="categories/view/{category_path}">{category_name}</a> </li> <! END subcatslist > </ul> Products template The products template is as follows: <h2>Products</h2> <p>This category has the following products associated with it</p> <ul> <! START productlist > <li><a href="products/view/{product_path}">{product_name}</a></li> <! END productlist > </ul> The end result is a product category view. This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Chapter 3 [ 89 ] Controller Based off our previous controllers and the difference in the categories model, the following is our controller for viewing categories: <?php /** * Categories Controller * * @author Michael Peacock * @version 1.0 */ class Categories{ /** * Registry object reference */ private $registry; /** * Categories model object reference */ private $model; // The constructor simply checks that the object is being created // by a direct call to the category section by the user (and isn't // being used by another controller, which won't want the default // behavior), and calls the view category method. /** * Controller constructor - direct call to false when being * embedded via another controller * @param PHPEcommerceFrameworkRegistry $registry our registry * @param bool $directCall - are we calling it directly via the * framework (true), or via another controller (false) */ public function __construct( PHPEcommerceFrameworkRegistry $registry, $directCall ) { $this->registry = $registry; if( $directCall == true ) { $this->viewCategory(); } } // The viewCategory method creates a category model, passes the // category path, and then builds the view out of the appropriate // templates, depending on if the category has products within it // and a number of subcategories. /** This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Products and Categories [ 90 ] * View a category * @return void */ private function viewCategory() { $pathToRemove = 'categories/view/'; $categoryPath = str_replace( $pathToRemove, '', $this->registry->getURLPath() ); require_once( FRAMEWORK_PATH . 'models/categories/model.php'); $this->model = new Category( $this->registry, $categoryPath ); if( $this->model->isValid() ) { if( $this->model->isEmpty() && $this->model-> numSubcats() == 0 ) { $this->emptyCategory(); } else { $categoryData = $this->model->getProperties(); $this->registry->getObject('template')-> dataToTags( $categoryData, 'category_' ); $this->registry->getObject('template')->getPage()-> addTag( 'metakeywords', $categoryData['metakeywords'] ); $this->registry->getObject('template')->getPage()-> addTag( 'metadescription', $categoryData['metadescription'] ); $this->registry->getObject('template')->getPage()-> addTag( 'metarobots', $categoryData['metarobots'] ); $this->registry->getObject('template')-> buildFromTemplates('header.tpl.php', 'category.tpl.php', 'footer.tpl.php'); $this->registry->getObject('template')->getPage()-> setTitle('Viewing category ' . $categoryData['name'] ); // Here the category has no subcategories. if( $this->model->numSubcats() == 0 ) { $this->registry->getObject('template')->getPage()-> addTag( 'subcats', '' ); } // Here the category has sub categories. else { $this->registry->getObject('template')-> This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Chapter 3 [ 91 ] addTemplateBit( 'subcats', 'subcategories.tpl.php' ); $this->registry->getObject('template')->getPage()-> addTag( 'subcatslist', array('SQL', $this->model->getSubCatsCache() ) ); } // Similarly, if the category is empty, or has products // within it, different templates are used. if( $this->model->isEmpty() ) { $this->registry->getObject('template')->getPage()-> addTag( 'catproducts', '' ); } else { $this->registry->getObject('template')-> addTemplateBit( 'catproducts', 'categoryproducts.tpl.php' ); $this->registry->getObject('template')->getPage()-> addTag( 'productslist', array('SQL', $this->model-> getProductsCache() ) ); } } } else { $this->categoryNotFound(); } } /** * Display invalid category page * @return void */ private function categoryNotFound() { $this->registry->getObject('template')-> buildFromTemplates('header.tpl.php', 'invalid-category.tpl.php', 'footer.tpl.php'); } private function emptyCategory() { $this->registry->getObject('template')-> buildFromTemplates('header.tpl.php', 'empty-category.tpl.php', 'footer.tpl.php'); } } ?> This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 Products and Categories [ 92 ] Some thoughts At present, all of our models and controllers follow an incredibly similar format; one potential area for improvement would be for us to make use of inheritance within PHP, for our controllers and models to inherit their core methods from an interface, and, where appropriate, deviate from the standard page model and controller. I leave this improvement for you to consider and implement if you so wish. Product and category images One very important aspect which we have so far neglected is photographs of our products, and photographs we may wish to have to represent our categories. Having an image associated with our products is great, but most customers want more than just one image, so let's implement additional image functionality for our products. Ideally, we will also want our customers to be able to toggle between different images from the "product view" page too. These are aspects we will come to in the next chapter. Routing products and categories The rst part of our URL path should indicate the area of the site the user is trying to access, for example products. We need to maintain a list of active controllers in use by the framework, and if this part of the URL matches an active controller, we should include the controller le, create a controller object for that controller, and pass control of the framework to that controller. If the rst part of the URL isn't an active controller, then we should include the page controller and pass control to that, which should in turn either display a page, or detect that the page isn't valid and therefore display a 404 error ("Page not found") page. $activeControllers = array(); $registry->getObject('db')->executeQuery('SELECT controller FROM controllers WHERE active=1'); while( $activeController = $registry->getObject('db')->getRows() ) { $activeControllers[] = $activeController['controller']; } $currentController = $registry->getURLBit( 0 ); if( in_array( $currentController, $activeControllers ) ) { This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 Quincy Drive, , Brick, , 08724 . buildFromTemplates('header.tpl .php& apos;, 'empty-category.tpl .php& apos;, 'footer.tpl .php& apos;); } } ?> This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010 953 . $this->registry->getObject('template')-> buildFromTemplates('header.tpl .php& apos;, 'invalid-category.tpl .php& apos;, 'footer.tpl .php& apos;); } private function emptyCategory() { $this->registry->getObject('template')->. $this->registry->getObject('template')-> buildFromTemplates('header.tpl .php& apos;, 'category.tpl .php& apos;, 'footer.tpl .php& apos;); $this->registry->getObject('template')->getPage()->