├── README.md
└── webex.php
/README.md:
--------------------------------------------------------------------------------
1 | php-webex
2 | =========
3 |
4 | PHPebEx - A Unofficial WebEx PHP API
5 |
--------------------------------------------------------------------------------
/webex.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright Copyright (c) 2013, RedRat Consultoria
9 | * @license GPL version 2
10 | * @see Github, animes and mangás, cute girls and PHP, much PHP
11 | * @link http://developer.cisco.com/documents/4733862/4736722/xml_api_5+9.pdf
12 | * @link https://github.com/joubertredrat/phpebex-php-webex
13 | */
14 |
15 | class Webex {
16 |
17 | private $username;
18 | private $password;
19 | private $siteID;
20 | private $partnerID;
21 |
22 | private $url_prefix;
23 | private $url_host;
24 |
25 | private $send_mode;
26 |
27 | private $data;
28 |
29 | private $action;
30 |
31 | const SEND_CURL = 'curl';
32 | const SEND_FSOCKS = 'fsocks';
33 | const PREFIX_HTTP = 'http';
34 | const PREFIX_HTTPS = 'https';
35 | const SUFIX_XML_API = 'WBXService/XMLService';
36 | const WEBEX_DOMAIN = 'webex.com';
37 | const XML_VERSION = '1.0';
38 | const XML_ENCODING = 'UTF-8';
39 | const USER_AGENT = 'PHPebEx - WebEx PHP API (https://github.com/joubertredrat/phpebex-php-webex)';
40 |
41 | const API_SCHEMA_MEETING = 'http://www.webex.com/schemas/2002/06/service/meeting';
42 | const API_SCHEMA_SERVICE = 'http://www.webex.com/schemas/2002/06/service';
43 |
44 | const DATA_SENDER = 'sender';
45 | const DATA_SENDER_POST_HEADER = 'post_header';
46 | const DATA_SENDER_POST_BODY = 'post_body';
47 | const DATA_SENDER_XML = 'xml';
48 | const DATA_RESPONSE = 'response';
49 | const DATA_RESPONSE_XML = 'xml';
50 | const DATA_RESPONSE_DATA = 'data';
51 |
52 | /**
53 | * Constructor of class.
54 | *
55 | * @return void
56 | */
57 | public function __construct() {
58 | $this->action = 0;
59 | $this->response = array();
60 | $this->send_mode = in_array(self::SEND_CURL, get_loaded_extensions()) ? self::SEND_CURL : self::SEND_FSOCKS;
61 | }
62 |
63 | /**
64 | * Get a possible modes to send a POST data.
65 | *
66 | * @return array Returns a list of send modes.
67 | */
68 | public static function get_sendmode() {
69 | return array(self::SEND_CURL, self::SEND_FSOCKS);
70 | }
71 |
72 | /**
73 | * Validates a customer webex domain.
74 | *
75 | * @param string $url Url to validate.
76 | * @return bool Return true if a valid url or false if not.
77 | */
78 | public static function validate_url($url) {
79 | $regex = "/^(http|https):\/\/(([A-Z0-9][A-Z0-9_-]*)+.(" . self::WEBEX_DOMAIN . ")$)/i";
80 | return (bool) preg_match($regex, $url);
81 | }
82 |
83 | /**
84 | * Get port used by API.
85 | *
86 | * @param string $prefix Prefix to get a port.
87 | * @return int Return a port.
88 | */
89 | public static function get_port($prefix) {
90 | switch($prefix) {
91 | case self::PREFIX_HTTP:
92 | return 80;
93 | break;
94 | case self::PREFIX_HTTPS:
95 | return 443;
96 | break;
97 | default:
98 | exit(__CLASS__ . ' error report: Wrong prefix');
99 | break;
100 | }
101 | }
102 |
103 | /**
104 | * Set a url to integrate to webex.
105 | *
106 | * @param string $url Customer url.
107 | * @return void
108 | */
109 | public function set_url($url) {
110 | if(!self::validate_url($url))
111 | exit(__CLASS__ . ' error report: Wrong webex url');
112 | list($this->url_prefix, $this->url_host) = preg_split("$://$", $url);
113 | }
114 |
115 | /**
116 | * Mode to send data.
117 | *
118 | * @param string mode to send.
119 | * @return void
120 | */
121 | public function set_sendmode($mode) {
122 | if(!in_array($mode, self::get_sendmode()))
123 | exit(__CLASS__ . ' error report: Wrong send mode');
124 | $this->send_mode = $mode;
125 | }
126 |
127 | /**
128 | * Auth data to integrate with API.
129 | *
130 | * @param string $username Username to auth.
131 | * @param string $password Password to auth.
132 | * @param string $siteID Customer site id.
133 | * @param string $partnerID Customer partnerID id.
134 | * @return void
135 | */
136 | public function set_auth($username, $password, $siteID, $partnerID) {
137 | $this->username = $username;
138 | $this->password = $password;
139 | $this->siteID = $siteID;
140 | $this->partnerID = $partnerID;
141 | }
142 |
143 | /**
144 | * Generates a XML to send a data to API.
145 | *
146 | * @param array $data Data to insert in XML in format:
147 | * $data['service'] = 'meeting';
148 | * $data['xml_header'] = '- data
';
149 | * $data['xml_body'] = '- data
';
150 | * @return string Returns a XML generated.
151 | */
152 | private function get_xml($data) {
153 | $xml = array();
154 | $xml[] = '';
155 | $xml[] = '';
156 | $xml[] = '';
157 | $xml[] = '';
158 | $xml[] = '' . $this->username . '';
159 | $xml[] = '' . $this->password . '';
160 | $xml[] = '' . $this->siteID . '';
161 | $xml[] = '' . $this->partnerID . '';
162 | if(isset($data['xml_header']))
163 | $xml[] = $data['xml_header'];
164 | $xml[] = '';
165 | $xml[] = '';
166 | $xml[] = '';
167 | $xml[] = '';
168 | $xml[] = $data['xml_body'];
169 | $xml[] = '';
170 | $xml[] = '';
171 | $xml[] = '';
172 | return implode('', $xml);
173 | }
174 |
175 | /**
176 | * Test if have a auth data to use a API.
177 | *
178 | * @return bool Returns true if have data and false if not.
179 | */
180 | public function has_auth() {
181 | return (bool) $this->username && $this->password && $this->siteID && $this->partnerID;
182 | }
183 |
184 | /**
185 | * Generates a header and a body to send data to API.
186 | *
187 | * @return string Returns a response from API.
188 | */
189 | private function send($xml) {
190 | $post_data['UID'] = $this->username;
191 | $post_data['PWD'] = $this->password;
192 | $post_data['SID'] = $this->siteID;
193 | $post_data['PID'] = $this->partnerID;
194 | $post_data['XML'] = $xml;
195 |
196 | // Really I dont know why xml api give a error on http_build_query :(
197 | $post_string = '';
198 | foreach ($post_data as $variable => $value) {
199 | $post_string .= '' . $variable . '=' . urlencode($value) . '&';
200 | }
201 |
202 | $post_header = array();
203 | $post_header[] = 'POST /' . self::SUFIX_XML_API . ' HTTP/1.0';
204 | $post_header[] = 'Host: ' . $this->url_host;
205 | $post_header[] = 'User-Agent: ' . self::USER_AGENT;
206 | if($this->send_mode == self::SEND_FSOCKS) {
207 | $post_header[] = 'Content-Type: application/xml';
208 | $post_header[] = 'Content-Length: ' . strlen($xml);
209 | }
210 | $data = array();
211 | $data['post_header'] = $post_header;
212 | $data['post_string'] = $post_string;
213 |
214 | $this->data[$this->action][self::DATA_SENDER][self::DATA_SENDER_POST_HEADER] = $post_header;
215 | $this->data[$this->action][self::DATA_SENDER][self::DATA_SENDER_POST_BODY] = $post_header;
216 | $this->data[$this->action][self::DATA_SENDER][self::DATA_SENDER_XML] = $xml;
217 |
218 | return $this->{'send_' . $this->send_mode}($data);
219 | }
220 |
221 | /**
222 | * Send a data to Webex API using PHP curl.
223 | *
224 | * @param array $data Data to send to API in format:
225 | * $data['post_header'] = "blablabla";
226 | * $data['post_header'] = "post_string";
227 | * @return string Returns a response from API.
228 | */
229 | private function send_curl($data) {
230 | extract($data);
231 | $ch = curl_init();
232 | curl_setopt($ch, CURLOPT_URL, $this->url_prefix . '://' . $this->url_host . '/' . self::SUFIX_XML_API);
233 | curl_setopt($ch, CURLOPT_PORT, self::get_port($this->url_prefix));
234 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
235 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
236 | curl_setopt($ch, CURLOPT_HTTPHEADER, $post_header);
237 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
238 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
239 | $response = curl_exec($ch);
240 | if($response === false)
241 | exit(__CLASS__ . ' error report: Curl error - ' . curl_error($ch));
242 | curl_close($ch);
243 | return $response;
244 | }
245 |
246 | /**
247 | * Send a data to Webex API using PHP file functions.
248 | *
249 | * @param array $data Data to send to API in format:
250 | * $data['post_header'] = "blablabla";
251 | * $data['post_header'] = "post_string";
252 | * @return string Returns a response from API.
253 | * @todo haha, I need to test this :)
254 | */
255 | private function send_fsocks($data) {
256 | extract($data);
257 | $post_data = implode("\n", $post_header) . "\n\n" . $post_string . "\n";
258 | $fp = fsockopen($this->url_host, self::get_port($this->url_prefix), $errno, $error);
259 | if($fp) {
260 | fwrite($fp, $post_data);
261 | $response = '';
262 | while(!feof($fp)) {
263 | $response .= fgets($fp, 1024);
264 | }
265 | return $response;
266 | }
267 | else
268 | exit(__CLASS__ . ' error report: Fsocks error - (' . $errno . ') ' . $error);
269 | }
270 |
271 | /**
272 | * Get response from a API.
273 | *
274 | * @param string $type Type of data to be requested.
275 | * @param int $number number of sender to be requested.
276 | * @return string|object Return a response.
277 | */
278 | public function get_response($type = self::DATA_RESPONSE_DATA, $number = null) {
279 | if(isset($number) && is_int($number)) {
280 | if($number < 1 || $number > ($this->action - 1))
281 | exit(__CLASS__ . ' error report: Invalid response number');
282 | $number--;
283 | }
284 | else
285 | $number = ($this->action - 1);
286 | var_dump($number);
287 | switch($type) {
288 | case self::DATA_RESPONSE_XML:
289 | case self::DATA_RESPONSE_DATA:
290 | return $this->data[$number][self::DATA_RESPONSE][$type];
291 | break;
292 | default:
293 | exit(__CLASS__ . ' error report: I don\'t undestood that data you needs');
294 | break;
295 | }
296 | }
297 |
298 | /**
299 | * @todo documentate in future.
300 | */
301 | public function meeting_LstsummaryMeeting($maximumNum = 5) {
302 | if(!$this->has_auth())
303 | exit(__CLASS__ . ' error report: Auth data not found');
304 | $xml_body = array();
305 | $xml_body[] = '';
306 | $xml_body[] = '';
307 | $xml_body[] = '' . $maximumNum . '';
308 | $xml_body[] = '';
309 | $xml_body[] = '';
310 | $xml_body[] = 'STARTTIME';
311 | $xml_body[] = '';
312 | $xml_body[] = '';
313 | $xml_body[] = '';
314 |
315 | $data['xml_body'] = implode('', $xml_body);
316 | $data['service'] = str_replace("_", ".", __FUNCTION__);
317 | $xml = $this->get_xml($data);
318 | $response = $this->send($xml);
319 |
320 | $xml = simplexml_load_string($response);
321 | $Data = new stdClass;
322 | $Data->header = new stdClass;
323 | $Data->header->response = new stdClass;
324 | $Data->bodyContent = array();
325 |
326 | $node = $xml->children(self::API_SCHEMA_SERVICE);
327 | $Data->header->response->result = (string) $node[0]->response->result;
328 | $Data->header->response->gsbStatus = (string) $node[0]->response->gsbStatus;
329 |
330 | $node_meeting = $node[1]->bodyContent;
331 |
332 | foreach($node_meeting->children(self::API_SCHEMA_MEETING) as $meeting) {
333 | if($meeting->meetingKey) {
334 | $MeetingData = new stdClass;
335 | $MeetingData->meetingKey = (string) $meeting->meetingKey;
336 | $MeetingData->confName = (string) $meeting->confName;
337 | $MeetingData->meetingType = (string) $meeting->meetingType;
338 | $MeetingData->hostWebExID = (string) $meeting->hostWebExID;
339 | $MeetingData->otherHostWebExID = (string) $meeting->otherHostWebExID;
340 | $MeetingData->timeZoneID = (string) $meeting->timeZoneID;
341 | $MeetingData->timeZone = (string) $meeting->timeZone;
342 | $MeetingData->status = (string) $meeting->status;
343 | $MeetingData->startDate = (string) $meeting->startDate;
344 | $MeetingData->duration = (string) $meeting->duration;
345 | $MeetingData->listStatus = (string) $meeting->listStatus;
346 | $MeetingData->hostJoined = (string) $meeting->hostJoined;
347 | $MeetingData->participantsJoined = (string) $meeting->participantsJoined;
348 | $MeetingData->telePresence = (string) $meeting->telePresence;
349 | $Data->bodyContent[] = $MeetingData;
350 | }
351 | }
352 |
353 | $this->data[$this->action][self::DATA_RESPONSE][self::DATA_RESPONSE_DATA] = $Data;
354 | $this->data[$this->action][self::DATA_RESPONSE][self::DATA_RESPONSE_XML] = $response;
355 | $this->action++;
356 | }
357 |
358 | //public function user_AuthenticateUser()
359 | //public function user_CreateUser()
360 | //public function user_DelUser()
361 | //public function user_DelSessionTemplates()
362 | //public function user_GetloginTicket()
363 | //public function user_GetloginurlUser()
364 | //public function user_GetlogouturlUser()
365 | //public function user_GetUser()
366 | //public function user_LstsummaryUser()
367 | //public function user_SetUser()
368 | //public function user_UploadPMRIImage()
369 |
370 | //public function meeting_CreateMeeting()
371 | //public function meeting_CreateTeleconferenceSession()
372 | //public function meeting_DelMeeting()
373 | //public function meeting_GethosturlMeeting()
374 | //public function meeting_GetMeeting()
375 | //public function meeting_GetTeleconferenceSession()
376 | //public function meeting_LstsummaryMeeting()
377 | //public function meeting_SetMeeting()
378 | //public function meeting_SetTeleconferenceSession()
379 | //public function meeting_GetjoinurlMeeting()
380 |
381 | //public function event_CreateEvent()
382 | //public function event_DelEvent()
383 | //public function event_GetEvent()
384 | //public function event_LstRecordedEvent()
385 | //public function event_LstsummaryProgram()
386 | //public function event_SendInvitationEmail()
387 | //public function event_SetEvent()
388 | //public function event_UploadEventImage()
389 | //public function event_LstsummaryEvent()
390 |
391 | //public function attendee_CreateMeetingAttendee()
392 | //public function attendee_LstMeetingAttendee()
393 | //public function attendee_RegisterMeetingAttendee()
394 | //public function history_LstmeetingattendeeHistory()
395 | }
--------------------------------------------------------------------------------