| 1 |
<?php |
<?php |
| 2 |
// $Id: xmpp_roster.module,v 1.1 2008/09/25 06:45:41 t0talmeltd0wn Exp $ |
// $Id: xmpp_roster.module,v 1.2 2008/09/25 08:23:38 t0talmeltd0wn Exp $ |
| 3 |
|
|
| 4 |
define("XMPP_ROSTER_NONE", 0); |
define("XMPP_ROSTER_NONE", 0); |
| 5 |
define("XMPP_ROSTER_SUBSCRIBED", 1); |
define("XMPP_ROSTER_SUBSCRIBED", 1); |
| 11 |
* Implementation of hook_xmpp_disco_features(). |
* Implementation of hook_xmpp_disco_features(). |
| 12 |
*/ |
*/ |
| 13 |
function xmpp_roster_xmpp_disco_features($client) { |
function xmpp_roster_xmpp_disco_features($client) { |
|
echo "Disco features!\n"; |
|
| 14 |
return array('jabber:iq:roster'); |
return array('jabber:iq:roster'); |
| 15 |
} |
} |
| 16 |
|
|
| 17 |
/** |
function xmpp_roster_xmpp_router_presence($client, $node) { |
| 18 |
* Implementation of hook_xmpp_server_start(). |
$session = xmpp_server_get_session($client); |
| 19 |
*/ |
if (!$session['initial_presence']) { |
| 20 |
function xmpp_roster_xmpp_server_start() { |
$session['initial_presence'] = TRUE; |
| 21 |
|
xmpp_server_save_session($session); |
| 22 |
|
|
| 23 |
|
$res = db_query("SELECT fid FROM {xmpp_roster_presence} |
| 24 |
|
WHERE uid=%d AND state=%d", |
| 25 |
|
$session['uid'], XMPP_ROSTER_SUBSCRIBED); |
| 26 |
|
while ($row = db_fetch_object($res)) { |
| 27 |
|
$fid = $row->fid; |
| 28 |
|
|
| 29 |
|
$cids = xmpp_server_id_map($fid, 'uid'); |
| 30 |
|
foreach ($cids as $cid) { |
| 31 |
|
$c = xmpp_server_get_client($cid); |
| 32 |
|
$csess = xmpp_server_get_session($c); |
| 33 |
|
$p = $csess['presence']; |
| 34 |
|
if ($p) { |
| 35 |
|
$p->options['to'] = xmpp_serialize_jid($session['jid']); |
| 36 |
|
$p->options['from'] = xmpp_serialize_jid($csess['jid']); |
| 37 |
|
xmpp_server_send($client, $p); |
| 38 |
|
} |
| 39 |
|
} |
| 40 |
|
} |
| 41 |
|
} |
| 42 |
|
|
| 43 |
|
_xmpp_send_to_subscribers($session, $node); |
| 44 |
|
} |
| 45 |
|
|
| 46 |
|
function xmpp_roster_xmpp_client_close($client) { |
| 47 |
|
$session = xmpp_server_get_session($client); |
| 48 |
|
|
| 49 |
|
$presence = new XmlNode(); |
| 50 |
|
$presence->tag = 'presence'; |
| 51 |
|
$presence->options['type'] = 'unavailable'; |
| 52 |
|
$presence->options['from'] = xmpp_serialize_jid($session['jid']); |
| 53 |
|
|
| 54 |
|
_xmpp_send_to_subscribers($session, $presence); |
| 55 |
} |
} |
| 56 |
|
|
| 57 |
/** |
/** |
| 94 |
'children' => array( |
'children' => array( |
| 95 |
'item' => array( |
'item' => array( |
| 96 |
'options' => array( |
'options' => array( |
| 97 |
'jid' => '*', |
'jid' => '+', |
| 98 |
'subscription' => '!*', |
'subscription' => '!', |
| 99 |
), |
), |
| 100 |
), |
), |
| 101 |
), |
), |
| 119 |
'children' => array( |
'children' => array( |
| 120 |
'item' => array( |
'item' => array( |
| 121 |
'options' => array( |
'options' => array( |
| 122 |
'jid' => '*', |
'jid' => '+', |
| 123 |
'subscription' => 'remove', |
'subscription' => 'remove', |
| 124 |
), |
), |
| 125 |
), |
), |
| 135 |
'protocol' => 'jabber:client', |
'protocol' => 'jabber:client', |
| 136 |
'tag' => 'presence', |
'tag' => 'presence', |
| 137 |
'options' => array( |
'options' => array( |
| 138 |
'to' => '*', |
'to' => '+', |
| 139 |
'type' => 'subscribe', |
'type' => 'subscribe', |
| 140 |
), |
), |
| 141 |
); |
); |
| 145 |
'bound' => TRUE, |
'bound' => TRUE, |
| 146 |
'tag' => 'presence', |
'tag' => 'presence', |
| 147 |
'options' => array( |
'options' => array( |
| 148 |
'to' => '*', |
'to' => '+', |
| 149 |
'type' => 'subscribed', |
'type' => 'subscribed', |
| 150 |
), |
), |
| 151 |
); |
); |
| 155 |
'bound' => TRUE, |
'bound' => TRUE, |
| 156 |
'tag' => 'presence', |
'tag' => 'presence', |
| 157 |
'options' => array( |
'options' => array( |
| 158 |
'to' => '*', |
'to' => '+', |
| 159 |
'type' => 'unsubscribe', |
'type' => 'unsubscribe', |
| 160 |
), |
), |
| 161 |
|
|
| 166 |
'bound' => TRUE, |
'bound' => TRUE, |
| 167 |
'tag' => 'presence', |
'tag' => 'presence', |
| 168 |
'options' => array( |
'options' => array( |
| 169 |
'to' => '*', |
'to' => '+', |
| 170 |
'type' => 'unsubscribed', |
'type' => 'unsubscribed', |
| 171 |
), |
), |
| 172 |
|
|
| 270 |
$uid = xmpp_get_uid_by_jid($node->options['to']); |
$uid = xmpp_get_uid_by_jid($node->options['to']); |
| 271 |
$jid = xmpp_parse_jid($node->options['to']); |
$jid = xmpp_parse_jid($node->options['to']); |
| 272 |
|
|
| 273 |
|
//If already subscribed or the user doesn't exist, silently ignore. |
| 274 |
$session = xmpp_server_get_session($client); |
$session = xmpp_server_get_session($client); |
| 275 |
if (!$uid || _xmpp_roster_is_subscribed($session['uid'], $uid)) { |
if (!$uid || _xmpp_roster_is_subscribed($session['uid'], $uid)) { |
| 276 |
return; |
return; |
| 277 |
} |
} |
| 278 |
|
|
| 279 |
|
//Subscribe |
| 280 |
xmpp_subscribe($session['uid'], $uid); |
xmpp_subscribe($session['uid'], $uid); |
| 281 |
|
|
| 282 |
|
//Forward this stanza to the user's available resources. |
| 283 |
$node->options['from'] = xmpp_serialize_jid($session['jid'], true); |
$node->options['from'] = xmpp_serialize_jid($session['jid'], true); |
| 284 |
xmpp_server_send_to($uid, 'uid', $node, true); |
xmpp_server_send_to($uid, 'uid', $node, true); |
| 285 |
|
|
| 286 |
|
//Do a roster push. |
| 287 |
_xmpp_perform_roster_set($client); |
_xmpp_perform_roster_set($client); |
| 288 |
} |
} |
| 289 |
|
|
| 291 |
$uid = xmpp_get_uid_by_jid($node->options['to']); |
$uid = xmpp_get_uid_by_jid($node->options['to']); |
| 292 |
$jid = xmpp_parse_jid($node->options['to']); |
$jid = xmpp_parse_jid($node->options['to']); |
| 293 |
|
|
| 294 |
|
//If the user doesn't exist, silently ignore. |
| 295 |
$session = xmpp_server_get_session($client); |
$session = xmpp_server_get_session($client); |
| 296 |
if (!$uid) { |
if (!$uid) { |
| 297 |
return; |
return; |
| 298 |
} |
} |
| 299 |
|
|
| 300 |
|
/*If finalization fails (I.E. user doesn't exist or doesn't have a pending |
| 301 |
|
subscription) then silently ignore.*/ |
| 302 |
if (!xmpp_finalize_subscription($uid, $session['uid'])) { |
if (!xmpp_finalize_subscription($uid, $session['uid'])) { |
| 303 |
return; |
return; |
| 304 |
} |
} |
| 305 |
|
|
| 306 |
|
//Forward the subscribe stanza to the target's available resources. |
| 307 |
$node->options['from'] = xmpp_serialize_jid($session['jid'], true); |
$node->options['from'] = xmpp_serialize_jid($session['jid'], true); |
| 308 |
xmpp_server_send_to($uid, 'uid', $node, true); |
xmpp_server_send_to($uid, 'uid', $node, true); |
| 309 |
|
|
| 310 |
|
//Do a roster push for both the subscriber and the subscribee. |
| 311 |
_xmpp_perform_roster_set($uid); |
_xmpp_perform_roster_set($uid); |
| 312 |
_xmpp_perform_roster_set($session['uid']); |
_xmpp_perform_roster_set($session['uid']); |
| 313 |
|
|
| 314 |
|
$cids = xmpp_server_id_map($session['uid'], 'uid'); |
| 315 |
|
foreach ($cids as $cid) { |
| 316 |
|
$c = xmpp_server_get_client($cid); |
| 317 |
|
$csess = xmpp_server_get_session($c); |
| 318 |
|
if ($csess['presence']) { |
| 319 |
|
xmpp_server_send_to($uid, 'uid', $session['presence']); |
| 320 |
|
} |
| 321 |
|
} |
| 322 |
} |
} |
| 323 |
|
|
| 324 |
function xmpp_presence_unsubscribe($client, $node) { |
function xmpp_presence_unsubscribe($client, $node) { |
| 325 |
$uid = xmpp_get_uid_by_jid($node->options['jid']); |
$uid = xmpp_get_uid_by_jid($node->options['to']); |
| 326 |
$session = xmpp_server_get_session($client); |
$session = xmpp_server_get_session($client); |
| 327 |
if (!$uid || _is_subscribed($session['uid'], $uid)) { |
if (!$uid || !_xmpp_roster_is_subscribed($session['uid'], $uid)) { |
| 328 |
return; |
return; |
| 329 |
} |
} |
| 330 |
|
|
| 331 |
|
//Perform unsubscription |
| 332 |
|
xmpp_unsubscribe($session['uid'], $uid); |
| 333 |
|
|
| 334 |
|
//Forward the unsubscribe stanza to all clients in the id map where |
| 335 |
|
// uid=$uid |
| 336 |
|
$node->options['from'] = xmpp_serialize_jid($session['jid'], true); |
| 337 |
|
xmpp_server_send_to($uid, 'uid', $node, true); |
| 338 |
|
|
| 339 |
|
//Do a roster push for the client. |
| 340 |
|
_xmpp_perform_roster_set($session['uid']); |
| 341 |
|
|
| 342 |
|
$cids = xmpp_server_id_map($uid, 'uid'); |
| 343 |
|
foreach ($cids as $cid) { |
| 344 |
|
$c = xmpp_server_get_client($cid); |
| 345 |
|
$csess = xmpp_server_get_session($c); |
| 346 |
|
|
| 347 |
|
$presence = new XmlNode(); |
| 348 |
|
$presence->tag = 'presence'; |
| 349 |
|
$presence->options['type'] = 'unavailable'; |
| 350 |
|
$presence->options['from'] = xmpp_serialize_jid($csess['jid']); |
| 351 |
|
|
| 352 |
|
xmpp_server_send_to($session['uid'], 'uid', $presence); |
| 353 |
|
} |
| 354 |
} |
} |
| 355 |
|
|
| 356 |
function xmpp_presence_unsubscribed($client, $node) { |
function xmpp_presence_unsubscribed($client, $node) { |
| 357 |
$uid = xmpp_get_uid_by_jid($node->options['jid']); |
$uid = xmpp_get_uid_by_jid($node->options['to']); |
| 358 |
$session = xmpp_server_get_session($client); |
if (!$uid) { |
|
if (!$uid || _is_subscribed($session['uid'], $uid)) { |
|
| 359 |
return; |
return; |
| 360 |
} |
} |
| 361 |
|
$session = xmpp_server_get_session($client); |
| 362 |
|
|
| 363 |
|
xmpp_unsubscribe($uid, $session['uid']); |
| 364 |
|
|
| 365 |
|
$node->options['from'] = xmpp_serialize_jid($session['jid'], true); |
| 366 |
|
xmpp_server_send_to($uid, 'uid', $node, true); |
| 367 |
|
|
| 368 |
|
_xmpp_perform_roster_set($uid); |
| 369 |
|
|
| 370 |
|
$cids = xmpp_server_id_map($session['uid'], 'uid'); |
| 371 |
|
foreach ($cids as $cid) { |
| 372 |
|
$c = xmpp_server_get_client($cid); |
| 373 |
|
$csess = xmpp_server_get_session($c); |
| 374 |
|
|
| 375 |
|
$presence = new XmlNode(); |
| 376 |
|
$presence->tag = 'presence'; |
| 377 |
|
$presence->options['type'] = 'unavailable'; |
| 378 |
|
$presence->options['from'] = xmpp_serialize_jid($session['jid']); |
| 379 |
|
|
| 380 |
|
xmpp_server_send_to($uid, 'uid', $presence); |
| 381 |
|
} |
| 382 |
} |
} |
| 383 |
|
|
| 384 |
/* ==== Below are utility/wrapper functions ==== */ |
/* ==== Below are utility/wrapper functions ==== */ |
| 466 |
return $q; |
return $q; |
| 467 |
} |
} |
| 468 |
|
|
| 469 |
|
function _xmpp_send_to_subscribers(&$session, $node) { |
| 470 |
|
if (is_object($node)) { |
| 471 |
|
$node = (object)$node; |
| 472 |
|
} |
| 473 |
|
|
| 474 |
|
$res = db_query("SELECT uid FROM {xmpp_roster_presence |
| 475 |
|
WHERE fid=%d AND state=%d", |
| 476 |
|
$session['uid'], XMPP_ROSTER_SUBSCRIBED); |
| 477 |
|
while($row = db_fetch_object($res)) { |
| 478 |
|
$node->options['from'] = xmpp_serialize_jid($session['jid']); |
| 479 |
|
xmpp_server_send_to($row->uid, 'uid', $node); |
| 480 |
|
} |
| 481 |
|
} |
| 482 |
|
|
| 483 |
/* ==== Below are API functions ==== */ |
/* ==== Below are API functions ==== */ |
| 484 |
|
|
| 485 |
/** |
/** |
| 641 |
$which = 'fid'; |
$which = 'fid'; |
| 642 |
} |
} |
| 643 |
$whichname = "{$which}name"; |
$whichname = "{$which}name"; |
| 644 |
|
|
| 645 |
//'$which' is now the column that is /not/ $uid |
//'$which' is now the column that is /not/ $uid |
| 646 |
if (!isset($ret[$row->$which])) { |
if (!isset($ret[$row->$which])) { |
| 647 |
$ret[$row->$which]->subscription = _get_subscription_state($uid, $row->$which); |
$ret[$row->$which]->subscription = _get_subscription_state($uid, $row->$which); |
| 652 |
if (variable_get('xmpp_server_cache_lists', false)) { |
if (variable_get('xmpp_server_cache_lists', false)) { |
| 653 |
cache_set($uid, $ret, 'cache_xmpp_subscriptions'); |
cache_set($uid, $ret, 'cache_xmpp_subscriptions'); |
| 654 |
} |
} |
|
|
|
| 655 |
return $ret; |
return $ret; |
| 656 |
} |
} |
| 657 |
|
|