| [ Index ] |
|
Code source de Dolibarr 2.0.1 |
1 <?php 2 3 /*************************************************************************** 4 5 Class.Jabber.PHP v0.4 6 (c) 2002 Carlo "Gossip" Zottmann 7 http://phpjabber.g-blog.net *** gossip@jabber.g-blog.net 8 9 The FULL documentation and examples for this software can be found at 10 http://phpjabber.g-blog.net (not many doc comments in here, sorry) 11 12 last modified: 27.04.2003 13:01:53 CET 13 14 ***************************************************************************/ 15 16 /*************************************************************************** 17 * 18 19 * 20 ***************************************************************************/ 21 22 /* 23 Jabber::Connect() 24 Jabber::Disconnect() 25 Jabber::SendAuth() 26 Jabber::AccountRegistration($reg_email {string}, $reg_name {string}) 27 28 Jabber::Listen() 29 Jabber::SendPacket($xml {string}) 30 31 Jabber::RosterUpdate() 32 Jabber::RosterAddUser($jid {string}, $id {string}, $name {string}) 33 Jabber::RosterRemoveUser($jid {string}, $id {string}) 34 Jabber::RosterExistsJID($jid {string}) 35 36 Jabber::Subscribe($jid {string}) 37 Jabber::Unsubscribe($jid {string}) 38 39 Jabber::CallHandler($message {array}) 40 Jabber::CruiseControl([$seconds {number}]) 41 42 Jabber::SubscriptionApproveRequest($to {string}) 43 Jabber::SubscriptionDenyRequest($to {string}) 44 45 Jabber::GetFirstFromQueue() 46 Jabber::GetFromQueueById($packet_type {string}, $id {string}) 47 48 Jabber::SendMessage($to {string}, $id {number}, $type {string}, $content {array}[, $payload {array}]) 49 Jabber::SendIq($to {string}, $type {string}, $id {string}, $xmlns {string}[, $payload {string}]) 50 Jabber::SendPresence($type {string}[, $to {string}[, $status {string}[, $show {string}[, $priority {number}]]]]) 51 52 Jabber::SendError($to {string}, $id {string}, $error_number {number}[, $error_message {string}]) 53 54 Jabber::TransportRegistrationDetails($transport {string}) 55 Jabber::TransportRegistration($transport {string}, $details {array}) 56 57 Jabber::GetvCard($jid {string}[, $id {string}]) -- EXPERIMENTAL -- 58 59 Jabber::GetInfoFromMessageFrom($packet {array}) 60 Jabber::GetInfoFromMessageType($packet {array}) 61 Jabber::GetInfoFromMessageId($packet {array}) 62 Jabber::GetInfoFromMessageThread($packet {array}) 63 Jabber::GetInfoFromMessageSubject($packet {array}) 64 Jabber::GetInfoFromMessageBody($packet {array}) 65 Jabber::GetInfoFromMessageError($packet {array}) 66 67 Jabber::GetInfoFromIqFrom($packet {array}) 68 Jabber::GetInfoFromIqType($packet {array}) 69 Jabber::GetInfoFromIqId($packet {array}) 70 Jabber::GetInfoFromIqKey($packet {array}) 71 Jabber::GetInfoFromIqError($packet {array}) 72 73 Jabber::GetInfoFromPresenceFrom($packet {array}) 74 Jabber::GetInfoFromPresenceType($packet {array}) 75 Jabber::GetInfoFromPresenceStatus($packet {array}) 76 Jabber::GetInfoFromPresenceShow($packet {array}) 77 Jabber::GetInfoFromPresencePriority($packet {array}) 78 79 Jabber::AddToLog($string {string}) 80 Jabber::PrintLog() 81 82 MakeXML::AddPacketDetails($string {string}[, $value {string/number}]) 83 MakeXML::BuildPacket([$array {array}]) 84 */ 85 86 /*! \file htdocs/lib/jabber/class.jabber.php 87 \brief Fichier de la classe jabber. 88 \author Carlo "Gossip" Zottmann. 89 \version 0.4. 90 91 Ensemble des fonctions permettant de se connecter à un serveur jabber. 92 */ 93 94 95 /*! \class Jabber 96 \brief Classe de communication Jabber 97 */ 98 99 class Jabber 100 { 101 var $server; 102 var $port; 103 var $username; 104 var $password; 105 var $resource; 106 var $jid; 107 108 var $connection; 109 var $delay_disconnect; 110 111 var $stream_id; 112 var $roster; 113 114 var $enable_logging; 115 var $log_array; 116 var $log_filename; 117 var $log_filehandler; 118 119 var $iq_sleep_timer; 120 var $last_ping_time; 121 122 var $packet_queue; 123 var $subscription_queue; 124 125 var $iq_version_name; 126 var $iq_version_os; 127 var $iq_version_version; 128 129 var $error_codes; 130 131 var $connected; 132 var $keep_alive_id; 133 var $returned_keep_alive; 134 var $txnid; 135 136 var $CONNECTOR; 137 138 139 140 function Jabber() 141 { 142 $this->server = "localhost"; 143 $this->port = "5222"; 144 145 $this->username = "larry"; 146 $this->password = "curly"; 147 $this->resource = NULL; 148 149 $this->enable_logging = FALSE; 150 $this->log_array = array(); 151 $this->log_filename = ''; 152 $this->log_filehandler = FALSE; 153 154 $this->packet_queue = array(); 155 $this->subscription_queue = array(); 156 157 $this->iq_sleep_timer = 1; 158 $this->delay_disconnect = 1; 159 160 $this->returned_keep_alive = TRUE; 161 $this->txnid = 0; 162 163 $this->iq_version_name = "Class.Jabber.PHP -- http://phpjabber.g-blog.net -- by Carlo 'Gossip' Zottmann, gossip@jabber.g-blog.net"; 164 $this->iq_version_version = "0.4"; 165 $this->iq_version_os = $_SERVER['SERVER_SOFTWARE']; 166 167 $this->connection_class = "CJP_StandardConnector"; 168 169 $this->error_codes = array(400 => "Bad Request", 170 401 => "Unauthorized", 171 402 => "Payment Required", 172 403 => "Forbidden", 173 404 => "Not Found", 174 405 => "Not Allowed", 175 406 => "Not Acceptable", 176 407 => "Registration Required", 177 408 => "Request Timeout", 178 409 => "Conflict", 179 500 => "Internal Server Error", 180 501 => "Not Implemented", 181 502 => "Remove Server Error", 182 503 => "Service Unavailable", 183 504 => "Remove Server Timeout", 184 510 => "Disconnected"); 185 } 186 187 188 189 function Connect() 190 { 191 $this->_create_logfile(); 192 193 $this->CONNECTOR = new $this->connection_class; 194 195 if ($this->CONNECTOR->OpenSocket($this->server, $this->port)) 196 { 197 $this->SendPacket("<?xml version='1.0' encoding='UTF-8' ?" . ">\n"); 198 $this->SendPacket("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>\n"); 199 200 sleep(2); 201 202 if ($this->_check_connected()) 203 { 204 $this->connected = TRUE; // Nathan Fritz 205 return TRUE; 206 } 207 else 208 { 209 $this->AddToLog("ERROR: Connect() #1"); 210 return FALSE; 211 } 212 } 213 else 214 { 215 $this->AddToLog("ERROR: Connect() #2"); 216 return FALSE; 217 } 218 } 219 220 221 222 function Disconnect() 223 { 224 if (is_int($this->delay_disconnect)) 225 { 226 sleep($this->delay_disconnect); 227 } 228 229 $this->SendPacket("</stream:stream>"); 230 $this->CONNECTOR->CloseSocket(); 231 232 $this->_close_logfile(); 233 $this->PrintLog(); 234 } 235 236 237 238 function SendAuth() 239 { 240 $this->auth_id = "auth_" . md5(time() . $_SERVER['REMOTE_ADDR']); 241 242 $this->resource = ($this->resource != NULL) ? $this->resource : ("Class.Jabber.PHP " . md5($this->auth_id)); 243 $this->jid = "{$this->username}@{$this->server}/{$this->resource}"; 244 245 // request available authentication methods 246 $payload = "<username>{$this->username}</username>"; 247 $packet = $this->SendIq(NULL, 'get', $this->auth_id, "jabber:iq:auth", $payload); 248 249 // was a result returned? 250 if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id) 251 { 252 // yes, now check for auth method availability in descending order (best to worst) 253 254 if (!function_exists(mhash)) 255 { 256 $this->AddToLog("ATTENTION: SendAuth() - mhash() is not available; screw 0k and digest method, we need to go with plaintext auth"); 257 } 258 259 // auth_0k 260 if (function_exists(mhash) && isset($packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]) && isset($packet['iq']['#']['query'][0]['#']['token'][0]["#"])) 261 { 262 return $this->_sendauth_0k($packet['iq']['#']['query'][0]['#']['token'][0]["#"], $packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]); 263 } 264 // digest 265 elseif (function_exists(mhash) && isset($packet['iq']['#']['query'][0]['#']['digest'])) 266 { 267 return $this->_sendauth_digest(); 268 } 269 // plain text 270 elseif ($packet['iq']['#']['query'][0]['#']['password']) 271 { 272 return $this->_sendauth_plaintext(); 273 } 274 // dude, you're fucked 275 { 276 $this->AddToLog("ERROR: SendAuth() #2 - No auth method available!"); 277 return FALSE; 278 } 279 } 280 else 281 { 282 // no result returned 283 $this->AddToLog("ERROR: SendAuth() #1"); 284 return FALSE; 285 } 286 } 287 288 289 290 function AccountRegistration($reg_email = NULL, $reg_name = NULL) 291 { 292 $packet = $this->SendIq($this->server, 'get', 'reg_01', 'jabber:iq:register'); 293 294 if ($packet) 295 { 296 $key = $this->GetInfoFromIqKey($packet); // just in case a key was passed back from the server 297 unset($packet); 298 299 $payload = "<username>{$this->username}</username> 300 <password>{$this->password}</password> 301 <email>$reg_email</email> 302 <name>$reg_name</name>\n"; 303 304 $payload .= ($key) ? "<key>$key</key>\n" : ''; 305 306 $packet = $this->SendIq($this->server, 'set', "reg_01", "jabber:iq:register", $payload); 307 308 if ($this->GetInfoFromIqType($packet) == 'result') 309 { 310 if (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#'])) 311 { 312 $return_code = 1; 313 } 314 else 315 { 316 $return_code = 2; 317 } 318 319 if ($this->resource) 320 { 321 $this->jid = "{$this->username}@{$this->server}/{$this->resource}"; 322 } 323 else 324 { 325 $this->jid = "{$this->username}@{$this->server}"; 326 } 327 328 } 329 elseif ($this->GetInfoFromIqType($packet) == 'error' && isset($packet['iq']['#']['error'][0]['#'])) 330 { 331 // "conflict" error, i.e. already registered 332 if ($packet['iq']['#']['error'][0]['@']['code'] == '409') 333 { 334 $return_code = 1; 335 } 336 else 337 { 338 $return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#']; 339 } 340 } 341 342 return $return_code; 343 344 } 345 else 346 { 347 return 3; 348 } 349 } 350 351 352 353 function SendPacket($xml) 354 { 355 $xml = trim($xml); 356 357 if ($this->CONNECTOR->WriteToSocket($xml)) 358 { 359 $this->AddToLog("SEND: $xml"); 360 return TRUE; 361 } 362 else 363 { 364 $this->AddToLog('ERROR: SendPacket() #1'); 365 return FALSE; 366 } 367 } 368 369 370 371 function Listen() 372 { 373 unset($incoming); 374 375 while ($line = $this->CONNECTOR->ReadFromSocket(4096)) 376 { 377 $incoming .= $line; 378 } 379 380 $incoming = trim($incoming); 381 382 if ($incoming != "") 383 { 384 $this->AddToLog("RECV: $incoming"); 385 } 386 387 if ($incoming != "") 388 { 389 $temp = $this->_split_incoming($incoming); 390 391 for ($a = 0; $a < count($temp); $a++) 392 { 393 $this->packet_queue[] = $this->xmlize($temp[$a]); 394 } 395 } 396 397 return TRUE; 398 } 399 400 401 402 function StripJID($jid = NULL) 403 { 404 preg_match("/(.*)\/(.*)/Ui", $jid, $temp); 405 return ($temp[1] != "") ? $temp[1] : $jid; 406 } 407 408 409 410 function SendMessage($to, $type = "normal", $id = NULL, $content = NULL, $payload = NULL) 411 { 412 if ($to && is_array($content)) 413 { 414 if (!$id) 415 { 416 $id = $type . "_" . time(); 417 } 418 419 $content = $this->_array_htmlspecialchars($content); 420 421 $xml = "<message to='$to' type='$type' id='$id'>\n"; 422 423 if ($content['subject']) 424 { 425 $xml .= "<subject>" . $content['subject'] . "</subject>\n"; 426 } 427 428 if ($content['thread']) 429 { 430 $xml .= "<thread>" . $content['thread'] . "</thread>\n"; 431 } 432 433 $xml .= "<body>" . $content['body'] . "</body>\n"; 434 $xml .= $payload; 435 $xml .= "</message>\n"; 436 437 438 if ($this->SendPacket($xml)) 439 { 440 return TRUE; 441 } 442 else 443 { 444 $this->AddToLog("ERROR: SendMessage() #1"); 445 return FALSE; 446 } 447 } 448 else 449 { 450 $this->AddToLog("ERROR: SendMessage() #2"); 451 return FALSE; 452 } 453 } 454 455 456 457 function SendPresence($type = NULL, $to = NULL, $status = NULL, $show = NULL, $priority = NULL) 458 { 459 $xml = "<presence"; 460 $xml .= ($to) ? " to='$to'" : ''; 461 $xml .= ($type) ? " type='$type'" : ''; 462 $xml .= ($status || $show || $priority) ? ">\n" : " />\n"; 463 464 $xml .= ($status) ? " <status>$status</status>\n" : ''; 465 $xml .= ($show) ? " <show>$show</show>\n" : ''; 466 $xml .= ($priority) ? " <priority>$priority</priority>\n" : ''; 467 468 $xml .= ($status || $show || $priority) ? "</presence>\n" : ''; 469 470 if ($this->SendPacket($xml)) 471 { 472 return TRUE; 473 } 474 else 475 { 476 $this->AddToLog("ERROR: SendPresence() #1"); 477 return FALSE; 478 } 479 } 480 481 482 483 function SendError($to, $id = NULL, $error_number, $error_message = NULL) 484 { 485 $xml = "<iq type='error' to='$to'"; 486 $xml .= ($id) ? " id='$id'" : ''; 487 $xml .= ">\n"; 488 $xml .= " <error code='$error_number'>"; 489 $xml .= ($error_message) ? $error_message : $this->error_codes[$error_number]; 490 $xml .= "</error>\n"; 491 $xml .= "</iq>"; 492 493 $this->SendPacket($xml); 494 } 495 496 497 498 function RosterUpdate() 499 { 500 $roster_request_id = "roster_" . time(); 501 502 $incoming_array = $this->SendIq(NULL, 'get', $roster_request_id, "jabber:iq:roster"); 503 504 if (is_array($incoming_array)) 505 { 506 if ($incoming_array['iq']['@']['type'] == 'result' 507 && $incoming_array['iq']['@']['id'] == $roster_request_id 508 && $incoming_array['iq']['#']['query']['0']['@']['xmlns'] == "jabber:iq:roster") 509 { 510 $number_of_contacts = count($incoming_array['iq']['#']['query'][0]['#']['item']); 511 $this->roster = array(); 512 513 for ($a = 0; $a < $number_of_contacts; $a++) 514 { 515 $this->roster[$a] = array( "jid" => strtolower($incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['jid']), 516 "name" => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['name'], 517 "subscription" => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['@']['subscription'], 518 "group" => $incoming_array['iq']['#']['query'][0]['#']['item'][$a]['#']['group'][0]['#'] 519 ); 520 } 521 522 return TRUE; 523 } 524 else 525 { 526 $this->AddToLog("ERROR: RosterUpdate() #1"); 527 return FALSE; 528 } 529 } 530 else 531 { 532 $this->AddToLog("ERROR: RosterUpdate() #2"); 533 return FALSE; 534 } 535 } 536 537 538 539 function RosterAddUser($jid = NULL, $id = NULL, $name = NULL) 540 { 541 $id = ($id) ? $id : "adduser_" . time(); 542 543 if ($jid) 544 { 545 $payload = " <item jid='$jid'"; 546 $payload .= ($name) ? " name='" . htmlspecialchars($name) . "'" : ''; 547 $payload .= "/>\n"; 548 549 $packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", $payload); 550 551 if ($this->GetInfoFromIqType($packet) == 'result') 552 { 553 $this->RosterUpdate(); 554 return TRUE; 555 } 556 else 557 { 558 $this->AddToLog("ERROR: RosterAddUser() #2"); 559 return FALSE; 560 } 561 } 562 else 563 { 564 $this->AddToLog("ERROR: RosterAddUser() #1"); 565 return FALSE; 566 } 567 } 568 569 570 571 function RosterRemoveUser($jid = NULL, $id = NULL) 572 { 573 $id = ($id) ? $id : 'deluser_' . time(); 574 575 if ($jid && $id) 576 { 577 $packet = $this->SendIq(NULL, 'set', $id, "jabber:iq:roster", "<item jid='$jid' subscription='remove'/>"); 578 579 if ($this->GetInfoFromIqType($packet) == 'result') 580 { 581 $this->RosterUpdate(); 582 return TRUE; 583 } 584 else 585 { 586 $this->AddToLog("ERROR: RosterRemoveUser() #2"); 587 return FALSE; 588 } 589 } 590 else 591 { 592 $this->AddToLog("ERROR: RosterRemoveUser() #1"); 593 return FALSE; 594 } 595 } 596 597 598 599 function RosterExistsJID($jid = NULL) 600 { 601 if ($jid) 602 { 603 if ($this->roster) 604 { 605 for ($a = 0; $a < count($this->roster); $a++) 606 { 607 if ($this->roster[$a]['jid'] == strtolower($jid)) 608 { 609 return $a; 610 } 611 } 612 } 613 else 614 { 615 $this->AddToLog("ERROR: RosterExistsJID() #2"); 616 return FALSE; 617 } 618 } 619 else 620 { 621 $this->AddToLog("ERROR: RosterExistsJID() #1"); 622 return FALSE; 623 } 624 } 625 626 627 628 function GetFirstFromQueue() 629 { 630 return array_shift($this->packet_queue); 631 } 632 633 634 635 function GetFromQueueById($packet_type, $id) 636 { 637 $found_message = FALSE; 638 639 foreach ($this->packet_queue as $key => $value) 640 { 641 if ($value[$packet_type]['@']['id'] == $id) 642 { 643 $found_message = $value; 644 unset($this->packet_queue[$key]); 645 646 break; 647 } 648 } 649 650 return (is_array($found_message)) ? $found_message : FALSE; 651 } 652 653 654 655 function CallHandler($packet = NULL) 656 { 657 $packet_type = $this->_get_packet_type($packet); 658 659 if ($packet_type == "message") 660 { 661 $type = $packet['message']['@']['type']; 662 $type = ($type != "") ? $type : "normal"; 663 $funcmeth = "Handler_message_$type"; 664 } 665 elseif ($packet_type == "iq") 666 { 667 $namespace = $packet['iq']['#']['query'][0]['@']['xmlns']; 668 $namespace = str_replace(":", "_", $namespace); 669 $funcmeth = "Handler_iq_$namespace"; 670 } 671 elseif ($packet_type == "presence") 672 { 673 $type = $packet['presence']['@']['type']; 674 $type = ($type != "") ? $type : "available"; 675 $funcmeth = "Handler_presence_$type"; 676 } 677 678 679 if ($funcmeth != '') 680 { 681 if (function_exists($funcmeth)) 682 { 683 call_user_func($funcmeth, $packet); 684 } 685 elseif (method_exists($this, $funcmeth)) 686 { 687 call_user_func(array(&$this, $funcmeth), $packet); 688 } 689 else 690 { 691 $this->Handler_NOT_IMPLEMENTED($packet); 692 $this->AddToLog("ERROR: CallHandler() #1 - neither method nor function $funcmeth() available"); 693 } 694 } 695 } 696 697 698 699 function CruiseControl($seconds = -1) 700 { 701 $count = 0; 702 703 while ($count != $seconds) 704 { 705 $this->Listen(); 706 707 do { 708 $packet = $this->GetFirstFromQueue(); 709 710 if ($packet) { 711 $this->CallHandler($packet); 712 } 713 714 } while (count($this->packet_queue) > 1); 715 716 $count += 0.25; 717 usleep(250000); 718 719 if ($this->last_ping_time != date('H:i')) 720 { 721 // Modified by Nathan Fritz 722 if ($this->returned_keep_alive == FALSE) 723 { 724 $this->connected = FALSE; 725 $this->AddToLog('EVENT: Disconnected'); 726 } 727 728 $this->returned_keep_alive = FALSE; 729 $this->keep_alive_id = 'keep_alive_' . time(); 730 $this->SendPacket("<iq id='{$this->keep_alive_id}'/>", 'CruiseControl'); 731 // ** 732 733 $this->last_ping_time = date("H:i"); 734 } 735 } 736 737 return TRUE; 738 } 739 740 741 742 function SubscriptionAcceptRequest($to = NULL) 743 { 744 return ($to) ? $this->SendPresence("subscribed", $to) : FALSE; 745 } 746 747 748 749 function SubscriptionDenyRequest($to = NULL) 750 { 751 return ($to) ? $this->SendPresence("unsubscribed", $to) : FALSE; 752 } 753 754 755 756 function Subscribe($to = NULL) 757 { 758 return ($to) ? $this->SendPresence("subscribe", $to) : FALSE; 759 } 760 761 762 763 function Unsubscribe($to = NULL) 764 { 765 return ($to) ? $this->SendPresence("unsubscribe", $to) : FALSE; 766 } 767 768 769 770 function SendIq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL) 771 { 772 if (!preg_match("/^(get|set|result|error)$/", $type)) 773 { 774 unset($type); 775 776 $this->AddToLog("ERROR: SendIq() #2 - type must be 'get', 'set', 'result' or 'error'"); 777 return FALSE; 778 } 779 elseif ($id && $xmlns) 780 { 781 $xml = "<iq type='$type' id='$id'"; 782 $xml .= ($to) ? " to='$to'" : ''; 783 $xml .= ($from) ? " from='$from'" : ''; 784 $xml .= "> 785 <query xmlns='$xmlns'> 786 $payload 787 </query> 788 </iq>"; 789 790 $this->SendPacket($xml); 791 sleep($this->iq_sleep_timer); 792 $this->Listen(); 793 794 return (preg_match("/^(get|set)$/", $type)) ? $this->GetFromQueueById("iq", $id) : TRUE; 795 } 796 else 797 { 798 $this->AddToLog("ERROR: SendIq() #1 - to, id and xmlns are mandatory"); 799 return FALSE; 800 } 801 } 802 803 804 805 // get the transport registration fields 806 // method written by Steve Blinch, http://www.blitzaffe.com 807 function TransportRegistrationDetails($transport) 808 { 809 $this->txnid++; 810 $packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid); 811 812 if ($packet) 813 { 814 $res = array(); 815 816 foreach ($packet['iq']['#']['query'][0]['#'] as $element => $data) 817 { 818 if ($element != 'instructions' && $element != 'key') 819 { 820 $res[] = $element; 821 } 822 } 823 824 return $res; 825 } 826 else 827 { 828 return 3; 829 } 830 } 831 832 833 834 // register with the transport 835 // method written by Steve Blinch, http://www.blitzaffe.com 836 function TransportRegistration($transport, $details) 837 { 838 $this->txnid++; 839 $packet = $this->SendIq($transport, 'get', "reg_{$this->txnid}", "jabber:iq:register", NULL, $this->jid); 840 841 if ($packet) 842 { 843 $key = $this->GetInfoFromIqKey($packet); // just in case a key was passed back from the server 844 unset($packet); 845 846 $payload = ($key) ? "<key>$key</key>\n" : ''; 847 foreach ($details as $element => $value) 848 { 849 $payload .= "<$element>$value</$element>\n"; 850 } 851 852 $packet = $this->SendIq($transport, 'set', "reg_{$this->txnid}", "jabber:iq:register", $payload); 853 854 if ($this->GetInfoFromIqType($packet) == 'result') 855 { 856 if (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#'])) 857 { 858 $return_code = 1; 859 } 860 else 861 { 862 $return_code = 2; 863 } 864 } 865 elseif ($this->GetInfoFromIqType($packet) == 'error') 866 { 867 if (isset($packet['iq']['#']['error'][0]['#'])) 868 { 869 $return_code = "Error " . $packet['iq']['#']['error'][0]['@']['code'] . ": " . $packet['iq']['#']['error'][0]['#']; 870 $this->AddToLog('ERROR: TransportRegistration()'); 871 } 872 } 873 874 return $return_code; 875 } 876 else 877 { 878 return 3; 879 } 880 } 881 882 883 884 function GetvCard($jid = NULL, $id = NULL) 885 { 886 if (!$id) 887 { 888 $id = "vCard_" . md5(time() . $_SERVER['REMOTE_ADDR']); 889 } 890 891 if ($jid) 892 { 893 $xml = "<iq type='get' to='$jid' id='$id'> 894 <vCard xmlns='vcard-temp'/> 895 </iq>"; 896 897 $this->SendPacket($xml); 898 sleep($this->iq_sleep_timer); 899 $this->Listen(); 900 901 return $this->GetFromQueueById("iq", $id); 902 } 903 else 904 { 905 $this->AddToLog("ERROR: GetvCard() #1 - to and id are mandatory"); 906 return FALSE; 907 } 908 } 909 910 911 912 function PrintLog() 913 { 914 if ($this->enable_logging) 915 { 916 if ($this->log_filehandler) 917 { 918 echo "<h2>Logging enabled, logged events have been written to the file {$this->log_filename}.</h2>\n"; 919 } 920 else 921 { 922 echo "<h2>Logging enabled, logged events below:</h2>\n"; 923 echo "<pre>\n"; 924 echo (count($this->log_array) > 0) ? implode("\n\n\n", $this->log_array) : "No logged events."; 925 echo "</pre>\n"; 926 } 927 } 928 } 929 930 931 932 // ====================================================================== 933 // private methods 934 // ====================================================================== 935 936 937 938 function _sendauth_0k($zerok_token, $zerok_sequence) 939 { 940 // initial hash of password 941 $zerok_hash = mhash(MHASH_SHA1, $this->password); 942 $zerok_hash = bin2hex($zerok_hash); 943 944 // sequence 0: hash of hashed-password and token 945 $zerok_hash = mhash(MHASH_SHA1, $zerok_hash . $zerok_token); 946 $zerok_hash = bin2hex($zerok_hash); 947 948 // repeat as often as needed 949 for ($a = 0; $a < $zerok_sequence; $a++) 950 { 951 $zerok_hash = mhash(MHASH_SHA1, $zerok_hash); 952 $zerok_hash = bin2hex($zerok_hash); 953 } 954 955 $payload = "<username>{$this->username}</username> 956 <hash>$zerok_hash</hash> 957 <resource>{$this->resource}</resource>"; 958 959 $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload); 960 961 // was a result returned? 962 if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id) 963 { 964 return TRUE; 965 } 966 else 967 { 968 $this->AddToLog("ERROR: _sendauth_0k() #1"); 969 return FALSE; 970 } 971 } 972 973 974 975 function _sendauth_digest() 976 { 977 $payload = "<username>{$this->username}</username> 978 <resource>{$this->resource}</resource> 979 <digest>" . bin2hex(mhash(MHASH_SHA1, $this->stream_id . $this->password)) . "</digest>"; 980 981 $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload); 982 983 // was a result returned? 984 if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id) 985 { 986 return TRUE; 987 } 988 else 989 { 990 $this->AddToLog("ERROR: _sendauth_digest() #1"); 991 return FALSE; 992 } 993 } 994 995 996 997 function _sendauth_plaintext() 998 { 999 $payload = "<username>{$this->username}</username> 1000 <password>{$this->password}</password> 1001 <resource>{$this->resource}</resource>"; 1002 1003 $packet = $this->SendIq(NULL, 'set', $this->auth_id, "jabber:iq:auth", $payload); 1004 1005 // was a result returned? 1006 if ($this->GetInfoFromIqType($packet) == 'result' && $this->GetInfoFromIqId($packet) == $this->auth_id) 1007 { 1008 return TRUE; 1009 } 1010 else 1011 { 1012 $this->AddToLog("ERROR: _sendauth_plaintext() #1"); 1013 return FALSE; 1014 } 1015 } 1016 1017 1018 1019 function _listen_incoming() 1020 { 1021 unset($incoming); 1022 1023 while ($line = $this->CONNECTOR->ReadFromSocket(4096)) 1024 { 1025 $incoming .= $line; 1026 } 1027 1028 $incoming = trim($incoming); 1029 1030 if ($incoming != "") 1031 { 1032 $this->AddToLog("RECV: $incoming"); 1033 } 1034 1035 return $this->xmlize($incoming); 1036 } 1037 1038 1039 1040 function _check_connected() 1041 { 1042 $incoming_array = $this->_listen_incoming(); 1043 1044 if (is_array($incoming_array)) 1045 { 1046 if ($incoming_array["stream:stream"]['@']['from'] == $this->server 1047 && $incoming_array["stream:stream"]['@']['xmlns'] == "jabber:client" 1048 && $incoming_array["stream:stream"]['@']["xmlns:stream"] == "http://etherx.jabber.org/streams") 1049 { 1050 $this->stream_id = $incoming_array["stream:stream"]['@']['id']; 1051 1052 return TRUE; 1053 } 1054 else 1055 { 1056 $this->AddToLog("ERROR: _check_connected() #1"); 1057 return FALSE; 1058 } 1059 } 1060 else 1061 { 1062 $this->AddToLog("ERROR: _check_connected() #2"); 1063 return FALSE; 1064 } 1065 } 1066 1067 1068 1069 function _get_packet_type($packet = NULL) 1070 { 1071 if (is_array($packet)) 1072 { 1073 reset($packet); 1074 $packet_type = key($packet); 1075 } 1076 1077 return ($packet_type) ? $packet_type : FALSE; 1078 } 1079 1080 1081 1082 function _split_incoming($incoming) 1083 { 1084 $temp = preg_split("/<(message|iq|presence|stream)/", $incoming, -1, PREG_SPLIT_DELIM_CAPTURE); 1085 $array = array(); 1086 1087 for ($a = 1; $a < count($temp); $a = $a + 2) 1088 { 1089 $array[] = "<" . $temp[$a] . $temp[($a + 1)]; 1090 } 1091 1092 return $array; 1093 } 1094 1095 1096 1097 function _create_logfile() 1098 { 1099 if ($this->log_filename != '' && $this->enable_logging) 1100 { 1101 $this->log_filehandler = fopen($this->log_filename, 'w'); 1102 } 1103 } 1104 1105 1106 1107 function AddToLog($string) 1108 { 1109 if ($this->enable_logging) 1110 { 1111 if ($this->log_filehandler) 1112 { 1113 fwrite($this->log_filehandler, $string . "\n\n"); 1114 } 1115 else 1116 { 1117 $this->log_array[] = htmlspecialchars($string); 1118 } 1119 } 1120 } 1121 1122 1123 1124 function _close_logfile() 1125 { 1126 if ($this->log_filehandler) 1127 { 1128 fclose($this->log_filehandler); 1129 } 1130 } 1131 1132 1133 1134 // _array_htmlspecialchars() 1135 // applies htmlspecialchars() to all values in an array 1136 1137 function _array_htmlspecialchars($array) 1138 { 1139 if (is_array($array)) 1140 { 1141 foreach ($array as $k => $v) 1142 { 1143 if (is_array($v)) 1144 { 1145 $v = $this->_array_htmlspecialchars($v); 1146 } 1147 else 1148 { 1149 $v = htmlspecialchars($v); 1150 } 1151 } 1152 } 1153 1154 return $array; 1155 } 1156 1157 1158 1159 // ====================================================================== 1160 // <message/> parsers 1161 // ====================================================================== 1162 1163 1164 1165 function GetInfoFromMessageFrom($packet = NULL) 1166 { 1167 return (is_array($packet)) ? $packet['message']['@']['from'] : FALSE; 1168 } 1169 1170 1171 1172 function GetInfoFromMessageType($packet = NULL) 1173 { 1174 return (is_array($packet)) ? $packet['message']['@']['type'] : FALSE; 1175 } 1176 1177 1178 1179 function GetInfoFromMessageId($packet = NULL) 1180 { 1181 return (is_array($packet)) ? $packet['message']['@']['id'] : FALSE; 1182 } 1183 1184 1185 1186 function GetInfoFromMessageThread($packet = NULL) 1187 { 1188 return (is_array($packet)) ? $packet['message']['#']['thread'][0]['#'] : FALSE; 1189 } 1190 1191 1192 1193 function GetInfoFromMessageSubject($packet = NULL) 1194 { 1195 return (is_array($packet)) ? $packet['message']['#']['subject'][0]['#'] : FALSE; 1196 } 1197 1198 1199 1200 function GetInfoFromMessageBody($packet = NULL) 1201 { 1202 return (is_array($packet)) ? $packet['message']['#']['body'][0]['#'] : FALSE; 1203 } 1204 1205 1206 1207 function GetInfoFromMessageError($packet = NULL) 1208 { 1209 $error = preg_replace("/^\/$/", "", ($packet['message']['#']['error'][0]['@']['code'] . "/" . $packet['message']['#']['error'][0]['#'])); 1210 return (is_array($packet)) ? $error : FALSE; 1211 } 1212 1213 1214 1215 // ====================================================================== 1216 // <iq/> parsers 1217 // ====================================================================== 1218 1219 1220 1221 function GetInfoFromIqFrom($packet = NULL) 1222 { 1223 return (is_array($packet)) ? $packet['iq']['@']['from'] : FALSE; 1224 } 1225 1226 1227 1228 function GetInfoFromIqType($packet = NULL) 1229 { 1230 return (is_array($packet)) ? $packet['iq']['@']['type'] : FALSE; 1231 } 1232 1233 1234 1235 function GetInfoFromIqId($packet = NULL) 1236 { 1237 return (is_array($packet)) ? $packet['iq']['@']['id'] : FALSE; 1238 } 1239 1240 1241 1242 function GetInfoFromIqKey($packet = NULL) 1243 { 1244 return (is_array($packet)) ? $packet['iq']['#']['query'][0]['#']['key'][0]['#'] : FALSE; 1245 } 1246 1247 1248 1249 function GetInfoFromIqError($packet = NULL) 1250 { 1251 $error = preg_replace("/^\/$/", "", ($packet['iq']['#']['error'][0]['@']['code'] . "/" . $packet['iq']['#']['error'][0]['#'])); 1252 return (is_array($packet)) ? $error : FALSE; 1253 } 1254 1255 1256 1257 // ====================================================================== 1258 // <presence/> parsers 1259 // ====================================================================== 1260 1261 1262 1263 function GetInfoFromPresenceFrom($packet = NULL) 1264 { 1265 return (is_array($packet)) ? $packet['presence']['@']['from'] : FALSE; 1266 } 1267 1268 1269 1270 function GetInfoFromPresenceType($packet = NULL) 1271 { 1272 return (is_array($packet)) ? $packet['presence']['@']['type'] : FALSE; 1273 } 1274 1275 1276 1277 function GetInfoFromPresenceStatus($packet = NULL) 1278 { 1279 return (is_array($packet)) ? $packet['presence']['#']['status'][0]['#'] : FALSE; 1280 } 1281 1282 1283 1284 function GetInfoFromPresenceShow($packet = NULL) 1285 { 1286 return (is_array($packet)) ? $packet['presence']['#']['show'][0]['#'] : FALSE; 1287 } 1288 1289 1290 1291 function GetInfoFromPresencePriority($packet = NULL) 1292 { 1293 return (is_array($packet)) ? $packet['presence']['#']['priority'][0]['#'] : FALSE; 1294 } 1295 1296 1297 1298 // ====================================================================== 1299 // <message/> handlers 1300 // ====================================================================== 1301 1302 1303 1304 function Handler_message_normal($packet) 1305 { 1306 $from = $packet['message']['@']['from']; 1307 $this->AddToLog("EVENT: Message (type normal) from $from"); 1308 } 1309 1310 1311 1312 function Handler_message_chat($packet) 1313 { 1314 $from = $packet['message']['@']['from']; 1315 $this->AddToLog("EVENT: Message (type chat) from $from"); 1316 } 1317 1318 1319 1320 function Handler_message_groupchat($packet) 1321 { 1322 $from = $packet['message']['@']['from']; 1323 $this->AddToLog("EVENT: Message (type groupchat) from $from"); 1324 } 1325 1326 1327 1328 function Handler_message_headline($packet) 1329 { 1330 $from = $packet['message']['@']['from']; 1331 $this->AddToLog("EVENT: Message (type headline) from $from"); 1332 } 1333 1334 1335 1336 function Handler_message_error($packet) 1337 { 1338 $from = $packet['message']['@']['from']; 1339 $this->AddToLog("EVENT: Message (type error) from $from"); 1340 } 1341 1342 1343 1344 // ====================================================================== 1345 // <iq/> handlers 1346 // ====================================================================== 1347 1348 1349 1350 // application version updates 1351 function Handler_iq_jabber_iq_autoupdate($packet) 1352 { 1353 $from = $this->GetInfoFromIqFrom($packet); 1354 $id = $this->GetInfoFromIqId($packet); 1355 1356 $this->SendError($from, $id, 501); 1357 $this->AddToLog("EVENT: jabber:iq:autoupdate from $from"); 1358 } 1359 1360 1361 1362 // interactive server component properties 1363 function Handler_iq_jabber_iq_agent($packet) 1364 { 1365 $from = $this->GetInfoFromIqFrom($packet); 1366 $id = $this->GetInfoFromIqId($packet); 1367 1368 $this->SendError($from, $id, 501); 1369 $this->AddToLog("EVENT: jabber:iq:agent from $from"); 1370 } 1371 1372 1373 1374 // method to query interactive server components 1375 function Handler_iq_jabber_iq_agents($packet) 1376 { 1377 $from = $this->GetInfoFromIqFrom($packet); 1378 $id = $this->GetInfoFromIqId($packet); 1379 1380 $this->SendError($from, $id, 501); 1381 $this->AddToLog("EVENT: jabber:iq:agents from $from"); 1382 } 1383 1384 1385 1386 // simple client authentication 1387 function Handler_iq_jabber_iq_auth($packet) 1388 { 1389 $from = $this->GetInfoFromIqFrom($packet); 1390 $id = $this->GetInfoFromIqId($packet); 1391 1392 $this->SendError($from, $id, 501); 1393 $this->AddToLog("EVENT: jabber:iq:auth from $from"); 1394 } 1395 1396 1397 1398 // out of band data 1399 function Handler_iq_jabber_iq_oob($packet) 1400 { 1401 $from = $this->GetInfoFromIqFrom($packet); 1402 $id = $this->GetInfoFromIqId($packet); 1403 1404 $this->SendError($from, $id, 501); 1405 $this->AddToLog("EVENT: jabber:iq:oob from $from"); 1406 } 1407 1408 1409 1410 // method to store private data on the server 1411 function Handler_iq_jabber_iq_private($packet) 1412 { 1413 $from = $this->GetInfoFromIqFrom($packet); 1414 $id = $this->GetInfoFromIqId($packet); 1415 1416 $this->SendError($from, $id, 501); 1417 $this->AddToLog("EVENT: jabber:iq:private from $from"); 1418 } 1419 1420 1421 1422 // method for interactive registration 1423 function Handler_iq_jabber_iq_register($packet) 1424 { 1425 $from = $this->GetInfoFromIqFrom($packet); 1426 $id = $this->GetInfoFromIqId($packet); 1427 1428 $this->SendError($from, $id, 501); 1429 $this->AddToLog("EVENT: jabber:iq:register from $from"); 1430 } 1431 1432 1433 1434 // client roster management 1435 function Handler_iq_jabber_iq_roster($packet) 1436 { 1437 $from = $this->GetInfoFromIqFrom($packet); 1438 $id = $this->GetInfoFromIqId($packet); 1439 1440 $this->SendError($from, $id, 501); 1441 $this->AddToLog("EVENT: jabber:iq:roster from $from"); 1442 } 1443 1444 1445 1446 // method for searching a user database 1447 function Handler_iq_jabber_iq_search($packet) 1448 { 1449 $from = $this->GetInfoFromIqFrom($packet); 1450 $id = $this->GetInfoFromIqId($packet); 1451 1452 $this->SendError($from, $id, 501); 1453 $this->AddToLog("EVENT: jabber:iq:search from $from"); 1454 } 1455 1456 1457 1458 // method for requesting the current time 1459 function Handler_iq_jabber_iq_time($packet) 1460 { 1461 $type = $this->GetInfoFromIqType($packet); 1462 $from = $this->GetInfoFromIqFrom($packet); 1463 $id = $this->GetInfoFromIqId($packet); 1464 $id = ($id != "") ? $id : "time_" . time(); 1465 1466 if ($type == 'get') 1467 { 1468 $payload = "<utc>" . gmdate("Ydm\TH:i:s") . "</utc> 1469 <tz>" . date("T") . "</tz> 1470 <display>" . date("Y/d/m h:i:s A") . "</display>"; 1471 1472 $this->SendIq($from, 'result', $id, "jabber:iq:time", $payload); 1473 } 1474 1475 $this->AddToLog("EVENT: jabber:iq:time (type $type) from $from"); 1476 } 1477 1478 1479 1480 // method for requesting version 1481 function Handler_iq_jabber_iq_version($packet) 1482 { 1483 $type = $this->GetInfoFromIqType($packet); 1484 $from = $this->GetInfoFromIqFrom($packet); 1485 $id = $this->GetInfoFromIqId($packet); 1486 $id = ($id != "") ? $id : "version_" . time(); 1487 1488 if ($type == 'get') 1489 { 1490 $payload = "<name>{$this->iq_version_name}</name> 1491 <os>{$this->iq_version_os}</os> 1492 <version>{$this->iq_version_version}</version>"; 1493 1494 $this->SendIq($from, 'result', $id, "jabber:iq:version", $payload); 1495 } 1496 1497 $this->AddToLog("EVENT: jabber:iq:version (type $type) from $from"); 1498 } 1499 1500 1501 1502 // keepalive method, added by Nathan Fritz 1503 function Handler_iq_($packet) 1504 { 1505 if ($this->keep_alive_id == $this->GetInfoFromIqId($packet)) 1506 { 1507 $this->returned_keep_alive = TRUE; 1508 $this->AddToLog('EVENT: Keep-Alive returned, connection alive.'); 1509 } 1510 } 1511 1512 1513 1514 // ====================================================================== 1515 // <presence/> handlers 1516 // ====================================================================== 1517 1518 1519 1520 function Handler_presence_available($packet) 1521 { 1522 $from = $this->GetInfoFromPresenceFrom($packet); 1523 1524 $show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet); 1525 $show_status = ($show_status != " / ") ? " ($addendum)" : ''; 1526 1527 $this->AddToLog("EVENT: Presence (type: available) - $from is available $show_status"); 1528 } 1529 1530 1531 1532 function Handler_presence_unavailable($packet) 1533 { 1534 $from = $this->GetInfoFromPresenceFrom($packet); 1535 1536 $show_status = $this->GetInfoFromPresenceStatus($packet) . " / " . $this->GetInfoFromPresenceShow($packet); 1537 $show_status = ($show_status != " / ") ? " ($addendum)" : ''; 1538 1539 $this->AddToLog("EVENT: Presence (type: unavailable) - $from is unavailable $show_status"); 1540 } 1541 1542 1543 1544 function Handler_presence_subscribe($packet) 1545 { 1546 $from = $this->GetInfoFromPresenceFrom($packet); 1547 $this->SubscriptionAcceptRequest($from); 1548 $this->RosterUpdate(); 1549 1550 $this->log_array[] = "<b>Presence:</b> (type: subscribe) - Subscription request from $from, was added to \$this->subscription_queue, roster updated"; 1551 } 1552 1553 1554 1555 function Handler_presence_subscribed($packet) 1556 { 1557 $from = $this->GetInfoFromPresenceFrom($packet); 1558 $this->RosterUpdate(); 1559 1560 $this->AddToLog("EVENT: Presence (type: subscribed) - Subscription allowed by $from, roster updated"); 1561 } 1562 1563 1564 1565 function Handler_presence_unsubscribe($packet) 1566 { 1567 $from = $this->GetInfoFromPresenceFrom($packet); 1568 $this->SendPresence("unsubscribed", $from); 1569 $this->RosterUpdate(); 1570 1571 $this->AddToLog("EVENT: Presence (type: unsubscribe) - Request to unsubscribe from $from, was automatically approved, roster updated"); 1572 } 1573 1574 1575 1576 function Handler_presence_unsubscribed($packet) 1577 { 1578 $from = $this->GetInfoFromPresenceFrom($packet); 1579 $this->RosterUpdate(); 1580 1581 $this->AddToLog("EVENT: Presence (type: unsubscribed) - Unsubscribed from $from's presence"); 1582 } 1583 1584 1585 1586 // Added By Nathan Fritz 1587 function Handler_presence_error($packet) 1588 { 1589 $from = $this->GetInfoFromPresenceFrom($packet); 1590 $this->AddToLog("EVENT: Presence (type: error) - Error in $from's presence"); 1591 } 1592 1593 1594 1595 // ====================================================================== 1596 // Generic handlers 1597 // ====================================================================== 1598 1599 1600 1601 // Generic handler for unsupported requests 1602 function Handler_NOT_IMPLEMENTED($packet) 1603 { 1604 $packet_type = $this->_get_packet_type($packet); 1605 $from = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "From"), $packet); 1606 $id = call_user_func(array(&$this, "GetInfoFrom" . ucfirst($packet_type) . "Id"), $packet); 1607 1608 $this->SendError($from, $id, 501); 1609 $this->AddToLog("EVENT: Unrecognized <$packet_type/> from $from"); 1610 } 1611 1612 1613 1614 // ====================================================================== 1615 // Third party code 1616 // m@d pr0ps to the coders ;) 1617 // ====================================================================== 1618 1619 1620 1621 // xmlize() 1622 // (c) Hans Anderson / http://www.hansanderson.com/php/xml/ 1623 1624 function xmlize($data) 1625 { 1626 $vals = $index = $array = array(); 1627 $parser = xml_parser_create(); 1628 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 1629 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 1630 xml_parse_into_struct($parser, $data, $vals, $index); 1631 xml_parser_free($parser); 1632 1633 $i = 0; 1634 1635 $tagname = $vals[$i]['tag']; 1636 $array[$tagname]['@'] = $vals[$i]['attributes']; 1637 $array[$tagname]['#'] = $this->_xml_depth($vals, $i); 1638 1639 return $array; 1640 } 1641 1642 1643 1644 // _xml_depth() 1645 // (c) Hans Anderson / http://www.hansanderson.com/php/xml/ 1646 1647 function _xml_depth($vals, &$i) 1648 { 1649 $children = array(); 1650 1651 if ($vals[$i]['value']) 1652 { 1653 array_push($children, trim($vals[$i]['value'])); 1654 } 1655 1656 while (++$i < count($vals)) 1657 { 1658 switch ($vals[$i]['type']) 1659 { 1660 case 'cdata': 1661 array_push($children, trim($vals[$i]['value'])); 1662 break; 1663 1664 case 'complete': 1665 $tagname = $vals[$i]['tag']; 1666 $size = sizeof($children[$tagname]); 1667 $children[$tagname][$size]['#'] = trim($vals[$i]['value']); 1668 if ($vals[$i]['attributes']) 1669 { 1670 $children[$tagname][$size]['@'] = $vals[$i]['attributes']; 1671 } 1672 break; 1673 1674 case 'open': 1675 $tagname = $vals[$i]['tag']; 1676 $size = sizeof($children[$tagname]); 1677 if ($vals[$i]['attributes']) 1678 { 1679 $children[$tagname][$size]['@'] = $vals[$i]['attributes']; 1680 $children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i); 1681 } 1682 else 1683 { 1684 $children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i); 1685 } 1686 break; 1687 1688 case 'close': 1689 return $children; 1690 break; 1691 } 1692 } 1693 1694 return $children; 1695 } 1696 1697 1698 1699 // TraverseXMLize() 1700 // (c) acebone@f2s.com, a HUGE help! 1701 1702 function TraverseXMLize($array, $arrName = "array", $level = 0) 1703 { 1704 if ($level == 0) 1705 { 1706 echo "<pre>"; 1707 } 1708 1709 while (list($key, $val) = @each($array)) 1710 { 1711 if (is_array($val)) 1712 { 1713 $this->TraverseXMLize($val, $arrName . "[" . $key . "]", $level + 1); 1714 } 1715 else 1716 { 1717 echo '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n"; 1718 } 1719 } 1720 1721 if ($level == 0) 1722 { 1723 echo "</pre>"; 1724 } 1725 } 1726 } 1727 1728 1729 1730 class MakeXML extends Jabber 1731 { 1732 var $nodes; 1733 1734 1735 function MakeXML() 1736 { 1737 $nodes = array(); 1738 } 1739 1740 1741 1742 function AddPacketDetails($string, $value = NULL) 1743 { 1744 if (preg_match("/\(([0-9]*)\)$/i", $string)) 1745 { 1746 $string .= "/[\"#\"]"; 1747 } 1748 1749 $temp = @explode("/", $string); 1750 1751 for ($a = 0; $a < count($temp); $a++) 1752 { 1753 $temp[$a] = preg_replace("/^[@]{1}([a-z0-9_]*)$/i", "[\"@\"][\"\\1\"]", $temp[$a]); 1754 $temp[$a] = preg_replace("/^([a-z0-9_]*)\(([0-9]*)\)$/i", "[\"\\1\"][\\2]", $temp[$a]); 1755 $temp[$a] = preg_replace("/^([a-z0-9_]*)$/i", "[\"\\1\"]", $temp[$a]); 1756 } 1757 1758 $node = implode("", $temp); 1759 1760 // Yeahyeahyeah, I know it's ugly... get over it. ;) 1761 echo "\$this->nodes$node = \"" . htmlspecialchars($value) . "\";<br/>"; 1762 eval("\$this->nodes$node = \"" . htmlspecialchars($value) . "\";"); 1763 } 1764 1765 1766 1767 function BuildPacket($array = NULL) 1768 { 1769 1770 if (!$array) 1771 { 1772 $array = $this->nodes; 1773 } 1774 1775 if (is_array($array)) 1776 { 1777 array_multisort($array, SORT_ASC, SORT_STRING); 1778 1779 foreach ($array as $key => $value) 1780 { 1781 if (is_array($value) && $key == "@") 1782 { 1783 foreach ($value as $subkey => $subvalue) 1784 { 1785 $subvalue = htmlspecialchars($subvalue); 1786 $text .= " $subkey='$subvalue'"; 1787 } 1788 1789 $text .= ">\n"; 1790 1791 } 1792 elseif ($key == "#") 1793 { 1794 $text .= htmlspecialchars($value); 1795 } 1796 elseif (is_array($value)) 1797 { 1798 for ($a = 0; $a < count($value); $a++) 1799 { 1800 $text .= "<$key"; 1801 1802 if (!$this->_preg_grep_keys("/^@/", $value[$a])) 1803 { 1804 $text .= ">"; 1805 } 1806 1807 $text .= $this->BuildPacket($value[$a]); 1808 1809 $text .= "</$key>\n"; 1810 } 1811 } 1812 else 1813 { 1814 $value = htmlspecialchars($value); 1815 $text .= "<$key>$value</$key>\n"; 1816 } 1817 } 1818 1819 return $text; 1820 } 1821 } 1822 1823 1824 1825 function _preg_grep_keys($pattern, $array) 1826 { 1827 while (list($key, $val) = each($array)) 1828 { 1829 if (preg_match($pattern, $key)) 1830 { 1831 $newarray[$key] = $val; 1832 } 1833 } 1834 return (is_array($newarray)) ? $newarray : FALSE; 1835 } 1836 } 1837 1838 1839 1840 class CJP_StandardConnector 1841 { 1842 var $active_socket; 1843 1844 function OpenSocket($server, $port) 1845 { 1846 if ($this->active_socket = fsockopen($server, $port)) 1847 { 1848 socket_set_blocking($this->active_socket, 0); 1849 socket_set_timeout($this->active_socket, 31536000); 1850 1851 return TRUE; 1852 } 1853 else 1854 { 1855 return FALSE; 1856 } 1857 } 1858 1859 1860 1861 function CloseSocket() 1862 { 1863 return fclose($this->active_socket); 1864 } 1865 1866 1867 1868 function WriteToSocket($data) 1869 { 1870 return fwrite($this->active_socket, $data); 1871 } 1872 1873 1874 1875 function ReadFromSocket($chunksize) 1876 { 1877 set_magic_quotes_runtime(0); 1878 $buffer = fread($this->active_socket, $chunksize); 1879 set_magic_quotes_runtime(get_magic_quotes_gpc()); 1880 1881 return $buffer; 1882 } 1883 } 1884 1885 1886 1887 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 12:29:37 2007 | par Balluche grâce à PHPXref 0.7 |
|