View source
<?php
function linkedin_access_token($account) {
if ($account->uid < 1) {
$anon = TRUE;
$back = 'login';
}
else {
$anon = FALSE;
$back = 'token';
}
$base_url = "https://api.linkedin.com/uas/oauth";
$signature = new OAuthSignatureMethod_HMAC_SHA1();
$consumer_key = variable_get('linkedin_consumer_key', '');
$consumer_secret = variable_get('linkedin_consumer_secret', '');
$consumer = new OAuthConsumer($consumer_key, $consumer_secret, NULL);
$random = md5(rand());
$callback = url('linkedin/' . $back . '/' . $account->uid, array(
'absolute' => TRUE,
)) . '&action=' . $random;
if (!isset($_GET['action']) || $_GET['action'] != $_SESSION['random']) {
$_SESSION['random'] = $random;
$url = $base_url . "/requestToken";
$request = OAuthRequest::from_consumer_and_token($consumer, NULL, 'POST', $url);
$request
->set_parameter("oauth_callback", $callback);
$request
->sign_request($signature, $consumer, NULL);
$header = $request
->to_header();
$response = _linkedin_http_request($url, $header, 'token_request');
parse_str($response, $oauth);
if ($oauth['oauth_problem']) {
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message(t('LinkedIn debug : received error response : @error'), array(
'@error' => $oauth['oauth_problem'],
), 'warning');
}
else {
drupal_set_message(t('There was a problem with the configuration of LinkedIn on this website. Please try again later.'), 'error');
}
watchdog('linkedin', t('Linkedin reported the following response : @error'), array(
'@error' => $oauth['oauth_problem'],
), WATCHDOG_ERROR);
drupal_goto();
}
if ($oauth['oauth_token']) {
if (!$anon) {
db_query("DELETE FROM {linkedin_token} WHERE uid = %d", $account->uid);
$sql = array(
'uid' => $account->uid,
'token_key' => $oauth['oauth_token'],
'token_secret' => $oauth['oauth_token_secret'],
'type' => 'request',
);
drupal_write_record('linkedin_token', $sql);
drupal_goto($base_url . '/authorize?oauth_token=' . $oauth['oauth_token']);
}
else {
$_SESSION['oauth_token_secret'] = $oauth['oauth_token_secret'];
drupal_goto($base_url . '/authenticate?oauth_token=' . $oauth['oauth_token']);
}
}
else {
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message(t('LinkedIn debug : received no answer from linkedin.com. Check your API credential at admin/settings/linkedin'));
}
else {
drupal_set_message(t('There was a problem with the configuration of LinkedIn on this website. Please try again later.'), 'error');
}
watchdog('linkedin', t('The website could not communicate with LinkedIn. It is likely your API credentials are misconfigured.'), array(), WATCHDOG_ERROR);
drupal_goto();
}
}
else {
$url = $base_url . '/accessToken';
if (!$anon) {
$result = db_result(db_query("SELECT token_secret FROM {linkedin_token} WHERE uid = %d AND type = 'request'", $account->uid));
}
else {
$result = $_SESSION['oauth_token_secret'];
}
$token = new OAuthConsumer($_REQUEST['oauth_token'], $result, 1);
$request = OAuthRequest::from_consumer_and_token($consumer, $token, "POST", $url);
$request
->set_parameter("oauth_verifier", $_REQUEST['oauth_verifier']);
$request
->sign_request($signature, $consumer, $token);
$header = $request
->to_header();
$response = _linkedin_http_request($url, $header, 'token_request');
parse_str($response, $oauth);
if (!$anon) {
$result = db_result(db_query("SELECT uid FROM {linkedin_token} WHERE token_key = '%s' AND token_secret = '%s' AND type = 'access' ", $oauth['oauth_token'], $oauth['oauth_token_secret']));
if ($result) {
$registered = user_load($result);
drupal_set_message(t('Sorry, this LinkedIn account is already associated with user !registered', array(
'!registered' => l($registered->name, 'user/' . $result),
)), 'warning');
drupal_goto('user/' . $account->uid . '/edit/linkedin');
}
$sql = array(
'uid' => $account->uid,
'token_key' => $oauth['oauth_token'],
'token_secret' => $oauth['oauth_token_secret'],
'type' => 'access',
);
drupal_write_record('linkedin_token', $sql, array(
'uid',
));
$id = linkedin_get_profile_fields($account->uid, array(
'id',
), TRUE);
user_set_authmaps($account, array(
'authmap_linkedin' => $id[id],
));
drupal_goto("user/{$account->uid}/edit/linkedin");
}
else {
$uid = db_result(db_query("SELECT uid FROM {linkedin_token} WHERE token_key = '%s' AND token_secret = '%s' AND type = 'access' ", $oauth['oauth_token'], $oauth['oauth_token_secret']));
if ($uid > 0) {
module_invoke_all('linkedin_external_login', $uid);
}
else {
module_invoke_all('linkedin_tie_external_login', $uid, $oauth['oauth_token'], $oauth['oauth_token_secret']);
}
}
}
}
function linkedin_get_profile_fields($uid, $fields = array()) {
$base_url = "https://api.linkedin.com/v1/people/";
$row = db_fetch_array(db_query("SELECT * FROM {linkedin_token} WHERE uid = %d AND type = 'access'", $uid));
if (!$row) {
$response = array(
'status' => '401',
'error-code' => 'custom',
'message' => 'No LinkedIn account is associated with this user',
);
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message(t('Linkedin debug : @status : @message', array(
'@status' => $response['status'],
'@message' => $response['message'],
)));
}
return $response;
}
global $user;
if ($user->uid == $uid) {
$tokens = $row;
$append = '~';
$type = 'auth';
}
else {
$tokens = db_fetch_array(db_query("SELECT * FROM {linkedin_token} WHERE uid = %d AND type = 'access'", $user->uid));
if (!$tokens) {
$tokens = $row;
$append = '~:public';
$type = 'public';
}
else {
$authname = db_result(db_query("SELECT authname FROM {authmap} WHERE uid = %d AND module = 'linkedin'", $uid));
$append = 'id=' . $authname;
$type = 'auth';
}
}
$append .= _linkedin_build_fields_request($fields, $type);
$url = $base_url . $append;
$response = linkedin_get_fields($url, $tokens);
if ($response['error']['status'] == 401 || $response['error']['status'] == 403) {
$tokens = $row;
$append = '~:public';
$append .= _linkedin_build_fields_request($fields, 'public');
$url = $base_url . $append;
$response = linkedin_get_fields($url, $tokens, $flat);
}
if (isset($response['person'])) {
$response = $response['person'];
}
else {
$response = $response['error'];
}
if (variable_get('linkedin_debug_mode', 0) == 1) {
if (isset($response['error-code'])) {
drupal_set_message(t('Linkedin debug : LinkedIn.com answered "@status : @message', array(
'@status' => $response['status'],
'@message' => $response['message'],
)));
}
}
return $response;
}
function linkedin_get_fields($url, $tokens) {
$signature = new OAuthSignatureMethod_HMAC_SHA1();
$consumer_key = variable_get('linkedin_consumer_key', '');
$consumer_secret = variable_get('linkedin_consumer_secret', '');
$consumer = new OAuthConsumer($consumer_key, $consumer_secret, NULL);
$token = new OAuthConsumer($tokens['token_key'], $tokens['token_secret'], 1);
$request = OAuthRequest::from_consumer_and_token($consumer, $token, "GET", $url);
$request
->sign_request($signature, $consumer, $token);
$header = $request
->to_header("https://api.linkedin.com");
$response = _linkedin_http_request($url, $header);
parse_str($response);
$response = _linkedin_parse_fields($response);
if (isset($response['error-code'])) {
$message = t('Linkedin debug : LinkedIn.com answered "@status : @message', array(
'@status' => $response['status'],
'@message' => $response['message'],
));
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message($message, 'warning');
}
watchdog('warning', $message);
}
return $response;
}
function linkedin_put_profile_field($uid, $body, $api = 'shares') {
$base_url = 'https://api.linkedin.com/v1/people/~/';
$url = $base_url . $api;
if ($api == 'shares') {
$xml = '<share>';
if (isset($body['comment'])) {
$xml .= '<comment>' . $body['comment'] . '</comment>';
}
if (isset($body['title']) && isset($body['submitted-url'])) {
$xml .= '<content>';
$xml .= '<title>' . $body['title'] . '</title>';
$xml .= '<submitted-url>' . $body['submitted-url'] . '</submitted-url>';
if (isset($body['submitted-image-url'])) {
$xml .= '<submitted-image-url>' . $body['submitted-image-url'] . '</submitted-image-url>';
}
if (isset($body['description'])) {
$xml .= '<description>' . $body['description'] . '</description>';
}
$xml .= '</content>';
}
$xml .= '<visibility><code>anyone</code></visibility>';
$xml .= '</share>';
}
else {
$message = t('Linkedin debug : Unsupported update method "@method"', array(
'@method' => $api,
));
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message($message, 'warning');
}
watchdog('warning', $message);
return;
}
$signature = new OAuthSignatureMethod_HMAC_SHA1();
$consumer_key = variable_get('linkedin_consumer_key', '');
$consumer_secret = variable_get('linkedin_consumer_secret', '');
$consumer = new OAuthConsumer($consumer_key, $consumer_secret, NULL);
$row = db_fetch_array(db_query("SELECT * FROM {linkedin_token} WHERE uid = %d AND type = 'access'", $uid));
$token = new OAuthConsumer($row['token_key'], $row['token_secret'], 1);
$request = OAuthRequest::from_consumer_and_token($consumer, $token, 'POST', $url, array());
$request
->sign_request($signature, $consumer, $token);
$header = $request
->to_header();
$response = _linkedin_http_request($url, $header, $xml);
if (isset($response['error-code'])) {
$message = t('Linkedin debug : LinkedIn.com answered "@status : @message', array(
'@status' => $response['status'],
'@message' => $response['message'],
));
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message($message, 'warning');
}
watchdog('warning', $message);
}
return $response;
}
function _linkedin_http_request($url, $header, $body = NULL) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
$header,
));
curl_setopt($ch, CURLOPT_URL, $url);
if ($body) {
curl_setopt($ch, CURLOPT_POST, 1);
if ($body == 'token_request') {
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
}
else {
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
$header,
'Content-Type: text/xml;charset=utf-8',
));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
}
}
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
function _linkedin_parse_fields($contents) {
if (!$contents) {
return array();
}
if (!function_exists('xml_parser_create')) {
if (variable_get('linkedin_debug_mode', 0) == 1) {
drupal_set_message(t('Unable to find PHP parser. This module needs php-xml lib'), 'warning');
}
return array();
}
$parser = xml_parser_create('');
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, trim($contents), $xml_values);
xml_parser_free($parser);
if (!$xml_values) {
return;
}
$xml_array = array();
$parents = array();
$opened_tags = array();
$arr = array();
$current =& $xml_array;
$repeated_tag_index = array();
foreach ($xml_values as $data) {
unset($attributes, $value);
extract($data);
$result = array();
$attributes_data = array();
if (isset($value)) {
$result = $value;
}
if ($type == "open") {
$parent[$level - 1] =& $current;
if (!is_array($current) or !in_array($tag, array_keys($current))) {
$current[$tag] = $result;
if ($attributes_data) {
$current[$tag . '_attr'] = $attributes_data;
}
$repeated_tag_index[$tag . '_' . $level] = 1;
$current =& $current[$tag];
}
else {
if (isset($current[$tag][0])) {
$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
$repeated_tag_index[$tag . '_' . $level]++;
}
else {
$current[$tag] = array(
$current[$tag],
$result,
);
$repeated_tag_index[$tag . '_' . $level] = 2;
if (isset($current[$tag . '_attr'])) {
$current[$tag]['0_attr'] = $current[$tag . '_attr'];
unset($current[$tag . '_attr']);
}
}
$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
$current =& $current[$tag][$last_item_index];
}
}
elseif ($type == "complete") {
if (!isset($current[$tag])) {
$current[$tag] = $result;
$repeated_tag_index[$tag . '_' . $level] = 1;
if ($attributes_data) {
$current[$tag . '_attr'] = $attributes_data;
}
}
else {
if (isset($current[$tag][0]) && is_array($current[$tag])) {
$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
$repeated_tag_index[$tag . '_' . $level]++;
}
else {
$current[$tag] = array(
$current[$tag],
$result,
);
$repeated_tag_index[$tag . '_' . $level] = 2;
}
}
}
elseif ($type == 'close') {
$current =& $parent[$level - 1];
}
}
return $xml_array;
}
function _linkedin_build_fields_request($fields, $type = 'auth') {
if (!empty($fields) || is_array($fields)) {
$fieldslist = _linkedin_list_fields($type);
$requested = '';
foreach ($fields as $field) {
if (in_array($field, $fieldslist)) {
$requested .= $field . ',';
}
}
$request .= ':(' . trim($requested, ',') . ')';
}
return $request;
}
function _linkedin_list_fields($type = 'auth') {
$fields = array(
'id',
'first-name',
'last-name',
'headline',
'location',
'industry',
'summary',
'specialties',
'honors',
'interests',
'num-recommenders',
'member-url-resources',
'picture-url',
'public-profile-url',
'positions',
'educations',
);
if ($type == 'auth') {
$standard_fields = array(
'distance',
'current-status',
'current-status-timestamp',
'num-connections',
'num-connections-capped',
'associations',
'phone-numbers',
'im-accounts',
'twitter-accounts',
'date-of-birth',
'main-address',
);
$fields = array_merge($fields, $standard_fields);
}
return $fields;
}