Here is what I came up with - it's one way to have polymorphic
capabilities in your components.

You define your component as an abstract class with abstract
functions, and thereafter, except for a single call before you use the
component the first time, it behaves exactly as a regular component
would, but you gain polymorphism.

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 abstractComponent($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->abstractComponent('Reservation', HOTELS);
                debug("Calling ReservationHotels: ".$this-
>Reservation-

>getPrice());

                $this->abstractComponent('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:

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

                        case CARS:

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

                        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 $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