1 | <?php |
---|
2 | // http://code.google.com/p/simple-linkedinphp/ |
---|
3 | // 3.2.0 - November 29, 2011 |
---|
4 | // hacked into the code to handel new scope (r_basicprofile+r_emailaddress) - until Paul update linkedinphp library! |
---|
5 | |
---|
6 | /** |
---|
7 | * This file defines the 'LinkedIn' class. This class is designed to be a |
---|
8 | * simple, stand-alone implementation of the LinkedIn API functions. |
---|
9 | * |
---|
10 | * COPYRIGHT: |
---|
11 | * |
---|
12 | * Copyright (C) 2011, fiftyMission Inc. |
---|
13 | * |
---|
14 | * Permission is hereby granted, free of charge, to any person obtaining a |
---|
15 | * copy of this software and associated documentation files (the "Software"), |
---|
16 | * to deal in the Software without restriction, including without limitation |
---|
17 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
---|
18 | * and/or sell copies of the Software, and to permit persons to whom the |
---|
19 | * Software is furnished to do so, subject to the following conditions: |
---|
20 | * |
---|
21 | * The above copyright notice and this permission notice shall be included in |
---|
22 | * all copies or substantial portions of the Software. |
---|
23 | * |
---|
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
---|
29 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
---|
30 | * IN THE SOFTWARE. |
---|
31 | * |
---|
32 | * SOURCE CODE LOCATION: |
---|
33 | * |
---|
34 | * http://code.google.com/p/simple-linkedinphp/ |
---|
35 | * |
---|
36 | * REQUIREMENTS: |
---|
37 | * |
---|
38 | * 1. You must have cURL installed on the server and available to PHP. |
---|
39 | * 2. You must be running PHP 5+. |
---|
40 | * |
---|
41 | * QUICK START: |
---|
42 | * |
---|
43 | * There are two files needed to enable LinkedIn API functionality from PHP; the |
---|
44 | * stand-alone OAuth library, and this LinkedIn class. The latest version of |
---|
45 | * the stand-alone OAuth library can be found on Google Code: |
---|
46 | * |
---|
47 | * http://code.google.com/p/oauth/ |
---|
48 | * |
---|
49 | * Install these two files on your server in a location that is accessible to |
---|
50 | * the scripts you wish to use them in. Make sure to change the file |
---|
51 | * permissions such that your web server can read the files. |
---|
52 | * |
---|
53 | * Next, make sure the path to the OAuth library is correct (you can change this |
---|
54 | * as needed, depending on your file organization scheme, etc). |
---|
55 | * |
---|
56 | * Finally, test the class by attempting to connect to LinkedIn using the |
---|
57 | * associated demo.php page, also located at the Google Code location |
---|
58 | * referenced above. |
---|
59 | * |
---|
60 | * RESOURCES: |
---|
61 | * |
---|
62 | * REST API Documentation: http://developer.linkedin.com/rest |
---|
63 | * |
---|
64 | * @version 3.2.0 - November 8, 2011 |
---|
65 | * @author Paul Mennega <paul@fiftymission.net> |
---|
66 | * @copyright Copyright 2011, fiftyMission Inc. |
---|
67 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License |
---|
68 | */ |
---|
69 | |
---|
70 | /** |
---|
71 | * 'LinkedInException' class declaration. |
---|
72 | * |
---|
73 | * This class extends the base 'Exception' class. |
---|
74 | * |
---|
75 | * @access public |
---|
76 | * @package classpackage |
---|
77 | */ |
---|
78 | class LinkedInException extends Exception {} |
---|
79 | |
---|
80 | /** |
---|
81 | * 'LinkedIn' class declaration. |
---|
82 | * |
---|
83 | * This class provides generalized LinkedIn oauth functionality. |
---|
84 | * |
---|
85 | * @access public |
---|
86 | * @package classpackage |
---|
87 | */ |
---|
88 | class LinkedIn { |
---|
89 | // api/oauth settings |
---|
90 | const _API_OAUTH_REALM = 'http://api.linkedin.com'; |
---|
91 | const _API_OAUTH_VERSION = '1.0'; |
---|
92 | |
---|
93 | // the default response format from LinkedIn |
---|
94 | const _DEFAULT_RESPONSE_FORMAT = 'xml'; |
---|
95 | |
---|
96 | // helper constants used to standardize LinkedIn <-> API communication. See demo page for usage. |
---|
97 | const _GET_RESPONSE = 'lResponse'; |
---|
98 | const _GET_TYPE = 'lType'; |
---|
99 | |
---|
100 | // Invitation API constants. |
---|
101 | const _INV_SUBJECT = 'Invitation to connect'; |
---|
102 | const _INV_BODY_LENGTH = 200; |
---|
103 | |
---|
104 | // API methods |
---|
105 | const _METHOD_TOKENS = 'POST'; |
---|
106 | |
---|
107 | // Network API constants. |
---|
108 | const _NETWORK_LENGTH = 1000; |
---|
109 | const _NETWORK_HTML = '<a>'; |
---|
110 | |
---|
111 | // response format type constants, see http://developer.linkedin.com/docs/DOC-1203 |
---|
112 | const _RESPONSE_JSON = 'JSON'; |
---|
113 | const _RESPONSE_JSONP = 'JSONP'; |
---|
114 | const _RESPONSE_XML = 'XML'; |
---|
115 | |
---|
116 | // Share API constants |
---|
117 | const _SHARE_COMMENT_LENGTH = 700; |
---|
118 | const _SHARE_CONTENT_TITLE_LENGTH = 200; |
---|
119 | const _SHARE_CONTENT_DESC_LENGTH = 400; |
---|
120 | |
---|
121 | // LinkedIn API end-points |
---|
122 | const _URL_ACCESS = 'https://api.linkedin.com/uas/oauth/accessToken'; |
---|
123 | const _URL_API = 'https://api.linkedin.com'; |
---|
124 | const _URL_AUTH = 'https://www.linkedin.com/uas/oauth/authenticate?oauth_token='; |
---|
125 | // const _URL_REQUEST = 'https://api.linkedin.com/uas/oauth/requestToken'; |
---|
126 | const _URL_REQUEST = 'https://api.linkedin.com/uas/oauth/requestToken?scope=r_basicprofile+r_emailaddress'; |
---|
127 | const _URL_REVOKE = 'https://api.linkedin.com/uas/oauth/invalidateToken'; |
---|
128 | |
---|
129 | // Library version |
---|
130 | const _VERSION = '3.2.0'; |
---|
131 | |
---|
132 | // oauth properties |
---|
133 | protected $callback; |
---|
134 | protected $token = NULL; |
---|
135 | |
---|
136 | // application properties |
---|
137 | protected $application_key, |
---|
138 | $application_secret; |
---|
139 | |
---|
140 | // the format of the data to return |
---|
141 | protected $response_format = self::_DEFAULT_RESPONSE_FORMAT; |
---|
142 | |
---|
143 | // last request fields |
---|
144 | public $last_request_headers, |
---|
145 | $last_request_url; |
---|
146 | |
---|
147 | /** |
---|
148 | * Create a LinkedIn object, used for OAuth-based authentication and |
---|
149 | * communication with the LinkedIn API. |
---|
150 | * |
---|
151 | * @param arr $config |
---|
152 | * The 'start-up' object properties: |
---|
153 | * - appKey => The application's API key |
---|
154 | * - appSecret => The application's secret key |
---|
155 | * - callbackUrl => [OPTIONAL] the callback URL |
---|
156 | * |
---|
157 | * @return obj |
---|
158 | * A new LinkedIn object. |
---|
159 | */ |
---|
160 | public function __construct($config) { |
---|
161 | if(!is_array($config)) { |
---|
162 | // bad data passed |
---|
163 | throw new LinkedInException('LinkedIn->__construct(): bad data passed, $config must be of type array.'); |
---|
164 | } |
---|
165 | $this->setApplicationKey($config['appKey']); |
---|
166 | $this->setApplicationSecret($config['appSecret']); |
---|
167 | $this->setCallbackUrl($config['callbackUrl']); |
---|
168 | } |
---|
169 | |
---|
170 | /** |
---|
171 | * The class destructor. |
---|
172 | * |
---|
173 | * Explicitly clears LinkedIn object from memory upon destruction. |
---|
174 | */ |
---|
175 | public function __destruct() { |
---|
176 | unset($this); |
---|
177 | } |
---|
178 | |
---|
179 | /** |
---|
180 | * Bookmark a job. |
---|
181 | * |
---|
182 | * Calling this method causes the current user to add a bookmark for the |
---|
183 | * specified job: |
---|
184 | * |
---|
185 | * http://developer.linkedin.com/docs/DOC-1323 |
---|
186 | * |
---|
187 | * @param str $jid |
---|
188 | * Job ID you want to bookmark. |
---|
189 | * |
---|
190 | * @return arr |
---|
191 | * Array containing retrieval success, LinkedIn response. |
---|
192 | */ |
---|
193 | public function bookmarkJob($jid) { |
---|
194 | // check passed data |
---|
195 | if(!is_string($jid)) { |
---|
196 | // bad data passed |
---|
197 | throw new LinkedInException('LinkedIn->bookmarkJob(): bad data passed, $jid must be of type string.'); |
---|
198 | } |
---|
199 | |
---|
200 | // construct and send the request |
---|
201 | $query = self::_URL_API . '/v1/people/~/job-bookmarks'; |
---|
202 | $response = $this->fetch('POST', $query, '<job-bookmark><job><id>' . trim($jid) . '</id></job></job-bookmark>'); |
---|
203 | |
---|
204 | /** |
---|
205 | * Check for successful request (a 201 response from LinkedIn server) |
---|
206 | * per the documentation linked in method comments above. |
---|
207 | */ |
---|
208 | return $this->checkResponse(201, $response); |
---|
209 | } |
---|
210 | |
---|
211 | /** |
---|
212 | * Get list of jobs you have bookmarked. |
---|
213 | * |
---|
214 | * Returns a list of jobs the current user has bookmarked, per: |
---|
215 | * |
---|
216 | * http://developer.linkedin.com/docs/DOC-1323 |
---|
217 | * |
---|
218 | * @return arr |
---|
219 | * Array containing retrieval success, LinkedIn response. |
---|
220 | */ |
---|
221 | public function bookmarkedJobs() { |
---|
222 | // construct and send the request |
---|
223 | $query = self::_URL_API . '/v1/people/~/job-bookmarks'; |
---|
224 | $response = $this->fetch('GET', $query); |
---|
225 | |
---|
226 | /** |
---|
227 | * Check for successful request (a 200 response from LinkedIn server) |
---|
228 | * per the documentation linked in method comments above. |
---|
229 | */ |
---|
230 | return $this->checkResponse(200, $response); |
---|
231 | } |
---|
232 | |
---|
233 | /** |
---|
234 | * Custom addition to make code compatible with PHP 5.2 |
---|
235 | */ |
---|
236 | private function intWalker($value, $key) { |
---|
237 | if(!is_int($value)) { |
---|
238 | throw new LinkedInException('LinkedIn->checkResponse(): $http_code_required must be an integer or an array of integer values'); |
---|
239 | } |
---|
240 | } |
---|
241 | |
---|
242 | /** |
---|
243 | * Used to check whether a response LinkedIn object has the required http_code or not and |
---|
244 | * returns an appropriate LinkedIn object. |
---|
245 | * |
---|
246 | * @param var $http_code_required |
---|
247 | * The required http response from LinkedIn, passed in either as an integer, |
---|
248 | * or an array of integers representing the expected values. |
---|
249 | * @param arr $response |
---|
250 | * An array containing a LinkedIn response. |
---|
251 | * |
---|
252 | * @return boolean |
---|
253 | * TRUE or FALSE depending on if the passed LinkedIn response matches the expected response. |
---|
254 | */ |
---|
255 | private function checkResponse($http_code_required, $response) { |
---|
256 | // check passed data |
---|
257 | if(is_array($http_code_required)) { |
---|
258 | array_walk($http_code_required, array($this, 'intWalker')); |
---|
259 | } else { |
---|
260 | if(!is_int($http_code_required)) { |
---|
261 | throw new LinkedInException('LinkedIn->checkResponse(): $http_code_required must be an integer or an array of integer values'); |
---|
262 | } else { |
---|
263 | $http_code_required = array($http_code_required); |
---|
264 | } |
---|
265 | } |
---|
266 | if(!is_array($response)) { |
---|
267 | throw new LinkedInException('LinkedIn->checkResponse(): $response must be an array'); |
---|
268 | } |
---|
269 | |
---|
270 | // check for a match |
---|
271 | if(in_array($response['info']['http_code'], $http_code_required)) { |
---|
272 | // response found |
---|
273 | $response['success'] = TRUE; |
---|
274 | } else { |
---|
275 | // response not found |
---|
276 | $response['success'] = FALSE; |
---|
277 | $response['error'] = 'HTTP response from LinkedIn end-point was not code ' . implode(', ', $http_code_required); |
---|
278 | } |
---|
279 | return $response; |
---|
280 | } |
---|
281 | |
---|
282 | /** |
---|
283 | * Close a job. |
---|
284 | * |
---|
285 | * Calling this method causes the passed job to be closed, per: |
---|
286 | * |
---|
287 | * http://developer.linkedin.com/docs/DOC-1151 |
---|
288 | * |
---|
289 | * @param str $jid |
---|
290 | * Job ID you want to close. |
---|
291 | * |
---|
292 | * @return arr |
---|
293 | * Array containing retrieval success, LinkedIn response. |
---|
294 | */ |
---|
295 | public function closeJob($jid) { |
---|
296 | // check passed data |
---|
297 | if(!is_string($jid)) { |
---|
298 | // bad data passed |
---|
299 | throw new LinkedInException('LinkedIn->closeJob(): bad data passed, $jid must be of string value.'); |
---|
300 | } |
---|
301 | |
---|
302 | // construct and send the request |
---|
303 | $query = self::_URL_API . '/v1/jobs/partner-job-id=' . trim($jid); |
---|
304 | $response = $this->fetch('DELETE', $query); |
---|
305 | |
---|
306 | /** |
---|
307 | * Check for successful request (a 204 response from LinkedIn server) |
---|
308 | * per the documentation linked in method comments above. |
---|
309 | */ |
---|
310 | return $this->checkResponse(204, $response); |
---|
311 | } |
---|
312 | |
---|
313 | /** |
---|
314 | * Share comment posting method. |
---|
315 | * |
---|
316 | * Post a comment on an existing connections shared content. API details can |
---|
317 | * be found here: |
---|
318 | * |
---|
319 | * http://developer.linkedin.com/docs/DOC-1043 |
---|
320 | * |
---|
321 | * @param str $uid |
---|
322 | * The LinkedIn update ID. |
---|
323 | * @param str $comment |
---|
324 | * The share comment to be posted. |
---|
325 | * |
---|
326 | * @return arr |
---|
327 | * Array containing retrieval success, LinkedIn response. |
---|
328 | */ |
---|
329 | public function comment($uid, $comment) { |
---|
330 | // check passed data |
---|
331 | if(!is_string($uid)) { |
---|
332 | // bad data passed |
---|
333 | throw new LinkedInException('LinkedIn->comment(): bad data passed, $uid must be of type string.'); |
---|
334 | } |
---|
335 | if(!is_string($comment)) { |
---|
336 | // nothing/non-string passed, raise an exception |
---|
337 | throw new LinkedInException('LinkedIn->comment(): bad data passed, $comment must be a non-zero length string.'); |
---|
338 | } |
---|
339 | |
---|
340 | /** |
---|
341 | * Share comment rules: |
---|
342 | * |
---|
343 | * 1) No HTML permitted. |
---|
344 | * 2) Comment cannot be longer than 700 characters. |
---|
345 | */ |
---|
346 | $comment = substr(trim(htmlspecialchars(strip_tags($comment))), 0, self::_SHARE_COMMENT_LENGTH); |
---|
347 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
348 | <update-comment> |
---|
349 | <comment>' . $comment . '</comment> |
---|
350 | </update-comment>'; |
---|
351 | |
---|
352 | // construct and send the request |
---|
353 | $query = self::_URL_API . '/v1/people/~/network/updates/key=' . $uid . '/update-comments'; |
---|
354 | $response = $this->fetch('POST', $query, $data); |
---|
355 | |
---|
356 | /** |
---|
357 | * Check for successful request (a 201 response from LinkedIn server) |
---|
358 | * per the documentation linked in method comments above. |
---|
359 | */ |
---|
360 | return $this->checkResponse(201, $response); |
---|
361 | } |
---|
362 | |
---|
363 | /** |
---|
364 | * Share comment retrieval. |
---|
365 | * |
---|
366 | * Return all comments associated with a given network update: |
---|
367 | * |
---|
368 | * http://developer.linkedin.com/docs/DOC-1043 |
---|
369 | * |
---|
370 | * @param str $uid |
---|
371 | * The LinkedIn update ID. |
---|
372 | * |
---|
373 | * @return arr |
---|
374 | * Array containing retrieval success, LinkedIn response. |
---|
375 | */ |
---|
376 | public function comments($uid) { |
---|
377 | // check passed data |
---|
378 | if(!is_string($uid)) { |
---|
379 | // bad data passed |
---|
380 | throw new LinkedInException('LinkedIn->comments(): bad data passed, $uid must be of type string.'); |
---|
381 | } |
---|
382 | |
---|
383 | // construct and send the request |
---|
384 | $query = self::_URL_API . '/v1/people/~/network/updates/key=' . $uid . '/update-comments'; |
---|
385 | $response = $this->fetch('GET', $query); |
---|
386 | |
---|
387 | /** |
---|
388 | * Check for successful request (a 200 response from LinkedIn server) |
---|
389 | * per the documentation linked in method comments above. |
---|
390 | */ |
---|
391 | return $this->checkResponse(200, $response); |
---|
392 | } |
---|
393 | |
---|
394 | /** |
---|
395 | * Company profile retrieval function. |
---|
396 | * |
---|
397 | * Takes a string of parameters as input and requests company profile data |
---|
398 | * from the LinkedIn Company Profile API. See the official documentation for |
---|
399 | * $options 'field selector' formatting: |
---|
400 | * |
---|
401 | * http://developer.linkedin.com/docs/DOC-1014 |
---|
402 | * http://developer.linkedin.com/docs/DOC-1259 |
---|
403 | * |
---|
404 | * @param str $options |
---|
405 | * Data retrieval options. |
---|
406 | * @param bool $by_email |
---|
407 | * [OPTIONAL] Search by email domain? |
---|
408 | * |
---|
409 | * @return arr |
---|
410 | * Array containing retrieval success, LinkedIn response. |
---|
411 | */ |
---|
412 | public function company($options, $by_email = FALSE) { |
---|
413 | // check passed data |
---|
414 | if(!is_string($options)) { |
---|
415 | // bad data passed |
---|
416 | throw new LinkedInException('LinkedIn->company(): bad data passed, $options must be of type string.'); |
---|
417 | } |
---|
418 | if(!is_bool($by_email)) { |
---|
419 | // bad data passed |
---|
420 | throw new LinkedInException('LinkedIn->company(): bad data passed, $by_email must be of type boolean.'); |
---|
421 | } |
---|
422 | |
---|
423 | // construct and send the request |
---|
424 | $query = self::_URL_API . '/v1/companies' . ($by_email ? '' : '/') . trim($options); |
---|
425 | $response = $this->fetch('GET', $query); |
---|
426 | |
---|
427 | /** |
---|
428 | * Check for successful request (a 200 response from LinkedIn server) |
---|
429 | * per the documentation linked in method comments above. |
---|
430 | */ |
---|
431 | return $this->checkResponse(200, $response); |
---|
432 | } |
---|
433 | |
---|
434 | /** |
---|
435 | * Company products and their associated recommendations. |
---|
436 | * |
---|
437 | * The product data type contains details about a company's product or |
---|
438 | * service, including recommendations from LinkedIn members, and replies from |
---|
439 | * company representatives. |
---|
440 | * |
---|
441 | * http://developer.linkedin.com/docs/DOC-1327 |
---|
442 | * |
---|
443 | * @param str $cid |
---|
444 | * Company ID you want the producte for. |
---|
445 | * @param str $options |
---|
446 | * [OPTIONAL] Data retrieval options. |
---|
447 | * |
---|
448 | * @return arr |
---|
449 | * Array containing retrieval success, LinkedIn response. |
---|
450 | */ |
---|
451 | public function companyProducts($cid, $options = '') { |
---|
452 | // check passed data |
---|
453 | if(!is_string($cid)) { |
---|
454 | // bad data passed |
---|
455 | throw new LinkedInException('LinkedIn->companyProducts(): bad data passed, $cid must be of type string.'); |
---|
456 | } |
---|
457 | if(!is_string($options)) { |
---|
458 | // bad data passed |
---|
459 | throw new LinkedInException('LinkedIn->companyProducts(): bad data passed, $options must be of type string.'); |
---|
460 | } |
---|
461 | |
---|
462 | // construct and send the request |
---|
463 | $query = self::_URL_API . '/v1/companies/' . trim($cid) . '/products' . trim($options); |
---|
464 | $response = $this->fetch('GET', $query); |
---|
465 | |
---|
466 | /** |
---|
467 | * Check for successful request (a 200 response from LinkedIn server) |
---|
468 | * per the documentation linked in method comments above. |
---|
469 | */ |
---|
470 | return $this->checkResponse(200, $response); |
---|
471 | } |
---|
472 | |
---|
473 | /** |
---|
474 | * Connection retrieval function. |
---|
475 | * |
---|
476 | * Takes a string of parameters as input and requests connection-related data |
---|
477 | * from the Linkedin Connections API. See the official documentation for |
---|
478 | * $options 'field selector' formatting: |
---|
479 | * |
---|
480 | * http://developer.linkedin.com/docs/DOC-1014 |
---|
481 | * |
---|
482 | * @param str $options |
---|
483 | * [OPTIONAL] Data retrieval options. |
---|
484 | * |
---|
485 | * @return arr |
---|
486 | * Array containing retrieval success, LinkedIn response. |
---|
487 | */ |
---|
488 | public function connections($options = '~/connections') { |
---|
489 | // check passed data |
---|
490 | if(!is_string($options)) { |
---|
491 | // bad data passed |
---|
492 | throw new LinkedInException('LinkedIn->connections(): bad data passed, $options must be of type string.'); |
---|
493 | } |
---|
494 | |
---|
495 | // construct and send the request |
---|
496 | $query = self::_URL_API . '/v1/people/' . trim($options); |
---|
497 | $response = $this->fetch('GET', $query); |
---|
498 | |
---|
499 | /** |
---|
500 | * Check for successful request (a 200 response from LinkedIn server) |
---|
501 | * per the documentation linked in method comments above. |
---|
502 | */ |
---|
503 | return $this->checkResponse(200, $response); |
---|
504 | } |
---|
505 | |
---|
506 | /** |
---|
507 | * This creates a post in the specified group with the specified title and specified summary. |
---|
508 | * |
---|
509 | * http://developer.linkedin.com/documents/groups-api |
---|
510 | * |
---|
511 | * @param str $gid |
---|
512 | * The group id. |
---|
513 | * @param str $title |
---|
514 | * The title of the post. This must be non-empty. |
---|
515 | * @param str $summary |
---|
516 | * [OPTIONAL] The content or summary of the post. This can be empty. |
---|
517 | * |
---|
518 | * @return arr |
---|
519 | * Array containing retrieval success, LinkedIn response. |
---|
520 | */ |
---|
521 | public function createPost($gid, $title, $summary = '') { |
---|
522 | if(!is_string($gid)) { |
---|
523 | throw new LinkedInException('LinkedIn->createPost(): bad data passed, $gid must be of type string.'); |
---|
524 | } |
---|
525 | if(!is_string($title) || empty($title)) { |
---|
526 | throw new LinkedInException('LinkedIn->createPost(): bad data passed, $title must be a non-empty string.'); |
---|
527 | } |
---|
528 | if(!is_string($summary)) { |
---|
529 | throw new LinkedInException('LinkedIn->createPost(): bad data passed, $summary must be of type string.'); |
---|
530 | } |
---|
531 | |
---|
532 | // construct the XML |
---|
533 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
534 | <post> |
---|
535 | <title>'. $title . '</title> |
---|
536 | <summary>' . $summary . '</summary> |
---|
537 | </post>'; |
---|
538 | |
---|
539 | // construct and send the request |
---|
540 | $query = self::_URL_API . '/v1/groups/' . trim($gid) . '/posts'; |
---|
541 | $response = $this->fetch('POST', $query, $data); |
---|
542 | |
---|
543 | /** |
---|
544 | * Check for successful request (a 201 response from LinkedIn server) |
---|
545 | * per the documentation linked in method comments above. |
---|
546 | */ |
---|
547 | return $this->checkResponse(201, $response); |
---|
548 | } |
---|
549 | |
---|
550 | /** |
---|
551 | * This deletes the specified post if you are the owner or moderator that post. |
---|
552 | * Otherwise, it just flags the post as inappropriate. |
---|
553 | * |
---|
554 | * https://developer.linkedin.com/documents/groups-api |
---|
555 | * |
---|
556 | * @param str $pid |
---|
557 | * The post id. |
---|
558 | * |
---|
559 | * @return arr |
---|
560 | * Array containing retrieval success, LinkedIn response. |
---|
561 | */ |
---|
562 | public function deletePost($pid) { |
---|
563 | if(!is_string($pid)) { |
---|
564 | throw new LinkedInException('LinkedIn->deletePost(): bad data passed, $pid must be of type string'); |
---|
565 | } |
---|
566 | |
---|
567 | // construct and send the request |
---|
568 | $query = self::_URL_API . '/v1/posts/' . trim($pid); |
---|
569 | $response = $this->fetch('DELETE', $query); |
---|
570 | |
---|
571 | /** |
---|
572 | * Check for successful request (a 204 response from LinkedIn server) |
---|
573 | * per the documentation linked in method comments above. |
---|
574 | */ |
---|
575 | return $this->checkResponse(204, $response); |
---|
576 | } |
---|
577 | |
---|
578 | /** |
---|
579 | * Edit a job. |
---|
580 | * |
---|
581 | * Calling this method causes the passed job to be edited, with the passed |
---|
582 | * XML instructing which fields to change, per: |
---|
583 | * |
---|
584 | * http://developer.linkedin.com/docs/DOC-1154 |
---|
585 | * http://developer.linkedin.com/docs/DOC-1142 |
---|
586 | * |
---|
587 | * @param str $jid |
---|
588 | * Job ID you want to renew. |
---|
589 | * @param str $xml |
---|
590 | * The XML containing the job fields to edit. |
---|
591 | * |
---|
592 | * @return arr |
---|
593 | * Array containing retrieval success, LinkedIn response. |
---|
594 | */ |
---|
595 | public function editJob($jid, $xml) { |
---|
596 | // check passed data |
---|
597 | if(!is_string($jid)) { |
---|
598 | // bad data passed |
---|
599 | throw new LinkedInException('LinkedIn->editJob(): bad data passed, $jid must be of string value.'); |
---|
600 | } |
---|
601 | if(is_string($xml)) { |
---|
602 | $xml = trim(stripslashes($xml)); |
---|
603 | } else { |
---|
604 | // bad data passed |
---|
605 | throw new LinkedInException('LinkedIn->editJob(): bad data passed, $xml must be of string value.'); |
---|
606 | } |
---|
607 | |
---|
608 | // construct and send the request |
---|
609 | $query = self::_URL_API . '/v1/jobs/partner-job-id=' . trim($jid); |
---|
610 | $response = $this->fetch('PUT', $query, $xml); |
---|
611 | |
---|
612 | /** |
---|
613 | * Check for successful request (a 200 response from LinkedIn server) |
---|
614 | * per the documentation linked in method comments above. |
---|
615 | */ |
---|
616 | return $this->checkResponse(200, $response); |
---|
617 | } |
---|
618 | |
---|
619 | /** |
---|
620 | * General data send/request method. |
---|
621 | * |
---|
622 | * @param str $method |
---|
623 | * The data communication method. |
---|
624 | * @param str $url |
---|
625 | * The Linkedin API endpoint to connect with. |
---|
626 | * @param str $data |
---|
627 | * [OPTIONAL] The data to send to LinkedIn. |
---|
628 | * @param arr $parameters |
---|
629 | * [OPTIONAL] Addition OAuth parameters to send to LinkedIn. |
---|
630 | * |
---|
631 | * @return arr |
---|
632 | * Array containing: |
---|
633 | * |
---|
634 | * array( |
---|
635 | * 'info' => Connection information, |
---|
636 | * 'linkedin' => LinkedIn response, |
---|
637 | * 'oauth' => The OAuth request string that was sent to LinkedIn |
---|
638 | * ) |
---|
639 | */ |
---|
640 | protected function fetch($method, $url, $data = NULL, $parameters = array()) { |
---|
641 | // check for cURL |
---|
642 | if(!extension_loaded('curl')) { |
---|
643 | // cURL not present |
---|
644 | throw new LinkedInException('LinkedIn->fetch(): PHP cURL extension does not appear to be loaded/present.'); |
---|
645 | } |
---|
646 | |
---|
647 | try { |
---|
648 | // generate OAuth values |
---|
649 | $oauth_consumer = new OAuthConsumer($this->getApplicationKey(), $this->getApplicationSecret(), $this->getCallbackUrl()); |
---|
650 | $oauth_token = $this->getToken(); |
---|
651 | $oauth_token = (!is_null($oauth_token)) ? new OAuthToken($oauth_token['oauth_token'], $oauth_token['oauth_token_secret']) : NULL; |
---|
652 | $defaults = array( |
---|
653 | 'oauth_version' => self::_API_OAUTH_VERSION |
---|
654 | ); |
---|
655 | $parameters = array_merge($defaults, $parameters); |
---|
656 | |
---|
657 | // generate OAuth request |
---|
658 | $oauth_req = OAuthRequest::from_consumer_and_token($oauth_consumer, $oauth_token, $method, $url, $parameters); |
---|
659 | $oauth_req->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $oauth_consumer, $oauth_token); |
---|
660 | |
---|
661 | // start cURL, checking for a successful initiation |
---|
662 | if(!$handle = curl_init()) { |
---|
663 | // cURL failed to start |
---|
664 | throw new LinkedInException('LinkedIn->fetch(): cURL did not initialize properly.'); |
---|
665 | } |
---|
666 | |
---|
667 | // set cURL options, based on parameters passed |
---|
668 | curl_setopt($handle, CURLOPT_CUSTOMREQUEST, $method); |
---|
669 | curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); |
---|
670 | curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE); |
---|
671 | curl_setopt($handle, CURLOPT_URL, $url); |
---|
672 | curl_setopt($handle, CURLOPT_VERBOSE, FALSE); |
---|
673 | |
---|
674 | // configure the header we are sending to LinkedIn - http://developer.linkedin.com/docs/DOC-1203 |
---|
675 | $header = array($oauth_req->to_header(self::_API_OAUTH_REALM)); |
---|
676 | if(is_null($data)) { |
---|
677 | // not sending data, identify the content type |
---|
678 | $header[] = 'Content-Type: text/plain; charset=UTF-8'; |
---|
679 | switch($this->getResponseFormat()) { |
---|
680 | case self::_RESPONSE_JSON: |
---|
681 | $header[] = 'x-li-format: json'; |
---|
682 | break; |
---|
683 | case self::_RESPONSE_JSONP: |
---|
684 | $header[] = 'x-li-format: jsonp'; |
---|
685 | break; |
---|
686 | } |
---|
687 | } else { |
---|
688 | $header[] = 'Content-Type: text/xml; charset=UTF-8'; |
---|
689 | curl_setopt($handle, CURLOPT_POSTFIELDS, $data); |
---|
690 | } |
---|
691 | curl_setopt($handle, CURLOPT_HTTPHEADER, $header); |
---|
692 | |
---|
693 | // set the last url, headers |
---|
694 | $this->last_request_url = $url; |
---|
695 | $this->last_request_headers = $header; |
---|
696 | |
---|
697 | // gather the response |
---|
698 | $return_data['linkedin'] = curl_exec($handle); |
---|
699 | $return_data['info'] = curl_getinfo($handle); |
---|
700 | $return_data['oauth']['header'] = $oauth_req->to_header(self::_API_OAUTH_REALM); |
---|
701 | $return_data['oauth']['string'] = $oauth_req->base_string; |
---|
702 | |
---|
703 | // check for throttling |
---|
704 | if(self::isThrottled($return_data['linkedin'])) { |
---|
705 | throw new LinkedInException('LinkedIn->fetch(): throttling limit for this user/application has been reached for LinkedIn resource - ' . $url); |
---|
706 | } |
---|
707 | |
---|
708 | //TODO - add check for NO response (http_code = 0) from cURL |
---|
709 | |
---|
710 | // close cURL connection |
---|
711 | curl_close($handle); |
---|
712 | |
---|
713 | // no exceptions thrown, return the data |
---|
714 | return $return_data; |
---|
715 | } catch(OAuthException $e) { |
---|
716 | // oauth exception raised |
---|
717 | throw new LinkedInException('OAuth exception caught: ' . $e->getMessage()); |
---|
718 | } |
---|
719 | } |
---|
720 | |
---|
721 | /** |
---|
722 | * This flags a specified post as specified by type. |
---|
723 | * |
---|
724 | * http://developer.linkedin.com/documents/groups-api |
---|
725 | * |
---|
726 | * @param str $pid |
---|
727 | * The post id. |
---|
728 | * @param str $type |
---|
729 | * The type to flag the post as. |
---|
730 | * |
---|
731 | * @return arr |
---|
732 | * Array containing retrieval success, LinkedIn response. |
---|
733 | */ |
---|
734 | public function flagPost($pid, $type) { |
---|
735 | if(!is_string($pid)) { |
---|
736 | throw new LinkedInException('LinkedIn->flagPost(): bad data passed, $pid must be of type string'); |
---|
737 | } |
---|
738 | if(!is_string($type)) { |
---|
739 | throw new LinkedInException('LinkedIn->flagPost(): bad data passed, $like must be of type string'); |
---|
740 | } |
---|
741 | //Constructing the xml |
---|
742 | $data = '<?xml version="1.0" encoding="UTF-8"?>'; |
---|
743 | switch($type) { |
---|
744 | case 'promotion': |
---|
745 | $data .= '<code>promotion</code>'; |
---|
746 | break; |
---|
747 | case 'job': |
---|
748 | $data .= '<code>job</code>'; |
---|
749 | break; |
---|
750 | default: |
---|
751 | throw new LinkedInException('LinkedIn->flagPost(): invalid value for $type, must be one of: "promotion", "job"'); |
---|
752 | break; |
---|
753 | } |
---|
754 | |
---|
755 | // construct and send the request |
---|
756 | $query = self::_URL_API . '/v1/posts/' . $pid . '/category/code'; |
---|
757 | $response = $this->fetch('PUT', $query, $data); |
---|
758 | |
---|
759 | /** |
---|
760 | * Check for successful request (a 204 response from LinkedIn server) |
---|
761 | * per the documentation linked in method comments above. |
---|
762 | */ |
---|
763 | return $this->checkResponse(204, $response); |
---|
764 | } |
---|
765 | |
---|
766 | /** |
---|
767 | * Follow a company. |
---|
768 | * |
---|
769 | * Calling this method causes the current user to start following the |
---|
770 | * specified company, per: |
---|
771 | * |
---|
772 | * http://developer.linkedin.com/docs/DOC-1324 |
---|
773 | * |
---|
774 | * @param str $cid |
---|
775 | * Company ID you want to follow. |
---|
776 | * |
---|
777 | * @return arr |
---|
778 | * Array containing retrieval success, LinkedIn response. |
---|
779 | */ |
---|
780 | public function followCompany($cid) { |
---|
781 | // check passed data |
---|
782 | if(!is_string($cid)) { |
---|
783 | // bad data passed |
---|
784 | throw new LinkedInException('LinkedIn->followCompany(): bad data passed, $cid must be of type string.'); |
---|
785 | } |
---|
786 | |
---|
787 | // construct and send the request |
---|
788 | $query = self::_URL_API . '/v1/people/~/following/companies'; |
---|
789 | $response = $this->fetch('POST', $query, '<company><id>' . trim($cid) . '</id></company>'); |
---|
790 | |
---|
791 | /** |
---|
792 | * Check for successful request (a 201 response from LinkedIn server) |
---|
793 | * per the documentation linked in method comments above. |
---|
794 | */ |
---|
795 | return $this->checkResponse(201, $response); |
---|
796 | } |
---|
797 | |
---|
798 | /** |
---|
799 | * Follows/Unfollows the specified post. |
---|
800 | * |
---|
801 | * https://developer.linkedin.com/documents/groups-api |
---|
802 | * |
---|
803 | * @param str $pid |
---|
804 | * The post id. |
---|
805 | * @param bool $follow |
---|
806 | * Determines whether to follow or unfollow the post. TRUE = follow, FALSE = unfollow |
---|
807 | * |
---|
808 | * @return arr |
---|
809 | * Array containing retrieval success, LinkedIn response. |
---|
810 | */ |
---|
811 | |
---|
812 | public function followPost($pid, $follow) { |
---|
813 | if(!is_string($pid)) { |
---|
814 | throw new LinkedInException('LinkedIn->followPost(): bad data passed, $pid must be of type string'); |
---|
815 | } |
---|
816 | if(!($follow === TRUE || $follow === FALSE)) { |
---|
817 | throw new LinkedInException('LinkedIn->followPost(): bad data passed, $follow must be of type boolean'); |
---|
818 | } |
---|
819 | |
---|
820 | // construct the XML |
---|
821 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
822 | <is-following>'. (($follow) ? 'true' : 'false'). '</is-following>'; |
---|
823 | |
---|
824 | // construct and send the request |
---|
825 | $query = self::_URL_API . '/v1/posts/' . trim($pid) . '/relation-to-viewer/is-following'; |
---|
826 | $response = $this->fetch('PUT', $query, $data); |
---|
827 | |
---|
828 | /** |
---|
829 | * Check for successful request (a 204 response from LinkedIn server) |
---|
830 | * per the documentation linked in method comments above. |
---|
831 | */ |
---|
832 | return $this->checkResponse(204, $response); |
---|
833 | } |
---|
834 | |
---|
835 | /** |
---|
836 | * Get list of companies you follow. |
---|
837 | * |
---|
838 | * Returns a list of companies the current user is currently following, per: |
---|
839 | * |
---|
840 | * http://developer.linkedin.com/docs/DOC-1324 |
---|
841 | * |
---|
842 | * @return arr |
---|
843 | * Array containing retrieval success, LinkedIn response. |
---|
844 | */ |
---|
845 | public function followedCompanies() { |
---|
846 | // construct and send the request |
---|
847 | $query = self::_URL_API . '/v1/people/~/following/companies'; |
---|
848 | $response = $this->fetch('GET', $query); |
---|
849 | |
---|
850 | /** |
---|
851 | * Check for successful request (a 200 response from LinkedIn server) |
---|
852 | * per the documentation linked in method comments above. |
---|
853 | */ |
---|
854 | return $this->checkResponse(200, $response); |
---|
855 | } |
---|
856 | |
---|
857 | /** |
---|
858 | * Get the application_key property. |
---|
859 | * |
---|
860 | * @return str |
---|
861 | * The application key. |
---|
862 | */ |
---|
863 | public function getApplicationKey() { |
---|
864 | return $this->application_key; |
---|
865 | } |
---|
866 | |
---|
867 | /** |
---|
868 | * Get the application_secret property. |
---|
869 | * |
---|
870 | * @return str |
---|
871 | * The application secret. |
---|
872 | */ |
---|
873 | public function getApplicationSecret() { |
---|
874 | return $this->application_secret; |
---|
875 | } |
---|
876 | |
---|
877 | /** |
---|
878 | * Get the callback property. |
---|
879 | * |
---|
880 | * @return str |
---|
881 | * The callback url. |
---|
882 | */ |
---|
883 | public function getCallbackUrl() { |
---|
884 | return $this->callback; |
---|
885 | } |
---|
886 | |
---|
887 | /** |
---|
888 | * Get the response_format property. |
---|
889 | * |
---|
890 | * @return str |
---|
891 | * The response format. |
---|
892 | */ |
---|
893 | public function getResponseFormat() { |
---|
894 | return $this->response_format; |
---|
895 | } |
---|
896 | |
---|
897 | /** |
---|
898 | * Get the token_access property. |
---|
899 | * |
---|
900 | * @return arr |
---|
901 | * The access token. |
---|
902 | */ |
---|
903 | public function getToken() { |
---|
904 | return $this->token; |
---|
905 | } |
---|
906 | |
---|
907 | /** |
---|
908 | * [DEPRECATED] Get the token_access property. |
---|
909 | * |
---|
910 | * @return arr |
---|
911 | * The access token. |
---|
912 | */ |
---|
913 | public function getTokenAccess() { |
---|
914 | return $this->getToken(); |
---|
915 | } |
---|
916 | |
---|
917 | /** |
---|
918 | * |
---|
919 | * Get information about a specific group. |
---|
920 | * |
---|
921 | * http://developer.linkedin.com/documents/groups-api |
---|
922 | * |
---|
923 | * @param str $gid |
---|
924 | * The group id. |
---|
925 | * |
---|
926 | * @param str $options |
---|
927 | * [OPTIONAL] Field selectors for the group. |
---|
928 | * |
---|
929 | * @return arr |
---|
930 | * Array containing retrieval success, LinkedIn response. |
---|
931 | */ |
---|
932 | |
---|
933 | public function group($gid, $options = '') { |
---|
934 | if(!is_string($gid)){ |
---|
935 | throw new LinkedInException('LinkedIn->group(): bad data passed, $gid must be of type string.'); |
---|
936 | } |
---|
937 | if(!is_string($options)) { |
---|
938 | throw new LinkedInException('LinkedIn->group(): bad data passed, $options must be of type string'); |
---|
939 | } |
---|
940 | |
---|
941 | // construct and send the request |
---|
942 | $query = self::_URL_API . '/v1/groups/' . trim($gid) . trim($options); |
---|
943 | $response = $this->fetch('GET', $query); |
---|
944 | |
---|
945 | /** |
---|
946 | * Check for successful request (a 200 response from LinkedIn server) |
---|
947 | * per the documentation linked in method comments above. |
---|
948 | */ |
---|
949 | return $this->checkResponse(200, $response); |
---|
950 | } |
---|
951 | |
---|
952 | /** |
---|
953 | * This returns all the groups the user is a member of. |
---|
954 | * |
---|
955 | * http://developer.linkedin.com/documents/groups-api |
---|
956 | * |
---|
957 | * @param str $options |
---|
958 | * [OPTIONAL] Field selectors for the groups. |
---|
959 | * |
---|
960 | * @return arr |
---|
961 | * Array containing retrieval success, LinkedIn response. |
---|
962 | */ |
---|
963 | public function groupMemberships($options = '') { |
---|
964 | if(!is_string($options)) { |
---|
965 | throw new LinkedInException('LinkedIn->groupMemberships(): bad data passed, $options must be of type string'); |
---|
966 | } |
---|
967 | |
---|
968 | // construct and send the request |
---|
969 | $query = self::_URL_API . '/v1/people/~/group-memberships' . trim($options) . '?membership-state=member'; |
---|
970 | $response = $this->fetch('GET', $query); |
---|
971 | |
---|
972 | /** |
---|
973 | * Check for successful request (a 200 response from LinkedIn server) |
---|
974 | * per the documentation linked in method comments above. |
---|
975 | */ |
---|
976 | return $this->checkResponse(200, $response); |
---|
977 | } |
---|
978 | |
---|
979 | /** |
---|
980 | * This gets a specified post made within a group. |
---|
981 | * |
---|
982 | * http://developer.linkedin.com/documents/groups-api |
---|
983 | * |
---|
984 | * @param str $pid |
---|
985 | * The post id. |
---|
986 | * @param str $options |
---|
987 | * [OPTIONAL] Field selectors for the post. |
---|
988 | * |
---|
989 | * @return arr |
---|
990 | * Array containing retrieval success, LinkedIn response. |
---|
991 | */ |
---|
992 | public function groupPost($pid, $options = '') { |
---|
993 | if(!is_string($pid)) { |
---|
994 | throw new LinkedInException('LinkedIn->groupPost(): bad data passed, $pid must be of type string.'); |
---|
995 | } |
---|
996 | if(!is_string($options)) { |
---|
997 | throw new LinkedInException('LinkedIn->groupPost(): bad data passed, $options must be of type string.'); |
---|
998 | } |
---|
999 | |
---|
1000 | // construct and send the request |
---|
1001 | $query = self::_URL_API . '/v1/posts/' . trim($pid) . trim($options); |
---|
1002 | $response = $this->fetch('GET', $query); |
---|
1003 | |
---|
1004 | /** |
---|
1005 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1006 | * per the documentation linked in method comments above. |
---|
1007 | */ |
---|
1008 | return $this->checkResponse(200, $response); |
---|
1009 | } |
---|
1010 | |
---|
1011 | /** |
---|
1012 | * This returns all the comments made on the specified post within a group. |
---|
1013 | * |
---|
1014 | * http://developer.linkedin.com/documents/groups-api |
---|
1015 | * |
---|
1016 | * @param str $pid |
---|
1017 | * The post id. |
---|
1018 | * @param str $options |
---|
1019 | * [OPTIONAL] Field selectors for the post comments. |
---|
1020 | * |
---|
1021 | * @return arr |
---|
1022 | * Array containing retrieval success, LinkedIn response. |
---|
1023 | */ |
---|
1024 | public function groupPostComments($pid, $options = ''){ |
---|
1025 | if(!is_string($pid)){ |
---|
1026 | throw new LinkedInException('LinkedIn->groupPostComments(): bad data passed, $pid must be of type string.'); |
---|
1027 | } |
---|
1028 | if(!is_string($options)) { |
---|
1029 | throw new LinkedInException('LinkedIn->groupPostComments(): bad data passed, $options must be of type string.'); |
---|
1030 | } |
---|
1031 | |
---|
1032 | // construct and send the request |
---|
1033 | $query = self::_URL_API . '/v1/posts/' . trim($pid) . '/comments' . trim($options); |
---|
1034 | $response = $this->fetch('GET', $query); |
---|
1035 | |
---|
1036 | /** |
---|
1037 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1038 | * per the documentation linked in method comments above. |
---|
1039 | */ |
---|
1040 | return $this->checkResponse(200, $response); |
---|
1041 | } |
---|
1042 | |
---|
1043 | /** |
---|
1044 | * This returns all the posts within a group. |
---|
1045 | * |
---|
1046 | * http://developer.linkedin.com/documents/groups-api |
---|
1047 | * |
---|
1048 | * @param str $gid |
---|
1049 | * The group id. |
---|
1050 | * |
---|
1051 | * @return arr |
---|
1052 | * Array containing retrieval success, LinkedIn response. |
---|
1053 | */ |
---|
1054 | public function groupPosts($gid, $options = '') { |
---|
1055 | if(!is_string($gid)){ |
---|
1056 | throw new LinkedInException('LinkedIn->groupPosts(): bad data passed, $gid must be of type string'); |
---|
1057 | } |
---|
1058 | if(!is_string($options)){ |
---|
1059 | throw new LinkedInException('LinkedIn->groupPosts(): bad data passed, $options must be of type string'); |
---|
1060 | } |
---|
1061 | |
---|
1062 | // construct and send the request |
---|
1063 | $query = self::_URL_API . '/v1/groups/' . trim($gid) .'/posts' . trim($options); |
---|
1064 | $response = $this->fetch('GET', $query); |
---|
1065 | |
---|
1066 | /** |
---|
1067 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1068 | * per the documentation linked in method comments above. |
---|
1069 | */ |
---|
1070 | return $this->checkResponse(200, $response); |
---|
1071 | } |
---|
1072 | |
---|
1073 | /** |
---|
1074 | * This returns the group settings of the specified group |
---|
1075 | * |
---|
1076 | * http://developer.linkedin.com/documents/groups-api |
---|
1077 | * |
---|
1078 | * @param str $gid |
---|
1079 | * The group id. |
---|
1080 | * @param str $options |
---|
1081 | * [OPTIONAL] Field selectors for the group. |
---|
1082 | * |
---|
1083 | * @return arr |
---|
1084 | * Array containing retrieval success, LinkedIn response. |
---|
1085 | */ |
---|
1086 | public function groupSettings($gid, $options = '') { |
---|
1087 | if(!is_string($gid)) { |
---|
1088 | throw new LinkedInException('LinkedIn->groupSettings(): bad data passed, $gid must be of type string'); |
---|
1089 | } |
---|
1090 | if(!is_string($options)) { |
---|
1091 | throw new LinkedInException('LinkedIn->groupSettings(): bad data passed, $options must be of type string'); |
---|
1092 | } |
---|
1093 | |
---|
1094 | // construct and send the request |
---|
1095 | $query = self::_URL_API . '/v1/people/~/group-memberships/' . trim($gid) . trim($options); |
---|
1096 | $response = $this->fetch('GET', $query); |
---|
1097 | |
---|
1098 | /** |
---|
1099 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1100 | * per the documentation linked in method comments above. |
---|
1101 | */ |
---|
1102 | return $this->checkResponse(200, $response); |
---|
1103 | } |
---|
1104 | |
---|
1105 | /** |
---|
1106 | * Send connection invitations. |
---|
1107 | * |
---|
1108 | * Send an invitation to connect to your network, either by email address or |
---|
1109 | * by LinkedIn ID. Details on the API here: |
---|
1110 | * |
---|
1111 | * http://developer.linkedin.com/docs/DOC-1012 |
---|
1112 | * |
---|
1113 | * @param str $method |
---|
1114 | * The invitation method to process. |
---|
1115 | * @param str $recipient |
---|
1116 | * The email/id to send the invitation to. |
---|
1117 | * @param str $subject |
---|
1118 | * The subject of the invitation to send. |
---|
1119 | * @param str $body |
---|
1120 | * The body of the invitation to send. |
---|
1121 | * @param str $type |
---|
1122 | * [OPTIONAL] The invitation request type (only friend is supported at this time by the Invite API). |
---|
1123 | * |
---|
1124 | * @return arr |
---|
1125 | * Array containing retrieval success, LinkedIn response. |
---|
1126 | */ |
---|
1127 | public function invite($method, $recipient, $subject, $body, $type = 'friend') { |
---|
1128 | /** |
---|
1129 | * Clean up the passed data per these rules: |
---|
1130 | * |
---|
1131 | * 1) Message must be sent to one recipient (only a single recipient permitted for the Invitation API) |
---|
1132 | * 2) No HTML permitted |
---|
1133 | * 3) 200 characters max in the invitation subject |
---|
1134 | * 4) Only able to connect as a friend at this point |
---|
1135 | */ |
---|
1136 | // check passed data |
---|
1137 | if(empty($recipient)) { |
---|
1138 | throw new LinkedInException('LinkedIn->invite(): you must provide an invitation recipient.'); |
---|
1139 | } |
---|
1140 | switch($method) { |
---|
1141 | case 'email': |
---|
1142 | if(is_array($recipient)) { |
---|
1143 | $recipient = array_map('trim', $recipient); |
---|
1144 | } else { |
---|
1145 | // bad format for recipient for email method |
---|
1146 | throw new LinkedInException('LinkedIn->invite(): invitation recipient email/name array is malformed.'); |
---|
1147 | } |
---|
1148 | break; |
---|
1149 | case 'id': |
---|
1150 | $recipient = trim($recipient); |
---|
1151 | if(!self::isId($recipient)) { |
---|
1152 | // bad format for recipient for id method |
---|
1153 | throw new LinkedInException('LinkedIn->invite(): invitation recipient ID does not match LinkedIn format.'); |
---|
1154 | } |
---|
1155 | break; |
---|
1156 | default: |
---|
1157 | throw new LinkedInException('LinkedIn->invite(): bad invitation method, must be one of: email, id.'); |
---|
1158 | break; |
---|
1159 | } |
---|
1160 | if(!empty($subject)) { |
---|
1161 | $subject = trim(htmlspecialchars(strip_tags(stripslashes($subject)))); |
---|
1162 | } else { |
---|
1163 | throw new LinkedInException('LinkedIn->invite(): message subject is empty.'); |
---|
1164 | } |
---|
1165 | if(!empty($body)) { |
---|
1166 | $body = trim(htmlspecialchars(strip_tags(stripslashes($body)))); |
---|
1167 | if(strlen($body) > self::_INV_BODY_LENGTH) { |
---|
1168 | throw new LinkedInException('LinkedIn->invite(): message body length is too long - max length is ' . self::_INV_BODY_LENGTH . ' characters.'); |
---|
1169 | } |
---|
1170 | } else { |
---|
1171 | throw new LinkedInException('LinkedIn->invite(): message body is empty.'); |
---|
1172 | } |
---|
1173 | switch($type) { |
---|
1174 | case 'friend': |
---|
1175 | break; |
---|
1176 | default: |
---|
1177 | throw new LinkedInException('LinkedIn->invite(): bad invitation type, must be one of: friend.'); |
---|
1178 | break; |
---|
1179 | } |
---|
1180 | |
---|
1181 | // construct the xml data |
---|
1182 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
1183 | <mailbox-item> |
---|
1184 | <recipients> |
---|
1185 | <recipient>'; |
---|
1186 | switch($method) { |
---|
1187 | case 'email': |
---|
1188 | // email-based invitation |
---|
1189 | $data .= '<person path="/people/email=' . $recipient['email'] . '"> |
---|
1190 | <first-name>' . htmlspecialchars($recipient['first-name']) . '</first-name> |
---|
1191 | <last-name>' . htmlspecialchars($recipient['last-name']) . '</last-name> |
---|
1192 | </person>'; |
---|
1193 | break; |
---|
1194 | case 'id': |
---|
1195 | // id-based invitation |
---|
1196 | $data .= '<person path="/people/id=' . $recipient . '"/>'; |
---|
1197 | break; |
---|
1198 | } |
---|
1199 | $data .= ' </recipient> |
---|
1200 | </recipients> |
---|
1201 | <subject>' . $subject . '</subject> |
---|
1202 | <body>' . $body . '</body> |
---|
1203 | <item-content> |
---|
1204 | <invitation-request> |
---|
1205 | <connect-type>'; |
---|
1206 | switch($type) { |
---|
1207 | case 'friend': |
---|
1208 | $data .= 'friend'; |
---|
1209 | break; |
---|
1210 | } |
---|
1211 | $data .= ' </connect-type>'; |
---|
1212 | switch($method) { |
---|
1213 | case 'id': |
---|
1214 | // id-based invitation, we need to get the authorization information |
---|
1215 | $query = 'id=' . $recipient . ':(api-standard-profile-request)'; |
---|
1216 | $response = self::profile($query); |
---|
1217 | if($response['info']['http_code'] == 200) { |
---|
1218 | $response['linkedin'] = self::xmlToArray($response['linkedin']); |
---|
1219 | if($response['linkedin'] === FALSE) { |
---|
1220 | // bad XML data |
---|
1221 | throw new LinkedInException('LinkedIn->invite(): LinkedIn returned bad XML data.'); |
---|
1222 | } |
---|
1223 | $authentication = explode(':', $response['linkedin']['person']['children']['api-standard-profile-request']['children']['headers']['children']['http-header']['children']['value']['content']); |
---|
1224 | |
---|
1225 | // complete the xml |
---|
1226 | $data .= '<authorization> |
---|
1227 | <name>' . $authentication[0] . '</name> |
---|
1228 | <value>' . $authentication[1] . '</value> |
---|
1229 | </authorization>'; |
---|
1230 | } else { |
---|
1231 | // bad response from the profile request, not a valid ID? |
---|
1232 | throw new LinkedInException('LinkedIn->invite(): could not send invitation, LinkedIn says: ' . print_r($response['linkedin'], TRUE)); |
---|
1233 | } |
---|
1234 | break; |
---|
1235 | } |
---|
1236 | $data .= ' </invitation-request> |
---|
1237 | </item-content> |
---|
1238 | </mailbox-item>'; |
---|
1239 | |
---|
1240 | // send request |
---|
1241 | $query = self::_URL_API . '/v1/people/~/mailbox'; |
---|
1242 | $response = $this->fetch('POST', $query, $data); |
---|
1243 | |
---|
1244 | /** |
---|
1245 | * Check for successful request (a 201 response from LinkedIn server) |
---|
1246 | * per the documentation linked in method comments above. |
---|
1247 | */ |
---|
1248 | return $this->checkResponse(201, $response); |
---|
1249 | } |
---|
1250 | |
---|
1251 | /** |
---|
1252 | * LinkedIn ID validation. |
---|
1253 | * |
---|
1254 | * Checks the passed string $id to see if it has a valid LinkedIn ID format, |
---|
1255 | * which is, as of October 15th, 2010: |
---|
1256 | * |
---|
1257 | * 10 alpha-numeric mixed-case characters, plus underscores and dashes. |
---|
1258 | * |
---|
1259 | * @param str $id |
---|
1260 | * A possible LinkedIn ID. |
---|
1261 | * |
---|
1262 | * @return bool |
---|
1263 | * TRUE/FALSE depending on valid ID format determination. |
---|
1264 | */ |
---|
1265 | public static function isId($id) { |
---|
1266 | // check passed data |
---|
1267 | if(!is_string($id)) { |
---|
1268 | // bad data passed |
---|
1269 | throw new LinkedInException('LinkedIn->isId(): bad data passed, $id must be of type string.'); |
---|
1270 | } |
---|
1271 | |
---|
1272 | $pattern = '/^[a-z0-9_\-]{10}$/i'; |
---|
1273 | if($match = preg_match($pattern, $id)) { |
---|
1274 | // we have a match |
---|
1275 | $return_data = TRUE; |
---|
1276 | } else { |
---|
1277 | // no match |
---|
1278 | $return_data = FALSE; |
---|
1279 | } |
---|
1280 | return $return_data; |
---|
1281 | } |
---|
1282 | |
---|
1283 | /** |
---|
1284 | * Throttling check. |
---|
1285 | * |
---|
1286 | * Checks the passed LinkedIn response to see if we have hit a throttling |
---|
1287 | * limit: |
---|
1288 | * |
---|
1289 | * http://developer.linkedin.com/docs/DOC-1112 |
---|
1290 | * |
---|
1291 | * @param arr $response |
---|
1292 | * The LinkedIn response. |
---|
1293 | * |
---|
1294 | * @return bool |
---|
1295 | * TRUE/FALSE depending on content of response. |
---|
1296 | */ |
---|
1297 | public static function isThrottled($response) { |
---|
1298 | $return_data = FALSE; |
---|
1299 | |
---|
1300 | // check the variable |
---|
1301 | if(!empty($response) && is_string($response)) { |
---|
1302 | // we have an array and have a properly formatted LinkedIn response |
---|
1303 | |
---|
1304 | // store the response in a temp variable |
---|
1305 | $temp_response = self::xmlToArray($response); |
---|
1306 | if($temp_response !== FALSE) { |
---|
1307 | // check to see if we have an error |
---|
1308 | if(array_key_exists('error', $temp_response) && ($temp_response['error']['children']['status']['content'] == 403) && preg_match('/throttle/i', $temp_response['error']['children']['message']['content'])) { |
---|
1309 | // we have an error, it is 403 and we have hit a throttle limit |
---|
1310 | $return_data = TRUE; |
---|
1311 | } |
---|
1312 | } |
---|
1313 | } |
---|
1314 | return $return_data; |
---|
1315 | } |
---|
1316 | |
---|
1317 | /** |
---|
1318 | * Job posting detail info retrieval function. |
---|
1319 | * |
---|
1320 | * The Jobs API returns detailed information about job postings on LinkedIn. |
---|
1321 | * Find the job summary, description, location, and apply our professional graph |
---|
1322 | * to present the relationship between the current member and the job poster or |
---|
1323 | * hiring manager. |
---|
1324 | * |
---|
1325 | * http://developer.linkedin.com/docs/DOC-1322 |
---|
1326 | * |
---|
1327 | * @param str $jid |
---|
1328 | * ID of the job you want to look up. |
---|
1329 | * @param str $options |
---|
1330 | * [OPTIONAL] Data retrieval options. |
---|
1331 | * |
---|
1332 | * @return arr |
---|
1333 | * Array containing retrieval success, LinkedIn response. |
---|
1334 | */ |
---|
1335 | public function job($jid, $options = '') { |
---|
1336 | // check passed data |
---|
1337 | if(!is_string($jid)) { |
---|
1338 | // bad data passed |
---|
1339 | throw new LinkedInException('LinkedIn->job(): bad data passed, $jid must be of type string.'); |
---|
1340 | } |
---|
1341 | if(!is_string($options)) { |
---|
1342 | // bad data passed |
---|
1343 | throw new LinkedInException('LinkedIn->job(): bad data passed, $options must be of type string.'); |
---|
1344 | } |
---|
1345 | |
---|
1346 | // construct and send the request |
---|
1347 | $query = self::_URL_API . '/v1/jobs/' . trim($jid) . trim($options); |
---|
1348 | $response = $this->fetch('GET', $query); |
---|
1349 | |
---|
1350 | /** |
---|
1351 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1352 | * per the documentation linked in method comments above. |
---|
1353 | */ |
---|
1354 | return $this->checkResponse(200, $response); |
---|
1355 | } |
---|
1356 | |
---|
1357 | /** |
---|
1358 | * Join the specified group, per: |
---|
1359 | * |
---|
1360 | * http://developer.linkedin.com/documents/groups-api |
---|
1361 | * |
---|
1362 | * @param str $gid |
---|
1363 | * The group id. |
---|
1364 | * |
---|
1365 | * @return arr |
---|
1366 | * Array containing retrieval success, LinkedIn response. |
---|
1367 | */ |
---|
1368 | public function joinGroup($gid) { |
---|
1369 | if(!is_string($gid)) { |
---|
1370 | throw new LinkedInException('LinkedIn->joinGroup(): bad data passed, $gid must be of type string.'); |
---|
1371 | } |
---|
1372 | |
---|
1373 | // constructing the XML |
---|
1374 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
1375 | <group-membership> |
---|
1376 | <membership-state> |
---|
1377 | <code>member</code> |
---|
1378 | </membership-state> |
---|
1379 | </group-membership>'; |
---|
1380 | |
---|
1381 | // construct and send the request |
---|
1382 | $query = self::_URL_API . '/v1/people/~/group-memberships/' . trim($gid); |
---|
1383 | $response = $this->fetch('PUT', $query, $data); |
---|
1384 | |
---|
1385 | /** |
---|
1386 | * Check for successful request (a 200 or 201 response from LinkedIn server) |
---|
1387 | * per the documentation linked in method comments above. |
---|
1388 | */ |
---|
1389 | return $this->checkResponse(array(200, 201), $response); |
---|
1390 | } |
---|
1391 | |
---|
1392 | /** |
---|
1393 | * Returns the last request header from the previous call to the |
---|
1394 | * LinkedIn API. |
---|
1395 | * |
---|
1396 | * @returns str |
---|
1397 | * The header, in string format. |
---|
1398 | */ |
---|
1399 | public function lastRequestHeader() { |
---|
1400 | return $this->last_request_headers; |
---|
1401 | } |
---|
1402 | |
---|
1403 | /** |
---|
1404 | * Returns the last request url from the previous call to the |
---|
1405 | * LinkedIn API. |
---|
1406 | * |
---|
1407 | * @returns str |
---|
1408 | * The url, in string format. |
---|
1409 | */ |
---|
1410 | public function lastRequestUrl() { |
---|
1411 | return $this->last_request_url; |
---|
1412 | } |
---|
1413 | |
---|
1414 | /** |
---|
1415 | * Leave the specified group, per:. |
---|
1416 | * |
---|
1417 | * http://developer.linkedin.com/documents/groups-api |
---|
1418 | * |
---|
1419 | * @param str $gid |
---|
1420 | * The group id. |
---|
1421 | * |
---|
1422 | * @return arr |
---|
1423 | * Array containing retrieval success, LinkedIn response. |
---|
1424 | */ |
---|
1425 | public function leaveGroup($gid){ |
---|
1426 | if(!is_string($gid)) { |
---|
1427 | throw new LinkedInException('LinkedIn->leaveGroup(): bad data passed, $gid must be of type string'); |
---|
1428 | } |
---|
1429 | |
---|
1430 | // construct and send the request |
---|
1431 | $query = self::_URL_API . '/v1/people/~/group-memberships/' .trim($gid); |
---|
1432 | $response = $this->fetch('DELETE', $query); |
---|
1433 | |
---|
1434 | /** |
---|
1435 | * Check for successful request (a 204 response from LinkedIn server) |
---|
1436 | * per the documentation linked in method comments above. |
---|
1437 | */ |
---|
1438 | return $this->checkResponse(204, $response); |
---|
1439 | } |
---|
1440 | |
---|
1441 | /** |
---|
1442 | * Like another user's network update, per: |
---|
1443 | * |
---|
1444 | * http://developer.linkedin.com/docs/DOC-1043 |
---|
1445 | * |
---|
1446 | * @param str $uid |
---|
1447 | * The LinkedIn update ID. |
---|
1448 | * |
---|
1449 | * @return arr |
---|
1450 | * Array containing retrieval success, LinkedIn response. |
---|
1451 | */ |
---|
1452 | public function like($uid) { |
---|
1453 | // check passed data |
---|
1454 | if(!is_string($uid)) { |
---|
1455 | // bad data passed |
---|
1456 | throw new LinkedInException('LinkedIn->like(): bad data passed, $uid must be of type string.'); |
---|
1457 | } |
---|
1458 | |
---|
1459 | // construct the XML |
---|
1460 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
1461 | <is-liked>true</is-liked>'; |
---|
1462 | |
---|
1463 | // construct and send the request |
---|
1464 | $query = self::_URL_API . '/v1/people/~/network/updates/key=' . $uid . '/is-liked'; |
---|
1465 | $response = $this->fetch('PUT', $query, $data); |
---|
1466 | |
---|
1467 | /** |
---|
1468 | * Check for successful request (a 201 response from LinkedIn server) |
---|
1469 | * per the documentation linked in method comments above. |
---|
1470 | */ |
---|
1471 | return $this->checkResponse(201, $response); |
---|
1472 | } |
---|
1473 | |
---|
1474 | /** |
---|
1475 | * Likes/unlikes the specified post, per: |
---|
1476 | * |
---|
1477 | * http://developer.linkedin.com/documents/groups-api |
---|
1478 | * |
---|
1479 | * @param str $pid |
---|
1480 | * The post id. |
---|
1481 | * @param bool $like |
---|
1482 | * Determines whether to like or unlike. TRUE = like, FALSE = unlike. |
---|
1483 | * |
---|
1484 | * @return arr |
---|
1485 | * Array containing retrieval success, LinkedIn response. |
---|
1486 | */ |
---|
1487 | public function likePost($pid, $like) { |
---|
1488 | if(!is_string($pid)) { |
---|
1489 | throw new LinkedInException ('LinkedIn->likePost(): bad data passed, $pid must be of type string'); |
---|
1490 | } |
---|
1491 | if(!($like === TRUE || $like === FALSE)) { |
---|
1492 | throw new LinkedInException('LinkedIn->likePost(): bad data passed, $like must be of type boolean'); |
---|
1493 | } |
---|
1494 | |
---|
1495 | // construct the XML |
---|
1496 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
1497 | <is-liked>'.(($like) ? 'true': 'false').'</is-liked>'; |
---|
1498 | |
---|
1499 | // construct and send the request |
---|
1500 | $query = self::_URL_API . '/v1/posts/' . trim($pid) . '/relation-to-viewer/is-liked'; |
---|
1501 | $response = $this->fetch('PUT', $query, $data); |
---|
1502 | |
---|
1503 | /** |
---|
1504 | * Check for successful request (a 204 response from LinkedIn server) |
---|
1505 | * per the documentation linked in method comments above. |
---|
1506 | */ |
---|
1507 | return $this->checkResponse(204, $response); |
---|
1508 | } |
---|
1509 | |
---|
1510 | /** |
---|
1511 | * Retrieve network update likes. |
---|
1512 | * |
---|
1513 | * Return all likes associated with a given network update: |
---|
1514 | * |
---|
1515 | * http://developer.linkedin.com/docs/DOC-1043 |
---|
1516 | * |
---|
1517 | * @param str $uid |
---|
1518 | * The LinkedIn update ID. |
---|
1519 | * |
---|
1520 | * @return arr |
---|
1521 | * Array containing retrieval success, LinkedIn response. |
---|
1522 | */ |
---|
1523 | public function likes($uid) { |
---|
1524 | // check passed data |
---|
1525 | if(!is_string($uid)) { |
---|
1526 | // bad data passed |
---|
1527 | throw new LinkedInException('LinkedIn->likes(): bad data passed, $uid must be of type string.'); |
---|
1528 | } |
---|
1529 | |
---|
1530 | // construct and send the request |
---|
1531 | $query = self::_URL_API . '/v1/people/~/network/updates/key=' . $uid . '/likes'; |
---|
1532 | $response = $this->fetch('GET', $query); |
---|
1533 | |
---|
1534 | /** |
---|
1535 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1536 | * per the documentation linked in method comments above. |
---|
1537 | */ |
---|
1538 | return $this->checkResponse(200, $response); |
---|
1539 | } |
---|
1540 | |
---|
1541 | /** |
---|
1542 | * Connection messaging method. |
---|
1543 | * |
---|
1544 | * Send a message to your network connection(s), optionally copying yourself. |
---|
1545 | * Full details from LinkedIn on this functionality can be found here: |
---|
1546 | * |
---|
1547 | * http://developer.linkedin.com/docs/DOC-1044 |
---|
1548 | * |
---|
1549 | * @param arr $recipients |
---|
1550 | * The connection(s) to send the message to. |
---|
1551 | * @param str $subject |
---|
1552 | * The subject of the message to send. |
---|
1553 | * @param str $body |
---|
1554 | * The body of the message to send. |
---|
1555 | * @param bool $copy_self |
---|
1556 | * [OPTIONAL] Also update the teathered Twitter account. |
---|
1557 | * |
---|
1558 | * @return arr |
---|
1559 | * Array containing retrieval success, LinkedIn response. |
---|
1560 | */ |
---|
1561 | public function message($recipients, $subject, $body, $copy_self = FALSE) { |
---|
1562 | /** |
---|
1563 | * Clean up the passed data per these rules: |
---|
1564 | * |
---|
1565 | * 1) Message must be sent to at least one recipient |
---|
1566 | * 2) No HTML permitted |
---|
1567 | */ |
---|
1568 | if(!empty($subject) && is_string($subject)) { |
---|
1569 | $subject = trim(strip_tags(stripslashes($subject))); |
---|
1570 | } else { |
---|
1571 | throw new LinkedInException('LinkedIn->message(): bad data passed, $subject must be of type string.'); |
---|
1572 | } |
---|
1573 | if(!empty($body) && is_string($body)) { |
---|
1574 | $body = trim(strip_tags(stripslashes($body))); |
---|
1575 | } else { |
---|
1576 | throw new LinkedInException('LinkedIn->message(): bad data passed, $body must be of type string.'); |
---|
1577 | } |
---|
1578 | if(!is_array($recipients) || count($recipients) < 1) { |
---|
1579 | // no recipients, and/or bad data |
---|
1580 | throw new LinkedInException('LinkedIn->message(): at least one message recipient required.'); |
---|
1581 | } |
---|
1582 | |
---|
1583 | // construct the xml data |
---|
1584 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
1585 | <mailbox-item> |
---|
1586 | <recipients>'; |
---|
1587 | $data .= ($copy_self) ? '<recipient><person path="/people/~"/></recipient>' : ''; |
---|
1588 | for($i = 0; $i < count($recipients); $i++) { |
---|
1589 | if(is_string($recipients[$i])) { |
---|
1590 | $data .= '<recipient><person path="/people/' . trim($recipients[$i]) . '"/></recipient>'; |
---|
1591 | } else { |
---|
1592 | throw new LinkedInException ('LinkedIn->message(): bad data passed, $recipients must be an array of type string.'); |
---|
1593 | } |
---|
1594 | } |
---|
1595 | $data .= ' </recipients> |
---|
1596 | <subject>' . htmlspecialchars($subject) . '</subject> |
---|
1597 | <body>' . htmlspecialchars($body) . '</body> |
---|
1598 | </mailbox-item>'; |
---|
1599 | |
---|
1600 | // send request |
---|
1601 | $query = self::_URL_API . '/v1/people/~/mailbox'; |
---|
1602 | $response = $this->fetch('POST', $query, $data); |
---|
1603 | |
---|
1604 | /** |
---|
1605 | * Check for successful request (a 201 response from LinkedIn server) |
---|
1606 | * per the documentation linked in method comments above. |
---|
1607 | */ |
---|
1608 | return $this->checkResponse(201, $response); |
---|
1609 | } |
---|
1610 | |
---|
1611 | /** |
---|
1612 | * Job posting method. |
---|
1613 | * |
---|
1614 | * Post a job to LinkedIn, assuming that you have access to this feature. |
---|
1615 | * Full details from LinkedIn on this functionality can be found here: |
---|
1616 | * |
---|
1617 | * http://developer.linkedin.com/community/jobs?view=documents |
---|
1618 | * |
---|
1619 | * @param str $xml |
---|
1620 | * The XML defining a job to post. |
---|
1621 | * |
---|
1622 | * @return arr |
---|
1623 | * Array containing retrieval success, LinkedIn response. |
---|
1624 | */ |
---|
1625 | public function postJob($xml) { |
---|
1626 | // check passed data |
---|
1627 | if(is_string($xml)) { |
---|
1628 | $xml = trim(stripslashes($xml)); |
---|
1629 | } else { |
---|
1630 | throw new LinkedInException('LinkedIn->postJob(): bad data passed, $xml must be of type string.'); |
---|
1631 | } |
---|
1632 | |
---|
1633 | // construct and send the request |
---|
1634 | $query = self::_URL_API . '/v1/jobs'; |
---|
1635 | $response = $this->fetch('POST', $query, $xml); |
---|
1636 | |
---|
1637 | /** |
---|
1638 | * Check for successful request (a 201 response from LinkedIn server) |
---|
1639 | * per the documentation linked in method comments above. |
---|
1640 | */ |
---|
1641 | return $this->checkResponse(201, $response); |
---|
1642 | } |
---|
1643 | |
---|
1644 | /** |
---|
1645 | * General profile retrieval function. |
---|
1646 | * |
---|
1647 | * Takes a string of parameters as input and requests profile data from the |
---|
1648 | * Linkedin Profile API. See the official documentation for $options |
---|
1649 | * 'field selector' formatting: |
---|
1650 | * |
---|
1651 | * http://developer.linkedin.com/docs/DOC-1014 |
---|
1652 | * http://developer.linkedin.com/docs/DOC-1002 |
---|
1653 | * |
---|
1654 | * @param str $options |
---|
1655 | * [OPTIONAL] Data retrieval options. |
---|
1656 | * |
---|
1657 | * @return arr |
---|
1658 | * Array containing retrieval success, LinkedIn response. |
---|
1659 | */ |
---|
1660 | public function profile($options = '~') { |
---|
1661 | // check passed data |
---|
1662 | if(!is_string($options)) { |
---|
1663 | // bad data passed |
---|
1664 | throw new LinkedInException('LinkedIn->profile(): bad data passed, $options must be of type string.'); |
---|
1665 | } |
---|
1666 | |
---|
1667 | // construct and send the request |
---|
1668 | $query = self::_URL_API . '/v1/people/' . trim($options); |
---|
1669 | $response = $this->fetch('GET', $query); |
---|
1670 | |
---|
1671 | /** |
---|
1672 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1673 | * per the documentation linked in method comments above. |
---|
1674 | */ |
---|
1675 | return $this->checkResponse(200, $response); |
---|
1676 | } |
---|
1677 | |
---|
1678 | /** |
---|
1679 | * Manual API call method, allowing for support for un-implemented API |
---|
1680 | * functionality to be supported. |
---|
1681 | * |
---|
1682 | * @param str $method |
---|
1683 | * The data communication method. |
---|
1684 | * @param str $url |
---|
1685 | * The Linkedin API endpoint to connect with - should NOT include the |
---|
1686 | * leading https://api.linkedin.com/v1. |
---|
1687 | * @param str $body |
---|
1688 | * [OPTIONAL] The URL-encoded body data to send to LinkedIn with the request. |
---|
1689 | * |
---|
1690 | * @return arr |
---|
1691 | * Array containing retrieval information, LinkedIn response. Note that you |
---|
1692 | * must manually check the return code and compare this to the expected |
---|
1693 | * API response to determine if the raw call was successful. |
---|
1694 | */ |
---|
1695 | public function raw($method, $url, $body = NULL) { |
---|
1696 | if(!is_string($method)) { |
---|
1697 | // bad data passed |
---|
1698 | throw new LinkedInException('LinkedIn->raw(): bad data passed, $method must be of string value.'); |
---|
1699 | } |
---|
1700 | if(!is_string($url)) { |
---|
1701 | // bad data passed |
---|
1702 | throw new LinkedInException('LinkedIn->raw(): bad data passed, $url must be of string value.'); |
---|
1703 | } |
---|
1704 | if(!is_null($body) && !is_string($url)) { |
---|
1705 | // bad data passed |
---|
1706 | throw new LinkedInException('LinkedIn->raw(): bad data passed, $body must be of string value.'); |
---|
1707 | } |
---|
1708 | |
---|
1709 | // construct and send the request |
---|
1710 | $query = self::_URL_API . '/v1' . trim($url); |
---|
1711 | return $this->fetch($method, $query, $body); |
---|
1712 | } |
---|
1713 | |
---|
1714 | /** |
---|
1715 | * This removes the specified group from the group suggestions, per: |
---|
1716 | * |
---|
1717 | * http://developer.linkedin.com/documents/groups-api |
---|
1718 | * |
---|
1719 | * @param str $gid |
---|
1720 | * The group id. |
---|
1721 | * |
---|
1722 | * @return arr |
---|
1723 | * Array containing retrieval success, LinkedIn response. |
---|
1724 | */ |
---|
1725 | public function removeSuggestedGroup($gid) { |
---|
1726 | if(!is_string($gid)) { |
---|
1727 | throw new LinkedInException('LinkedIn->removeSuggestedGroup(): bad data passed, $gid must be of type string'); |
---|
1728 | } |
---|
1729 | |
---|
1730 | // construct and send the request |
---|
1731 | $query = self::_URL_API . '/v1/people/~/suggestions/groups/' .trim($gid); |
---|
1732 | $response = $this->fetch('DELETE', $query); |
---|
1733 | |
---|
1734 | /** |
---|
1735 | * Check for successful request (a 204 response from LinkedIn server) |
---|
1736 | * per the documentation linked in method comments above. |
---|
1737 | */ |
---|
1738 | return $this->checkResponse(204, $response); |
---|
1739 | } |
---|
1740 | |
---|
1741 | /** |
---|
1742 | * Renew a job. |
---|
1743 | * |
---|
1744 | * Calling this method causes the passed job to be renewed, per: |
---|
1745 | * |
---|
1746 | * http://developer.linkedin.com/docs/DOC-1154 |
---|
1747 | * |
---|
1748 | * @param str $jid |
---|
1749 | * Job ID you want to renew. |
---|
1750 | * @param str $cid |
---|
1751 | * Contract ID that covers the passed Job ID. |
---|
1752 | * |
---|
1753 | * @return arr |
---|
1754 | * Array containing retrieval success, LinkedIn response. |
---|
1755 | */ |
---|
1756 | public function renewJob($jid, $cid) { |
---|
1757 | // check passed data |
---|
1758 | if(!is_string($jid)) { |
---|
1759 | // bad data passed |
---|
1760 | throw new LinkedInException('LinkedIn->renewJob(): bad data passed, $jid must be of string value.'); |
---|
1761 | } |
---|
1762 | if(!is_string($cid)) { |
---|
1763 | // bad data passed |
---|
1764 | throw new LinkedInException('LinkedIn->renewJob(): bad data passed, $cid must be of string value.'); |
---|
1765 | } |
---|
1766 | |
---|
1767 | // construct the xml data |
---|
1768 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
1769 | <job> |
---|
1770 | <contract-id>' . trim($cid) . '</contract-id> |
---|
1771 | <renewal/> |
---|
1772 | </job>'; |
---|
1773 | |
---|
1774 | // construct and send the request |
---|
1775 | $query = self::_URL_API . '/v1/jobs/partner-job-id=' . trim($jid); |
---|
1776 | $response = $this->fetch('PUT', $query, $data); |
---|
1777 | |
---|
1778 | /** |
---|
1779 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1780 | * per the documentation linked in method comments above. |
---|
1781 | */ |
---|
1782 | return $this->checkResponse(200, $response); |
---|
1783 | } |
---|
1784 | |
---|
1785 | /** |
---|
1786 | * Access token retrieval. |
---|
1787 | * |
---|
1788 | * Request the user's access token from the Linkedin API. |
---|
1789 | * |
---|
1790 | * @param str $token |
---|
1791 | * The token returned from the user authorization stage. |
---|
1792 | * @param str $secret |
---|
1793 | * The secret returned from the request token stage. |
---|
1794 | * @param str $verifier |
---|
1795 | * The verification value from LinkedIn. |
---|
1796 | * |
---|
1797 | * @return arr |
---|
1798 | * The Linkedin OAuth/http response, in array format. |
---|
1799 | */ |
---|
1800 | public function retrieveTokenAccess($token, $secret, $verifier) { |
---|
1801 | // check passed data |
---|
1802 | if(!is_string($token) || !is_string($secret) || !is_string($verifier)) { |
---|
1803 | // nothing passed, raise an exception |
---|
1804 | throw new LinkedInException('LinkedIn->retrieveTokenAccess(): bad data passed, string type is required for $token, $secret and $verifier.'); |
---|
1805 | } |
---|
1806 | |
---|
1807 | // start retrieval process |
---|
1808 | $this->setToken(array('oauth_token' => $token, 'oauth_token_secret' => $secret)); |
---|
1809 | $parameters = array( |
---|
1810 | 'oauth_verifier' => $verifier |
---|
1811 | ); |
---|
1812 | $response = $this->fetch(self::_METHOD_TOKENS, self::_URL_ACCESS, NULL, $parameters); |
---|
1813 | parse_str($response['linkedin'], $response['linkedin']); |
---|
1814 | |
---|
1815 | /** |
---|
1816 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1817 | * per the documentation linked in method comments above. |
---|
1818 | */ |
---|
1819 | if($response['info']['http_code'] == 200) { |
---|
1820 | // tokens retrieved |
---|
1821 | $this->setToken($response['linkedin']); |
---|
1822 | |
---|
1823 | // set the response |
---|
1824 | $return_data = $response; |
---|
1825 | $return_data['success'] = TRUE; |
---|
1826 | } else { |
---|
1827 | // error getting the request tokens |
---|
1828 | $this->setToken(NULL); |
---|
1829 | |
---|
1830 | // set the response |
---|
1831 | $return_data = $response; |
---|
1832 | $return_data['error'] = 'HTTP response from LinkedIn end-point was not code 200'; |
---|
1833 | $return_data['success'] = FALSE; |
---|
1834 | } |
---|
1835 | return $return_data; |
---|
1836 | } |
---|
1837 | |
---|
1838 | /** |
---|
1839 | * Request token retrieval. |
---|
1840 | * |
---|
1841 | * Get the request token from the Linkedin API. |
---|
1842 | * |
---|
1843 | * @return arr |
---|
1844 | * The Linkedin OAuth/http response, in array format. |
---|
1845 | */ |
---|
1846 | public function retrieveTokenRequest() { |
---|
1847 | $parameters = array( |
---|
1848 | 'oauth_callback' => $this->getCallbackUrl() |
---|
1849 | ); |
---|
1850 | $response = $this->fetch(self::_METHOD_TOKENS, self::_URL_REQUEST, NULL, $parameters); |
---|
1851 | parse_str($response['linkedin'], $response['linkedin']); |
---|
1852 | |
---|
1853 | /** |
---|
1854 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1855 | * per the documentation linked in method comments above. |
---|
1856 | */ |
---|
1857 | if(($response['info']['http_code'] == 200) && (array_key_exists('oauth_callback_confirmed', $response['linkedin'])) && ($response['linkedin']['oauth_callback_confirmed'] == 'true')) { |
---|
1858 | // tokens retrieved |
---|
1859 | $this->setToken($response['linkedin']); |
---|
1860 | |
---|
1861 | // set the response |
---|
1862 | $return_data = $response; |
---|
1863 | $return_data['success'] = TRUE; |
---|
1864 | } else { |
---|
1865 | // error getting the request tokens |
---|
1866 | $this->setToken(NULL); |
---|
1867 | |
---|
1868 | // set the response |
---|
1869 | $return_data = $response; |
---|
1870 | if((array_key_exists('oauth_callback_confirmed', $response['linkedin'])) && ($response['linkedin']['oauth_callback_confirmed'] == 'true')) { |
---|
1871 | $return_data['error'] = 'HTTP response from LinkedIn end-point was not code 200'; |
---|
1872 | } else { |
---|
1873 | $return_data['error'] = 'OAuth callback URL was not confirmed by the LinkedIn end-point'; |
---|
1874 | } |
---|
1875 | $return_data['success'] = FALSE; |
---|
1876 | } |
---|
1877 | return $return_data; |
---|
1878 | } |
---|
1879 | |
---|
1880 | /** |
---|
1881 | * User authorization revocation. |
---|
1882 | * |
---|
1883 | * Revoke the current user's access token, clear the access token's from |
---|
1884 | * current LinkedIn object. The current documentation for this feature is |
---|
1885 | * found in a blog entry from April 29th, 2010: |
---|
1886 | * |
---|
1887 | * http://developer.linkedin.com/community/apis/blog/2010/04/29/oauth--now-for-authentication |
---|
1888 | * |
---|
1889 | * @return arr |
---|
1890 | * Array containing retrieval success, LinkedIn response. |
---|
1891 | */ |
---|
1892 | public function revoke() { |
---|
1893 | // construct and send the request |
---|
1894 | $response = $this->fetch('GET', self::_URL_REVOKE); |
---|
1895 | |
---|
1896 | /** |
---|
1897 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1898 | * per the documentation linked in method comments above. |
---|
1899 | */ |
---|
1900 | return $this->checkResponse(200, $response); |
---|
1901 | } |
---|
1902 | |
---|
1903 | /** |
---|
1904 | * [DEPRECATED] General people search function. |
---|
1905 | * |
---|
1906 | * Takes a string of parameters as input and requests profile data from the |
---|
1907 | * Linkedin People Search API. See the official documentation for $options |
---|
1908 | * querystring formatting: |
---|
1909 | * |
---|
1910 | * http://developer.linkedin.com/docs/DOC-1191 |
---|
1911 | * |
---|
1912 | * @param str $options |
---|
1913 | * [OPTIONAL] Data retrieval options. |
---|
1914 | * |
---|
1915 | * @return arr |
---|
1916 | * Array containing retrieval success, LinkedIn response. |
---|
1917 | */ |
---|
1918 | public function search($options = NULL) { |
---|
1919 | return searchPeople($options); |
---|
1920 | } |
---|
1921 | |
---|
1922 | /** |
---|
1923 | * Company search. |
---|
1924 | * |
---|
1925 | * Uses the Company Search API to find companies using keywords, industry, |
---|
1926 | * location, or some other criteria. It returns a collection of matching |
---|
1927 | * companies. |
---|
1928 | * |
---|
1929 | * http://developer.linkedin.com/docs/DOC-1325 |
---|
1930 | * |
---|
1931 | * @param str $options |
---|
1932 | * [OPTIONAL] Search options. |
---|
1933 | * @return arr |
---|
1934 | * Array containing retrieval success, LinkedIn response. |
---|
1935 | */ |
---|
1936 | public function searchCompanies($options = '') { |
---|
1937 | // check passed data |
---|
1938 | if(!is_string($options)) { |
---|
1939 | // bad data passed |
---|
1940 | throw new LinkedInException('LinkedIn->searchCompanies(): bad data passed, $options must be of type string.'); |
---|
1941 | } |
---|
1942 | |
---|
1943 | // construct and send the request |
---|
1944 | $query = self::_URL_API . '/v1/company-search' . trim($options); |
---|
1945 | $response = $this->fetch('GET', $query); |
---|
1946 | |
---|
1947 | /** |
---|
1948 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1949 | * per the documentation linked in method comments above. |
---|
1950 | */ |
---|
1951 | return $this->checkResponse(200, $response); |
---|
1952 | } |
---|
1953 | |
---|
1954 | /** |
---|
1955 | * Jobs search. |
---|
1956 | * |
---|
1957 | * Use the Job Search API to find jobs using keywords, company, location, |
---|
1958 | * or some other criteria. It returns a collection of matching jobs. Each |
---|
1959 | * entry can contain much of the information available on the job listing. |
---|
1960 | * |
---|
1961 | * http://developer.linkedin.com/docs/DOC-1321 |
---|
1962 | * |
---|
1963 | * @param str $options |
---|
1964 | * [OPTIONAL] Data retrieval options. |
---|
1965 | * |
---|
1966 | * @return arr |
---|
1967 | * Array containing retrieval success, LinkedIn response. |
---|
1968 | */ |
---|
1969 | public function searchJobs($options = '') { |
---|
1970 | // check passed data |
---|
1971 | if(!is_string($options)) { |
---|
1972 | // bad data passed |
---|
1973 | throw new LinkedInException('LinkedIn->jobsSearch(): bad data passed, $options must be of type string.'); |
---|
1974 | } |
---|
1975 | |
---|
1976 | // construct and send the request |
---|
1977 | $query = self::_URL_API . '/v1/job-search' . trim($options); |
---|
1978 | $response = $this->fetch('GET', $query); |
---|
1979 | |
---|
1980 | /** |
---|
1981 | * Check for successful request (a 200 response from LinkedIn server) |
---|
1982 | * per the documentation linked in method comments above. |
---|
1983 | */ |
---|
1984 | return $this->checkResponse(200, $response); |
---|
1985 | } |
---|
1986 | |
---|
1987 | /** |
---|
1988 | * General people search function. |
---|
1989 | * |
---|
1990 | * Takes a string of parameters as input and requests profile data from the |
---|
1991 | * Linkedin People Search API. See the official documentation for $options |
---|
1992 | * querystring formatting: |
---|
1993 | * |
---|
1994 | * http://developer.linkedin.com/docs/DOC-1191 |
---|
1995 | * |
---|
1996 | * @param str $options |
---|
1997 | * [OPTIONAL] Data retrieval options. |
---|
1998 | * |
---|
1999 | * @return arr |
---|
2000 | * Array containing retrieval success, LinkedIn response. |
---|
2001 | */ |
---|
2002 | public function searchPeople($options = NULL) { |
---|
2003 | // check passed data |
---|
2004 | if(!is_null($options) && !is_string($options)) { |
---|
2005 | // bad data passed |
---|
2006 | throw new LinkedInException('LinkedIn->search(): bad data passed, $options must be of type string.'); |
---|
2007 | } |
---|
2008 | |
---|
2009 | // construct and send the request |
---|
2010 | $query = self::_URL_API . '/v1/people-search' . trim($options); |
---|
2011 | $response = $this->fetch('GET', $query); |
---|
2012 | |
---|
2013 | /** |
---|
2014 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2015 | * per the documentation linked in method comments above. |
---|
2016 | */ |
---|
2017 | return $this->checkResponse(200, $response); |
---|
2018 | } |
---|
2019 | |
---|
2020 | /** |
---|
2021 | * Set the application_key property. |
---|
2022 | * |
---|
2023 | * @param str $key |
---|
2024 | * The application key. |
---|
2025 | */ |
---|
2026 | public function setApplicationKey($key) { |
---|
2027 | $this->application_key = $key; |
---|
2028 | } |
---|
2029 | |
---|
2030 | /** |
---|
2031 | * Set the application_secret property. |
---|
2032 | * |
---|
2033 | * @param str $secret |
---|
2034 | * The application secret. |
---|
2035 | */ |
---|
2036 | public function setApplicationSecret($secret) { |
---|
2037 | $this->application_secret = $secret; |
---|
2038 | } |
---|
2039 | |
---|
2040 | /** |
---|
2041 | * Set the callback property. |
---|
2042 | * |
---|
2043 | * @param str $url |
---|
2044 | * The callback url. |
---|
2045 | */ |
---|
2046 | public function setCallbackUrl($url) { |
---|
2047 | $this->callback = $url; |
---|
2048 | } |
---|
2049 | |
---|
2050 | /** |
---|
2051 | * This sets the group settings of the specified group. |
---|
2052 | * |
---|
2053 | * http://developer.linkedin.com/documents/groups-api |
---|
2054 | * |
---|
2055 | * @param str $gid |
---|
2056 | * The group id. |
---|
2057 | * @param str $xml |
---|
2058 | * The group settings to set. The settings are: |
---|
2059 | * -<show-group-logo-in-profle> |
---|
2060 | * -<contact-email> |
---|
2061 | * -<email-digest-frequency> |
---|
2062 | * -<email-annoucements-from-managers> |
---|
2063 | * -<allow-messages-from-members> |
---|
2064 | * -<email-for-every-new-post> |
---|
2065 | * |
---|
2066 | * @return arr |
---|
2067 | * Array containing retrieval success, LinkedIn response. |
---|
2068 | */ |
---|
2069 | public function setGroupSettings($gid, $xml) { |
---|
2070 | if(!is_string ($gid)) { |
---|
2071 | throw new LinkedInException('LinkedIn->setGroupSettings(): bad data passed, $token_access should be in array format.'); |
---|
2072 | } |
---|
2073 | if(!is_string ($xml)) { |
---|
2074 | throw new LinkedInException('LinkedIn->setGroupSettings(): bad data passed, $token_access should be in array format.'); |
---|
2075 | } |
---|
2076 | |
---|
2077 | // construct and send the request |
---|
2078 | $query = self::_URL_API . '/v1/people/~/group-memberships/' . trim($gid); |
---|
2079 | $response = $this->fetch('PUT', $query, $xml); |
---|
2080 | |
---|
2081 | /** |
---|
2082 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2083 | * per the documentation linked in method comments above. |
---|
2084 | */ |
---|
2085 | return $this->checkResponse(200, $response); |
---|
2086 | } |
---|
2087 | |
---|
2088 | /** |
---|
2089 | * Set the response_format property. |
---|
2090 | * |
---|
2091 | * @param str $format |
---|
2092 | * [OPTIONAL] The response format to specify to LinkedIn. |
---|
2093 | */ |
---|
2094 | public function setResponseFormat($format = self::_DEFAULT_RESPONSE_FORMAT) { |
---|
2095 | $this->response_format = $format; |
---|
2096 | } |
---|
2097 | |
---|
2098 | /** |
---|
2099 | * Set the token property. |
---|
2100 | * |
---|
2101 | * @return arr $token |
---|
2102 | * The LinkedIn OAuth token. |
---|
2103 | */ |
---|
2104 | public function setToken($token) { |
---|
2105 | // check passed data |
---|
2106 | if(!is_null($token) && !is_array($token)) { |
---|
2107 | // bad data passed |
---|
2108 | throw new LinkedInException('LinkedIn->setToken(): bad data passed, $token_access should be in array format.'); |
---|
2109 | } |
---|
2110 | |
---|
2111 | // set token |
---|
2112 | $this->token = $token; |
---|
2113 | } |
---|
2114 | |
---|
2115 | /** |
---|
2116 | * [DEPRECATED] Set the token_access property. |
---|
2117 | * |
---|
2118 | * @return arr $token_access |
---|
2119 | * [OPTIONAL] The LinkedIn OAuth access token. |
---|
2120 | */ |
---|
2121 | public function setTokenAccess($token_access) { |
---|
2122 | $this->setToken($token_access); |
---|
2123 | } |
---|
2124 | |
---|
2125 | /** |
---|
2126 | * Post a share. |
---|
2127 | * |
---|
2128 | * Create a new or reshare another user's shared content. Full details from |
---|
2129 | * LinkedIn on this functionality can be found here: |
---|
2130 | * |
---|
2131 | * http://developer.linkedin.com/docs/DOC-1212 |
---|
2132 | * |
---|
2133 | * $action values: ('new', 'reshare') |
---|
2134 | * $content format: |
---|
2135 | * $action = 'new'; $content => ('comment' => 'xxx', 'title' => 'xxx', 'submitted-url' => 'xxx', 'submitted-image-url' => 'xxx', 'description' => 'xxx') |
---|
2136 | * $action = 'reshare'; $content => ('comment' => 'xxx', 'id' => 'xxx') |
---|
2137 | * |
---|
2138 | * @param str $action |
---|
2139 | * The sharing action to perform. |
---|
2140 | * @param str $content |
---|
2141 | * The share content. |
---|
2142 | * @param bool $private |
---|
2143 | * [OPTIONAL] Should we restrict this shared item to connections only? |
---|
2144 | * @param bool $twitter |
---|
2145 | * [OPTIONAL] Also update the teathered Twitter account. |
---|
2146 | * |
---|
2147 | * @return arr |
---|
2148 | * Array containing retrieval success, LinkedIn response. |
---|
2149 | */ |
---|
2150 | public function share($action, $content, $private = TRUE, $twitter = FALSE) { |
---|
2151 | // check the status itself |
---|
2152 | if(!empty($action) && !empty($content)) { |
---|
2153 | /** |
---|
2154 | * Status is not empty, wrap a cleaned version of it in xml. Status |
---|
2155 | * rules: |
---|
2156 | * |
---|
2157 | * 1) Comments are 700 chars max (if this changes, change _SHARE_COMMENT_LENGTH constant) |
---|
2158 | * 2) Content/title 200 chars max (if this changes, change _SHARE_CONTENT_TITLE_LENGTH constant) |
---|
2159 | * 3) Content/description 400 chars max (if this changes, change _SHARE_CONTENT_DESC_LENGTH constant) |
---|
2160 | * 4a) New shares must contain a comment and/or (content/title and content/submitted-url) |
---|
2161 | * 4b) Reshared content must contain an attribution id. |
---|
2162 | * 4c) Reshared content must contain actual content, not just a comment. |
---|
2163 | * 5) No HTML permitted in comment, content/title, content/description. |
---|
2164 | */ |
---|
2165 | |
---|
2166 | // prepare the share data per the rules above |
---|
2167 | $share_flag = FALSE; |
---|
2168 | $content_xml = NULL; |
---|
2169 | switch($action) { |
---|
2170 | case 'new': |
---|
2171 | // share can be an article |
---|
2172 | if(array_key_exists('title', $content) && array_key_exists('submitted-url', $content)) { |
---|
2173 | // we have shared content, format it as needed per rules above |
---|
2174 | $content_title = trim(htmlspecialchars(strip_tags(stripslashes($content['title'])))); |
---|
2175 | if(strlen($content_title) > self::_SHARE_CONTENT_TITLE_LENGTH) { |
---|
2176 | throw new LinkedInException('LinkedIn->share(): title length is too long - max length is ' . self::_SHARE_CONTENT_TITLE_LENGTH . ' characters.'); |
---|
2177 | } |
---|
2178 | $content_xml .= '<content> |
---|
2179 | <title>' . $content_title . '</title> |
---|
2180 | <submitted-url>' . trim(htmlspecialchars($content['submitted-url'])) . '</submitted-url>'; |
---|
2181 | if(array_key_exists('submitted-image-url', $content)) { |
---|
2182 | $content_xml .= '<submitted-image-url>' . trim(htmlspecialchars($content['submitted-image-url'])) . '</submitted-image-url>'; |
---|
2183 | } |
---|
2184 | if(array_key_exists('description', $content)) { |
---|
2185 | $content_desc = trim(htmlspecialchars(strip_tags(stripslashes($content['description'])))); |
---|
2186 | if(strlen($content_desc) > self::_SHARE_CONTENT_DESC_LENGTH) { |
---|
2187 | throw new LinkedInException('LinkedIn->share(): description length is too long - max length is ' . self::_SHARE_CONTENT_DESC_LENGTH . ' characters.'); |
---|
2188 | } |
---|
2189 | $content_xml .= '<description>' . $content_desc . '</description>'; |
---|
2190 | } |
---|
2191 | $content_xml .= '</content>'; |
---|
2192 | |
---|
2193 | $share_flag = TRUE; |
---|
2194 | } |
---|
2195 | |
---|
2196 | // share can be just a comment |
---|
2197 | if(array_key_exists('comment', $content)) { |
---|
2198 | // comment located |
---|
2199 | $comment = htmlspecialchars(trim(strip_tags(stripslashes($content['comment'])))); |
---|
2200 | if(strlen($comment) > self::_SHARE_COMMENT_LENGTH) { |
---|
2201 | throw new LinkedInException('LinkedIn->share(): comment length is too long - max length is ' . self::_SHARE_COMMENT_LENGTH . ' characters.'); |
---|
2202 | } |
---|
2203 | $content_xml .= '<comment>' . $comment . '</comment>'; |
---|
2204 | |
---|
2205 | $share_flag = TRUE; |
---|
2206 | } |
---|
2207 | break; |
---|
2208 | case 'reshare': |
---|
2209 | if(array_key_exists('id', $content)) { |
---|
2210 | // put together the re-share attribution XML |
---|
2211 | $content_xml .= '<attribution> |
---|
2212 | <share> |
---|
2213 | <id>' . trim($content['id']) . '</id> |
---|
2214 | </share> |
---|
2215 | </attribution>'; |
---|
2216 | |
---|
2217 | // optional additional comment |
---|
2218 | if(array_key_exists('comment', $content)) { |
---|
2219 | // comment located |
---|
2220 | $comment = htmlspecialchars(trim(strip_tags(stripslashes($content['comment'])))); |
---|
2221 | if(strlen($comment) > self::_SHARE_COMMENT_LENGTH) { |
---|
2222 | throw new LinkedInException('LinkedIn->share(): comment length is too long - max length is ' . self::_SHARE_COMMENT_LENGTH . ' characters.'); |
---|
2223 | } |
---|
2224 | $content_xml .= '<comment>' . $comment . '</comment>'; |
---|
2225 | } |
---|
2226 | |
---|
2227 | $share_flag = TRUE; |
---|
2228 | } |
---|
2229 | break; |
---|
2230 | default: |
---|
2231 | // bad action passed |
---|
2232 | throw new LinkedInException('LinkedIn->share(): share action is an invalid value, must be one of: share, reshare.'); |
---|
2233 | break; |
---|
2234 | } |
---|
2235 | |
---|
2236 | // should we proceed? |
---|
2237 | if($share_flag) { |
---|
2238 | // put all of the xml together |
---|
2239 | $visibility = ($private) ? 'connections-only' : 'anyone'; |
---|
2240 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
2241 | <share> |
---|
2242 | ' . $content_xml . ' |
---|
2243 | <visibility> |
---|
2244 | <code>' . $visibility . '</code> |
---|
2245 | </visibility> |
---|
2246 | </share>'; |
---|
2247 | |
---|
2248 | // create the proper url |
---|
2249 | $share_url = self::_URL_API . '/v1/people/~/shares'; |
---|
2250 | if($twitter) { |
---|
2251 | // update twitter as well |
---|
2252 | $share_url .= '?twitter-post=true'; |
---|
2253 | } |
---|
2254 | |
---|
2255 | // send request |
---|
2256 | $response = $this->fetch('POST', $share_url, $data); |
---|
2257 | } else { |
---|
2258 | // data contraints/rules not met, raise an exception |
---|
2259 | throw new LinkedInException('LinkedIn->share(): sharing data constraints not met; check that you have supplied valid content and combinations of content to share.'); |
---|
2260 | } |
---|
2261 | } else { |
---|
2262 | // data missing, raise an exception |
---|
2263 | throw new LinkedInException('LinkedIn->share(): sharing action or shared content is missing.'); |
---|
2264 | } |
---|
2265 | |
---|
2266 | /** |
---|
2267 | * Check for successful request (a 201 response from LinkedIn server) |
---|
2268 | * per the documentation linked in method comments above. |
---|
2269 | */ |
---|
2270 | return $this->checkResponse(201, $response); |
---|
2271 | } |
---|
2272 | |
---|
2273 | /** |
---|
2274 | * Network statistics. |
---|
2275 | * |
---|
2276 | * General network statistics retrieval function, returns the number of connections, |
---|
2277 | * second-connections an authenticated user has. More information here: |
---|
2278 | * |
---|
2279 | * http://developer.linkedin.com/docs/DOC-1006 |
---|
2280 | * |
---|
2281 | * @return arr |
---|
2282 | * Array containing retrieval success, LinkedIn response. |
---|
2283 | */ |
---|
2284 | public function statistics() { |
---|
2285 | // construct and send the request |
---|
2286 | $query = self::_URL_API . '/v1/people/~/network/network-stats'; |
---|
2287 | $response = $this->fetch('GET', $query); |
---|
2288 | |
---|
2289 | /** |
---|
2290 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2291 | * per the documentation linked in method comments above. |
---|
2292 | */ |
---|
2293 | return $this->checkResponse(200, $response); |
---|
2294 | } |
---|
2295 | |
---|
2296 | /** |
---|
2297 | * Companies you may want to follow. |
---|
2298 | * |
---|
2299 | * Returns a list of companies the current user may want to follow, per: |
---|
2300 | * |
---|
2301 | * http://developer.linkedin.com/docs/DOC-1324 |
---|
2302 | * |
---|
2303 | * @return arr |
---|
2304 | * Array containing retrieval success, LinkedIn response. |
---|
2305 | */ |
---|
2306 | public function suggestedCompanies() { |
---|
2307 | // construct and send the request |
---|
2308 | $query = self::_URL_API . '/v1/people/~/suggestions/to-follow/companies'; |
---|
2309 | $response = $this->fetch('GET', $query); |
---|
2310 | |
---|
2311 | /** |
---|
2312 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2313 | * per the documentation linked in method comments above. |
---|
2314 | */ |
---|
2315 | return $this->checkResponse(200, $response); |
---|
2316 | } |
---|
2317 | |
---|
2318 | /** |
---|
2319 | * Retrieves suggested groups for the user, per: |
---|
2320 | * |
---|
2321 | * http://developer.linkedin.com/documents/groups-api |
---|
2322 | * |
---|
2323 | * @return arr |
---|
2324 | * Array containing retrieval success, LinkedIn response. |
---|
2325 | */ |
---|
2326 | public function suggestedGroups() { |
---|
2327 | // construct and send the request |
---|
2328 | $query = self::_URL_API . '/v1/people/~/suggestions/groups:(id,name,is-open-to-non-members)'; |
---|
2329 | $response = $this->fetch('GET', $query); |
---|
2330 | |
---|
2331 | /** |
---|
2332 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2333 | * per the documentation linked in method comments above. |
---|
2334 | */ |
---|
2335 | return $this->checkResponse (200, $response); |
---|
2336 | } |
---|
2337 | |
---|
2338 | /** |
---|
2339 | * Jobs you may be interested in. |
---|
2340 | * |
---|
2341 | * Returns a list of jobs the current user may be interested in, per: |
---|
2342 | * |
---|
2343 | * http://developer.linkedin.com/docs/DOC-1323 |
---|
2344 | * |
---|
2345 | * @param str $options |
---|
2346 | * [OPTIONAL] Data retrieval options. |
---|
2347 | * |
---|
2348 | * @return arr |
---|
2349 | * Array containing retrieval success, LinkedIn response. |
---|
2350 | */ |
---|
2351 | public function suggestedJobs($options = ':(jobs)') { |
---|
2352 | // check passed data |
---|
2353 | if(!is_string($options)) { |
---|
2354 | // bad data passed |
---|
2355 | throw new LinkedInException('LinkedIn->suggestedJobs(): bad data passed, $options must be of type string.'); |
---|
2356 | } |
---|
2357 | |
---|
2358 | // construct and send the request |
---|
2359 | $query = self::_URL_API . '/v1/people/~/suggestions/job-suggestions' . trim($options); |
---|
2360 | $response = $this->fetch('GET', $query); |
---|
2361 | |
---|
2362 | /** |
---|
2363 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2364 | * per the documentation linked in method comments above. |
---|
2365 | */ |
---|
2366 | return $this->checkResponse(200, $response); |
---|
2367 | } |
---|
2368 | |
---|
2369 | /** |
---|
2370 | * Unbookmark a job. |
---|
2371 | * |
---|
2372 | * Calling this method causes the current user to remove a bookmark for the |
---|
2373 | * specified job: |
---|
2374 | * |
---|
2375 | * http://developer.linkedin.com/docs/DOC-1323 |
---|
2376 | * |
---|
2377 | * @param str $jid |
---|
2378 | * Job ID you want to unbookmark. |
---|
2379 | * |
---|
2380 | * @return arr |
---|
2381 | * Array containing retrieval success, LinkedIn response. |
---|
2382 | */ |
---|
2383 | public function unbookmarkJob($jid) { |
---|
2384 | // check passed data |
---|
2385 | if(!is_string($jid)) { |
---|
2386 | // bad data passed |
---|
2387 | throw new LinkedInException('LinkedIn->unbookmarkJob(): bad data passed, $jid must be of type string.'); |
---|
2388 | } |
---|
2389 | |
---|
2390 | // construct and send the request |
---|
2391 | $query = self::_URL_API . '/v1/people/~/job-bookmarks/' . trim($jid); |
---|
2392 | $response = $this->fetch('DELETE', $query); |
---|
2393 | |
---|
2394 | /** |
---|
2395 | * Check for successful request (a 204 response from LinkedIn server) |
---|
2396 | * per the documentation linked in method comments above. |
---|
2397 | */ |
---|
2398 | return $this->checkResponse(204, $response); |
---|
2399 | } |
---|
2400 | |
---|
2401 | /** |
---|
2402 | * Unfollow a company. |
---|
2403 | * |
---|
2404 | * Calling this method causes the current user to stop following the specified |
---|
2405 | * company, per: |
---|
2406 | * |
---|
2407 | * http://developer.linkedin.com/docs/DOC-1324 |
---|
2408 | * |
---|
2409 | * @param str $cid |
---|
2410 | * Company ID you want to unfollow. |
---|
2411 | * |
---|
2412 | * @return arr |
---|
2413 | * Array containing retrieval success, LinkedIn response. |
---|
2414 | */ |
---|
2415 | public function unfollowCompany($cid) { |
---|
2416 | // check passed data |
---|
2417 | if(!is_string($cid)) { |
---|
2418 | // bad data passed |
---|
2419 | throw new LinkedInException('LinkedIn->unfollowCompany(): bad data passed, $cid must be of string value.'); |
---|
2420 | } |
---|
2421 | |
---|
2422 | // construct and send the request |
---|
2423 | $query = self::_URL_API . '/v1/people/~/following/companies/id=' . trim($cid); |
---|
2424 | $response = $this->fetch('DELETE', $query); |
---|
2425 | |
---|
2426 | /** |
---|
2427 | * Check for successful request (a 204 response from LinkedIn server) |
---|
2428 | * per the documentation linked in method comments above. |
---|
2429 | */ |
---|
2430 | return $this->checkResponse(204, $response); |
---|
2431 | } |
---|
2432 | |
---|
2433 | /** |
---|
2434 | * Unlike a network update. |
---|
2435 | * |
---|
2436 | * Unlike another user's network update: |
---|
2437 | * |
---|
2438 | * http://developer.linkedin.com/docs/DOC-1043 |
---|
2439 | * |
---|
2440 | * @param str $uid |
---|
2441 | * The LinkedIn update ID. |
---|
2442 | * |
---|
2443 | * @return arr |
---|
2444 | * Array containing retrieval success, LinkedIn response. |
---|
2445 | */ |
---|
2446 | public function unlike($uid) { |
---|
2447 | // check passed data |
---|
2448 | if(!is_string($uid)) { |
---|
2449 | // bad data passed |
---|
2450 | throw new LinkedInException('LinkedIn->unlike(): bad data passed, $uid must be of type string.'); |
---|
2451 | } |
---|
2452 | |
---|
2453 | // construct the xml data |
---|
2454 | $data = '<?xml version="1.0" encoding="UTF-8"?> |
---|
2455 | <is-liked>false</is-liked>'; |
---|
2456 | |
---|
2457 | // send request |
---|
2458 | $query = self::_URL_API . '/v1/people/~/network/updates/key=' . $uid . '/is-liked'; |
---|
2459 | $response = $this->fetch('PUT', $query, $data); |
---|
2460 | |
---|
2461 | /** |
---|
2462 | * Check for successful request (a 201 response from LinkedIn server) |
---|
2463 | * per the documentation linked in method comments above. |
---|
2464 | */ |
---|
2465 | return $this->checkResponse(201, $response); |
---|
2466 | } |
---|
2467 | |
---|
2468 | /** |
---|
2469 | * Post network update. |
---|
2470 | * |
---|
2471 | * Update the user's Linkedin network status. Full details from LinkedIn |
---|
2472 | * on this functionality can be found here: |
---|
2473 | * |
---|
2474 | * http://developer.linkedin.com/docs/DOC-1009 |
---|
2475 | * http://developer.linkedin.com/docs/DOC-1009#comment-1077 |
---|
2476 | * |
---|
2477 | * @param str $update |
---|
2478 | * The network update. |
---|
2479 | * |
---|
2480 | * @return arr |
---|
2481 | * Array containing retrieval success, LinkedIn response. |
---|
2482 | */ |
---|
2483 | public function updateNetwork($update) { |
---|
2484 | // check passed data |
---|
2485 | if(!is_string($update)) { |
---|
2486 | // nothing/non-string passed, raise an exception |
---|
2487 | throw new LinkedInException('LinkedIn->updateNetwork(): bad data passed, $update must be a non-zero length string.'); |
---|
2488 | } |
---|
2489 | |
---|
2490 | /** |
---|
2491 | * Network update is not empty, wrap a cleaned version of it in xml. |
---|
2492 | * Network update rules: |
---|
2493 | * |
---|
2494 | * 1) No HTML permitted except those found in _NETWORK_HTML constant |
---|
2495 | * 2) Update cannot be longer than 140 characters. |
---|
2496 | */ |
---|
2497 | // get the user data |
---|
2498 | $response = self::profile('~:(first-name,last-name,site-standard-profile-request)'); |
---|
2499 | if($response['success'] === TRUE) { |
---|
2500 | /** |
---|
2501 | * We are converting response to usable data. I'd use SimpleXML here, but |
---|
2502 | * to keep the class self-contained, we will use a portable XML parsing |
---|
2503 | * routine, self::xmlToArray. |
---|
2504 | */ |
---|
2505 | $person = self::xmlToArray($response['linkedin']); |
---|
2506 | if($person === FALSE) { |
---|
2507 | // bad xml data |
---|
2508 | throw new LinkedInException('LinkedIn->updateNetwork(): LinkedIn returned bad XML data.'); |
---|
2509 | } |
---|
2510 | $fields = $person['person']['children']; |
---|
2511 | |
---|
2512 | // prepare user data |
---|
2513 | $first_name = trim($fields['first-name']['content']); |
---|
2514 | $last_name = trim($fields['last-name']['content']); |
---|
2515 | $profile_url = trim($fields['site-standard-profile-request']['children']['url']['content']); |
---|
2516 | |
---|
2517 | // create the network update |
---|
2518 | $update = trim(htmlspecialchars(strip_tags($update, self::_NETWORK_HTML))); |
---|
2519 | if(strlen($update) > self::_NETWORK_LENGTH) { |
---|
2520 | throw new LinkedInException('LinkedIn->share(): update length is too long - max length is ' . self::_NETWORK_LENGTH . ' characters.'); |
---|
2521 | } |
---|
2522 | $user = htmlspecialchars('<a href="' . $profile_url . '">' . $first_name . ' ' . $last_name . '</a>'); |
---|
2523 | $data = '<activity locale="en_US"> |
---|
2524 | <content-type>linkedin-html</content-type> |
---|
2525 | <body>' . $user . ' ' . $update . '</body> |
---|
2526 | </activity>'; |
---|
2527 | |
---|
2528 | // send request |
---|
2529 | $query = self::_URL_API . '/v1/people/~/person-activities'; |
---|
2530 | $response = $this->fetch('POST', $query, $data); |
---|
2531 | |
---|
2532 | /** |
---|
2533 | * Check for successful request (a 201 response from LinkedIn server) |
---|
2534 | * per the documentation linked in method comments above. |
---|
2535 | */ |
---|
2536 | return $this->checkResponse(201, $response); |
---|
2537 | } else { |
---|
2538 | // profile retrieval failed |
---|
2539 | throw new LinkedInException('LinkedIn->updateNetwork(): profile data could not be retrieved.'); |
---|
2540 | } |
---|
2541 | } |
---|
2542 | |
---|
2543 | /** |
---|
2544 | * General network update retrieval function. |
---|
2545 | * |
---|
2546 | * Takes a string of parameters as input and requests update-related data |
---|
2547 | * from the Linkedin Network Updates API. See the official documentation for |
---|
2548 | * $options parameter formatting: |
---|
2549 | * |
---|
2550 | * http://developer.linkedin.com/docs/DOC-1006 |
---|
2551 | * |
---|
2552 | * For getting more comments, likes, etc, see here: |
---|
2553 | * |
---|
2554 | * http://developer.linkedin.com/docs/DOC-1043 |
---|
2555 | * |
---|
2556 | * @param str $options |
---|
2557 | * [OPTIONAL] Data retrieval options. |
---|
2558 | * @param str $id |
---|
2559 | * [OPTIONAL] The LinkedIn ID to restrict the updates for. |
---|
2560 | * |
---|
2561 | * @return arr |
---|
2562 | * Array containing retrieval success, LinkedIn response. |
---|
2563 | */ |
---|
2564 | public function updates($options = NULL, $id = NULL) { |
---|
2565 | // check passed data |
---|
2566 | if(!is_null($options) && !is_string($options)) { |
---|
2567 | // bad data passed |
---|
2568 | throw new LinkedInException('LinkedIn->updates(): bad data passed, $options must be of type string.'); |
---|
2569 | } |
---|
2570 | if(!is_null($id) && !is_string($id)) { |
---|
2571 | // bad data passed |
---|
2572 | throw new LinkedInException('LinkedIn->updates(): bad data passed, $id must be of type string.'); |
---|
2573 | } |
---|
2574 | |
---|
2575 | // construct and send the request |
---|
2576 | if(!is_null($id) && self::isId($id)) { |
---|
2577 | $query = self::_URL_API . '/v1/people/' . $id . '/network/updates' . trim($options); |
---|
2578 | } else { |
---|
2579 | $query = self::_URL_API . '/v1/people/~/network/updates' . trim($options); |
---|
2580 | } |
---|
2581 | $response = $this->fetch('GET', $query); |
---|
2582 | |
---|
2583 | /** |
---|
2584 | * Check for successful request (a 200 response from LinkedIn server) |
---|
2585 | * per the documentation linked in method comments above. |
---|
2586 | */ |
---|
2587 | return $this->checkResponse(200, $response); |
---|
2588 | } |
---|
2589 | |
---|
2590 | /** |
---|
2591 | * Converts passed XML data to an array. |
---|
2592 | * |
---|
2593 | * @param str $xml |
---|
2594 | * The XML to convert to an array. |
---|
2595 | * |
---|
2596 | * @return arr |
---|
2597 | * Array containing the XML data. |
---|
2598 | * @return bool |
---|
2599 | * FALSE if passed data cannot be parsed to an array. |
---|
2600 | */ |
---|
2601 | public static function xmlToArray($xml) { |
---|
2602 | // check passed data |
---|
2603 | if(!is_string($xml)) { |
---|
2604 | // bad data possed |
---|
2605 | throw new LinkedInException('LinkedIn->xmlToArray(): bad data passed, $xml must be a non-zero length string.'); |
---|
2606 | } |
---|
2607 | |
---|
2608 | $parser = xml_parser_create(); |
---|
2609 | xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); |
---|
2610 | xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); |
---|
2611 | if(xml_parse_into_struct($parser, $xml, $tags)) { |
---|
2612 | $elements = array(); |
---|
2613 | $stack = array(); |
---|
2614 | foreach($tags as $tag) { |
---|
2615 | $index = count($elements); |
---|
2616 | if($tag['type'] == 'complete' || $tag['type'] == 'open') { |
---|
2617 | $elements[$tag['tag']] = array(); |
---|
2618 | $elements[$tag['tag']]['attributes'] = (array_key_exists('attributes', $tag)) ? $tag['attributes'] : NULL; |
---|
2619 | $elements[$tag['tag']]['content'] = (array_key_exists('value', $tag)) ? $tag['value'] : NULL; |
---|
2620 | if($tag['type'] == 'open') { |
---|
2621 | $elements[$tag['tag']]['children'] = array(); |
---|
2622 | $stack[count($stack)] = &$elements; |
---|
2623 | $elements = &$elements[$tag['tag']]['children']; |
---|
2624 | } |
---|
2625 | } |
---|
2626 | if($tag['type'] == 'close') { |
---|
2627 | $elements = &$stack[count($stack) - 1]; |
---|
2628 | unset($stack[count($stack) - 1]); |
---|
2629 | } |
---|
2630 | } |
---|
2631 | $return_data = $elements; |
---|
2632 | } else { |
---|
2633 | // not valid xml data |
---|
2634 | $return_data = FALSE; |
---|
2635 | } |
---|
2636 | xml_parser_free($parser); |
---|
2637 | return $return_data; |
---|
2638 | } |
---|
2639 | } |
---|