Your IP : 18.189.43.15


Current Path : /var/www/axolotl/data/www/yar.axolotls.ru/bitrix/modules/xmpp/classes/
Upload File :
Current File : /var/www/axolotl/data/www/yar.axolotls.ru/bitrix/modules/xmpp/classes/util.php

<?
class CXMPPUtility
{
	static function GetUserByJId($jId)
	{
		if (strlen($jId) <= 0)
			return false;

		$pos = strpos($jId, "@");
		if ($pos !== false)
			$login = substr($jId, 0, $pos);
		else
			$login = $jId;

		if (strlen($login) <= 0)
			return false;

		$dbUsers = CUser::GetList($by = "ID", $order = "desc", array("LOGIN_EQUAL_EXACT" => $login, "!UF_DEPARTMENT" => false));
		$arUser = $dbUsers->Fetch();
		if (!$arUser)
			return false;

		return $arUser;
	}

	static function GetJIdByUserId($arUserID, $domain = "")
	{
		if(is_array($arUserID) && count($arUserID) > 0)
		{
			foreach ($arUserID as $key => $ID)
			{
				$ID = intval($ID);
				if($ID > 0)
					$arUserID[$key] = $ID;
				else
					unset($arUserID[$key]);
			}
		}
		else
		{
			return false;
		}

		$userID = implode(' | ', $arUserID);

		if (strlen($userID) == 0)
			return false;

		$arUserJID = array();
		$dbUsers = CUser::GetList($by = "ID", $order = "desc", array("ID" => $userID, "!UF_DEPARTMENT" => false), array('FIELDS' => array('ID', 'LOGIN')));
		while($arUser = $dbUsers->Fetch())
		{
			$arUserJID[$arUser['ID']] = CXMPPUtility::GetJId($arUser, $domain);
		}

		if (count($arUserJID) == 0)
			return false;

		return $arUserJID;
	}

	static function GetJId($arUser, $domain = "")
	{
		if (empty($domain))
			$domain = CXMPPServer::GetDomain();

		$login = preg_replace("/[^a-zA-Z0-9._-]/i", "_", $arUser["LOGIN"]);

		return strtolower($login."@".$domain);
	}

	static function Show($str, $level = 0)
	{
		if (CXMPPServer::IsServerStarted())
		{
			$server = CXMPPServer::GetServer();
			$server->WriteToLog($str, 0);
		}
	}

	static function _SendToServer($arMessage, &$errorNo, &$errorStr, $domain = "")
	{
		if (empty($domain))
			$domain = CXMPPServer::GetDomain();

		if ($f = @fsockopen(CXMPPServer::GetDomain(), 5222, $errNo, $errStr, 10))	//"127.0.0.1"
		{
			$arMessage['server'] = array(
				'.' => array('uniid' => CXMPPUtility::GetUniid($domain), "domain" => $domain),
				'#' => '',
			);

			$message = CXMPPParser::ToXml($arMessage);

			fwrite($f, $message);

			$responce = "";
			while (!feof($f))
				$responce .= trim(fread($f, 8192));

			fclose($f);

			$arResponce = CXMPPParser::ToArray($responce);

			return $arResponce;
		}

		$errorNo = $errNo;
		$errorStr = $errStr;

		return false;
	}

	static function SendToServer($arMessage, $domain = "")
	{
		if (empty($domain))
			$domain = CXMPPServer::GetDomain();

		$arResponce = CXMPPUtility::_SendToServer($arMessage, $errorNo, $errorStr, $domain);
		return ($arResponce && $arResponce['result']['.']['type'] == 'success');
	}

	static function _SendToServerXML($message, &$errorNo, &$errorStr, $domain = "")
	{
		if (empty($domain))
			$domain = CXMPPServer::GetDomain();

		if ($f = @fsockopen(CXMPPServer::GetDomain(), 5222, $errNo, $errStr, 10))	//CXMPPServer::GetDomain()
		{
			$message .= '<server uniid="'.CXMPPUtility::GetUniid($domain).'" domain="'.htmlspecialcharsbx($domain).'" />';

			fwrite($f, $message);

			$responce = "";
			while (!feof($f))
				$responce .= trim(fread($f, 8192));

			fclose($f);

			return $responce;
		}

		$errorNo = $errNo;
		$errorStr = $errStr;

		return false;
	}

	static function ClearOptionsCache($module = "main")
	{
		global $MAIN_OPTIONS;
		$MAIN_OPTIONS = array();
	}

	static function GetUniid($clientDomain = "")
	{
		static $arUniIdCache = array();

		if (!array_key_exists($clientDomain, $arUniIdCache))
		{
			self::ClearOptionsCache("main");
			$arUniIdCache[$clientDomain] = md5($GLOBALS["APPLICATION"]->GetServerUniqID());
		}

		return $arUniIdCache[$clientDomain];
	}

	static function GetMessageArray($senderJId, $receiverJId, $messageType, $body, $domain = "")
	{
		if (strlen($receiverJId) <= 0)
			return false;

		if (empty($domain))
			$domain = CXMPPServer::GetDomain();

		// chat - The message is sent in the context of a one-to-one chat conversation.
		// error - An error has occurred related to a previous message sent by the sender.
		// groupchat - The message is sent in the context of a multi-user chat environment.
		// headline - The message is probably generated by an automated service that delivers or broadcasts content.
		// normal - The message is a single message that is sent outside the context of a one-to-one conversation or
		//			groupchat, and to which it is expected that the recipient will reply.
		$arAllowableMessageTypes = array("chat", "groupchat", "headline", "normal");
		if (!in_array($messageType, $arAllowableMessageTypes))
			return false;

		$arResult = array(
			"message" => array(
				"." => array(
					"from" => CXMPPUtility::GetJIdWithResource($senderJId, $domain),
					"to" => CXMPPUtility::GetJIdWithResource($receiverJId, $domain),
					"type" => $messageType,
					"id" => "u".rand(1000, 9999),
				),
				"body" => array(
					"#" => $body,
				),
			),
		);

		return $arResult;
	}

	static function GetErrorArray($receiverJId, $stanzaKind, $errorType, $condition, $senderJId = "", $id = "", $text = "", $domain = "")
	{
		if (strlen($receiverJId) <= 0)
			return false;

		$arAllowableStanzaKinds = array("message", "presence", "iq");
		if (!in_array($stanzaKind, $arAllowableStanzaKinds))
			return false;

		// cancel - do not retry (the error is unrecoverable)
		// continue - proceed (the condition was only a warning)
		// modify - retry after changing the data sent
		// auth - retry after providing credentials
		// wait - retry after waiting (the error is temporary)
		$arAllowableErrorTypes = array("cancel", "continue", "modify", "auth", "wait");
		if (!in_array($errorType, $arAllowableErrorTypes))
			return false;

		switch ($condition)
		{
			// the sender has sent XML that is malformed or that cannot be processed (e.g., an IQ stanza that includes an
			// unrecognized value of the 'type' attribute); the associated error type SHOULD be "modify".
			case "bad-request":
				$errorType = "modify";
				break;
			// access cannot be granted because an existing resource or session exists with the same name or address; the
			// associated error type SHOULD be "cancel".
			case "conflict":
				$errorType = "cancel";
				break;
			// the feature requested is not implemented by the recipient or server and therefore cannot be
			// processed; the associated error type SHOULD be "cancel".
			case "feature-not-implemented":
				$errorType = "cancel";
				break;
			// the requesting entity does not possess the required permissions to perform the action; the associated
			// error type SHOULD be "auth".
			case "forbidden":
				$errorType = "auth";
				break;
			// the recipient or server can no longer be contacted at this address (the error stanza MAY contain a new address in the
			// XML character data of the <gone/> element); the associated error type SHOULD be "modify".
			case "gone":
				$errorType = "modify";
				break;
			// the server could not process the stanza because of a misconfiguration or an otherwise-undefined
			// internal server error; the associated error type SHOULD be "wait".
			case "internal-server-error":
				$errorType = "wait";
				break;
			// the addressed JID or item requested cannot be found; the associated error type SHOULD be "cancel".
			case "item-not-found":
				$errorType = "cancel";
				break;
			// the sending entity has provided or communicated an XMPP address (e.g., a value of the 'to' attribute)
			// or aspect thereof (e.g., a resource identifier) that does not adhere to the syntax defined in
			// Addressing Scheme; the associated error type SHOULD be "modify".
			case "jid-malformed":
				$errorType = "modify";
				break;
			// the recipient or server understands the request but is refusing to process it because it does not meet
			// criteria defined by the recipient or server (e.g., a local policy regarding acceptable words in
			// messages); the associated error type SHOULD be "modify".
			case "not-acceptable":
				$errorType = "modify";
				break;
			// the recipient or server does not allow any entity to perform the action; the associated
			// error type SHOULD be "cancel".
			case "not-allowed":
				$errorType = "cancel";
				break;
			// the sender must provide proper credentials before being allowed to perform the action,
			// or has provided improper credentials; the associated error type SHOULD be "auth".
			case "not-authorized":
				$errorType = "auth";
				break;
			// the requesting entity is not authorized to access the requested service because payment is
			// required; the associated error type SHOULD be "auth".
			case "payment-required":
				$errorType = "auth";
				break;
			// the intended recipient is temporarily unavailable; the associated error type SHOULD
			// be "wait" (note: an application MUST NOT return this error if doing so would provide
			// information about the intended recipient's network availability to
			// an entity that is not authorized to know such information).
			case "recipient-unavailable":
				$errorType = "wait";
				break;
			// the recipient or server is redirecting requests for this information to another entity,
			// usually temporarily (the error stanza SHOULD contain the alternate address, which MUST be
			// a valid JID, in the XML character data of the <redirect/> element); the
			// associated error type SHOULD be "modify".
			case "redirect":
				$errorType = "modify";
				break;
			// the requesting entity is not authorized to access the requested service because registration
			// is required; the associated error type SHOULD be "auth".
			case "registration-required":
				$errorType = "auth";
				break;
			// a remote server or service specified as part or all of the JID of the intended recipient
			// does not exist; the associated error type SHOULD be "cancel".
			case "remote-server-not-found":
				$errorType = "cancel";
				break;
			// a remote server or service specified as part or all of the JID of the intended recipient
			// (or required to fulfill a request) could not be contacted within a reasonable
			// amount of time; the associated error type SHOULD be "wait".
			case "remote-server-timeout":
				$errorType = "wait";
				break;
			// the server or recipient lacks the system resources necessary to service the request; the
			// associated error type SHOULD be "wait".
			case "resource-constraint":
				$errorType = "wait";
				break;
			// the server or recipient does not currently provide the requested service; the associated
			// error type SHOULD be "cancel".
			case "service-unavailable":
				$errorType = "cancel";
				break;
			// the requesting entity is not authorized to access the requested service because a subscription
			// is required; the associated error type SHOULD be "auth".
			case "subscription-required":
				$errorType = "auth";
				break;
			// the error condition is not one of those defined by the other conditions in this list;
			// any error type may be associated with this condition, and it SHOULD be used only in
			// conjunction with an application-specific condition.
			case "undefined-condition":
				break;
			// the recipient or server understood the request but was not expecting it at this
			// time (e.g., the request was out of order); the associated error type SHOULD be "wait".
			case "unexpected-request":
				$errorType = "wait";
				break;
			default:
				return false;
				break;
		}

		$arResult = array(
			$stanzaKind => array(
				"." => array(
					"to" => self::GetJIdWithResource($receiverJId, $domain),
					"type" => "error",
				),
				"error" => array(
					"." => array(
						"type" => $errorType,
					),
					$condition => array(
						"." => array(
							"xmlns" => "urn:ietf:params:xml:ns:xmpp-stanzas",
						),
					),
				),
			),
		);

		if (strlen($senderJId) > 0)
			$arResult[$stanzaKind]["."]["from"] = self::GetJIdWithResource($senderJId, $domain);

		if (strlen($id) > 0)
			$arResult[$stanzaKind]["."]["id"] = $id;

		if (strlen($text) > 0)
		{
			$arResult[$stanzaKind]["error"]["text"] = array(
				"." => array(
					"xmlns" => "urn:ietf:params:xml:ns:xmpp-stanzas",
					"xml:lang" => "en",
				),
				"#" => $text,
			);
		}

		return $arResult;
	}

	static function GetServerErrorArray($errorMessage)
	{
		return array(
			'result' => array(
				"." => array(
					"type" => "error",
				),
				"message" => array(
					"#" => $errorMessage
				),
			),
		);
	}

	static function IsBitrix24Mode()
	{
		if (!CXMPPServer::IsServerStarted())
			return false;

		$server = CXMPPServer::GetServer();
		return $server->IsBitrix24Mode();
	}

	static function SelectDatabase($clientDomain)
	{
		if (!CXMPPUtility::IsBitrix24Mode())
			return true;

		if (empty($clientDomain))
			return true;

		static $arDomainDatabases = array();

		if (!array_key_exists($clientDomain, $arDomainDatabases))
		{
			CXMPPUtility::Show("Creating connection to ".$clientDomain." database", 5);

			$dbHost = $GLOBALS["DB"]->DBHost;

			$dbTmp = new CDatabase;
			if ($dbTmp->Connect($dbHost, $clientDomain, "root", "12345"))	// ($dbTmp->Connect($dbHost, $clientDomain, $clientDomain, ""))
				$arDomainDatabases[$clientDomain] = $dbTmp;
			//$arDomainDatabases[$clientDomain] = $GLOBALS["DB"];
		}

		if (array_key_exists($clientDomain, $arDomainDatabases))
		{
			CXMPPUtility::Show("Database selected: ".$clientDomain, 0);

			$GLOBALS["DB"] = $arDomainDatabases[$clientDomain];
			return true;
		}

		CXMPPUtility::Show("Error connecting to ".$clientDomain." database", 5);
		return false;
	}

	public static function GetJIdWithResource($jid, $domain = "")
	{
		if (strpos($jid, "/") !== false)
			return $jid;

		if (!CXMPPServer::IsServerStarted())
			return $jid;

		$server = CXMPPServer::GetServer();
		$arClients = $server->GetClient($jid, $domain);

		if (is_null($arClients))
			return $jid;

		return $arClients[0]->GetJIdWithResource();
	}

	public static function MakeDump()
	{
		$server = CXMPPServer::GetServer();
		if ($fp = @fopen($_SERVER["DOCUMENT_ROOT"]."/xmpp_dump_".date("YmdHis"), "w"))
		{
			fwrite($fp, $server->GetDumpData());
			fclose($fp);
		}
	}

	public static function CheckXmppStatusOnline()
	{
		$LastActivityDate = COption::GetOptionInt('xmpp', 'LastActivityDate', 0);
		if (intval($LastActivityDate)+601 > time())
			return true;

		return false;
	}

	public static function GetNameFormat()
	{
		return str_replace(array("#NOBR#","#/NOBR#"), array("",""), COption::GetOptionString("xmpp", "name_template", "#LAST_NAME# #NAME#"));
	}
}
?>