3 * StatusNet - the distributed open-source microblogging tool
4 * Copyright (C) 2009, StatusNet, Inc.
6 * Send and receive notices using the XMPP network
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * @author Evan Prodromou <evan@status.net>
26 * @copyright 2009 StatusNet, Inc.
27 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
28 * @link http://status.net/
31 if (!defined('STATUSNET')) {
32 // This check helps protect against security problems;
33 // your code file can't be executed directly from the web.
42 * @author Evan Prodromou <evan@status.net>
43 * @copyright 2009 StatusNet, Inc.
44 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
45 * @link http://status.net/
48 class XmppPlugin extends ImPlugin
50 public $server = null;
52 public $user = 'update';
53 public $resource = null;
54 public $encryption = true;
55 public $password = null;
56 public $host = null; // only set if != server
57 public $debug = false; // print extra debug info
59 public $transport = 'xmpp';
63 function getDisplayName(){
64 return _m('XMPP/Jabber/GTalk');
67 function normalize($screenname)
69 if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $screenname, $matches)) {
71 $server = $matches[2];
72 return strtolower($node.'@'.$server);
78 function daemon_screenname()
80 $ret = $this->user . '@' . $this->server;
83 return $ret . '/' . $this->resource;
89 function validate($screenname)
91 // Cheap but effective
92 return Validate::email($screenname);
96 * Load related modules when needed
98 * @param string $cls Name of the class to be loaded
100 * @return boolean hook value; true means continue processing, false means stop.
103 function onAutoload($cls)
105 $dir = dirname(__FILE__);
111 include_once $dir . '/'.$cls.'.php';
114 include_once $dir . '/'.strtolower($cls).'.php';
121 function onStartImDaemonIoManagers(&$classes)
123 parent::onStartImDaemonIoManagers(&$classes);
124 $classes[] = new XmppManager($this); // handles pings/reconnects
128 function microiduri($screenname)
130 return 'xmpp:' . $screenname;
133 function send_message($screenname, $body)
135 $this->fake_xmpp->message($screenname, $body, 'chat');
136 $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
140 function send_notice($screenname, $notice)
142 $msg = $this->format_notice($notice);
143 $entry = $this->format_entry($notice);
145 $this->fake_xmpp->message($screenname, $msg, 'chat', null, $entry);
146 $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
151 * extra information for XMPP messages, as defined by Twitter
153 * @param Profile $profile Profile of the sending user
154 * @param Notice $notice Notice being sent
156 * @return string Extra information (Atom, HTML, addresses) in string format
159 function format_entry($notice)
161 $profile = $notice->getProfile();
163 $entry = $notice->asAtomEntry(true, true);
165 $xs = new XMLStringer();
166 $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
167 $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
168 $xs->element('a', array('href' => $profile->profileurl),
171 if (!empty($notice->rendered)) {
172 $xs->raw($notice->rendered);
174 $xs->raw(common_render_content($notice->content, $notice));
177 $xs->element('a', array(
178 'href'=>common_local_url('conversation',
179 array('id' => $notice->conversation)).'#notice-'.$notice->id
180 ),sprintf(_('[%s]'),$notice->id));
181 $xs->elementEnd('body');
182 $xs->elementEnd('html');
184 $html = $xs->getString();
186 return $html . ' ' . $entry;
189 function receive_raw_message($pl)
191 $from = $this->normalize($pl['from']);
193 if ($pl['type'] != 'chat') {
194 common_log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from.");
198 if (mb_strlen($pl['body']) == 0) {
199 common_log(LOG_WARNING, "Ignoring message with empty body from $from.");
203 return $this->handle_incoming($from, $pl['body']);
206 function initialize(){
207 if(!isset($this->server)){
208 throw new Exception("must specify a server");
210 if(!isset($this->port)){
211 throw new Exception("must specify a port");
213 if(!isset($this->user)){
214 throw new Exception("must specify a user");
216 if(!isset($this->password)){
217 throw new Exception("must specify a password");
220 $this->fake_xmpp = new Fake_XMPP($this->host ?
231 XMPPHP_Log::LEVEL_VERBOSE : null
236 function onPluginVersion(&$versions)
238 $versions[] = array('name' => 'XMPP',
239 'version' => STATUSNET_VERSION,
240 'author' => 'Craig Andrews, Evan Prodromou',
241 'homepage' => 'http://status.net/wiki/Plugin:XMPP',
243 _m('The XMPP plugin allows users to send and receive notices over the XMPP/Jabber network.'));