]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/PubSubHubBub/PubSubHubBubPlugin.php
OStatus update: now using standard save/delivery for incoming ostatus messages -...
[quix0rs-gnu-social.git] / plugins / PubSubHubBub / PubSubHubBubPlugin.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Plugin to push RSS/Atom updates to a PubSubHubBub hub
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Plugin
23  * @package   StatusNet
24  * @author    Craig Andrews <candrews@integralblue.com>
25  * @copyright 2009 Craig Andrews http://candrews.integralblue.com
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET')) {
31     exit(1);
32 }
33
34 define('DEFAULT_HUB', 'http://pubsubhubbub.appspot.com');
35
36 require_once INSTALLDIR.'/plugins/PubSubHubBub/publisher.php';
37
38 /**
39  * Plugin to provide publisher side of PubSubHubBub (PuSH)
40  * relationship.
41  *
42  * PuSH is a real-time or near-real-time protocol for Atom
43  * and RSS feeds. More information here:
44  *
45  * http://code.google.com/p/pubsubhubbub/
46  *
47  * To enable, add the following line to your config.php:
48  *
49  * addPlugin('PubSubHubBub');
50  *
51  * This will use the Google default hub. If you'd like to use
52  * another, try:
53  *
54  * addPlugin('PubSubHubBub',
55  *           array('hub' => 'http://yourhub.example.net/'));
56  *
57  * @category  Plugin
58  * @package   StatusNet
59  * @author    Craig Andrews <candrews@integralblue.com>
60  * @copyright 2009 Craig Andrews http://candrews.integralblue.com
61  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
62  * @link      http://status.net/
63  */
64
65 class PubSubHubBubPlugin extends Plugin
66 {
67     /**
68      * URL of the hub to advertise and publish to.
69      */
70
71     public $hub = DEFAULT_HUB;
72
73     /**
74      * Default constructor.
75      */
76
77     function __construct()
78     {
79         parent::__construct();
80     }
81
82     /**
83      * Check if plugin should be active; may be mass-enabled.
84      * @return boolean
85      */
86
87     function enabled()
88     {
89         if (common_config('site', 'private')) {
90             // PuSH relies on public feeds
91             return false;
92         }
93         // @fixme check for being on a private network?
94         return true;
95     }
96
97     /**
98      * Hooks the StartApiAtom event
99      *
100      * Adds the necessary bits to advertise PubSubHubBub
101      * for the Atom feed.
102      *
103      * @param Action $action The API action being shown.
104      *
105      * @return boolean hook value
106      */
107
108     function onStartApiAtom($action)
109     {
110         if ($this->enabled()) {
111             $action->element('link', array('rel' => 'hub', 'href' => $this->hub), null);
112         }
113         return true;
114     }
115
116     /**
117      * Hooks the StartApiRss event
118      *
119      * Adds the necessary bits to advertise PubSubHubBub
120      * for the RSS 2.0 feeds.
121      *
122      * @param Action $action The API action being shown.
123      *
124      * @return boolean hook value
125      */
126
127     function onStartApiRss($action)
128     {
129         if ($this->enabled()) {
130             $action->element('atom:link', array('rel' => 'hub',
131                                                 'href' => $this->hub),
132                              null);
133         }
134         return true;
135     }
136
137     /**
138      * Hook for a queued notice.
139      *
140      * When a notice has been queued, will ping the
141      * PuSH hub for each Atom and RSS feed in which
142      * the notice appears.
143      *
144      * @param Notice $notice The notice that's been queued
145      *
146      * @return boolean hook value
147      */
148
149     function onHandleQueuedNotice($notice)
150     {
151         if (!$this->enabled()) {
152             return false;
153         }
154         $publisher = new Publisher($this->hub);
155
156         $feeds = array();
157
158         //public timeline feeds
159         $feeds[] = common_local_url('ApiTimelinePublic', array('format' => 'rss'));
160         $feeds[] = common_local_url('ApiTimelinePublic', array('format' => 'atom'));
161
162         //author's own feeds
163         $user = User::staticGet('id', $notice->profile_id);
164
165         $feeds[] = common_local_url('ApiTimelineUser',
166                                     array('id' => $user->nickname,
167                                           'format' => 'rss'));
168         $feeds[] = common_local_url('ApiTimelineUser',
169                                     array('id' => $user->nickname,
170                                           'format' => 'atom'));
171
172         //tag feeds
173         $tag = new Notice_tag();
174
175         $tag->notice_id = $notice->id;
176         if ($tag->find()) {
177             while ($tag->fetch()) {
178                 $feeds[] = common_local_url('ApiTimelineTag',
179                                             array('tag' => $tag->tag,
180                                                   'format' => 'rss'));
181                 $feeds[] = common_local_url('ApiTimelineTag',
182                                             array('tag' => $tag->tag,
183                                                   'format' => 'atom'));
184             }
185         }
186
187         //group feeds
188         $group_inbox = new Group_inbox();
189
190         $group_inbox->notice_id = $notice->id;
191         if ($group_inbox->find()) {
192             while ($group_inbox->fetch()) {
193                 $group = User_group::staticGet('id', $group_inbox->group_id);
194
195                 $feeds[] = common_local_url('ApiTimelineGroup',
196                                             array('id' => $group->nickname,
197                                                   'format' => 'rss'));
198                 $feeds[] = common_local_url('ApiTimelineGroup',
199                                             array('id' => $group->nickname,
200                                                   'format' => 'atom'));
201             }
202         }
203
204         //feed of each user that subscribes to the notice's author
205
206         $ni = $notice->whoGets();
207
208         foreach (array_keys($ni) as $user_id) {
209             $user = User::staticGet('id', $user_id);
210             if (empty($user)) {
211                 continue;
212             }
213             $feeds[] = common_local_url('ApiTimelineFriends',
214                                         array('id' => $user->nickname,
215                                               'format' => 'rss'));
216             $feeds[] = common_local_url('ApiTimelineFriends',
217                                         array('id' => $user->nickname,
218                                               'format' => 'atom'));
219         }
220
221         $replies = $notice->getReplies();
222
223         //feed of user replied to
224         foreach ($replies as $recipient) {
225                 $user = User::staticGet('id', $recipient);
226             if (!empty($user)) {
227                 $feeds[] = common_local_url('ApiTimelineMentions',
228                                             array('id' => $user->nickname,
229                                                   'format' => 'rss'));
230                 $feeds[] = common_local_url('ApiTimelineMentions',
231                                             array('id' => $user->nickname,
232                                                   'format' => 'atom'));
233             }
234         }
235         $feeds = array_unique($feeds);
236
237         ob_start();
238         $ok = $publisher->publish_update($feeds);
239         $push_last_response = ob_get_clean();
240
241         if (!$ok) {
242             common_log(LOG_WARNING,
243                        'Failure publishing ' . count($feeds) . ' feeds to hub at '.
244                        $this->hub.': '.$push_last_response);
245         } else {
246             common_log(LOG_INFO,
247                        'Published ' . count($feeds) . ' feeds to hub at '.
248                        $this->hub.': '.$push_last_response);
249         }
250
251         return true;
252     }
253
254     /**
255      * Provide version information
256      *
257      * Adds this plugin's version data to the global
258      * version array, for e.g. displaying on the version page.
259      *
260      * @param array &$versions array of array of versions
261      *
262      * @return boolean hook value
263      */
264
265     function onPluginVersion(&$versions)
266     {
267         $about = _m('The PubSubHubBub plugin pushes RSS/Atom updates '.
268                     'to a <a href = "'.
269                     'http://pubsubhubbub.googlecode.com/'.
270                     '">PubSubHubBub</a> hub.');
271         if (!$this->enabled()) {
272             $about = '<span class="disabled" style="color:gray">' . $about . '</span> ' .
273                      _m('(inactive on private site)');
274         }
275         $versions[] = array('name' => 'PubSubHubBub',
276                             'version' => STATUSNET_VERSION,
277                             'author' => 'Craig Andrews',
278                             'homepage' =>
279                             'http://status.net/wiki/Plugin:PubSubHubBub',
280                             'rawdescription' =>
281                             $about);
282
283         return true;
284     }
285 }