Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (84)

View Page History
{info:title=Zend_Notification} {info:title=Zend_Message}
{zone-template-instance:ZFDEV:Zend Proposal Zone Template}
{composition-setup}
{zone-data:component-name}
Zend_Notification Zend_Message
{zone-data}


{zone-data:revision}
1.5 - 16 June 2008: Renamed, added usecase from comments
1.4 - 11 mMarch 2008: updated class skeletons and text
1.3 - 20 fFebruari 2008: Updated link and added another usecase
1.2 - 3 January 2008: Added some use cases, operation description and updated skeletons
1.1 - 30 December 2007: Refactoring and renaming

{zone-data:overview}
Zend_Notification Zend_Message provides an infrastructure to relay messages between objects that don't necessarily know eachother.
This provides a loose coupling between components and makes your app more flexible.

Also, this might be of interest for the Zend_Tool CLI tooling?

An implementation of this proposal is available in [Zym|http://www.zym-project.com/].
{zone-data}

{zone-data:operation}
The operation is very simple, but also very powerful. You can attach an object to a notification an event by calling the Notification's notification center's attach() method.
This method takes the observer and the name of the notification event as argument. More than one object can register to the same notification. event.
When a notification message is sent, all objects that subscribed to that notification event will be notified in order of subscription.
By default the observer's notify() method will be called. You can also register another method when registering the observering object at the notification center. message dispatcher.

The Notification message constructor takes three arguments (of which the last is optional). The first is the name of the notification. message. The second is (usually) the object thant sent the notification. message.
The last argument is an array that allows for extra data to be sent along with the notification. message.

When attaching an observer to an event you can either use a string to attach it to just one event, or provide an array with multiple event names. (See usecase UC-02)
* Milestone 2: \[DONE\] write documentation
* Milestone 3: \[DONE\] write unit tests
* Milestone 4: \[IN PROGRESS\] process comments
* Milestone 45: get approval and move the component to incubator
* Milestone 56: finish component and move it to core
{zone-data}

{zone-data:class-list}
* Zend_Notification Zend_Message
* Zend_Notification_Message Zend_Message_Dispatcher
* Zend_Notification_Registration Zend_Message_Registration
* Zend_Notification_Interface Zend_Message_Exception
* Zend_Notification_Exception
{zone-data}

public function __construct()
{
$notification $dispatcher = Zend_Notification::get(); Zend_Message_Dispatcher::get();

$notification->attach($this, $dispatcher->attach($this, CoffeeShop::PIE_READY) // Uses the default callback notify()
->attach($this, CoffeeShop::COFFEE_READY, 'drinkCoffee'); // Uses a custom callback
}

public function notify(Zend_Notification_Message $notification) notify(Zend_Message $message)
{
$sender = $notification->getSender(); $message->getSender();
$data = $notification->getData(); $message->getData();

$pie = $data['pie']; $data['pie']->eat();

$pie->eat();

echo "Eating the pie...\n";

}

public function drinkCoffee(Zend_Notification_Message $notification) drinkCoffee(Zend_Message $message)
{
$data = $notification->getData(); $message->getData();

$coffee = $data['coffee']; $data['coffee']->drink();

$coffee->drink();

echo "Drinking the coffee...\n";
const PIE_READY = 'pieReady';

protected $_notification; $_dispatcher;

public function __construct()
{
$this->_notification $this->_dispatcher = Zend_Notification::get(); Zend_Message_Dispatcher::get();
}

}

$this->_notification->post(CoffeeShop::PIE_READY, $this->_dispatcher->post(CoffeeShop::PIE_READY, $this, array('pie' => $pie));
}

$coffee = new Coffee();

$this->_notification->post(CoffeeShop::COFFEE_READY, $this->_dispatcher->post(CoffeeShop::COFFEE_READY, $this, array('coffee' => $coffee));
}

public function __construct()
{
$notification $dispatcher = Zend_Notification::get(); Zend_Message_Dispatcher::get();

// Assumes both use the default callback
$notification->attach($this, $dispatcher->attach($this, array(CoffeeShop::PIE_READY, CoffeeShop::COFFEE_READY)); // Uses the default callback notify()
}

public function __construct()
{
$notification $dispatcher = Zend_Notification::get(); Zend_Message_Dispatcher::get();

// Attaches the customer to all event starting with foo e.g. fooBar, fooBaz etc.
$notification->attach($this, $dispatcher->attach($this, 'foo*'); // Uses the default callback notify()
}

/** Front Controller **/

$notification = Zend_Notification::get();
$dispatcher = Zend_Message_Dispatcher::get();
/**
* Notify plugins of router startup
*/
$this->_plugins->routeStartup($this->_request);
$notification->post('FCRouteStartup', $dispatcher->post('FCRouteStartup', $this, array('request' => $this->_request));

$router->route($this->_request);
*/
$this->_plugins->routeShutdown($this->_request);
$notification->post('FCRouteShutdown', $dispatcher->post('FCRouteShutdown', $this, array('request' => $this->_request));

/**
*/
$this->_plugins->dispatchLoopStartup($this->_request);
$notification->post('FCDispatchLoopStartup', $dispatcher->post('FCDispatchLoopStartup', $this, array('request' => $this->_request));

/**
*/
$this->_plugins->preDispatch($this->_request);
$notification->post('FCPreDispatch', $dispatcher->post('FCPreDispatch', $this, array('request' => $this->_request));

/**
*/
$this->_plugins->postDispatch($this->_request);
$notification->post('FCPostDispatch', $dispatcher->post('FCPostDispatch', $this, array('request' => $this->_request));

} while (!$this->_request->isDispatched());
try {
$this->_plugins->dispatchLoopShutdown();
$notification->post('FCDispatchLoopShutdown', $dispatcher->post('FCDispatchLoopShutdown', $this, array('request' => $this->_request));
} catch (Exception $e) {
if ($this->throwExceptions()) {
public function __construct()
{
$notification $dispatcher = Zend_Notification::get(); Zend_Message_Dispatcher::get();

// Assumes both use the default callback
$notification->attach($this, $dispatcher->attach($this, 'FCPostDispatch'); // Uses the default callback notify()
}

{code}
{card}
{card:label=UC-05: Usage in dependicy problems (Zym_App)}
{code}
class SetupDb
{
public function __construct(Zend_Config $config)
{
if (!Zend_Registry::isRegistered('cache')) {
Zend_Message_Dispatcher::get()->attach($this, 'CacheIsAvailable');
} else {
$this->_setupFromRegistry();
}

$db = Zend_Db::factory($config);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
}

public function notify(Zend_Message $message)
{
// alternatively, we could've include the cache instance in the message

if ($message->getName() == 'CacheIsAvailable') {
$this->_setupFromRegistry();
}
}

protected function _setupFromRegistry()
{
$cache = Zend_Registry::get('cache');
Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
}
}

class SetupCache
{
public function __construct(Zend_Config $config)
{
// get front- and backedn options from config
$cache = Zym_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
Zend_Registry::set('cache', $cache);
Zend_Message_Dispatcher::get()->post('CacheIsAvailable', $this);
}
}

// Note that it doesn't matter in which order I instantiate these, the result will be the same: a db setup with a cache.
new SetupDb(new Zend_Config_Xml('dbconfig.xml'));
new SetupCache(new Zend_Config_Xml('cacheconfig.xml'));
{code}
{card}
{deck}
{zone-data}
{zone-data:skeletons}
{deck:id=Class Skeletons}
{card:label=Zend_Notification_Interface} {card:label=Zend_Message_Registration}
{code}
interface Zend_Notification_Interface
class Zend_Message_Registration
{
/**
* Notify the observer by passing the Zend_Notification instance
*
* @param Zend_Notification_Message $notification
*/
public function notify(Zend_Notification_Message $notification);
}
{code}
{card}
{card:label=Zend_Notification_Registration}
{code}
class Zend_Notification_Registration
{
/**
* @var object
*/
{code}
{card}
{card:label=Zend_Notification_Message}
{code}
class Zend_Notification_Message
{
/**
* Notification Message name
*
* @var string

/**
* The object that sent the notification message
*
* @var object

/**
* Get notification message name
*
* @return string

/**
* Get the object that sent the notification message
*
* @return object
{code}
{card}
{card:label=Zend_Notification} {card:label=Zend_Message_Dispatcher}
{code}
class Zend_Notification Zend_Message_Dispatcher
{
/**

/**
* The collection of objects that registered to notifications messages
*
* @var array

/**
* Singleton instance
* Messag dispatcher instances
*
* @var array

/**
* Get a notification dispatcher instance from the internal registry
*
* @param string name
* @return Zend_Notification Zend_Message_Dispatcher
*/
public static function get($namespace = 'default')

/**
* Remove a notification dispatcher instance from the internal registry
*
* @param string $name

/**
* Singleton Protected constructor
*
*/

/**
* Post a notification message
*
* @param string $name
* @param object $sender
* @param array $data
* @return Zend_Notification Zend_Message_Dispatcher
*/
public function post($name, $sender = null, array $data = array())
* Post the notification
*
* @param Zend_Notification_Message $message
* @param Zend_Notification_Registration Zend_Message_Registration $observerData
*/
protected function _postNotification(Zend_Notification_Message $message, Zend_Notification_Registration $registration)
protected function _postNotification(Zend_Message $message, Zend_Message_Registration $registration)
{
}

/**
* Register an observer for the specified notification event
*
* @param object $observer
* @param string|array $events
* @param string $callback
* @return Zend_Notification Zend_Message_Dispatcher
*/
public function attach($observer, $events = null, $callback = null)
* @param object $observer
* @param string|array $event
* @return Zend_Notification Zend_Message_Dispatcher
*/
public function detach($observer, $events = null)
*
* @param string $event
* @return Zend_Notification Zend_Message_Dispatcher
*/
public function reset($event = null)
{code}
{card}
{card:label=Zend_Notification_Exception} {card:label=Zend_Message_Exception}
{code}
class Zend_Notification_Exception Zend_Message_Exception extends Zend_Exception
{
}