]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Xmpp/XmppPlugin.php
9557f392bb15a794eaa36436e0e084e40c2ac78a
[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 set_include_path(get_include_path() . PATH_SEPARATOR . INSTALLDIR . '/extlib/XMPPHP');
38
39 /**
40  * Plugin for XMPP
41  *
42  * @category  Plugin
43  * @package   StatusNet
44  * @author    Evan Prodromou <evan@status.net>
45  * @copyright 2009 StatusNet, Inc.
46  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
47  * @link      http://status.net/
48  */
49
50 class XmppPlugin extends ImPlugin
51 {
52     public $server = null;
53     public $port = 5222;
54     public $user =  'update';
55     public $resource = null;
56     public $encryption = true;
57     public $password = null;
58     public $host = null;  // only set if != server
59     public $debug = false; // print extra debug info
60
61     public $transport = 'xmpp';
62
63     protected $fake_xmpp;
64
65     function getDisplayName(){
66         return _m('XMPP/Jabber/GTalk');
67     }
68
69     function normalize($screenname)
70     {
71         if (preg_match("/(?:([^\@]+)\@)?([^\/]+)(?:\/(.*))?$/", $screenname, $matches)) {
72             $node   = $matches[1];
73             $server = $matches[2];
74             return strtolower($node.'@'.$server);
75         } else {
76             return null;
77         }
78     }
79
80     function daemon_screenname()
81     {
82         $ret = $this->user . '@' . $this->server;
83         if($this->resource)
84         {
85             return $ret . '/' . $this->resource;
86         }else{
87             return $ret;
88         }
89     }
90
91     function validate($screenname)
92     {
93         // Cheap but effective
94         return Validate::email($screenname);
95     }
96
97     /**
98      * Load related modules when needed
99      *
100      * @param string $cls Name of the class to be loaded
101      *
102      * @return boolean hook value; true means continue processing, false means stop.
103      */
104
105     function onAutoload($cls)
106     {
107         $dir = dirname(__FILE__);
108
109         switch ($cls)
110         {
111         case 'XMPPHP_XMPP':
112             require_once 'XMPP.php';
113             return false;
114         case 'Sharing_XMPP':
115         case 'Fake_XMPP':
116             require_once $dir . '/'.$cls.'.php';
117             return false;
118         case 'XmppManager':
119             require_once $dir . '/'.strtolower($cls).'.php';
120             return false;
121         default:
122             return true;
123         }
124     }
125
126     function onStartImDaemonIoManagers(&$classes)
127     {
128         parent::onStartImDaemonIoManagers(&$classes);
129         $classes[] = new XmppManager($this); // handles pings/reconnects
130         return true;
131     }
132
133     function microiduri($screenname)
134     {
135         return 'xmpp:' . $screenname;    
136     }
137
138     function send_message($screenname, $body)
139     {
140         $this->fake_xmpp->message($screenname, $body, 'chat');
141         $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
142         return true;
143     }
144
145     function send_notice($screenname, $notice)
146     {
147         $msg   = $this->format_notice($notice);
148         $entry = $this->format_entry($notice);
149         
150         $this->fake_xmpp->message($screenname, $msg, 'chat', null, $entry);
151         $this->enqueue_outgoing_raw($this->fake_xmpp->would_be_sent);
152         return true;
153     }
154
155     /**
156      * extra information for XMPP messages, as defined by Twitter
157      *
158      * @param Profile $profile Profile of the sending user
159      * @param Notice  $notice  Notice being sent
160      *
161      * @return string Extra information (Atom, HTML, addresses) in string format
162      */
163
164     function format_entry($notice)
165     {
166         $profile = $notice->getProfile();
167
168         $entry = $notice->asAtomEntry(true, true);
169
170         $xs = new XMLStringer();
171         $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
172         $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
173         $xs->element('a', array('href' => $profile->profileurl),
174                      $profile->nickname);
175         $xs->text(": ");
176         if (!empty($notice->rendered)) {
177             $xs->raw($notice->rendered);
178         } else {
179             $xs->raw(common_render_content($notice->content, $notice));
180         }
181         $xs->text(" ");
182         $xs->element('a', array(
183             'href'=>common_local_url('conversation',
184                 array('id' => $notice->conversation)).'#notice-'.$notice->id
185              ),sprintf(_('[%s]'),$notice->id));
186         $xs->elementEnd('body');
187         $xs->elementEnd('html');
188
189         $html = $xs->getString();
190
191         return $html . ' ' . $entry;
192     }
193
194     function receive_raw_message($pl)
195     {
196         $from = $this->normalize($pl['from']);
197
198         if ($pl['type'] != 'chat') {
199             common_log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from.");
200             return true;
201         }
202
203         if (mb_strlen($pl['body']) == 0) {
204             common_log(LOG_WARNING, "Ignoring message with empty body from $from.");
205             return true;
206         }
207
208         return $this->handle_incoming($from, $pl['body']);
209     }
210
211     function initialize(){
212         if(!isset($this->server)){
213             throw new Exception("must specify a server");
214         }
215         if(!isset($this->port)){
216             throw new Exception("must specify a port");
217         }
218         if(!isset($this->user)){
219             throw new Exception("must specify a user");
220         }
221         if(!isset($this->password)){
222             throw new Exception("must specify a password");
223         }
224
225         $this->fake_xmpp = new Fake_XMPP($this->host ?
226                                     $this->host :
227                                     $this->server,
228                                     $this->port,
229                                     $this->user,
230                                     $this->password,
231                                     $this->resource,
232                                     $this->server,
233                                     $this->debug ?
234                                     true : false,
235                                     $this->debug ?
236                                     XMPPHP_Log::LEVEL_VERBOSE :  null
237                                     );
238         return true;
239     }
240
241     function onPluginVersion(&$versions)
242     {
243         $versions[] = array('name' => 'XMPP',
244                             'version' => STATUSNET_VERSION,
245                             'author' => 'Craig Andrews, Evan Prodromou',
246                             'homepage' => 'http://status.net/wiki/Plugin:XMPP',
247                             'rawdescription' =>
248                             _m('The XMPP plugin allows users to send and receive notices over the XMPP/Jabber network.'));
249         return true;
250     }
251 }
252