public function handle_iq($stanza) { $stanza = new XMPPStanza($stanza); // emit callback registered on stanza id's $emited = false; if ($stanza->id && $this->ev->exists('on_stanza_id_' . $stanza->id)) { //_debug("on stanza id callbackd"); $emited = true; $this->ev->emit('on_stanza_id_' . $stanza->id, array($stanza)); } // catch roster list if ($stanza->type == 'result' && ($query = $stanza->exists('query', 'jabber:iq:roster'))) { foreach ($query->childrens as $child) { if ($child->name == 'item') { $jid = $child->attrs['jid']; $subscription = $child->attrs['subscription']; $groups = array(); foreach ($child->childrens as $group) { if ($group->name == 'group') { $groups[] = $group->text; } } $this->roster[$jid] = new RosterItem($jid, $subscription, $groups); } } // emit this event if not emited above if (!$emited) { $this->ev->emit('on_roster_update'); } } // if managing roster // catch contact vcard results if ($this->manage_roster && $stanza->type == 'result' && ($query = $stanza->exists('vCard', 'vcard-temp'))) { if (@$this->roster[$stanza->from]) { $this->roster[$stanza->from]->vcard = $query; } } // on_get_iq, on_result_iq, and other events are only // emitted if on_stanza_id_{id} wasn't emitted above // TODO: can we add more checks here before calling back // e.g. checks on existence of an attribute, check on 1st level child ns and so on if (!$emited) { $this->ev->emit('on_' . $stanza->type . '_iq', array($stanza)); } }