]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Xmpp/XmppPlugin.php
Create IM plugin, Pluginize XMPP, Create AIM plugin
[quix0rs-gnu-social.git] / plugins / Xmpp / XmppPlugin.php
1 <?php
2 /**
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2009, StatusNet, Inc.
5  *
6  * Send and receive notices using the XMPP network
7  *
8  * PHP version 5
9  *
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.
14  *
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.
19  *
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/>.
22  *
23  * @category  IM
24  * @package   StatusNet
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/
29  */
30
31 if (!defined('STATUSNET')) {
32     // This check helps protect against security problems;
33     // your code file can't be executed directly from the web.
34     exit(1);
35 }
36
37 /**
38  * Plugin for XMPP
39  *
40  * @category  Plugin
41  * @package   StatusNet
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/
46  */
47
48 class XmppPlugin extends ImPlugin
49 {
50     public $server = null;
51     public $port = 5222;
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
58
59     public $transport = 'xmpp';
60
61     protected $fake_xmpp;
62
63     function getDisplayName(){
64         return _m('XMPP/Jabber/GTalk');
65     }
66
67     function normalize($screenname)
68     {
69         if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $screenname, $matches)) {
70             $node   = $matches[1];
71             $server = $matches[2];
72             return strtolower($node.'@'.$server);
73         } else {
74             return null;
75         }
76     }
77
78     function daemon_screenname()
79     {
80         $ret = $this->user . '@' . $this->server;
81         if($this->resource)
82         {
83             return $ret . '/' . $this->resource;
84         }else{
85             return $ret;
86         }
87     }
88
89     function validate($screenname)
90     {
91         // Cheap but effective
92         return Validate::email($screenname);
93     }
94
95     /**
96      * Load related modules when needed
97      *
98      * @param string $cls Name of the class to be loaded
99      *
100      * @return boolean hook value; true means continue processing, false means stop.
101      */
102
103     function onAutoload($cls)
104     {
105         $dir = dirname(__FILE__);
106
107         switch ($cls)
108         {
109         case 'Sharing_XMPP':
110         case 'Fake_XMPP':
111             include_once $dir . '/'.$cls.'.php';
112             return false;
113         case 'XmppManager':
114             include_once $dir . '/'.strtolower($cls).'.php';
115             return false;
116         default:
117             return true;
118         }
119     }
120
121     function onStartImDaemonIoManagers(&$classes)
122     {
123         parent::onStartImDaemonIoManagers(&$classes);
124         $classes[] = new XmppManager($this); // handles pings/reconnects
125         return true;
126     }
127
128     function microiduri($screenname)
129     {
130         return 'xmpp:' . $screenname;    
131     }
132
133     function send_message($screenname, $body)
134     {
135         $this->fake_xmpp->message($screenname, $body, 'chat');
136         $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
137         return true;
138     }
139
140     function send_notice($screenname, $notice)
141     {
142         $msg   = $this->format_notice($notice);
143         $entry = $this->format_entry($notice);
144         
145         $this->fake_xmpp->message($screenname, $msg, 'chat', null, $entry);
146         $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
147         return true;
148     }
149
150     /**
151      * extra information for XMPP messages, as defined by Twitter
152      *
153      * @param Profile $profile Profile of the sending user
154      * @param Notice  $notice  Notice being sent
155      *
156      * @return string Extra information (Atom, HTML, addresses) in string format
157      */
158
159     function format_entry($notice)
160     {
161         $profile = $notice->getProfile();
162
163         $entry = $notice->asAtomEntry(true, true);
164
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),
169                      $profile->nickname);
170         $xs->text(": ");
171         if (!empty($notice->rendered)) {
172             $xs->raw($notice->rendered);
173         } else {
174             $xs->raw(common_render_content($notice->content, $notice));
175         }
176         $xs->text(" ");
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');
183
184         $html = $xs->getString();
185
186         return $html . ' ' . $entry;
187     }
188
189     function receive_raw_message($pl)
190     {
191         $from = $this->normalize($pl['from']);
192
193         if ($pl['type'] != 'chat') {
194             common_log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from.");
195             return true;
196         }
197
198         if (mb_strlen($pl['body']) == 0) {
199             common_log(LOG_WARNING, "Ignoring message with empty body from $from.");
200             return true;
201         }
202
203         return $this->handle_incoming($from, $pl['body']);
204     }
205
206     function initialize(){
207         if(!isset($this->server)){
208             throw new Exception("must specify a server");
209         }
210         if(!isset($this->port)){
211             throw new Exception("must specify a port");
212         }
213         if(!isset($this->user)){
214             throw new Exception("must specify a user");
215         }
216         if(!isset($this->password)){
217             throw new Exception("must specify a password");
218         }
219
220         $this->fake_xmpp = new Fake_XMPP($this->host ?
221                                     $this->host :
222                                     $this->server,
223                                     $this->port,
224                                     $this->user,
225                                     $this->password,
226                                     $this->resource,
227                                     $this->server,
228                                     $this->debug ?
229                                     true : false,
230                                     $this->debug ?
231                                     XMPPHP_Log::LEVEL_VERBOSE :  null
232                                     );
233         return true;
234     }
235
236     function onPluginVersion(&$versions)
237     {
238         $versions[] = array('name' => 'XMPP',
239                             'version' => STATUSNET_VERSION,
240                             'author' => 'Craig Andrews, Evan Prodromou',
241                             'homepage' => 'http://status.net/wiki/Plugin:XMPP',
242                             'rawdescription' =>
243                             _m('The XMPP plugin allows users to send and receive notices over the XMPP/Jabber network.'));
244         return true;
245     }
246 }
247