* @revision 05 * @license http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons Attribution-Share Alike 3.0 Germany * @homepage http://oss.tiggerswelt.net/xmpp * @copyright Copyright © 2009 tiggersWelt.net */ require_once ('tiggerXMPP/component.php'); require_once ('tiggerXMPP/packet.php'); /** * XMPP Jabberd2 Component * ----------------------- * * @class tiggerXMPP_Component_Jabberd2 * @extends tiggerXMPP_Component * @author Bernd Holzmueller **/ class tiggerXMPP_Component_Jabberd2 extends tiggerXMPP_Component { const STREAM_OMIT_NAMESPACE = true; const STREAM_OMIT_DESTINATION = true; /* Jabberd2 Options */ const OPTIONS_NONE = 0; const OPTIONS_DEFAULT = 1; /* Use this domain as default transport */ const OPTIONS_LOG = 2; /* Receive a copy of each packet */ private $Sessions = array (); // {{{ __construct /** * Create a new Jabberd2 component * * @param string $Domain Domain to connect to * @param string $Server (optional) Manually specify server * @param int $Port (optional) Manually specify port on server * @param enum $Debug (optional) Set initial debug-value * * @access public * @return void * @see tiggerXMPP_Stream::__construct */ public function __construct ($Domain, $Server = '', $Port = null, $Debug = null) { $this->setComponentType (self::COMPONENT_TYPE_JABBERD2); parent::__construct ($Domain, $Server, $Port, $Debug); } // }}} // {{{ broadcastXML /** * Broadcast an XML-Block over the wire * * @param object $Tag * @param object $Packet * * @access public * @return void **/ public function broadcastXML ($Tag, $Packet) { // Check if we have a non-objective tag if (!is_object ($Tag)) { trigger_error ('Make sure that you send XML-Tags as an object to jabberd2'); $Tag = $this->toObject ($Tag); } // Append respond-packet if (is_object ($Packet) && isset ($Packet->id)) $Tag->id = $Packet->id; // Generate a jabberd2-envelope and inherit to our parent $Tag = $this->envelopeBroadcastTag ($Tag); return parent::sendXML ($Tag); } // }}} // {{{ envelopeBroadcastTag /** * Generate envelope for a broadcast-tag * * @param object $Tag * @param string $fromDomain (optional) * * @access protected * @return object **/ protected function envelopeBroadcastTag ($Tag, $fromDomain = null) { // Check if this is already a route-tag if (!is_object ($Tag) || ($Tag->getName () == 'route')) return $Tag; // Try to Auto-Detect our originator if (($fromDomain === null) && !($fromDomain = $this->detectDomain ($Tag))) return $Tag; // Create a new route $Envelope = new tiggerXMPP_Packet ('route'); $Envelope->setNamespace ('http://jabberd.jabberstudio.org/ns/component/1.0'); $Envelope->setAttribute ('type', 'broadcast'); $Envelope->setAttribute ('from', $fromDomain); // Attach the tag to the route $Tag->setParent ($Envelope); return $Envelope; } // }}} // {{{ smRegisterSession /** * Register a Session for a Jabber-ID at a foreign session-manager * * @param string $JID * @param string $toDomain (optional) * * @access public * @return bool **/ public function smRegisterSession ($JID, $toDomain = null) { // Set our default domain as bind-destination if ($toDomain === null) $toDomain = $this->Domain; $c2sID = strtolower ($JID); // Create an envelope to the desired Session-Manager $Envelope = new tiggerXMPP_Packet ('route'); $Envelope->setNamespace ('http://jabberd.jabberstudio.org/ns/component/1.0'); $Envelope->setAttribute ('to', $this->getJID (false, true, false, $JID)); $Envelope->setAttribute ('from', $toDomain); $Envelope->setAttribute ('id', 'setJID1' . $c2sID); // Create Session-Request $Session = new tiggerXMPP_Packet ('sc:session', $Envelope); $Session->setNamespace ('http://jabberd.jabberstudio.org/ns/session/1.0', 'sc'); $Session->setAttribute ('target', $JID); $Session->setAttribute ('action', 'start'); $Session->setAttribute ('sc:c2s', $c2sID); $this->sendXML ($Envelope); // Read the response if (!is_object ($Resp = $this->waitBlock (null, array ('setJID1' . $c2sID)))) return $this->__debug (self::DEBUG_ERROR, 'Failed to read next tag', __FUNCTION__, __LINE__, __CLASS__, __FILE__, false); if (!$Resp->haveSubtags ('sc:session')) return $this->__debug (self::DEBUG_ERROR, 'Missing sc:session-Subtag', __FUNCTION__, __LINE__, __CLASS__, __FILE__, false); $smID = $Resp->Subtags ['sc:session'][0]->getAttribute ('sc:sm'); // Start our session $Envelope->removeSubtagsByName ('sc:session'); $Envelope->setAttribute ('id', 'setJID2' . $c2sID); $IQ = new tiggerXMPP_Packet ('iq', $Envelope); $IQ->setNamespace ('jabber:client'); $IQ->setNamespace ('http://jabberd.jabberstudio.org/ns/session/1.0', 'sc'); $IQ->setAttribute ('sc:c2s', $c2sID); $IQ->setAttribute ('id', 'setJID2' . $c2sID); $IQ->setAttribute ('type', 'set'); $IQ->setAttribute ('sc:sm', $smID); $Session = new tiggerXMPP_Packet ('session', $IQ); $Session->setNamespace ('urn:ietf:params:xml:ns:xmpp-session'); $this->sendXML ($Envelope); // Read the response if (!is_object ($Resp = $this->waitBlock (null, array ('setJID2' . $c2sID)))) return $this->__debug (self::DEBUG_ERROR, 'Failed to read next tag', __FUNCTION__, __LINE__, __CLASS__, __FILE__, false); if (!$Resp->haveSubtags ('iq')) return $this->__debug (self::DEBUG_ERROR, 'Missing iq-Subtag', __FUNCTION__, __LINE__, __CLASS__, __FILE__, false); if ($Resp->Subtags ['iq'][0]->getAttribute ('type') != 'result') return $this->__debug (self::DEBUG_ERROR, 'Could not start session', __FUNCTION__, __LINE__, __CLASS__, __FILE__, false); // Set our presence to online $Envelope->removeSubtagsByName ('iq'); $Envelope->setAttribute ('id', 'setJID3' . $c2sID); $Presence = new tiggerXMPP_Packet ('presence', $Envelope); $Presence->setNamespace ('jabber:client'); $Presence->setNamespace ('http://jabberd.jabberstudio.org/ns/session/1.0', 'sc'); $Presence->setAttribute ('sc:sm', $smID); $Presence->setAttribute ('sc:c2s', $c2sID); $this->sendXML ($Envelope); // Register this session internally $this->Sessions [$c2sID] = array ( 'jid' => $JID, 'domain' => $toDomain, 'smID' => $smID, ); return true; } // }}} } ?>