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 system
17: *
18: * @category Horde
19: * @package PubSub
20: */
21: class Horde_PubSub
22: {
23: /**
24: * Subscribed topics and their handles
25: */
26: protected static $_topics = array();
27:
28: /**
29: * Publish to all handlers for a given topic
30: *
31: * @param string $topic
32: * @param mixed $args All arguments besides the topic are passed as arguments to the handler
33: * @return void
34: */
35: public static function publish($topic, $args = null)
36: {
37: if (empty(self::$_topics[$topic])) {
38: return;
39: }
40: $args = func_get_args();
41: array_shift($args);
42: foreach (self::$_topics[$topic] as $handle) {
43: $handle->call($args);
44: }
45: }
46:
47: /**
48: * Subscribe to a topic
49: *
50: * @param string $topic
51: * @param string|object $context Function name, class name, or object instance
52: * @param null|string $handler If $context is a class or object, the name of the method to call
53: * @return Horde_PubSub_Handle Pub-Sub handle (to allow later unsubscribe)
54: */
55: public static function subscribe($topic, $context, $handler = null)
56: {
57: if (empty(self::$_topics[$topic])) {
58: self::$_topics[$topic] = array();
59: }
60: $handle = new Horde_PubSub_Handle($topic, $context, $handler);
61: if (in_array($handle, self::$_topics[$topic])) {
62: $index = array_search($handle, self::$_topics[$topic]);
63: return self::$_topics[$topic][$index];
64: }
65: self::$_topics[$topic][] = $handle;
66: return $handle;
67: }
68:
69: /**
70: * Unsubscribe a handler from a topic
71: *
72: * @param Horde_PubSub_Handle $handle
73: * @return bool Returns true if topic and handle found, and unsubscribed; returns false if either topic or handle not found
74: */
75: public static function unsubscribe(Horde_PubSub_Handle $handle)
76: {
77: $topic = $handle->getTopic();
78: if (empty(self::$_topics[$topic])) {
79: return false;
80: }
81: if (false === ($index = array_search($handle, self::$_topics[$topic]))) {
82: return false;
83: }
84: unset(self::$_topics[$topic][$index]);
85: return true;
86: }
87:
88: /**
89: * Retrieve all registered topics
90: *
91: * @return array
92: */
93: public static function getTopics()
94: {
95: return array_keys(self::$_topics);
96: }
97:
98: /**
99: * Retrieve all handlers for a given topic
100: *
101: * @param string $topic
102: * @return array Array of Horde_PubSub_Handle objects
103: */
104: public static function getSubscribedHandles($topic)
105: {
106: if (empty(self::$_topics[$topic])) {
107: return array();
108: }
109: return self::$_topics[$topic];
110: }
111:
112: /**
113: * Clear all handlers for a given topic
114: *
115: * @param string $topic
116: * @return void
117: */
118: public static function clearHandles($topic)
119: {
120: if (!empty(self::$_topics[$topic])) {
121: unset(self::$_topics[$topic]);
122: }
123: }
124: }
125: