1: <?php
2: /**
3: * Publish-Subscribe system based on Phly_PubSub
4: * (http://weierophinney.net/matthew/archives/199-A-Simple-PHP-Publish-Subscribe-System.html)
5: *
6: * Copyright 2008-2011 Matthew Weier O'Phinney
7: * Copyright 2011-2012 Horde LLC (http://www.horde.org/)
8: *
9: * @category Horde
10: * @package PubSub
11: * @author Matthew Weier O'Phinney <mweierophinney@gmail.com>
12: * @license New BSD {@link http://www.opensource.org/licenses/bsd-license.php}
13: */
14:
15: /**
16: * Publish-Subscribe provider
17: *
18: * Use Horde_PubSub_Provider when you want to create a per-instance plugin
19: * system for your objects.
20: *
21: * @category Horde
22: * @package PubSub
23: */
24: class Horde_PubSub_Provider
25: {
26: /**
27: * Subscribed topics and their handles
28: */
29: protected $_topics = array();
30:
31: /**
32: * Publish to all handlers for a given topic
33: *
34: * @param string $topic
35: * @param mixed $args All arguments besides the topic are passed as arguments to the handler
36: * @return void
37: */
38: public function publish($topic, $args = null)
39: {
40: if (empty($this->_topics[$topic])) {
41: return;
42: }
43: $args = func_get_args();
44: array_shift($args);
45: foreach ($this->_topics[$topic] as $handle) {
46: $handle->call($args);
47: }
48: }
49:
50: /**
51: * Subscribe to a topic
52: *
53: * @param string $topic
54: * @param string|object $context Function name, class name, or object instance
55: * @param null|string $handler If $context is a class or object, the name of the method to call
56: * @return Horde_PubSub_Handle Pub-Sub handle (to allow later unsubscribe)
57: */
58: public function subscribe($topic, $context, $handler = null)
59: {
60: if (empty($this->_topics[$topic])) {
61: $this->_topics[$topic] = array();
62: }
63: $handle = new Horde_PubSub_Handle($topic, $context, $handler);
64: if (in_array($handle, $this->_topics[$topic])) {
65: $index = array_search($handle, $this->_topics[$topic]);
66: return $this->_topics[$topic][$index];
67: }
68: $this->_topics[$topic][] = $handle;
69: return $handle;
70: }
71:
72: /**
73: * Unsubscribe a handler from a topic
74: *
75: * @param Horde_PubSub_Handle $handle
76: * @return bool Returns true if topic and handle found, and unsubscribed; returns false if either topic or handle not found
77: */
78: public function unsubscribe(Horde_PubSub_Handle $handle)
79: {
80: $topic = $handle->getTopic();
81: if (empty($this->_topics[$topic])) {
82: return false;
83: }
84: if (false === ($index = array_search($handle, $this->_topics[$topic]))) {
85: return false;
86: }
87: unset($this->_topics[$topic][$index]);
88: return true;
89: }
90:
91: /**
92: * Retrieve all registered topics
93: *
94: * @return array
95: */
96: public function getTopics()
97: {
98: return array_keys($this->_topics);
99: }
100:
101: /**
102: * Retrieve all handlers for a given topic
103: *
104: * @param string $topic
105: * @return array Array of Horde_PubSub_Handle objects
106: */
107: public function getSubscribedHandles($topic)
108: {
109: if (empty($this->_topics[$topic])) {
110: return array();
111: }
112: return $this->_topics[$topic];
113: }
114:
115: /**
116: * Clear all handlers for a given topic
117: *
118: * @param string $topic
119: * @return void
120: */
121: public function clearHandles($topic)
122: {
123: if (!empty($this->_topics[$topic])) {
124: unset($this->_topics[$topic]);
125: }
126: }
127: }
128: