Here is what I came up with.

It's a way to use abstract classes as components, without anything
other than one call before you use the component the first time.

Thereafter, it behaves exactly as a regular component would.

In AppController:
============

//
// Imports, instantiates and stores an implementation instance of
// an abstract class just as cake would with a regular component.
// Enables abstract class components which need to be instantiated
only after
// the desired implementation is known.
//

function abstractComponentInst($componentName, $implementationType,
$import = true) {
                if ($import) {
                      App::import('Component',$componentName);
                }
                $this -> $componentName =
call_user_func($componentName.'Component::getInstance',
$implementationType);
                $this -> $componentName -> Startup($this);
}


In your controller:
=============
//
// Note: do not put the component in your $components class variable.
If you do, cake will try and instantiate
// it, but it will fail, because an abstract class cannot be
instantiated.
// You have to call the abstractComponentInst() function to do that.
//

function index() {
                $this->abstractComponentInst('Reservation', HOTELS);
                debug("Calling ReservationHotels: 
".$this->Reservation->getPrice());

                $this->abstractComponentInst('Reservation', CARS, false);
                debug("Calling ReservationCars: 
".$this->Reservation->getPrice());
}


The Component containing the abstract class:
=================================

<?php
//
// General Reservation component -
// Abstract class with subclassed implementations
// for each reservation type.
//

abstract class ReservationComponent extends Object
{
        var $controller;
        var $name = 'Reservation';


        function startup(& $controller) {
                $this->controller = $controller;
        }

        //
        // instantiate the appropriate implementation subclass and
        // store it as the Reservation component.
        //

        static function getInstance($reservationType) {

                switch ($reservationType) {

                        case HOTELS_PRODUCT_TYPE:
                                App::import('Component','ReservationHotels');
                                return new ReservationHotelsComponent();

                        case CARS_PRODUCT_TYPE:
                                App::import('Component','ReservationCars');
                                return new ReservationCarsComponent();

                        case CELL_PRODUCT_TYPE:
                                App::import('Component','ReservationCell');
                                return new ReservationCellComponent();

                        case GROUND_PRODUCT_TYPE:
                                App::import('Component','ReservationGround');
                                return new ReservationGroundComponent();

                        default:
                                return false;
                }
        }

        // Abstract functions...
        abstract function getPrice();
}
?>


Example of a subclassed implementation:
==============================

<?php

//
// Subclassed implementation of ReservationComponent for hotels.
//

class ReservationHotelsComponent extends ReservationComponent
{
        var $controller;
        var $name='ReservationHotels';

        function startup(& $controller) {
                parent::startup($controller);
        }

        //
        // Override the parent abstract functions.
        //

        function getPrice() {
                return "ReservationHotelsComponent: ".$this->name;
        }
}
?>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to