Subversion Repositories HomeAutomation

Rev

Rev 1217 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. <?php
  2.  
  3. require(dirname(__FILE__)."/config.php");
  4.  
  5. /*
  6.  
  7.   http://www.howtoforge.com/talking-soap-with-exchange
  8.  
  9. */
  10.  
  11. if (isset($_GET["function"]))
  12. {
  13.     switch ($_GET["function"])
  14.     {
  15.         case "getMeetingsRestOfDay":
  16.         if (isset($_GET["shortname"]))
  17.         {
  18.             echo getMeetingsRestOfDay($_GET["shortname"]);
  19.         }
  20.         break;
  21.        
  22.         case "bookMeeting":
  23.         if (isset($_GET["from"]) && isset($_GET["to"]) && isset($_GET["shortname"]))
  24.         {
  25.             if (preg_match("/^\d\d:\d\d$/", $_GET["from"]) && preg_match("/^\d\d:\d\d$/", $_GET["to"]))
  26.             {
  27.                 echo bookMeeting($_GET["shortname"], $_GET["from"], $_GET["to"]);
  28.             }
  29.         }
  30.         break;
  31.        
  32.         //case "":
  33.         //
  34.         //break;
  35.     }
  36. }
  37.  
  38.  
  39. /*
  40.   Book meeting
  41.   Return a JSON formed string with the result
  42. */
  43. function bookMeeting($shortname, $bookFrom, $bookTo)
  44. {
  45.     global $Calender;
  46.     global $wsdl;
  47.     $founditem = false;
  48.    
  49.     foreach($Calender as $item)
  50.     {
  51.         if ($item->Shortname == $shortname)
  52.         {
  53.             $founditem = $item;
  54.             break;
  55.         }
  56.     }
  57.    
  58.     $bookingsOk = true;
  59.  
  60.     $bookings = json_decode(getMeetingsRestOfDay($shortname));
  61.     //print_array($bookings);
  62.     //echo $bookings;
  63.     if ($bookings->{'error'})
  64.     {
  65.         $bookingsOk = false;
  66.     }
  67.    
  68.     if ($bookings->{'meetings'})
  69.     {
  70.         foreach ($bookings->{'meetings'} as $meeting)
  71.         {
  72.             $meetStart = strtotime($meeting->{'start'});
  73.             $meetEnd = strtotime($meeting->{'end'});
  74.             $start = strtotime($bookFrom);
  75.             $end = strtotime($bookTo);
  76.             //echo $meeting->{'start'}." ";
  77.             if (($start >= $meetStart && $start < $meetEnd)
  78.                 || ($end > $meetStart && $end <= $meetEnd)
  79.                 || ($start <= $meetStart && $end >= $meetEnd))
  80.             {
  81.                 $bookingsOk = false;
  82.                 break;
  83.             }
  84.         }
  85.     }
  86.  
  87.     if ($founditem !== false && $bookingsOk)
  88.     {
  89.         $CreateItem->SendMeetingInvitations = "SendToNone";
  90.         $CreateItem->SavedItemFolderId->DistinguishedFolderId->Id = "calendar";
  91.         $CreateItem->Items->CalendarItem = array();
  92.         $CreateItem->Items->CalendarItem[0]->Subject = "Booking from panel";
  93.         /* Dont forget to use the proper timezone and setting for daylight saving time (php handles this fine) */
  94.         $CreateItem->Items->CalendarItem[0]->Start = date("c",strtotime($bookFrom)); // "2009-05-22T17:00:00Z" ISO date format. Z denotes UTC time
  95.         $CreateItem->Items->CalendarItem[0]->End = date("c",strtotime($bookTo));
  96.         $CreateItem->Items->CalendarItem[0]->IsAllDayEvent = false;
  97.         $CreateItem->Items->CalendarItem[0]->LegacyFreeBusyStatus = "Busy";
  98.         $CreateItem->Items->CalendarItem[0]->Location = $founditem->Shortname;
  99.         $CreateItem->Items->CalendarItem[0]->Categories->String = "Meeting";
  100.  
  101.         stream_wrapper_unregister('https');
  102.         stream_wrapper_register('https', 'NTLMStream') or die("Failed to register protocol");
  103.          
  104.         try
  105.         {
  106.             $client = new ExchangeNTLMSoapClient($wsdl);
  107.             $client->user = $founditem->UserName;
  108.             $client->pass = $founditem->Password;
  109.             $result = $client->CreateItem($CreateItem);
  110.             if ($result)
  111.             {
  112.                 //print_array($result);
  113.                 if ($result->ResponseMessages->CreateItemResponseMessage->ResponseClass == "Success")
  114.                 {
  115.                     $returndata = "{ result:'success',\nshortname:'".$shortname."'}\n";
  116.                 }
  117.                 else
  118.                 {
  119.                     $errorcode=$result->ResponseMessages->CreateItemResponseMessage->MessageText;
  120.                     $returndata = "{ result:'error',\nerror:'".$errorcode."',\nshortname:'".$shortname."'}\n";
  121.                 }
  122.             }
  123.             else
  124.             {
  125.                 $returdata = "{ error:'No result',\nshortname:'".$shortname."'}\n";
  126.             }
  127.            
  128.         }
  129.         catch (SoapFault $exception)
  130.         {
  131.             $returdata = "{ error:'".$exception."',\nshortname:'".$shortname."'}\n";
  132.         }
  133.  
  134.         stream_wrapper_restore('https');
  135.         return $returndata;
  136.     }
  137.     else if ($founditem === false)
  138.     {
  139.         return "{ error:'Unknown shortname',\nshortname:'".$shortname."'}\n";
  140.     }
  141.     else
  142.     {
  143.         return "{ error:'Double booking',\nshortname:'".$shortname."'}\n";
  144.     }
  145. }
  146.  
  147.  
  148. /*
  149.  
  150. stdClass Object
  151. (
  152.     [ResponseMessages] => stdClass Object
  153.         (
  154.             [CreateItemResponseMessage] => stdClass Object
  155.                 (
  156.                     [ResponseCode] => NoError
  157.                     [ResponseClass] => Success
  158.                     [Items] => stdClass Object
  159.                         (
  160.                             [CalendarItem] => stdClass Object
  161.                                 (
  162.                                     [ItemId] => stdClass Object
  163.                                         (
  164.                                             [Id] =>
  165. AAAcAEVudGVyLktvbmZlcmVuc3J1bUBxcnRlY2guc2UARgAAAAAAWx3xkPMlnUyMluTTqIdb4AcAdM/rfM3YaEeMsdYGn8jOeAAAAClWOAAAK68xOGjBUkCXHxa/+2eMqAAah/ErtAAA
  166.                                             [ChangeKey] => DwAAABYAAAArrzE4aMFSQJcfFr/7Z4yoABqH8Tu3
  167.                                         )
  168.                                 )
  169.                         )
  170.                 )
  171.         )
  172. )
  173.  
  174. stdClass Object
  175. (
  176.     [ResponseMessages] => stdClass Object
  177.         (
  178.             [CreateItemResponseMessage] => stdClass Object
  179.                 (
  180.                     [MessageText] => EndDate is earlier than StartDate
  181.                     [ResponseCode] => ErrorCalendarEndDateIsEarlierThanStartDate
  182.                     [DescriptiveLinkKey] => 0
  183.                     [ResponseClass] => Error
  184.                     [Items] => stdClass Object
  185.                         (
  186.                         )
  187.                 )
  188.         )
  189. )
  190. */
  191.  
  192.  
  193.  
  194. /*
  195.   Get all meetings from now and 9 hours later
  196.   Return a JSON formed string
  197. */
  198. function getMeetingsRestOfDay($shortname)
  199. {
  200.     global $Calender;
  201.     global $wsdl;
  202.     $founditem = false;
  203.    
  204.     foreach($Calender as $item)
  205.     {
  206.         if ($item->Shortname == $shortname)
  207.         {
  208.             $founditem = $item;
  209.             break;
  210.         }
  211.     }
  212.    
  213.     if ($founditem !== false)
  214.     {
  215.         $FindItem->Traversal = "Shallow";
  216.         $FindItem->ItemShape->BaseShape = "AllProperties";
  217.         $FindItem->ParentFolderIds->DistinguishedFolderId->Id = "calendar";
  218.         /* Dont forget to use the proper timezone and setting for daylight saving time (php handles this fine) */
  219.         $FindItem->CalendarView->StartDate = date("c");                     //"2009-04-07T08:00:00Z";
  220.         $FindItem->CalendarView->EndDate = date("c", strtotime("+12 hour"));    //"2009-04-08T00:00:00Z";
  221.         //echo date("c")." ".date("c", strtotime("+8 hour"))." ".date("c", strtotime("18:00"))."\n";
  222.  
  223.         stream_wrapper_unregister('https');
  224.         stream_wrapper_register('https', 'NTLMStream') or die("Failed to register protocol");
  225.          
  226.         $returndata = "{ \n\t\"shortname\":\"".$shortname."\",\n\t\"meetings\":[\n";
  227.         try
  228.         {
  229.             $client = new ExchangeNTLMSoapClient($wsdl);
  230.             $client->user = $founditem->UserName;
  231.             $client->pass = $founditem->Password;
  232.             $result = $client->FindItem($FindItem);
  233.             if ($result)
  234.             {
  235.                 //print_array($result);
  236.                 $calendaritems = $result->ResponseMessages->FindItemResponseMessage->RootFolder->Items->CalendarItem;
  237.                 //print_array($calendaritems);
  238.                 for ($i = 0; $i < count($calendaritems); $i++)
  239.                 {
  240.                     if (count($calendaritems) > 1)
  241.                     {
  242.                         $item = $calendaritems[$i];
  243.                     }
  244.                     else
  245.                     {
  246.                         $item = $calendaritems;
  247.                     }
  248.                     $returndata .= "\t\t{\n";
  249.                     $returndata .= "\t\t\"organizer\":\"".$item->Organizer->Mailbox->Name."\",\n";
  250.                     $returndata .= "\t\t\"subject\":\"".$item->Subject."\",\n";
  251.                     $returndata .= "\t\t\"start\":\"".date("G:i", strtotime($item->Start))."\",\n";
  252.                     $returndata .= "\t\t\"end\":\"".date("G:i", strtotime($item->End))."\"\n";
  253.                     $returndata .= "\t\t}";
  254.                     if ($i+1 < count($calendaritems))
  255.                     {
  256.                         $returndata .= ",\n";
  257.                     }
  258.                 }
  259.             }
  260.             else
  261.             {
  262.                 //return "{ \"error\":\"No result\",\n\"shortname\":\"".$shortname."\"}\n";
  263.             }
  264.         }
  265.         catch (SoapFault $exception)
  266.         {
  267.             //return "{ \"error\":\"".$exception."\",\n\"shortname\":\"".$shortname."\"}\n";
  268.         }
  269.  
  270.         stream_wrapper_restore('https');
  271.         $returndata .= "\n\t]\n}\n";
  272.         return $returndata;
  273.     }
  274.     else
  275.     {
  276.         return "{ \"error\":\"Unknown shortname\",\n\"shortname\":\"".$shortname."\"}\n";
  277.     }
  278. }
  279.  
  280.  
  281. function print_array($var)
  282. {
  283.     echo "<pre>\n";
  284.     print_r($var);
  285.     echo "</pre>\n";
  286. }
  287.  
  288. class NTLMSoapClient extends SoapClient {
  289.     function __doRequest($request, $location, $action, $version)
  290.     {
  291.         global $exchangeurl;
  292.         $location=$exchangeurl; //override url to exchange server
  293.  
  294.         $headers = array( 'Method: POST',
  295.             'Connection: Keep-Alive',
  296.             'User-Agent: PHP-SOAP-CURL',
  297.             'Content-Type: text/xml; charset=utf-8',
  298.             'SOAPAction: "'.$action.'"',
  299.             );
  300.         $this->__last_request_headers = $headers;
  301.         $ch = curl_init($location);
  302.         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  303.         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  304.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  305.         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  306.         curl_setopt($ch, CURLOPT_POST, true );
  307.         curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
  308.         curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  309.         curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
  310.         curl_setopt($ch, CURLOPT_USERPWD, $this->user.':'.$this->pass);
  311.         $response = curl_exec($ch);
  312.  
  313. /*$myfile = "/tmp/debugex.txt";
  314. $fh = fopen($myfile, 'w+') or die("can't open file");
  315. fwrite($fh, "user: ". $this->user. " pass: ".$this->pass."\n");
  316. fwrite($fh, "req: ". $request ."loc: ". $location ." act: ". $action ." ver: ". $version."\n");
  317. fwrite($fh, "reponse: ". $response."\n\n");
  318. fclose($fh);
  319. */
  320.        
  321.         return $response;
  322.     }
  323.    
  324.     function __getLastRequestHeaders()
  325.     {
  326.         return implode("\n", $this->__last_request_headers)."\n";
  327.     }
  328. }
  329.  
  330. class ExchangeNTLMSoapClient extends NTLMSoapClient
  331. {
  332.     public $user = '';
  333.     public $password = '';
  334. }
  335.  
  336. class NTLMStream
  337. {
  338.     private $path;
  339.     private $mode;
  340.     private $options;
  341.     private $opened_path;
  342.     private $buffer;
  343.     private $pos;
  344.  
  345.     /**
  346.      * Open the stream
  347.      *
  348.      * @param unknown_type $path
  349.      * @param unknown_type $mode
  350.      * @param unknown_type $options
  351.      * @param unknown_type $opened_path
  352.      * @return unknown
  353.      */
  354.     public function stream_open($path, $mode, $options, $opened_path)
  355.     {
  356.         echo "[NTLMStream::stream_open] $path , mode=$mode \n";
  357.         $this->path = $path;
  358.         $this->mode = $mode;
  359.         $this->options = $options;
  360.         $this->opened_path = $opened_path;
  361.         $this->createBuffer($path);
  362.         return true;
  363.     }
  364.  
  365.     /**
  366.      * Close the stream
  367.      *
  368.      */
  369.     public function stream_close()
  370.     {
  371.         echo "[NTLMStream::stream_close] \n";
  372.         curl_close($this->ch);
  373.     }
  374.  
  375.     /**
  376.      * Read the stream
  377.      *
  378.      * @param int $count number of bytes to read
  379.      * @return content from pos to count
  380.      */
  381.     public function stream_read($count)
  382.     {
  383.         echo "[NTLMStream::stream_read] $count \n";
  384.         if(strlen($this->buffer) == 0)
  385.         {
  386.             return false;
  387.         }
  388.         $read = substr($this->buffer,$this->pos, $count);
  389.         $this->pos += $count;
  390.         return $read;
  391.     }
  392.  
  393.     /***
  394.      * write the stream
  395.      *
  396.      * @param $data
  397.      * @return
  398.      */
  399.     public function stream_write($data)
  400.     {
  401.         echo "[NTLMStream::stream_write] \n";
  402.         if(strlen($this->buffer) == 0)
  403.         {
  404.             return false;
  405.         }
  406.         return true;
  407.     }
  408.  
  409.     /**
  410.      *
  411.      * @return true if eof else false
  412.      */
  413.     public function stream_eof()
  414.     {
  415.         echo "[NTLMStream::stream_eof] ";
  416.         if($this->pos > strlen($this->buffer))
  417.         {
  418.             echo "true \n";
  419.             return true;
  420.         }
  421.         echo "false \n";
  422.         return false;
  423.     }
  424.  
  425.     /**
  426.      * @return int the position of the current read pointer
  427.      */
  428.     public function stream_tell()
  429.     {
  430.         echo "[NTLMStream::stream_tell] \n";
  431.         return $this->pos;
  432.     }
  433.  
  434.     /**
  435.      * Flush stream data
  436.      */
  437.     public function stream_flush()
  438.     {
  439.         echo "[NTLMStream::stream_flush] \n";
  440.         $this->buffer = null;
  441.         $this->pos = null;
  442.     }
  443.  
  444.     /**
  445.      * Stat the file, return only the size of the buffer
  446.      *
  447.      * @return array stat information
  448.      */
  449.     public function stream_stat()
  450.     {
  451.         echo "[NTLMStream::stream_stat] \n";
  452.         $this->createBuffer($this->path);
  453.         $stat = array( 'size' => strlen($this->buffer), );
  454.         return $stat;
  455.     }
  456.  
  457.     /**
  458.      * Stat the url, return only the size of the buffer
  459.      *
  460.      * @return array stat information
  461.      */
  462.     public function url_stat($path, $flags)
  463.     {
  464.         echo "[NTLMStream::url_stat] \n";
  465.         $this->createBuffer($path);
  466.         $stat = array( 'size' => strlen($this->buffer), );
  467.         return $stat;
  468.     }
  469.  
  470.     /* Create the buffer by requesting the url through cURL */
  471.     private function createBuffer($path)
  472.     {
  473.         if($this->buffer)
  474.         {
  475.             return;
  476.         }
  477.         echo "[NTLMStream::createBuffer] create buffer from : $path \n";
  478.         $this->ch = curl_init($path);
  479.         curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
  480.         curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, false);
  481.         curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
  482.         curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  483.         curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
  484.         curl_setopt($this->ch, CURLOPT_USERPWD, $user.':'.$pass);
  485.         echo $this->buffer = curl_exec($this->ch);
  486.        
  487.         echo "[NTLMStream::createBuffer] buffer size : ".strlen($this->buffer)."bytes \n";
  488.         $this->pos = 0;
  489. /*$myfile = "/tmp/debugex.txt";
  490. $fh = fopen($myfile, 'w+') or die("can't open file");
  491. fwrite($fh, "user: ". $this->user. " pass: ".$this->pass."\n");
  492. fwrite($fh, "req: ". $request ."loc: ". $location ." act: ". $action ." ver: ". $version."\n");
  493. fwrite($fh, "reponse: ". $response."\n\n");
  494. fclose($fh);
  495. */
  496.     }
  497. }
  498.  
  499. ?>
  500.