From e4638452fc8628f6e153cb871a243dfdd7698a27 Mon Sep 17 00:00:00 2001 From: Wayne Weibel Date: Tue, 20 Jan 2015 12:51:17 -0500 Subject: [PATCH] Issue 1542130: LinkedIn login D7; user auto registered and logged in, using email from LinkedIn account, return user to same page after login, using Drupal user_password() for new user, removed built-in linkedin_auth theme, css, and js (display should be controlled through installers theme package - will be basic html button with text now) --- README.txt | 206 ++-- linkedin.inc | 1231 +++++++++++--------- linkedin.info | 12 +- linkedin.install | 169 ++- linkedin.module | 378 +++--- linkedin.pages.inc | 335 +++--- linkedin_auth/README.txt | 46 +- linkedin_auth/linkedin_auth.css | 33 - linkedin_auth/linkedin_auth.info | 8 +- linkedin_auth/linkedin_auth.js | 37 - linkedin_auth/linkedin_auth.module | 289 ++--- linkedin_auth/linkedin_auth.pages.inc | 85 +- linkedin_auth/linkedin_auth.theme.inc | 36 - linkedin_auth/ln16.png | Bin 716 -> 0 bytes linkedin_auth/ln30.png | Bin 1405 -> 0 bytes linkedin_profile/README.txt | 106 +- .../linkedin-user-page-education-item.tpl.php | 88 +- .../linkedin-user-page-educations.tpl.php | 38 +- .../linkedin-user-page-position-item.tpl.php | 120 +- .../linkedin-user-page-positions.tpl.php | 38 +- linkedin_profile/linkedin-user-page.tpl.php | 72 +- linkedin_profile/linkedin_profile.info | 8 +- linkedin_profile/linkedin_profile.module | 537 ++++----- linkedin_profile/linkedin_profile.pages.inc | 284 ++--- linkedin_profile/linkedin_profile.theme.inc | 116 +- linkedin_status/README.txt | 68 +- linkedin_status/linkedin_status.css | 24 +- linkedin_status/linkedin_status.info | 8 +- linkedin_status/linkedin_status.js | 36 +- linkedin_status/linkedin_status.module | 268 ++--- linkedin_status/linkedin_status.pages.inc | 414 +++---- 31 files changed, 2564 insertions(+), 2526 deletions(-) delete mode 100644 linkedin_auth/linkedin_auth.css delete mode 100644 linkedin_auth/linkedin_auth.js delete mode 100644 linkedin_auth/linkedin_auth.theme.inc delete mode 100644 linkedin_auth/ln16.png delete mode 100644 linkedin_auth/ln30.png diff --git a/README.txt b/README.txt index f6cf9b3..4786b42 100644 --- a/README.txt +++ b/README.txt @@ -1,103 +1,103 @@ -=== LINKEDIN INTEGRATION === - -Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David -Landry (davad) Kyle Mathews (kyle_mathews) - -see http://drupal.org/node/919412 - -/********************************************* -Installation/initial configuration - - 1. LinkedIn Integration requires the OAuth.php library. You can either : - * install the Oauth module from http://drupal.org/project/oauth (7.x-3.x). You don't need to - activate it, the module only uses the library it provides. - * download the OAuth.php library from http://code.google.com/p/oauth/ and - specify the full path on the module admin interface - 2. Enable the base Linkedin module as usual. - 3. Request an API key by registering at -https://www.linkedin.com/secure/developer and creating a new application. Fill -the required fields (name, etc) and pay attention to - * provide an "Integration URL" : this field must match the URL of your - server. This means you'll need a separate key for each stage or - development server.[@todo : is this still true ?] - * leave the "Callback URL" blank, the module takes care of this. - 4. Configuration : go to admin/config/services/linkedin and fill the "API key" and -"Secret key" fields with the keys you got from -https://www.linkedin.com/secure/developer. If you downloaded the library -directly from http://code.google.com/p/oauth/, you should see an additional -"OAuth library full path" field above : don't forget to include the filename. - 5. Usage : Users will have to associate their LinkedIn account with their local -Drupal account (at user/%user/edit/linkedin) to use any functionality provided -by submodules. - - -/********************************************* -Troubleshooting - -If you encounter problems, please check the following points : - - * Integration URL : integration url you gave at - https://www.linkedin.com/secure/developer is the actual one from which you - are issuing the request. - * Callback URL : do not specifiy a callback url at - https://www.linkedin.com/secure/developer. - * Server time : an out of sync server will issue a wrong timestamp. Linkedin.com - requires that the timestamp must be within 5 minutes of accurate. - * Permissions : make sure users have the right to use the features provided by - the submodule you are trying to use. - -Also, the module offers a "debug mode" (see admin/config/services/linkedin) that will -try to give useful info. - - -/********************************************* -Developer use - -If you want to implement you own module, you can use the following : - - -Fetch fields from a LinkedIn profile. Copes with public/private LinkedIn profile -depending on the currently logged in user. -Parameters : - $uid : the uid of the Drupal user. - $fields : an array of field's names to retrieve (see -http://developer.linkedin.com/docs/DOC-1061 for a extensive list) -Return value : A structured array of fields and their values (or the error message -received from the API as an array) - - -Fetch fields from a LinkedIn profile. -Parameters : - $url : full request url to a LinkedIn API ressource (see -API doc for syntax) - $tokens : the user tokens, as an array containing keys 'token_key' and - 'token_secret' with their value -Return value : A structured array of fields and their values (or the error message -received from the API as an array) - - -Let us 'put' data into user profile. -Parameters : - $uid : the uid of the user we want to access - $body : The content to be sent. - $field : the field we want to update. Currently, only 'current-status' is - available from the API. -Return value : http answer from the API (or the error message as an array) - - -Let modules add their form elements to the user preferences edit form at -user/%user/edit/linkedin. Must return an array of form elements. - - -Let modules add their form elements to the admin settings at admin/config/services/linkedin. -Must return an array of form elements. - - -Mainly useful only if you don't use any of the bundled sub-modules. This function -is called from the access callback at user/%user/edit/linkedin to check if the user -has the right to access his own LinkedIn setting! It returns an array of permissions, -typically the return would be the same as the one from your hook_perm(). -Note that user is granted access if he has any permission implemented by a module using -this hook. That means you cannot deny access through this function and must make checks -in hook_linkedin_user_settings_page if you want to be selective on what to display -to the user. +=== LINKEDIN INTEGRATION === + +Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David +Landry (davad) Kyle Mathews (kyle_mathews) + +see http://drupal.org/node/919412 + +/********************************************* +Installation/initial configuration + + 1. LinkedIn Integration requires the OAuth.php library. You can either : + * install the Oauth module from http://drupal.org/project/oauth (7.x-3.x). You don't need to + activate it, the module only uses the library it provides. + * download the OAuth.php library from http://code.google.com/p/oauth/ and + specify the full path on the module admin interface + 2. Enable the base Linkedin module as usual. + 3. Request an API key by registering at +https://www.linkedin.com/secure/developer and creating a new application. Fill +the required fields (name, etc) and pay attention to + * provide an "Integration URL" : this field must match the URL of your + server. This means you'll need a separate key for each stage or + development server.[@todo : is this still true ?] + * leave the "Callback URL" blank, the module takes care of this. + 4. Configuration : go to admin/config/services/linkedin and fill the "API key" and +"Secret key" fields with the keys you got from +https://www.linkedin.com/secure/developer. If you downloaded the library +directly from http://code.google.com/p/oauth/, you should see an additional +"OAuth library full path" field above : don't forget to include the filename. + 5. Usage : Users will have to associate their LinkedIn account with their local +Drupal account (at user/%user/edit/linkedin) to use any functionality provided +by submodules. + + +/********************************************* +Troubleshooting + +If you encounter problems, please check the following points : + + * Integration URL : integration url you gave at + https://www.linkedin.com/secure/developer is the actual one from which you + are issuing the request. + * Callback URL : do not specifiy a callback url at + https://www.linkedin.com/secure/developer. + * Server time : an out of sync server will issue a wrong timestamp. Linkedin.com + requires that the timestamp must be within 5 minutes of accurate. + * Permissions : make sure users have the right to use the features provided by + the submodule you are trying to use. + +Also, the module offers a "debug mode" (see admin/config/services/linkedin) that will +try to give useful info. + + +/********************************************* +Developer use + +If you want to implement you own module, you can use the following : + + +Fetch fields from a LinkedIn profile. Copes with public/private LinkedIn profile +depending on the currently logged in user. +Parameters : + $uid : the uid of the Drupal user. + $fields : an array of field's names to retrieve (see +http://developer.linkedin.com/docs/DOC-1061 for a extensive list) +Return value : A structured array of fields and their values (or the error message +received from the API as an array) + + +Fetch fields from a LinkedIn profile. +Parameters : + $url : full request url to a LinkedIn API ressource (see +API doc for syntax) + $tokens : the user tokens, as an array containing keys 'token_key' and + 'token_secret' with their value +Return value : A structured array of fields and their values (or the error message +received from the API as an array) + + +Let us 'put' data into user profile. +Parameters : + $uid : the uid of the user we want to access + $body : The content to be sent. + $field : the field we want to update. Currently, only 'current-status' is + available from the API. +Return value : http answer from the API (or the error message as an array) + + +Let modules add their form elements to the user preferences edit form at +user/%user/edit/linkedin. Must return an array of form elements. + + +Let modules add their form elements to the admin settings at admin/config/services/linkedin. +Must return an array of form elements. + + +Mainly useful only if you don't use any of the bundled sub-modules. This function +is called from the access callback at user/%user/edit/linkedin to check if the user +has the right to access his own LinkedIn setting! It returns an array of permissions, +typically the return would be the same as the one from your hook_perm(). +Note that user is granted access if he has any permission implemented by a module using +this hook. That means you cannot deny access through this function and must make checks +in hook_linkedin_user_settings_page if you want to be selective on what to display +to the user. diff --git a/linkedin.inc b/linkedin.inc index ce79663..b08493f 100644 --- a/linkedin.inc +++ b/linkedin.inc @@ -1,529 +1,702 @@ -uid < 1) { - $anon = TRUE; - $back = 'login'; - } - else { - $anon = FALSE; - $back = 'token'; - } - //setting up variables - $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, 'query' => array('action' => $random))); // random will be used to discard direct call to the path and for anonymous - // First or renewal request - 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 (isset($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) { // Logged in user : store request token for next step in db instead of $_SESSION for security - db_delete('linkedin_token') - ->condition('uid', $account->uid) - ->execute(); - $sql = array( - 'uid' => $account->uid, - 'token_key' => $oauth['oauth_token'], - 'token_secret' => $oauth['oauth_token_secret'], - 'type' => 'request', - ); - drupal_write_record('linkedin_token', $sql); - //Redirect the user to the authentication/authorisation page. This will authorise the token in LinkedIn - drupal_goto($base_url . '/authorize?oauth_token=' . $oauth['oauth_token']); - } - else { // Anonymous user. We can't use db storage, but $_SESSION can not lead to identity forgery for anonymous - $_SESSION['oauth_token_secret'] = $oauth['oauth_token_secret']; - //Redirect the user to the authentication/authorisation page. This will authorise the token in LinkedIn - 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 { - //this is called when the OAuth callback is invoked. User has authorised the token. - //Now retrieve the stored request token and ask for an access token - - $url = $base_url . '/accessToken'; - if (!$anon) { - $result = db_query("SELECT token_secret FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $account->uid, ':type' => 'request'))->fetchField(); - } - 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) { - //Check if the same LinkedIn account is not already tied to another user - $result = db_query("SELECT uid FROM {linkedin_token} WHERE token_key = :token_key AND token_secret = :token_secret AND type = :type ", array(':token_key' => $oauth['oauth_token'], ':token_secret' => $oauth['oauth_token_secret'], ':type' => 'access'))->fetchField(); - 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'); - } - //save acces token for future requests - $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')); - //associate LinkedIn ID with uid for future use - $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_query("SELECT uid FROM {linkedin_token} WHERE token_key = :token_key AND token_secret = :token_secret AND type = :type ", array(':token_key' => $oauth['oauth_token'], ':token_secret' => $oauth['oauth_token_secret'], ':type' => 'access'))->fetchField(); - - 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']); - } - } - } -} - -/* - * Let us retrieve profile fields. - * Returns an array contening the fields requested. - * @params - * $uid : the uid of the user we want to access infos - * $fields : the fields we want to retrieve, as an array (see http://developer.linkedin.com/docs/DOC-1061 for complete list). - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function _linkedin_get_profile_fields($uid, $fields = array()) { - //Get sure library is loaded before doing anything. - linkedin_init(); - - $base_url = "https://api.linkedin.com/v1/people/"; - - $row = db_query("SELECT * FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $uid, ':type' => 'access'))->fetchAssoc(); - if (!$row || empty($row)) { - // This account does not have any LinkedIn account associated with. - $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) { - //User is requesting his own profile. - $tokens = $row; - $append = '~'; - $type = 'auth'; - } - else { - $tokens = db_query("SELECT * FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $user->uid, ':type' => 'access'))->fetchAssoc(); - if (!$tokens) { - //We don't have any LinkedIn account associated with the user viewing the profile. - //Make the request on the behalf on viewed user and switch to public profile. - $tokens = $row; - $append = '~:public'; - $type = 'public'; - } - else { - //Fetch profile. Fields returned will depend on the relationships between viewing/viewed users - $authname = db_query("SELECT authname FROM {authmap} WHERE uid = :uid AND module = :module", array(':uid' => $uid, ':module' => 'linkedin'))->fetchField(); - $append = 'id=' . $authname; - $type = 'auth'; - } - } - $tokens = (array) $tokens; - $append .= _linkedin_build_fields_request($fields, $type); - $url = $base_url . $append; - $response = linkedin_get_fields($url, $tokens); - - if (isset($response['error']['status']) && ($response['error']['status'] == 401 || $response['error']['status'] == 403)) { - // No relationships between users, switch back to public profile and retry - $tokens = (array) $row; - $append = '~:public'; - $append .= _linkedin_build_fields_request($fields, 'public'); - $url = $base_url . $append; - $response = linkedin_get_fields($url, $tokens); - } - 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; -} - -/* - * Returns an array contening the fields requested. - * @params - * $url : full request url to a linkedin API ressource (see API doc for syntax) - * $tokens : the user tokens, as an array containing keys 'token_key' and 'token_secret' with their value - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function _linkedin_get_fields($url, $tokens) { - //Get sure library is loaded before doing anything. - linkedin_init(); - - $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; -} - -/* - * Let us 'put' data into user profile. - * Usage : - * $uid : the uid of the user we want to access infos - * $api : the api we want to use to update. For now, only Share API is available - * $body : The content to be sent. - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function _linkedin_put_profile_field($uid, $body, $api = 'shares') { - //Get sure library is loaded before doing anything. - linkedin_init(); - - $base_url = 'https://api.linkedin.com/v1/people/~/'; - $url = $base_url . $api; - - if ($api == 'shares') { - $xml = ''; - if (isset($body['comment'])) { - $xml .= '' . $body['comment'] . ''; - } - if (isset($body['title']) && isset($body['submitted-url'])) { - $xml .= ''; - $xml .= '' . $body['title'] . ''; - $xml .= '' . $body['submitted-url'] . ''; - if (isset($body['submitted-image-url'])) { - $xml .= '' . $body['submitted-image-url'] . ''; - } - if (isset($body['description'])) { - $xml .= '' . $body['description'] . ''; - } - $xml .= ''; - } - $xml .= 'anyone'; - $xml .= ''; - } - else { - // Unsupported update method - $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_query("SELECT * FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $uid, ':type' => 'access'))->fetchAssoc(); - $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; -} - -/* - * Some internal helper functions... - */ - -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; -} - -/* - * Parser function. Based on xml2array() by Binny V A : http://www.bin-co.com/php/scripts/xml2array/ - */ - -function _linkedin_parse_fields($contents) { - if (!$contents) { - return array(); - } - - if (!function_exists('xml_parser_create')) { //Get the XML parser of PHP - PHP must have this module for the parser to work - 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"); // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss - 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; //Reference - //Go through the tags. - $repeated_tag_index = array(); //Multiple tags with same name will be turned into an array - foreach ($xml_values as $data) { - unset($attributes, $value); //Remove existing values, or there will be trouble - //This command will extract these variables into the foreach scope - // tag(string), type(string), level(int), attributes(array). - extract($data); //We could use the array by itself, but this cooler. - - $result = array(); - $attributes_data = array(); - - if (isset($value)) { - $result = $value; - } - //See tag status and do the needed. - if ($type == "open") { //The starting of the tag '' - $parent[$level - 1] = &$current; - if (!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag - $current[$tag] = $result; - if ($attributes_data) { - $current[$tag . '_attr'] = $attributes_data; - } - $repeated_tag_index[$tag . '_' . $level] = 1; - - $current = &$current[$tag]; - } - else { //There was another element with the same tag name - if (isset($current[$tag][0])) { //If there is a 0th element it is already an array - $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; - $repeated_tag_index[$tag . '_' . $level]++; - } - else { //This section will make the value an array if multiple tags with the same name appear together - $current[$tag] = array($current[$tag], $result); //This will combine the existing item and the new item together to make an array - $repeated_tag_index[$tag . '_' . $level] = 2; - - if (isset($current[$tag . '_attr'])) { //The attribute of the last(0th) tag must be moved as well - $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") { //Tags that ends in 1 line '' - //See if the key is already taken. - if (!isset($current[$tag])) { //New Key - $current[$tag] = $result; - $repeated_tag_index[$tag . '_' . $level] = 1; - if ($attributes_data) { - $current[$tag . '_attr'] = $attributes_data; - } - } - else { //If taken, put all things inside a list(array) - if (isset($current[$tag][0]) && is_array($current[$tag])) { //If it is already an array... - // ...push the new element into that array. - $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; - - - $repeated_tag_index[$tag . '_' . $level]++; - } - else { //If it is not an array... - $current[$tag] = array($current[$tag], $result); //...Make it an array using using the existing value and the new value - $repeated_tag_index[$tag . '_' . $level] = 2; //0 and 1 index is already taken - } - } - } - elseif ($type == 'close') { //End of tag '' - $current = &$parent[$level - 1]; - } - } - - return ($xml_array); -} - -/* - * Filter the requested fields to match the type of profile (public or auth) - */ - -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; -} - -/* - * Provides a list of available LinkedIn fields - * $type : 'public' or 'auth'. Wether we need 'public' or 'standard' fields - */ - -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', - // @TODO // 'site-standard-profile-request', // 'api-standard-profile-request', // 'api-public-profile-request', Deprecated ? // 'site-public-profile-request', Deprecated ? // 'member-url', // Deprecated ? - ); - 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', - // @TODO // 'relation-to-viewer', // 'proposal-comments', // 'recommendations-received', - ); - $fields = array_merge($fields, $standard_fields); - } - return $fields; -} +uid != 0) { + _authenticated_linkedin_access_token($account); + return; + } + + $anon = TRUE; + $back = 'login'; + + //setting up variables + $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, 'query' => array('action' => $random))); // random will be used to discard direct call to the path and for anonymous + // First or renewal request + if (!isset($_GET['action']) || $_GET['action'] != $_SESSION['random']) { + $_SESSION['return_to'] = $_SERVER['HTTP_REFERER']; + $_SESSION['random'] = $random; + $url = $base_url . "/requestToken?scope=r_basicprofile+r_emailaddress"; + $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 (isset($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) { // Logged in user : store request token for next step in db instead of $_SESSION for security + db_delete('linkedin_token') + ->condition('uid', $account->uid) + ->execute(); + $sql = array( + 'uid' => $account->uid, + 'token_key' => $oauth['oauth_token'], + 'token_secret' => $oauth['oauth_token_secret'], + 'type' => 'request', + ); + drupal_write_record('linkedin_token', $sql); + //Redirect the user to the authentication/authorisation page. This will authorise the token in LinkedIn + drupal_goto($base_url . '/authorize?oauth_token=' . $oauth['oauth_token']); + } + else { // Anonymous user. We can't use db storage, but $_SESSION can not lead to identity forgery for anonymous + $_SESSION['oauth_token_secret'] = $oauth['oauth_token_secret']; + //Redirect the user to the authentication/authorisation page. This will authorise the token in LinkedIn + 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 { + if ($_GET['oauth_problem']) { + if (variable_get('linkedin_debug_mode', 0) == 1) { + drupal_set_message(t('LinkedIn debug : received error response : @error'), array('@error' => $_GET['oauth_problem']), 'warning'); + } + watchdog('linkedin', t('Linkedin reported the following response : @error'), array('@error' => $_GET['oauth_problem']), WATCHDOG_ERROR); + drupal_goto(); + } + //this is called when the OAuth callback is invoked. User has authorised the token. + //Now retrieve the stored request token and ask for an access token + + $url = $base_url . '/accessToken'; + if (!$anon) { + $result = db_query("SELECT token_secret FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $account->uid, ':type' => 'request'))->fetchField(); + } + 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); + // Now we have linkedin access... Get the user information and create a user... + $base_user_url = "https://api.linkedin.com/v1/people/"; + $tokens = array('token_key' => $oauth['oauth_token'], 'token_secret' => $oauth['oauth_token_secret']); + $append = '~'; + $type = 'auth'; + $append .= _linkedin_build_fields_request(array('first-name', 'last-name', 'id'), $type); + $url = $base_user_url . $append; + $response = linkedin_get_fields($url, $tokens); + //Get email address + $url = $base_user_url .'~/email-address'; + $email_response = linkedin_get_fields($url, $tokens); + + // Now we have linkedin person information... + // Lets create the user and save all the information... + $account = user_external_load($response['person']['id']); + +// $result = db_query("SELECT uid FROM {linkedin_token} WHERE token_key = :token_key AND token_secret = :token_secret AND type = :access", array("token_key" => $oauth['oauth_token'], "token_secret" => $oauth['oauth_token_secret'], "access" => "access"))->fetchField(); +// if ($result) { +// $registered = user_load($result); +// //user_external_login_register($registered->name, 'linkedin'); +// global $user; +// $user = $registered; +// drupal_goto('user/' . $registered->uid); +// } + if (isset($account->uid)) { + user_external_login_register($response['person']['id'], 'linkedin'); + + } + else { + $newUser = array( + 'name' => $email_response['email-address'], + 'pass' => user_password(), + 'mail' => isset($email_response['email-address']) ? $email_response['email-address']: 'no_email@address.com', + 'status' => 1, + ); + + // assign role + $role = variable_get('linkedin_auto_assign_role', 0); + if ($role) { $newUser['roles'] = array($role => 'linkedin_auto_assign'); } + + $account = user_save('', $newUser); + // Save the linkedin access key information... + //Check if the same LinkedIn account is not already tied to another user + + //save acces token for future requests + $sql = db_insert('linkedin_token')->fields(array( + 'uid' => $account->uid, + 'token_key' => $oauth['oauth_token'], + 'token_secret' => $oauth['oauth_token_secret'], + 'type' => 'access', + ))->execute(); + + //associate LinkedIn ID with uid for future use + user_set_authmaps($account, array('authmap_linkedin' => $response['person']['id'])); + user_external_login_register($response['person']['id'], 'linkedin'); +// drupal_goto("user/$account->uid"); + } + + // set the boost cookie so on return the cache page is not served + if ( isset($account->uid) && module_exists('boost') ) { + // Give modules a chance to alter the cookie handler callback used. + // hook_boost_cookie_handler_callback_alter + $cookie_handler_callback = 'boost_cookie_handler'; + drupal_alter('boost_cookie_handler_callback', $cookie_handler_callback); + if (function_exists($cookie_handler_callback)) { + $cookie_handler_callback(); + } + } + + //drupal_goto("user/$account->uid"); + //drupal_goto("user"); + drupal_goto($_SESSION['return_to']); //should hopefully get back to same page the person was on when logging in + } +} + +function _authenticated_linkedin_access_token($account) { + //Get sure library is loaded before doing anything. + linkedin_init(); + + if ($account->uid < 1) { + $anon = TRUE; + $back = 'login'; + } + else { + $anon = FALSE; + $back = 'token'; + } + //setting up variables + $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, 'query' => array('action' => $random))); // random will be used to discard direct call to the path and for anonymous + // First or renewal request + if (!isset($_GET['action']) || $_GET['action'] != $_SESSION['random']) { + $_SESSION['random'] = $random; + $url = $base_url . "/requestToken?scope=r_basicprofile+r_emailaddress"; + $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 (isset($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) { // Logged in user : store request token for next step in db instead of $_SESSION for security + db_delete('linkedin_token') + ->condition('uid', $account->uid) + ->execute(); + $sql = array( + 'uid' => $account->uid, + 'token_key' => $oauth['oauth_token'], + 'token_secret' => $oauth['oauth_token_secret'], + 'type' => 'request', + ); + drupal_write_record('linkedin_token', $sql); + //Redirect the user to the authentication/authorisation page. This will authorise the token in LinkedIn + drupal_goto($base_url . '/authorize?oauth_token=' . $oauth['oauth_token']); + } + else { // Anonymous user. We can't use db storage, but $_SESSION can not lead to identity forgery for anonymous + $_SESSION['oauth_token_secret'] = $oauth['oauth_token_secret']; + //Redirect the user to the authentication/authorisation page. This will authorise the token in LinkedIn + 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 { + //this is called when the OAuth callback is invoked. User has authorised the token. + //Now retrieve the stored request token and ask for an access token + + $url = $base_url . '/accessToken'; + if (!$anon) { + $result = db_query("SELECT token_secret FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $account->uid, ':type' => 'request'))->fetchField(); + } + 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) { + //Check if the same LinkedIn account is not already tied to another user + $result = db_query("SELECT uid FROM {linkedin_token} WHERE token_key = :token_key AND token_secret = :token_secret AND type = :type ", array(':token_key' => $oauth['oauth_token'], ':token_secret' => $oauth['oauth_token_secret'], ':type' => 'access'))->fetchField(); + 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'); + } + //save acces token for future requests + $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')); + //associate LinkedIn ID with uid for future use + $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_query("SELECT uid FROM {linkedin_token} WHERE token_key = :token_key AND token_secret = :token_secret AND type = :type ", array(':token_key' => $oauth['oauth_token'], ':token_secret' => $oauth['oauth_token_secret'], ':type' => 'access'))->fetchField(); + + 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']); + } + } + } +} +/* + * Let us retrieve profile fields. + * Returns an array contening the fields requested. + * @params + * $uid : the uid of the user we want to access infos + * $fields : the fields we want to retrieve, as an array (see http://developer.linkedin.com/docs/DOC-1061 for complete list). + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function _linkedin_get_profile_fields($uid, $fields = array()) { + //Get sure library is loaded before doing anything. + linkedin_init(); + + $base_url = "https://api.linkedin.com/v1/people/"; + + $row = db_query("SELECT * FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $uid, ':type' => 'access'))->fetchAssoc(); + if (!$row || empty($row)) { + // This account does not have any LinkedIn account associated with. + $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) { + //User is requesting his own profile. + $tokens = $row; + $append = '~'; + $type = 'auth'; + } + else { + $tokens = db_query("SELECT * FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $user->uid, ':type' => 'access'))->fetchAssoc(); + if (!$tokens) { + //We don't have any LinkedIn account associated with the user viewing the profile. + //Make the request on the behalf on viewed user and switch to public profile. + $tokens = $row; + $append = '~:public'; + $type = 'public'; + } + else { + //Fetch profile. Fields returned will depend on the relationships between viewing/viewed users + $authname = db_query("SELECT authname FROM {authmap} WHERE uid = :uid AND module = :module", array(':uid' => $uid, ':module' => 'linkedin'))->fetchField(); + $append = 'id=' . $authname; + $type = 'auth'; + } + } + $tokens = (array) $tokens; + $append .= _linkedin_build_fields_request($fields, $type); + $url = $base_url . $append; + $response = linkedin_get_fields($url, $tokens); + + if (isset($response['error']['status']) && ($response['error']['status'] == 401 || $response['error']['status'] == 403)) { + // No relationships between users, switch back to public profile and retry + $tokens = (array) $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; +} + +/* + * Returns an array contening the fields requested. + * @params + * $url : full request url to a linkedin API ressource (see API doc for syntax) + * $tokens : the user tokens, as an array containing keys 'token_key' and 'token_secret' with their value + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function _linkedin_get_fields($url, $tokens) { + //Get sure library is loaded before doing anything. + linkedin_init(); + + $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; +} + +/* + * Let us 'put' data into user profile. + * Usage : + * $uid : the uid of the user we want to access infos + * $api : the api we want to use to update. For now, only Share API is available + * $body : The content to be sent. + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function _linkedin_put_profile_field($uid, $body, $api = 'shares') { + //Get sure library is loaded before doing anything. + linkedin_init(); + + $base_url = 'https://api.linkedin.com/v1/people/~/'; + $url = $base_url . $api; + + if ($api == 'shares') { + $xml = ''; + if (isset($body['comment'])) { + $xml .= '' . $body['comment'] . ''; + } + if (isset($body['title']) && isset($body['submitted-url'])) { + $xml .= ''; + $xml .= '' . $body['title'] . ''; + $xml .= '' . $body['submitted-url'] . ''; + if (isset($body['submitted-image-url'])) { + $xml .= '' . $body['submitted-image-url'] . ''; + } + if (isset($body['description'])) { + $xml .= '' . $body['description'] . ''; + } + $xml .= ''; + } + $xml .= 'anyone'; + $xml .= ''; + } + else { + // Unsupported update method + $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_query("SELECT * FROM {linkedin_token} WHERE uid = :uid AND type = :type", array(':uid' => $uid, ':type' => 'access'))->fetchAssoc(); + $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; +} + +/* + * Some internal helper functions... + */ + +function _linkedin_http_request($url, $header, $body = NULL) { + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + 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; +} + +/* + * Parser function. Based on xml2array() by Binny V A : http://www.bin-co.com/php/scripts/xml2array/ + */ + +function _linkedin_parse_fields($contents) { + if (!$contents) { + return array(); + } + + if (!function_exists('xml_parser_create')) { //Get the XML parser of PHP - PHP must have this module for the parser to work + 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"); // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss + 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; //Reference + //Go through the tags. + $repeated_tag_index = array(); //Multiple tags with same name will be turned into an array + foreach ($xml_values as $data) { + unset($attributes, $value); //Remove existing values, or there will be trouble + //This command will extract these variables into the foreach scope + // tag(string), type(string), level(int), attributes(array). + extract($data); //We could use the array by itself, but this cooler. + + $result = array(); + $attributes_data = array(); + + if (isset($value)) { + $result = $value; + } + //See tag status and do the needed. + if ($type == "open") { //The starting of the tag '' + $parent[$level - 1] = &$current; + if (!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag + $current[$tag] = $result; + if ($attributes_data) { + $current[$tag . '_attr'] = $attributes_data; + } + $repeated_tag_index[$tag . '_' . $level] = 1; + + $current = &$current[$tag]; + } + else { //There was another element with the same tag name + if (isset($current[$tag][0])) { //If there is a 0th element it is already an array + $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; + $repeated_tag_index[$tag . '_' . $level]++; + } + else { //This section will make the value an array if multiple tags with the same name appear together + $current[$tag] = array($current[$tag], $result); //This will combine the existing item and the new item together to make an array + $repeated_tag_index[$tag . '_' . $level] = 2; + + if (isset($current[$tag . '_attr'])) { //The attribute of the last(0th) tag must be moved as well + $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") { //Tags that ends in 1 line '' + //See if the key is already taken. + if (!isset($current[$tag])) { //New Key + $current[$tag] = $result; + $repeated_tag_index[$tag . '_' . $level] = 1; + if ($attributes_data) { + $current[$tag . '_attr'] = $attributes_data; + } + } + else { //If taken, put all things inside a list(array) + if (isset($current[$tag][0]) && is_array($current[$tag])) { //If it is already an array... + // ...push the new element into that array. + $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; + + + $repeated_tag_index[$tag . '_' . $level]++; + } + else { //If it is not an array... + $current[$tag] = array($current[$tag], $result); //...Make it an array using using the existing value and the new value + $repeated_tag_index[$tag . '_' . $level] = 2; //0 and 1 index is already taken + } + } + } + elseif ($type == 'close') { //End of tag '' + $current = &$parent[$level - 1]; + } + } + + return ($xml_array); +} + +/* + * Filter the requested fields to match the type of profile (public or auth) + */ + +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; +} + +/* + * Provides a list of available LinkedIn fields + * $type : 'public' or 'auth'. Wether we need 'public' or 'standard' fields + */ + +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', + // @TODO // 'site-standard-profile-request', // 'api-standard-profile-request', // 'api-public-profile-request', Deprecated ? // 'site-public-profile-request', Deprecated ? // 'member-url', // Deprecated ? + ); + 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', + // @TODO // 'relation-to-viewer', // 'proposal-comments', // 'recommendations-received', + ); + $fields = array_merge($fields, $standard_fields); + } + return $fields; +} diff --git a/linkedin.info b/linkedin.info index 725a4c9..92d3015 100644 --- a/linkedin.info +++ b/linkedin.info @@ -1,6 +1,6 @@ -name = "LinkedIn" -description = "Provides LinkedIn integration." -package = "Linkedin" -core = 7.x -configure = admin/config/services/linkedin - +name = "LinkedIn" +description = "Provides LinkedIn integration." +package = "Linkedin" +core = 7.x +configure = admin/config/services/linkedin + diff --git a/linkedin.install b/linkedin.install index 499dba2..b5dba1c 100644 --- a/linkedin.install +++ b/linkedin.install @@ -1,88 +1,81 @@ - 'Tokens for request and services accesses.', - 'fields' => array( - 'uid' => array( - 'description' => 'User ID from {user}.uid.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'token_key' => array( - 'description' => 'Tokens for request and services accesses.', - 'type' => 'varchar', - 'length' => 100, - 'not null' => TRUE, - ), - 'token_secret' => array( - 'description' => 'Token "password".', - 'type' => 'varchar', - 'length' => 100, - 'not null' => TRUE, - ), - 'type' => array( - 'description' => 'Type of the token: request or access.', - 'type' => 'varchar', - 'length' => 7, - 'not null' => TRUE, - ), - ), - 'primary key' => array('uid'), - 'indexes' => array( - 'token_key_type' => array('token_key'), - ), - ); - return $schema; -} - -/** - * Implements hook_uninstall(). - */ -function linkedin_uninstall() { - // Delete variables - variable_del('linkedin_consumer_key'); - variable_del('linkedin_consumer_secret'); - $types = node_type_get_names(); - array_push($types, 'event_signup'); - foreach ($types as $type) { - $type = strtolower($type); - variable_del('linkedin_enabled_' . $type); - variable_del('linkedin_default_format_' . $type); - } -} - -/** - * Implements hook_requirements(). - */ -function linkedin_requirements($phase) { - $requirements = array(); - $t = get_t(); - $has_curl = function_exists('curl_init'); - $requirements['curl'] = array( - 'title' => $t('cURL'), - 'value' => $has_curl ? $t('Enabled') : $t('Not found'), - ); - if (!$has_curl) { - $requirements['curl']['severity'] = REQUIREMENT_ERROR; - $requirements['curl']['description'] = $t('Linkedin module could not be installed because the PHP cURL library is not available.', array('@curl_url' => 'http://php.net/manual/en/curl.setup.php')); - } - return $requirements; -} - -/** - * Remove unused variable linkedin_auth_login_block. - */ -function linkedin_update_7100() { - variable_del('linkedin_auth_login_block'); -} + 'Tokens for request and services accesses.', + 'fields' => array( + 'uid' => array( + 'description' => 'User ID from {user}.uid.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'token_key' => array( + 'description' => 'Tokens for request and services accesses.', + 'type' => 'varchar', + 'length' => 100, + 'not null' => TRUE, + ), + 'token_secret' => array( + 'description' => 'Token "password".', + 'type' => 'varchar', + 'length' => 100, + 'not null' => TRUE, + ), + 'type' => array( + 'description' => 'Type of the token: request or access.', + 'type' => 'varchar', + 'length' => 7, + 'not null' => TRUE, + ), + ), + 'primary key' => array('uid'), + 'indexes' => array( + 'token_key_type' => array('token_key'), + ), + ); + return $schema; +} + +/** + * Implements hook_uninstall(). + */ +function linkedin_uninstall() { + // Delete variables + variable_del('linkedin_consumer_key'); + variable_del('linkedin_consumer_secret'); + $types = node_type_get_names(); + array_push($types, 'event_signup'); + foreach ($types as $type) { + $type = strtolower($type); + variable_del('linkedin_enabled_' . $type); + variable_del('linkedin_default_format_' . $type); + } +} + +/** + * Implements hook_requirements(). + */ +function linkedin_requirements($phase) { + $requirements = array(); + $t = get_t(); + $has_curl = function_exists('curl_init'); + $requirements['curl'] = array( + 'title' => $t('cURL'), + 'value' => $has_curl ? $t('Enabled') : $t('Not found'), + ); + if (!$has_curl) { + $requirements['curl']['severity'] = REQUIREMENT_ERROR; + $requirements['curl']['description'] = $t('Linkedin module could not be installed because the PHP cURL library is not available.', array('@curl_url' => 'http://php.net/manual/en/curl.setup.php')); + } + return $requirements; +} \ No newline at end of file diff --git a/linkedin.module b/linkedin.module index 801f32b..595d22e 100644 --- a/linkedin.module +++ b/linkedin.module @@ -1,190 +1,190 @@ - 'LinkedIn integration', - 'description' => 'linkedin module settings', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('linkedin_admin'), - 'access arguments' => array('administer site configuration'), - 'file' => 'linkedin.pages.inc', - ); - - //callback for oauth token request on linkedin API. - $items['linkedin/token/%user'] = array( - 'type' => MENU_CALLBACK, - 'description' => 'Let user tie their LI account with their local user account', - 'page callback' => 'linkedin_access_token', - 'page arguments' => array(2), - 'access callback' => 'linkedin_token_access', - 'access arguments' => array(2), - 'file' => 'linkedin.inc', - ); - - // User settings form : used by submodules. - $items['user/%user/edit/linkedin'] = array( - 'title' => 'Linkedin', - 'type' => MENU_LOCAL_TASK, - 'page callback' => 'linkedin_user_settings', - 'file' => 'linkedin.pages.inc', - 'page arguments' => array(1), - 'access callback' => 'linkedin_user_access', //access arguments don't support multiple arguments, so create our access handler - 'access arguments' => array(1), - ); - - return $items; -} - -/* - * Custom access callback for linkedin/token/%user - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_token_access($account) { - global $user; - if ($account->uid > 0 && $account->uid == $user->uid) { - return TRUE; - } - if (variable_get('linkedin_debug_mode', 0) == 1) { - drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested. Requesting user has uid @requesting, which is different from the requested account.', array('@requested' => $account->uid, '@requesting' => $user->uid)), 'warning'); - } - return FALSE; -} - -/* - * Custom access callback for user/%user/edit/linkedin - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_user_access($account) { - global $user; - if ($user->uid == $account->uid) { - // Check if some perms have been defined by submodules. - $perms = module_invoke_all('linkedin_user_edit_perms'); - foreach ($perms as $perm) { - if (user_access($perm)) { - return TRUE; - } - } - if (module_exists('linkedin_auth')) { - return TRUE; - } - } - if (variable_get('linkedin_debug_mode', 0) == 1) { - if ($user->uid != $account->uid) { - drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested.
- Requesting user (uid @requesting) is different from the requested account (uid @requested)', array('@requested' => $account->uid, '@requesting' => $user->uid))); - return FALSE; - } - if (empty($perms)) { - drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested.
- No module is implementing hook_linkedin_user_edit_perms. Enable at least one submodule and check permissions')); - return FALSE; - } - foreach ($perms as $perm) { - $permissions .= $perm . ', '; - } - drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested.
- User must have at least one of these permissions : @permissions', array('@permissions' => $permissions))); - } - - return FALSE; -} - -/* - * Let us retrieve profile fields. - * Returns an array contening the fields requested. - * @params - * $uid : the uid of the user we want to access infos - * $fields : the fields we want to retrieve, as an array (see http://developer.linkedin.com/docs/DOC-1061 for complete list). - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_get_profile_fields($uid, $fields = array()) { - module_load_include('inc', 'linkedin'); - return _linkedin_get_profile_fields($uid, $fields); -} - -/* - * Returns an array contening the fields requested. - * @params - * $url : full request url to a linkedin API ressource (see API doc for syntax) - * $tokens : the user tokens, as an array containing keys 'token_key' and 'token_secret' with their value - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_get_fields($url, $tokens) { - module_load_include('inc', 'linkedin'); - return _linkedin_get_fields($url, $tokens); -} - -/* - * Let us 'put' data into user profile. - * Usage : - * $uid : the uid of the user we want to access infos - * $api : the api we want to use to update. For now, only Share API is available - * $body : The content to be sent. - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_put_profile_field($uid, $body, $api = 'shares') { - module_load_include('inc', 'linkedin'); - return _linkedin_put_profile_field($uid, $body, $api); -} - -/** - * Implements hook_user_delete() - */ -function linkedin_user_delete($account) { - // Delete token when user is deleted - db_delete('linkedin_token') - ->condition('uid', $account->uid) - ->execute(); + 'LinkedIn integration', + 'description' => 'linkedin module settings', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('linkedin_admin'), + 'access arguments' => array('administer site configuration'), + 'file' => 'linkedin.pages.inc', + ); + + //callback for oauth token request on linkedin API. + $items['linkedin/token/%user'] = array( + 'type' => MENU_CALLBACK, + 'description' => 'Let user tie their LI account with their local user account', + 'page callback' => 'linkedin_access_token', + 'page arguments' => array(2), + 'access callback' => 'linkedin_token_access', + 'access arguments' => array(2), + 'file' => 'linkedin.inc', + ); + + // User settings form : used by submodules. + $items['user/%user/edit/linkedin'] = array( + 'title' => 'Linkedin', + 'type' => MENU_LOCAL_TASK, + 'page callback' => 'linkedin_user_settings', + 'file' => 'linkedin.pages.inc', + 'page arguments' => array(1), + 'access callback' => 'linkedin_user_access', //access arguments don't support multiple arguments, so create our access handler + 'access arguments' => array(1), + ); + + return $items; +} + +/* + * Custom access callback for linkedin/token/%user + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_token_access($account) { + global $user; + if ($account->uid > 0 && $account->uid == $user->uid) { + return TRUE; + } + if (variable_get('linkedin_debug_mode', 0) == 1) { + drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested. Requesting user has uid @requesting, which is different from the requested account.', array('@requested' => $account->uid, '@requesting' => $user->uid)), 'warning'); + } + return FALSE; +} + +/* + * Custom access callback for user/%user/edit/linkedin + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_user_access($account) { + global $user; + if ($user->uid == $account->uid) { + // Check if some perms have been defined by submodules. + $perms = module_invoke_all('linkedin_user_edit_perms'); + foreach ($perms as $perm) { + if (user_access($perm)) { + return TRUE; + } + } + if (module_exists('linkedin_auth')) { + return TRUE; + } + } + if (variable_get('linkedin_debug_mode', 0) == 1) { + if ($user->uid != $account->uid) { + drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested.
+ Requesting user (uid @requesting) is different from the requested account (uid @requested)', array('@requested' => $account->uid, '@requesting' => $user->uid))); + return FALSE; + } + if (empty($perms)) { + drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested.
+ No module is implementing hook_linkedin_user_edit_perms. Enable at least one submodule and check permissions')); + return FALSE; + } + foreach ($perms as $perm) { + $permissions .= $perm . ', '; + } + drupal_set_message(t('LinkedIn debug : Access denied to /linkedin/token/@requested.
+ User must have at least one of these permissions : @permissions', array('@permissions' => $permissions))); + } + + return FALSE; +} + +/* + * Let us retrieve profile fields. + * Returns an array contening the fields requested. + * @params + * $uid : the uid of the user we want to access infos + * $fields : the fields we want to retrieve, as an array (see http://developer.linkedin.com/docs/DOC-1061 for complete list). + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_get_profile_fields($uid, $fields = array()) { + module_load_include('inc', 'linkedin'); + return _linkedin_get_profile_fields($uid, $fields); +} + +/* + * Returns an array contening the fields requested. + * @params + * $url : full request url to a linkedin API ressource (see API doc for syntax) + * $tokens : the user tokens, as an array containing keys 'token_key' and 'token_secret' with their value + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_get_fields($url, $tokens) { + module_load_include('inc', 'linkedin'); + return _linkedin_get_fields($url, $tokens); +} + +/* + * Let us 'put' data into user profile. + * Usage : + * $uid : the uid of the user we want to access infos + * $api : the api we want to use to update. For now, only Share API is available + * $body : The content to be sent. + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_put_profile_field($uid, $body, $api = 'shares') { + module_load_include('inc', 'linkedin'); + return _linkedin_put_profile_field($uid, $body, $api); +} + +/** + * Implements hook_user_delete() + */ +function linkedin_user_delete($account) { + // Delete token when user is deleted + db_delete('linkedin_token') + ->condition('uid', $account->uid) + ->execute(); } \ No newline at end of file diff --git a/linkedin.pages.inc b/linkedin.pages.inc index 2317f64..434e89f 100644 --- a/linkedin.pages.inc +++ b/linkedin.pages.inc @@ -1,163 +1,172 @@ - t('Base settings'), - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - - $form['linkedin']['linkedin_liboauth_path'] = array( - '#default_value' => variable_get('linkedin_liboauth_path', ''), - '#title' => t('OAuth library full path (including filename)'), - '#type' => 'textfield', - '#description' => t('Linkedin module needs the OAuth php library from http://code.google.com/p/oauth/. You can either download OAuth.php from there and specify the full path here or install the OAuth module from http://drupal.org/project/oauth (both 6.x-2 and 6.x-3 versions are supported)'), - ); - - $form['linkedin']['consumer'] = array( - '#description' => t('You will get theses values by requesting an API key at https://www.linkedin.com/secure/developer.
Notice that the "integration url" you specify at Linkedin must match the base url (@url)', array('@url' => $base_url)), - '#title' => t('Consumer information'), - '#type' => 'fieldset', - ); - $form['linkedin']['consumer']['linkedin_consumer_key'] = array( - '#default_value' => variable_get('linkedin_consumer_key', ''), - '#title' => t('API key'), - '#type' => 'textfield', - ); - $form['linkedin']['consumer']['linkedin_consumer_secret'] = array( - '#default_value' => variable_get('linkedin_consumer_secret', ''), - '#title' => t('API Secret key'), - '#type' => 'textfield', - ); - $form['linkedin']['linkedin_debug_mode'] = array( - '#default_value' => variable_get('linkedin_debug_mode', 0), - '#title' => t('Turn on debug mode'), - '#type' => 'checkbox', - ); - - //Fetch forms from submodules. - $forms = array(); - $forms = module_invoke_all('linkedin_admin_page'); - //Tabs on user page don't always get rebuild, so manually trigger it. - $form['#submit'][] = 'menu_rebuild'; - $form = array_merge($form, $forms); - return system_settings_form($form); -} - -/* - * Callback for linkedin related user settings at user/%/edit/linkedin - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_user_settings($account) { - $output = ''; - $check = linkedin_get_profile_fields($account->uid, array('first-name', 'last-name', 'public-profile-url'), TRUE); - if (isset($check['error-code'])) { - $output .= t('You must first authorize LinkedIn integration to use related features.'); - $form = drupal_get_form('linkedin_user_enable_form', $account->uid); - $output .= drupal_render($form); - } - else { - $output .= t('Your account is associated with @name !public_profile.', array('@name' => $check['first-name'] . ' ' . $check['last-name'], '!public_profile' => l($check['public-profile-url'], $check['public-profile-url']))); - $form = drupal_get_form('linkedin_user_settings_form', $account); - $output .= drupal_render($form); - } - return $output; -} - -/* - * Take users to linkedin auth page - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_user_enable_form($form, $form_state, $uid) { - $form = array(); - $form['#user'] = $uid; - $form['#action'] = url('linkedin/token/' . $uid); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Go to LinkedIn'), - '#suffix' => '

' . t('You will be taken to the LinkedIn website in order to complete the process.') . '

', - ); - return $form; -} - -/* - * form for individual user settings - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_user_settings_form($form, &$form_state, $account) { - // Just fetch forms from submodules. - $form['linkedin']['elements'] = module_invoke_all('linkedin_user_settings_page', $account); - // We will need the account at submit - $form['#account'] = $account; - - $form['submit'] = array( - '#type' => 'submit', - '#value' => 'Save', - ); - $form['linkedin']['reset'] = array( - '#type' => 'submit', - '#description' => t('Click here to unlink your LinkedIn account.'), - '#value' => t('Unlink'), - ); - - return $form; -} - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_user_settings_form_submit($form, &$form_state) { - $op = $form_state['values']['op']; - - if ($op == $form['linkedin']['reset']['#value']) { - $data = array(); - foreach ($form_state['values'] as $key => $val) { - if (substr($key, 0, 8) == 'linkedin') { - $data[$key] = NULL; - } - } - user_save($form['#account'], array('data' => $data), 'linkedin'); - db_delete('linkedin_token') - ->condition('uid', $form['#account']->uid) - ->execute(); - drupal_set_message(t('LinkedIn preferences have been reset')); - } - else { - $data = array(); - foreach ($form_state['values'] as $key => $val) { - if (substr($key, 0, 8) == 'linkedin') { - $data[$key] = $val; - } - } - user_save($form['#account'], array('data' => $data), 'linkedin'); - drupal_set_message(t('LinkedIn preferences have been saved')); - } -} + t('Base settings'), + '#type' => 'fieldset', + '#collapsible' => TRUE, + //'#collapsed' => TRUE, + ); + + $form['linkedin']['linkedin_liboauth_path'] = array( + '#default_value' => variable_get('linkedin_liboauth_path', ''), + '#title' => t('OAuth library full path (including filename)'), + '#type' => 'textfield', + '#description' => t('Linkedin module needs the OAuth php library from http://code.google.com/p/oauth/. You can either download OAuth.php from there and specify the full path here or install the OAuth module from http://drupal.org/project/oauth (both 6.x-2 and 6.x-3 versions are supported)'), + ); + + $form['linkedin']['consumer'] = array( + '#description' => t('You will get theses values by requesting an API key at https://www.linkedin.com/secure/developer.
Notice that the "integration url" you specify at Linkedin must match the base url (@url)', array('@url' => $base_url)), + '#title' => t('Consumer information'), + '#type' => 'fieldset', + ); + $form['linkedin']['consumer']['linkedin_consumer_key'] = array( + '#default_value' => variable_get('linkedin_consumer_key', ''), + '#title' => t('API key'), + '#type' => 'textfield', + ); + $form['linkedin']['consumer']['linkedin_consumer_secret'] = array( + '#default_value' => variable_get('linkedin_consumer_secret', ''), + '#title' => t('API Secret key'), + '#type' => 'textfield', + ); + $form['linkedin']['linkedin_debug_mode'] = array( + '#default_value' => variable_get('linkedin_debug_mode', 0), + '#title' => t('Turn on debug mode'), + '#type' => 'checkbox', + ); + + $drupal_roles = array(0 => 'Ignore') + user_roles(true); + $form['linkedin']['linkedin_auto_assign_role'] = array( + '#type' => 'select', + '#title' => t("Auto Assign Role"), + '#description' => t('assign the role to users when registered via LinkedIn; authenticated is automstically assigned by Drupal for anyone logged in'), + '#default_value' => variable_get('linkedin_auto_assign_role', 0), + '#options' => $drupal_roles, + ); + + //Fetch forms from submodules. + $forms = array(); + $forms = module_invoke_all('linkedin_admin_page'); + //Tabs on user page don't always get rebuild, so manually trigger it. + $form['#submit'][] = 'menu_rebuild'; + $form = array_merge($form, $forms); + return system_settings_form($form); +} + +/* + * Callback for linkedin related user settings at user/%/edit/linkedin + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_user_settings($account) { + $output = ''; + $check = linkedin_get_profile_fields($account->uid, array('first-name', 'last-name', 'public-profile-url'), TRUE); + if (isset($check['error-code'])) { + $output .= t('You must first authorize LinkedIn integration to use related features.'); + $form = drupal_get_form('linkedin_user_enable_form', $account->uid); + $output .= drupal_render($form); + } + else { + $output .= t('Your account is associated with @name !public_profile.', array('@name' => $check['first-name'] . ' ' . $check['last-name'], '!public_profile' => l($check['public-profile-url'], $check['public-profile-url']))); + $form = drupal_get_form('linkedin_user_settings_form', $account); + $output .= drupal_render($form); + } + return $output; +} + +/* + * Take users to linkedin auth page + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_user_enable_form($form, $form_state, $uid) { + $form = array(); + $form['#user'] = $uid; + $form['#action'] = url('linkedin/token/' . $uid); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Go LinkedIn'), + '#suffix' => '

' . t('You will be taken to LinkedIn website in order to complete the process.') . '

', + ); + return $form; +} + +/* + * form for individual user settings + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_user_settings_form($form, &$form_state, $account) { + // Just fetch forms from submodules. + $form['linkedin']['elements'] = module_invoke_all('linkedin_user_settings_page', $account); + // We will need the account at submit + $form['#account'] = $account; + + $form['submit'] = array( + '#type' => 'submit', + '#value' => 'Save', + ); + $form['linkedin']['reset'] = array( + '#type' => 'submit', + '#description' => t('Click here to unlink your LinkedIn account.'), + '#value' => t('Unlink'), + ); + + return $form; +} + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_user_settings_form_submit($form, &$form_state) { + $op = $form_state['values']['op']; + + if ($op == $form['linkedin']['reset']['#value']) { + $data = array(); + foreach ($form_state['values'] as $key => $val) { + if (substr($key, 0, 8) == 'linkedin') { + $data[$key] = NULL; + } + } + user_save($form['#account'], array('data' => $data), 'linkedin'); + db_delete('linkedin_token') + ->condition('uid', $form['#account']->uid) + ->execute(); + drupal_set_message(t('LinkedIn preferences have been reset')); + } + else { + $data = array(); + foreach ($form_state['values'] as $key => $val) { + if (substr($key, 0, 8) == 'linkedin') { + $data[$key] = $val; + } + } + user_save($form['#account'], array('data' => $data), 'linkedin'); + drupal_set_message(t('LinkedIn preferences have been saved')); + } +} diff --git a/linkedin_auth/README.txt b/linkedin_auth/README.txt index 95d8a03..c84c535 100644 --- a/linkedin_auth/README.txt +++ b/linkedin_auth/README.txt @@ -1,23 +1,23 @@ -=== LINKEDIN INTEGRATION === - -Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David -Landry (davad) Kyle Mathews (kyle_mathews) - -see http://drupal.org/node/919550 - -/********************************************* -Installation/initial configuration - - See http://drupal.org/node/919412. - - -/********************************************* -Configuration/Usage - -After enabling the module, go to admin/settings/linkedin. You can enable/disable -Status Update availability per content type, for comments (and event sign-ups if -you use the module.) For each, you can also specify a default message that will -be posted (and use placeholders for node title, url) Don't forget to set the -permissions for users accordingly. Users have to link their LinkedIn account to -their local Drupal account from their preferences at user/%user/edit/linkedin. -Beware, text is limited to 140 characters +=== LINKEDIN INTEGRATION === + +Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David +Landry (davad) Kyle Mathews (kyle_mathews) + +see http://drupal.org/node/919550 + +/********************************************* +Installation/initial configuration + + See http://drupal.org/node/919412. + + +/********************************************* +Configuration/Usage + +After enabling the module, go to admin/settings/linkedin. You can enable/disable +Status Update availability per content type, for comments (and event sign-ups if +you use the module.) For each, you can also specify a default message that will +be posted (and use placeholders for node title, url) Don't forget to set the +permissions for users accordingly. Users have to link their LinkedIn account to +their local Drupal account from their preferences at user/%user/edit/linkedin. +Beware, text is limited to 140 characters diff --git a/linkedin_auth/linkedin_auth.css b/linkedin_auth/linkedin_auth.css deleted file mode 100644 index a1ab241..0000000 --- a/linkedin_auth/linkedin_auth.css +++ /dev/null @@ -1,33 +0,0 @@ - -.linkedin-auth-login-link a, -.linkedin-auth-login-link-drupal-login-page a, -.linkedin-auth-login-link-drupal-login-block a { - background: transparent url('ln16.png') no-repeat 0 50%; - padding: 0 18px; -} -.linkedin-auth-login-link-drupal-login-block a{ - background: transparent url('ln16.png') no-repeat 0 50%; - padding: 0 20px; -} - -.item-list ul li.linkedin-auth-login-link-linkedin-login-block{ - padding :0; - list-style-type: none ; - font-weight:bold; - background-image: none; -} -.item-list ul li.linkedin-auth-login-link-linkedin-login-block a{ - background: url('ln30.png') no-repeat 0 50%; - display:block; - line-height:32px; - padding-left:30px; -} -#user-login-form ul { - margin-top: 0; -} -#user-login ul { - margin: 0 0 5px; -} -#user-login ul li { - margin: 0; -} diff --git a/linkedin_auth/linkedin_auth.info b/linkedin_auth/linkedin_auth.info index 232e655..60b3eca 100644 --- a/linkedin_auth/linkedin_auth.info +++ b/linkedin_auth/linkedin_auth.info @@ -1,5 +1,5 @@ -name = "LinkedIn Authentication" -description = "Allows users to log into your site using their LindedIn account" -package = "Linkedin" -core = 7.x +name = "LinkedIn Authentication" +description = "Allows users to log into your site using their LindedIn account" +package = "Linkedin" +core = 7.x dependencies[] = "linkedin" \ No newline at end of file diff --git a/linkedin_auth/linkedin_auth.js b/linkedin_auth/linkedin_auth.js deleted file mode 100644 index f0bc5ca..0000000 --- a/linkedin_auth/linkedin_auth.js +++ /dev/null @@ -1,37 +0,0 @@ - -Drupal.behaviors.linkedin_status = function (context) { - var $loginElements = $("#edit-name-wrapper, #edit-pass-wrapper, li.linkedin_auth-link"); - var $linkedin_authElements = $("#edit-linkedin_auth-identifier-wrapper, li.user-link"); - - // This behavior attaches by ID, so is only valid once on a page. - if (!$("#edit-linkedin_auth-identifier.linkedin_auth-processed").size() && $("#edit-linkedin_auth-identifier").val()) { - $("#edit-linkedin_auth-identifier").addClass('linkedin_auth-processed'); - $loginElements.hide(); - // Use .css("display", "block") instead of .show() to be Konqueror friendly. - $linkedin_authElements.css("display", "block"); - } - $("li.linkedin_auth-link:not(.linkedin_auth-processed)", context) - .addClass('linkedin_auth-processed') - .click( function() { - $loginElements.hide(); - $linkedin_authElements.css("display", "block"); - // Remove possible error message. - $("#edit-name, #edit-pass").removeClass("error"); - $("div.messages.error").hide(); - // Set focus on linkedin_auth Identifier field. - $("#edit-linkedin_auth-identifier")[0].focus(); - return false; - }); - $("li.user-link:not(.linkedin_auth-processed)", context) - .addClass('linkedin_auth-processed') - .click(function() { - $linkedin_authElements.hide(); - $loginElements.css("display", "block"); - // Clear linkedin_auth Identifier field and remove possible error message. - $("#edit-linkedin_auth-identifier").val('').removeClass("error"); - $("div.messages.error").css("display", "block"); - // Set focus on username field. - $("#edit-name")[0].focus(); - return false; - }); -}; diff --git a/linkedin_auth/linkedin_auth.module b/linkedin_auth/linkedin_auth.module index 49922b1..bbd6868 100644 --- a/linkedin_auth/linkedin_auth.module +++ b/linkedin_auth/linkedin_auth.module @@ -1,163 +1,126 @@ - MENU_CALLBACK, - 'page callback' => 'linkedin_access_token', - 'page arguments' => array(2), - 'access callback' => 'linkedin_auth_token_access', - 'access arguments' => array(2), - 'file' => 'linkedin.inc', - 'file path' => drupal_get_path('module', 'linkedin'), - ); - return $items; -} - -/* - * Custom access callback for linkedin/login/%user - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_auth_token_access($account) { - if (user_is_anonymous()) { - return TRUE; - } - return FALSE; -} - -/** - * Implements hook_theme(). - */ -function linkedin_auth_theme($existing, $type, $theme, $path) { - return array( - 'linkedin_auth_display_login_block_button' => array( - 'variables' => array('display' => '', 'path' => 'linkedin/login/0', 'text' => 'Log in using LinkedIn'), - 'file' => 'linkedin_auth.theme.inc', - ), - ); -} - -/** - * Implements hook_form_alter : adds LinkedIn login to the login forms(). - */ -function linkedin_auth_form_alter(&$form, &$form_state, $form_id) { - switch ($form_id) { - //add login link to the login form - case 'user_login_block': - if (variable_get('linkedin_auth_login_link_on_block', 0) == 1) { - $form['linkedin_auth_links'] = array( - '#markup' => theme('linkedin_auth_display_login_block_button', array('display' => 'drupal_login_block')), - '#weight' => 1, - ); - } - break; - case 'user_login': - if (variable_get('linkedin_auth_login_link_on_page', 0) == 1) { - $form['linkedin_auth_links'] = array( - '#markup' => theme('linkedin_auth_display_login_block_button', array('display' => 'drupal_login_page')), - '#weight' => 1, - ); - } - break; - //Register using linkedin. - case 'user_register_form': - if (variable_get('linkedin_auth_bypass_register_checks', 0) == 1 && isset($_SESSION['linkedin_auth_register_bypass'])) { - $form_state['#redirect'] = isset($_GET['destination']) ? $_GET['destination'] : ''; - //Only remove standard register submit, but play nicely wth other modules. - $key = array_keys($form['#submit'], 'user_register_submit'); - unset($form['#submit'][$key[0]]); - $form['#submit'][] = 'linkedin_auth_register_form_submit'; - } - break; - } - return $form; -} - -/** - * Implements hook_block_info(). - */ -function linkedin_auth_block_info() { - $blocks['linkedin_auth_login_block'] = array( - 'info' => t('Login using LinkedIn'), - 'title' => t('LinkedIn Login'), - ); - return $blocks; -} - -/** - * Implements hook_block_view(). - */ -function linkedin_auth_block_view($delta = '') { - //No check on delta, we have only one block. - if (user_is_anonymous()) { - $content = theme('linkedin_auth_display_login_block_button', array('display' => 'linkedin_login_block')); - $block['subject'] = t('Subject'); - $block['content'] = $content; - return $block; - } -} - -/* - * Implementation of hook_linkedin_external_login - */ - -function linkedin_auth_linkedin_external_login($uid) { - $name = db_query("SELECT authname FROM {authmap} WHERE uid = :uid AND module = :module", array(':uid' => $uid, ':module' => 'linkedin'))->fetchField(); - user_external_login_register($name, 'linkedin'); - drupal_goto(); -} - -/* - * Implementation of hook_linkedin_tie_external_login - */ - -function linkedin_auth_linkedin_tie_external_login($uid, $token, $secret) { - drupal_set_message('No user associated with this LinkedIn account. Please register.'); - if (variable_get('linkedin_auth_bypass_register_checks', 0) == 1) { - $_SESSION['linkedin_auth_register_bypass'] = 1; - } - drupal_goto('user/register'); -} - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_auth_register_form_submit($form, &$form_state) { - user_external_login_register($form_state['values']['name'], 'linkedin'); - global $user; - $account = user_save($user, $form_state['values']); - if (!$account) { - drupal_set_message(t("Error saving user account."), 'error'); - drupal_goto(); - } - linkedin_access_token($account); - //Unset variables no longer needed. - unset($_SESSION['random']); - unset($_SESSION['oauth_token_secret']); - unset($_SESSION['linkedin_auth_register_bypass']); -} + MENU_CALLBACK, + 'page callback' => 'linkedin_access_token', + 'page arguments' => array(2), + 'access callback' => 'linkedin_auth_token_access', + 'access arguments' => array(2), + 'file' => 'linkedin.inc', + 'file path' => drupal_get_path('module', 'linkedin'), + ); + return $items; +} + +/* + * Custom access callback for linkedin/login/%user + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_auth_token_access($account) { + if (user_is_anonymous()) { + return TRUE; + } + return FALSE; +} + +/** + * Implements hook_form_alter : adds LinkedIn login to the login forms(). + */ +function linkedin_auth_form_alter(&$form, &$form_state, $form_id) { + if ( ($form_id == 'user_login_block' && variable_get('linkedin_auth_login_link_on_block', 0)) || + ($form_id == 'user_login' && variable_get('linkedin_auth_login_link_on_page', 0)) ) { + + if ($form_state['input']['op'] == 'Log in using LinkedIn') { + // user clicked the linkedin login button + $form['name']['#required'] = FALSE; + $form['pass']['#required'] = FALSE; + unset($form['#submit']); + drupal_goto('linkedin/login/0'); + } + + //add login link to the login form + $form['actions']['linkedin_auth_links'] = array( + '#type' => 'button', + '#id' => 'linkedin_login', + '#value' => t('Log in using LinkedIn'), + ); + } + + if ( $form_id == 'user_register_form' ) { + //Register using linkedin. + if (variable_get('linkedin_auth_bypass_register_checks', 0) == 1 && isset($_SESSION['linkedin_auth_register_bypass'])) { + $form_state['#redirect'] = isset($_GET['destination']) ? $_GET['destination'] : ''; + //Only remove standard register submit, but play nicely wth other modules. + $key = array_keys($form['#submit'], 'user_register_submit'); + unset($form['#submit'][$key[0]]); + $form['#submit'][] = 'linkedin_auth_register_form_submit'; + } + } + + return $form; +} + +/* + * Implementation of hook_linkedin_external_login + */ + +function linkedin_auth_linkedin_external_login($uid) { + $name = db_query("SELECT authname FROM {authmap} WHERE uid = :uid AND module = :module", array(':uid' => $uid, ':module' => 'linkedin'))->fetchField(); + user_external_login_register($name, 'linkedin'); + drupal_goto(); +} + +/* + * Implementation of hook_linkedin_tie_external_login + */ + +function linkedin_auth_linkedin_tie_external_login($uid, $token, $secret) { + drupal_set_message('No user associated with this LinkedIn account. Please register.'); + if (variable_get('linkedin_auth_bypass_register_checks', 0) == 1) { + $_SESSION['linkedin_auth_register_bypass'] = 1; + } + drupal_goto('user/register'); +} + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_auth_register_form_submit($form, &$form_state) { + user_external_login_register($form_state['values']['name'], 'linkedin'); + global $user; + $account = user_save($user, $form_state['values']); + if (!$account) { + drupal_set_message(t("Error saving user account."), 'error'); + drupal_goto(); + } + linkedin_access_token($account); + //Unset variables no longer needed. + unset($_SESSION['random']); + unset($_SESSION['oauth_token_secret']); + unset($_SESSION['linkedin_auth_register_bypass']); +} diff --git a/linkedin_auth/linkedin_auth.pages.inc b/linkedin_auth/linkedin_auth.pages.inc index f8cbfd5..03abe30 100644 --- a/linkedin_auth/linkedin_auth.pages.inc +++ b/linkedin_auth/linkedin_auth.pages.inc @@ -1,40 +1,45 @@ - t('Let users login using their LinkedIn account once they have tied it to their local account'), - '#title' => t('LinkedIn authentication'), - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['linkedin_auth']['linkedin_auth_login_link_on_block'] = array( - '#type' => 'checkbox', - '#title' => 'Display LinkedIn login link on login block form', - '#default_value' => variable_get('linkedin_auth_login_link_on_block', '0'), - ); - $form['linkedin_auth']['linkedin_auth_login_link_on_page'] = array( - '#type' => 'checkbox', - '#title' => 'Display LinkedIn login link on login page form', - '#default_value' => variable_get('linkedin_auth_login_link_on_page', '0'), - ); - $form['linkedin_auth']['linkedin_auth_bypass_register_checks'] = array( - '#type' => 'checkbox', - '#title' => t('Bypass user mail verification or administrator approval for user registering through LinkedIn'), - '#default_value' => variable_get('linkedin_auth_bypass_register_checks', 0), - ); - return $form; -} + t('Let users login using their LinkedIn account once they have tied it to their local account'), + '#title' => t('LinkedIn authentication'), + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['linkedin_auth']['linkedin_auth_login_link_on_block'] = array( + '#type' => 'checkbox', + '#title' => 'Display LinkedIn login link on login block form', + '#default_value' => variable_get('linkedin_auth_login_link_on_block', '0'), + ); + $form['linkedin_auth']['linkedin_auth_login_link_on_page'] = array( + '#type' => 'checkbox', + '#title' => 'Display LinkedIn login link on login page form', + '#default_value' => variable_get('linkedin_auth_login_link_on_page', '0'), + ); + $form['linkedin_auth']['linkedin_auth_login_block'] = array( + '#type' => 'checkbox', + '#title' => 'Provides a seperate "Linkedin login block"', + '#default_value' => variable_get('linkedin_auth_login_block', '0'), + ); + $form['linkedin_auth']['linkedin_auth_bypass_register_checks'] = array( + '#type' => 'checkbox', + '#title' => t('Bypass user mail verification or administrator approval for user registering through LinkedIn'), + '#default_value' => variable_get('linkedin_auth_bypass_register_checks', 0), + ); + return $form; +} \ No newline at end of file diff --git a/linkedin_auth/linkedin_auth.theme.inc b/linkedin_auth/linkedin_auth.theme.inc deleted file mode 100644 index 25b4038..0000000 --- a/linkedin_auth/linkedin_auth.theme.inc +++ /dev/null @@ -1,36 +0,0 @@ - $data, - 'attributes' => array( - 'class' => $class, - ), - ); - return theme('item_list', array('items' => $items)); -} diff --git a/linkedin_auth/ln16.png b/linkedin_auth/ln16.png deleted file mode 100644 index c717e80fdd8409f42400030904e95c53854bd90f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 716 zcmV;-0yF)IP)+P^&^ z+)%*}H3$eXOJXC~M(YAdS}fHZZ7n-~;AzJm8i?cENEUNH*YLEo0!vD4WeiYj`k_^6 zdZ@Vpu8!@+i9KnI=F@oep^UogLQ1hYO7|o%yyJziR$brtIp{zpj^|4?EY=(--DMKy z+@};7&yGj~!Z?1QAPSR3Pez2z7jykFR2?66LQX~_l!m|>spGRkCV^HE;&at8=|vbp z>A-S*g?b~zwebQjAJ5}`xqGxKFrxNoa1f|a=S;wzqfs^BFJ z7N4`-cveC_-G|~rg$rSDg`AkyidR0pRDCmUtb*Fcd75BW!$e-tX0~W=3;IY{7mn?| yJ3aT~l#2c{_)+WsKPcAoN&2799?s4D6<`3&2tQfo$JZ(V0000G)qSS diff --git a/linkedin_auth/ln30.png b/linkedin_auth/ln30.png deleted file mode 100644 index b9ef4655331944cc872a6aedc7b95347a0c31f94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1405 zcmV-@1%mpCP)X1^@s6CN-WK000F+TIhQ$ zn+~yMdaOV9Ti2tW0Vf-9U`_)O}-XO zbLvgT-oI?YA7yB;JnuUEvajNFV>^bICSxx?`QaLtU>8q7ITjdaa@XdgYrg{BVp zo~SeTG23XGn^BDqGDfr2;KPg>Q)iz5*e$6NGY_drRhXWtf;C)DK?CKW)yX;lMgS>V- zPzgWsFkfrHS#7(y4my7m&a{zFbL-9R=UQ~U7OV0bp}5n9yWRb0?(C&w=|Es!119gQ zfJd?l@6jgQ52`RTwMrQ5yhj1Iq|0#Jqr_(?Z}84IMcoQ6ssus5+#GTC9eDQ7zZhBi zC?l58CY@-lDf=tovbO>=l2xW|A+TdyIb0Ge@OErDyZXF^_Ey{lw?l?CXB+W`mtyr9TW~(5-ggvrqE#*kC7GSkEEr?z1G=u*5za4xb0{*-saOI*1QT$lta>Cy}@ zJ4>3uMMy34sLs^14cXYqFE~)jb|~9(l~}#(0XN(=Ms8T?jm$cE;e`wqp2ZUEu-5r7hq> z3b8!5-WI&I$TE-Wk>I)X8k&!R)^-p}jRqmG-A);WMMfbj!lEn<4-j2SAq_4-U@rgC zg)s0IiDe$u$yKd9@N5PqN4Q8CCPo*V4BexE?W|y*qkM1_18*q6vK&4**b26@f)A?r z9($*~0E?oEj7FhbZAV5XF5DIz%|gB50s?=mxAl0l#4>L)^Y|Xm?wv~D2mW-V6B0b*yljIL|`r~EQ}i%7_gi%CHk|WMP9XNL$eOowaS$h6TAr=5)#7o z_xD@>?8WDVkK0=C=c|Xy@Os$!$NP(}ty8NiIWI3SZquesL*V}agHAQd{vLTq00000 LNkvXXu0mjfBr2U( diff --git a/linkedin_profile/README.txt b/linkedin_profile/README.txt index d863e5a..7333c12 100644 --- a/linkedin_profile/README.txt +++ b/linkedin_profile/README.txt @@ -1,53 +1,53 @@ -=== LINKEDIN INTEGRATION === - -Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David -Landry (davad) Kyle Mathews (kyle_mathews) - -see http://drupal.org/node/919598 - -/********************************************* -Installation/initial configuration - - See http://drupal.org/node/919412. - - -/********************************************* -Configuration/Usage - -After enabling the module, go to admin/config/services/linkedin. You can choose to -display LinkedIn profile data as a tab, as a block, or inside the user profile -page. If you choose to use the block display, you still have to enable it at -admin/build/block. There is also a "hidden" display, which will output nothing -but keep the data available under $profile->linkedin in user-profile.tpl.php if -you need more control on the output. You can choose what fields to retrieve by -using the checkboxes (see http://developer.linkedin.com/docs/DOC-1061 for the -meaning of each), but keep in mind not all fields will output nicely by default -and you will need some theming work to display some of them. (This feature is -still in dev, and a few fields are missing.) Also beware that the amount of -information returned depends on the relationship (in LinkedIn.com) between the -viewing and the viewed user. There is currently no ability to map individual -fields to standard core "profile" module fields - -Be sure to check users have the permission to display this data. Users have to -link their LinkedIn account to their local Drupal account and to opt-in for -displaying these info from their preferences at user/%user/edit/linkedin . - - - -/********************************************* -Theming - -The module provides the following templates : - - * linkedin-user-page.tpl.php : main data output. - * linkedin-user-page-positions.tpl.php : renders the LinkedIn "positions" - items - * linkedin-user-page-position-item.tpl.php : renders individual LinkedIn - "position" item - * linkedin-user-page-educations.tpl.php : renders the LinkedIn "educations" - items - * linkedin-user-page-education-item.tpl.php : renders individual LinkedIn - "education" item - -You can also use the following function, which outputs each individual field item - +=== LINKEDIN INTEGRATION === + +Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David +Landry (davad) Kyle Mathews (kyle_mathews) + +see http://drupal.org/node/919598 + +/********************************************* +Installation/initial configuration + + See http://drupal.org/node/919412. + + +/********************************************* +Configuration/Usage + +After enabling the module, go to admin/config/services/linkedin. You can choose to +display LinkedIn profile data as a tab, as a block, or inside the user profile +page. If you choose to use the block display, you still have to enable it at +admin/build/block. There is also a "hidden" display, which will output nothing +but keep the data available under $profile->linkedin in user-profile.tpl.php if +you need more control on the output. You can choose what fields to retrieve by +using the checkboxes (see http://developer.linkedin.com/docs/DOC-1061 for the +meaning of each), but keep in mind not all fields will output nicely by default +and you will need some theming work to display some of them. (This feature is +still in dev, and a few fields are missing.) Also beware that the amount of +information returned depends on the relationship (in LinkedIn.com) between the +viewing and the viewed user. There is currently no ability to map individual +fields to standard core "profile" module fields + +Be sure to check users have the permission to display this data. Users have to +link their LinkedIn account to their local Drupal account and to opt-in for +displaying these info from their preferences at user/%user/edit/linkedin . + + + +/********************************************* +Theming + +The module provides the following templates : + + * linkedin-user-page.tpl.php : main data output. + * linkedin-user-page-positions.tpl.php : renders the LinkedIn "positions" + items + * linkedin-user-page-position-item.tpl.php : renders individual LinkedIn + "position" item + * linkedin-user-page-educations.tpl.php : renders the LinkedIn "educations" + items + * linkedin-user-page-education-item.tpl.php : renders individual LinkedIn + "education" item + +You can also use the following function, which outputs each individual field item + diff --git a/linkedin_profile/linkedin-user-page-education-item.tpl.php b/linkedin_profile/linkedin-user-page-education-item.tpl.php index 27844ca..7fcdccd 100644 --- a/linkedin_profile/linkedin-user-page-education-item.tpl.php +++ b/linkedin_profile/linkedin-user-page-education-item.tpl.php @@ -1,44 +1,44 @@ - -
- -

- - - - - - - - - - - - - - - - - - -

- -
- -
- -
- -
- -
- + +
+ +

+ + + + + + + + + + + + + + + + + + +

+ +
+ +
+ +
+ +
+ +
+ diff --git a/linkedin_profile/linkedin-user-page-educations.tpl.php b/linkedin_profile/linkedin-user-page-educations.tpl.php index f8fc39e..c9533db 100644 --- a/linkedin_profile/linkedin-user-page-educations.tpl.php +++ b/linkedin_profile/linkedin-user-page-educations.tpl.php @@ -1,19 +1,19 @@ - -
-
    - -
  • - -
-
- + +
+
    + +
  • + +
+
+ diff --git a/linkedin_profile/linkedin-user-page-position-item.tpl.php b/linkedin_profile/linkedin-user-page-position-item.tpl.php index ab5741f..9f82b1b 100644 --- a/linkedin_profile/linkedin-user-page-position-item.tpl.php +++ b/linkedin_profile/linkedin-user-page-position-item.tpl.php @@ -1,60 +1,60 @@ - -
- -
- - - - - - - - -
- -

- - - - - - - - - - - - - - - - - - - - - - -

- - -
- -
- - -
- - + +
+ +
+ + + + + + + + +
+ +

+ + + + + + + + + + + + + + + + + + + + + + +

+ + +
+ +
+ + +
+ + diff --git a/linkedin_profile/linkedin-user-page-positions.tpl.php b/linkedin_profile/linkedin-user-page-positions.tpl.php index b741600..516f397 100644 --- a/linkedin_profile/linkedin-user-page-positions.tpl.php +++ b/linkedin_profile/linkedin-user-page-positions.tpl.php @@ -1,19 +1,19 @@ - -
-
    - -
  • - -
-
- + +
+
    + +
  • + +
+
+ diff --git a/linkedin_profile/linkedin-user-page.tpl.php b/linkedin_profile/linkedin-user-page.tpl.php index f218b6a..aec6317 100644 --- a/linkedin_profile/linkedin-user-page.tpl.php +++ b/linkedin_profile/linkedin-user-page.tpl.php @@ -1,36 +1,36 @@ - -
- - - title="Public profile of on www.linkedin.com." > - <?php print $profile['first-name']['value'] . ' ' . $profile['last-name']['value']; ?> - - - - - -

-
- - -
    - $value) : ?> - -
  • : - - -
- -
- + +
+ + + title="Public profile of on www.linkedin.com." > + <?php print $profile['first-name']['value'] . ' ' . $profile['last-name']['value']; ?> + + + + + +

+
+ + +
    + $value) : ?> + +
  • : + + +
+ +
+ diff --git a/linkedin_profile/linkedin_profile.info b/linkedin_profile/linkedin_profile.info index 9c5aebe..914ba30 100644 --- a/linkedin_profile/linkedin_profile.info +++ b/linkedin_profile/linkedin_profile.info @@ -1,5 +1,5 @@ -name = "Linkedin profile integration" -description = "Retrieve profile infos from LinkedIn for registered users" -package = "Linkedin" -core = 7.x +name = "Linkedin profile integration" +description = "Retrieve profile infos from LinkedIn for registered users" +package = "Linkedin" +core = 7.x dependencies[] = "linkedin" \ No newline at end of file diff --git a/linkedin_profile/linkedin_profile.module b/linkedin_profile/linkedin_profile.module index 9a984c3..f1e7757 100644 --- a/linkedin_profile/linkedin_profile.module +++ b/linkedin_profile/linkedin_profile.module @@ -1,268 +1,269 @@ - 'Linkedin', - 'type' => MENU_LOCAL_TASK, - 'page callback' => 'linkedin_profile_display', - 'page arguments' => array(1), - 'access callback' => 'linkedin_profile_display_access', - 'access arguments' => array(1), - 'file' => 'linkedin_profile.pages.inc', - ); - } - return $items; -} - -/* - * Custom access callback for user/%user/linkedin - */ - -function linkedin_profile_display_access($account) { - if (variable_get('linkedin_profile_user_page_enabled', 0) < 1) { - return FALSE; - } - if (!user_access('display LinkedIn profile', $account)) { - return FALSE; - } - if (!isset($account->data['linkedin_profile_user_page_enabled']) || $account->data['linkedin_profile_user_page_enabled'] != 1) { - return FALSE; - } - global $user; - if (!user_access('access user profiles') && $user->uid != $account->uid) { - return FALSE; - } - $check = linkedin_get_profile_fields($account->uid, array('id')); - if (isset($check['error-code'])) { // no need to display an empty tab - return FALSE; - } - return TRUE; -} - -/* - * Implementation of hook_perm() - */ - -function linkedin_profile_permission() { - return array( - 'display LinkedIn profile' => array( - 'title' => t('display LinkedIn profile'), - 'description' => t('Display own LinkedIn profile on user page.'), - ), - ); -} - -/* - * Implementation of hook_linkedin_user_edit_perms : - * Let Linkedin module know what permissions are available at user/%user/edit/linkedin - */ - -function linkedin_profile_linkedin_user_edit_perms() { - return array('display LinkedIn profile'); -} - -/** - * Implements hook_user_load(). - */ -function linkedin_profile_user_load($users) { - if (variable_get('linkedin_profile_user_page_enabled', 0) > 0) { - foreach ($users as $account) { - module_load_include('inc', 'linkedin', 'linkedin'); - $fields = _linkedin_profile_vget_user_page_linkedin_fields(); - $profile = linkedin_get_profile_fields($account->uid, $fields); - - if (!isset($profile['error-code'])) { - //Let themers hook into items - $multiples = array( - 'positions' => 'position', - 'educations' => 'education', - ); - foreach ($profile as $key => $value) { - $item = array( - 'name' => $key, - 'value' => $value, - ); - //deal with multi-values structured fields - if (array_key_exists($key, $multiples)) { - $items = array(); - $items_val = $profile[$key][$multiples[$key]]; - if (is_array($items_val)) { - if ($items_val['id']) { - $variables[$multiples[$key]] = $items_val; - $items[] = theme('linkedin_profile_user_page_' . $multiples[$key] . '_item', $variables); - } - else { - foreach ($items_val as $item_val) { - $variables[$multiples[$key]] = $item_val; - $items[] = theme('linkedin_profile_user_page_' . $multiples[$key] . '_item', $variables); - } - } - $variables[$key] = $items; - $item['value'] = theme('linkedin_profile_user_page_' . $key, $variables); - } - else { - unset($item['value']); - } - } - //Simpler fields go directly through generic theme function - if (!empty($item['value'])) { - $account->linkedin[$key] = theme('linkedin_profile_user_page_item', array('item' => $item)); - } - } - } - } - } -} - -/** - * Implements hook_user_view(). - */ -function linkedin_profile_user_view($account, $view_mode) { - if (variable_get('linkedin_profile_user_page_enabled', 0) == 2 && linkedin_profile_display_access($account)) { - $account->content['linkedin'] = array( - '#type' => 'user_profile_item', - '#title' => t('Linkedin'), - '#markup' => theme('linkedin_profile_user_page', array('profile' => $account->linkedin)), - '#weight' => variable_get('linkedin_profile_user_page_weight', 2), - ); - } -} - -/* - * Implements hook_block_info(). - */ - -function linkedin_profile_block_info() { - $blocks = array(); - if (variable_get('linkedin_profile_user_page_enabled', 0) == 3) { - $blocks['linkedin_profile'] = array( - 'info' => t('LinkedIn Profile'), - 'description' => t('User\'s LinkedIn profile'), - ); - } - return $blocks; -} - -/* - * Implements hook_block_view(). - */ - -function linkedin_profile_block_view($delta = '') { - if (variable_get('linkedin_profile_user_page_enabled', '0') == 3 && arg(0) == 'user' && is_numeric(arg(1))) { - $account = user_load(arg(1)); - if (linkedin_profile_display_access($account)) { - $block['subject'] = t('Linkedin Profile'); - $block['content'] = theme('linkedin_profile_user_page', array('profile' => $account->linkedin)); - return $block; - } - } - return; -} - -/* - * Implementation of hook_theme() - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_profile_theme($existing, $type, $theme, $path) { - - $return = array(); - - //Define the main template file for users profile - $return['linkedin_profile_user_page'] = array( - 'variables' => array('profile' => NULL), - 'template' => 'linkedin-user-page', - ); - - //Deal with multi-structured fields - $multiples = array( - 'positions' => 'position', - 'educations' => 'education', - ); - foreach ($multiples as $key => $val) { - //Template files for multi-values structured fields - $return['linkedin_profile_user_page_' . $key] = array( - 'variables' => array($key => NULL), - 'template' => 'linkedin-user-page-' . $key, - ); - //Template file for multi-values structured fields items - $return['linkedin_profile_user_page_' . $val . '_item'] = array( - 'variables' => array($val => NULL), - 'template' => 'linkedin-user-page-' . $val . '-item', - ); - } - - //Let themers hook into other profile items - $return['linkedin_profile_user_page_item'] = array( - 'variables' => array('item' => NULL), - 'file' => 'linkedin_profile.theme.inc', - ); - - return $return; -} - -/* - * Helper function : defines default values - */ - -function _linkedin_profile_list_default_fields() { - $default_fields = array( - 'first-name', - 'last-name', - 'headline', - 'location', - 'industry', - 'summary', - 'specialties', - 'interests', - 'picture-url', - 'public-profile-url' - , - ); - return $default_fields; -} - -/* - * Helper function : wraps around variable_get - */ - -function _linkedin_profile_vget_user_page_linkedin_fields() { - $fields = array(); - $var_fields = variable_get('linkedin_profile_user_page_linkedin_fields', _linkedin_profile_list_default_fields()); - foreach ($var_fields as $field) { - if ($field !== 0) { - $fields[] = $field; - } - } - return $fields; -} + 'Linkedin', + 'type' => MENU_LOCAL_TASK, + 'page callback' => 'linkedin_profile_display', + 'page arguments' => array(1), + 'access callback' => 'linkedin_profile_display_access', + 'access arguments' => array(1), + 'file' => 'linkedin_profile.pages.inc', + ); + } + return $items; +} + +/* + * Custom access callback for user/%user/linkedin + */ + +function linkedin_profile_display_access($account) { + if (variable_get('linkedin_profile_user_page_enabled', 0) < 1) { + return FALSE; + } + if (!user_access('display LinkedIn profile', $account)) { + return FALSE; + } + if (!isset($account->data['linkedin_profile_user_page_enabled']) || $account->data['linkedin_profile_user_page_enabled'] != 1) { + return FALSE; + } + global $user; + if (!user_access('access user profiles') && $user->uid != $account->uid) { + return FALSE; + } + $check = linkedin_get_profile_fields($account->uid, array('id')); + if (isset($check['error-code'])) { // no need to display an empty tab + return FALSE; + } + return TRUE; +} + +/* + * Implementation of hook_perm() + */ + +function linkedin_profile_permission() { + return array( + 'display LinkedIn profile' => array( + 'title' => t('display LinkedIn profile'), + 'description' => t('Display own LinkedIn profile on user page.'), + ), + ); +} + +/* + * Implementation of hook_linkedin_user_edit_perms : + * Let Linkedin module know what permissions are available at user/%user/edit/linkedin + */ + +function linkedin_profile_linkedin_user_edit_perms() { + return array('display LinkedIn profile'); +} + +/** + * Implements hook_user_load(). + */ +function linkedin_profile_user_load($users) { + if (variable_get('linkedin_profile_user_page_enabled', 0) > 0) { + foreach ($users as $account) { + module_load_include('inc', 'linkedin', 'linkedin'); + $fields = _linkedin_profile_vget_user_page_linkedin_fields(); + $profile = linkedin_get_profile_fields($account->uid, $fields); + + if (!isset($profile['error-code'])) { + //Let themers hook into items + $multiples = array( + 'positions' => 'position', + 'educations' => 'education', + ); + foreach ($profile as $key => $value) { + $item = array( + 'name' => $key, + 'value' => $value, + ); + //deal with multi-values structured fields + if (array_key_exists($key, $multiples)) { + $items = array(); + $items_val = $profile[$key][$multiples[$key]]; + if (is_array($items_val)) { + if ($items_val['id']) { + $variables[$multiples[$key]] = $items_val; + $items[] = theme('linkedin_profile_user_page_' . $multiples[$key] . '_item', $variables); + } + else { + //iterate + foreach ($items_val as $item_val) { + $variables[$multiples[$key]] = $items_val; + $items[] = theme('linkedin_profile_user_page_' . $multiples[$key] . '_item', $variables); + } + } + $variables[$key] = $items; + $item['value'] = theme('linkedin_profile_user_page_' . $key, $variables); + } + else { + unset($item['value']); + } + } + //Simpler fields go directly through generic theme function + if (!empty($item['value'])) { + $account->linkedin[$key] = theme('linkedin_profile_user_page_item', array('item' => $item)); + } + } + } + } + } +} + +/** + * Implements hook_user_view(). + */ +function linkedin_profile_user_view($account, $view_mode) { + if (variable_get('linkedin_profile_user_page_enabled', 0) == 2 && linkedin_profile_display_access($account)) { + $account->content['linkedin'] = array( + '#type' => 'user_profile_item', + '#title' => t('Linkedin'), + '#markup' => theme('linkedin_profile_user_page', array('profile' => $account->linkedin)), + '#weight' => variable_get('linkedin_profile_user_page_weight', 2), + ); + } +} + +/* + * Implements hook_block_info(). + */ + +function linkedin_profile_block_info() { + $blocks = array(); + if (variable_get('linkedin_profile_user_page_enabled', 0) == 3) { + $blocks['linkedin_profile'] = array( + 'info' => t('LinkedIn Profile'), + 'description' => t('User\'s LinkedIn profile'), + ); + } + return $blocks; +} + +/* + * Implements hook_block_view(). + */ + +function linkedin_profile_block_view($delta = '') { + if (variable_get('linkedin_profile_user_page_enabled', '0') == 3 && arg(0) == 'user' && is_numeric(arg(1))) { + $account = user_load(arg(1)); + if (linkedin_profile_display_access($account)) { + $block['subject'] = t('Linkedin Profile'); + $block['content'] = theme('linkedin_profile_user_page', array('profile' => $account->linkedin)); + return $block; + } + } + return; +} + +/* + * Implementation of hook_theme() + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_profile_theme($existing, $type, $theme, $path) { + + $return = array(); + + //Define the main template file for users profile + $return['linkedin_profile_user_page'] = array( + 'variables' => array('profile' => NULL), + 'template' => 'linkedin-user-page', + ); + + //Deal with multi-structured fields + $multiples = array( + 'positions' => 'position', + 'educations' => 'education', + ); + foreach ($multiples as $key => $val) { + //Template files for multi-values structured fields + $return['linkedin_profile_user_page_' . $key] = array( + 'variables' => array($key => NULL), + 'template' => 'linkedin-user-page-' . $key, + ); + //Template file for multi-values structured fields items + $return['linkedin_profile_user_page_' . $val . '_item'] = array( + 'variables' => array($val => NULL), + 'template' => 'linkedin-user-page-' . $val . '-item', + ); + } + + //Let themers hook into other profile items + $return['linkedin_profile_user_page_item'] = array( + 'variables' => array('item' => NULL), + 'file' => 'linkedin_profile.theme.inc', + ); + + return $return; +} + +/* + * Helper function : defines default values + */ + +function _linkedin_profile_list_default_fields() { + $default_fields = array( + 'first-name', + 'last-name', + 'headline', + 'location', + 'industry', + 'summary', + 'specialties', + 'interests', + 'picture-url', + 'public-profile-url' + , + ); + return $default_fields; +} + +/* + * Helper function : wraps around variable_get + */ + +function _linkedin_profile_vget_user_page_linkedin_fields() { + $fields = array(); + $var_fields = variable_get('linkedin_profile_user_page_linkedin_fields', _linkedin_profile_list_default_fields()); + foreach ($var_fields as $field) { + if ($field !== 0) { + $fields[] = $field; + } + } + return $fields; +} diff --git a/linkedin_profile/linkedin_profile.pages.inc b/linkedin_profile/linkedin_profile.pages.inc index b498891..83d4f64 100644 --- a/linkedin_profile/linkedin_profile.pages.inc +++ b/linkedin_profile/linkedin_profile.pages.inc @@ -1,142 +1,142 @@ - t('Let users display information from their LinkedIn profile.'), - '#title' => t('User profile integration'), - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['linkedin_profile']['user_page'] = array( - '#description' => t('Enable users to display their LinkedIn profile page on their local user page.'), - '#title' => t('User page'), - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['linkedin_profile']['user_page']['linkedin_profile_user_page_enabled'] = array( - '#type' => 'select', - '#title' => 'Profile display', - '#options' => array( - 0 => t('Disabled'), - 1 => t('Tab'), - 2 => t('User page'), - 3 => t('Block'), - 4 => t('Hidden'), - ), - '#default_value' => variable_get('linkedin_profile_user_page_enabled', 0), - '#description' => '
  • ' . - t("Tab : will create a new tab containing the profile on the user's page") . '
  • ' . - t("User page : will display the profile amongst other elements on the user's page") . '
  • ' . - t("Block : will create a block containing the profile. Note you still have to activate it on the Blocks' admin page") . '
  • ' . - t('Hidden : Will not output anything, but make the data available as an array under $user->linkedin for theming') . - '
', - ); - - $form['linkedin_profile']['user_page']['linkedin_profile_user_page_weight'] = array( - '#type' => 'textfield', - '#title' => t('Profile item weight'), - '#maxlength' => 4, - '#size' => 2, - '#description' => t('"User Page" display only. Changing this value will make the profile display move below or after other elements on the user page. E.g. setting this to 100 will make it the very last element.'), - '#default_value' => variable_get('linkedin_profile_user_page_weight', 2), - ); - - $form['linkedin_profile']['user_page']['linkedin_profile_user_page_fields'] = array( - '#type' => 'fieldset', - '#title' => t('LinkedIn fields'), - '#description' => t('Choose what fields to retrieve from a user LinkedIn profile.'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['linkedin_profile']['user_page']['linkedin_profile_user_page_fields']['warning'] = array( - '#type' => 'markup', - '#value' => '
    ' . - '
  • ' . t('Be sure to observe what you are allowed to do with the data by checking the "Business and Legal" documents at http://developer.linkedin.com/community/apis?view=documents.') . '
  • ' . - '
  • ' . t('A description of each field is available at http://developer.linkedin.com/docs/DOC-1061.') . '
  • ' . - '
  • ' . t('Also, please note that the visibility of each field depends on the relation between the viewing and the viewed user at LinkedIn and his visibilty settings : be careful when theming the output.') . '
  • ' . - '
  • ' . t('And finally, the output might be buggy for some of them and will probably need some theming work.') . '
  • ' . - '
', - ); - module_load_include('inc', 'linkedin'); - $fields = _linkedin_list_fields('auth'); - $options = array(); - foreach ($fields as $field) { - $options[$field] = $field; - } - $form['linkedin_profile']['user_page']['linkedin_profile_user_page_fields']['linkedin_profile_user_page_linkedin_fields'] = array( - '#type' => 'checkboxes', - '#default_value' => _linkedin_profile_vget_user_page_linkedin_fields(), - '#options' => $options, - ); - - $form['#submit'][] = 'linkedin_profile_admin_submit'; - return $form; -} - -/* - * Additionnal submit for Linkedin admin page. - * Rebuild menu router to avoid problems when switching display from/to tab - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_profile_admin_submit(&$form_state) { - menu_rebuild(); -} - -/* - * Implementation of hook_linkedin_user_settings_page - * Add our settings to user/%user/edit/linkedin - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_profile_linkedin_user_settings_page($account) { - $elems = array(); - if (variable_get('linkedin_profile_user_page_enabled', 0) > 0 && user_access('display LinkedIn profile')) { - $elems['linkedin_profile_user_page_enabled'] = array( - '#type' => 'checkbox', - '#default_value' => isset($account->data['linkedin_profile_user_page_enabled']) ? $account->data['linkedin_profile_user_page_enabled'] : 0, - '#title' => t('Display an abstract of your LinkedIn page on your current profile page'), - ); - return $elems; - } - return; -} - -/* - * Page callback for user profile linkedin tab - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_profile_display($account) { - $profile = $account->linkedin; - if (!isset($profile['error-code'])) { - return theme('linkedin_profile_user_page', array('profile' => $account->linkedin)); - } -} + t('Let users display information from their LinkedIn profile.'), + '#title' => t('User profile integration'), + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['linkedin_profile']['user_page'] = array( + '#description' => t('Enable users to display their LinkedIn profile page on their local user page.'), + '#title' => t('User page'), + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['linkedin_profile']['user_page']['linkedin_profile_user_page_enabled'] = array( + '#type' => 'select', + '#title' => 'Profile display', + '#options' => array( + 0 => t('Disabled'), + 1 => t('Tab'), + 2 => t('User page'), + 3 => t('Block'), + 4 => t('Hidden'), + ), + '#default_value' => variable_get('linkedin_profile_user_page_enabled', 0), + '#description' => '
  • ' . + t("Tab : will create a new tab containing the profile on the user's page") . '
  • ' . + t("User page : will display the profile amongst other elements on the user's page") . '
  • ' . + t("Block : will create a block containing the profile. Note you still have to activate it on the Blocks' admin page") . '
  • ' . + t('Hidden : Will not output anything, but make the data available as an array under $user->linkedin for theming') . + '
', + ); + + $form['linkedin_profile']['user_page']['linkedin_profile_user_page_weight'] = array( + '#type' => 'textfield', + '#title' => t('Profile item weight'), + '#maxlength' => 4, + '#size' => 2, + '#description' => t('"User Page" display only. Changing this value will make the profile display move below or after other elements on the user page. E.g. setting this to 100 will make it the very last element.'), + '#default_value' => variable_get('linkedin_profile_user_page_weight', 2), + ); + + $form['linkedin_profile']['user_page']['linkedin_profile_user_page_fields'] = array( + '#type' => 'fieldset', + '#title' => t('LinkedIn fields'), + '#description' => t('Choose what fields to retrieve from a user LinkedIn profile.'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['linkedin_profile']['user_page']['linkedin_profile_user_page_fields']['warning'] = array( + '#type' => 'markup', + '#value' => '
    ' . + '
  • ' . t('Be sure to observe what you are allowed to do with the data by checking the "Business and Legal" documents at http://developer.linkedin.com/community/apis?view=documents.') . '
  • ' . + '
  • ' . t('A description of each field is available at http://developer.linkedin.com/docs/DOC-1061.') . '
  • ' . + '
  • ' . t('Also, please note that the visibility of each field depends on the relation between the viewing and the viewed user at LinkedIn and his visibilty settings : be careful when theming the output.') . '
  • ' . + '
  • ' . t('And finally, the output might be buggy for some of them and will probably need some theming work.') . '
  • ' . + '
', + ); + module_load_include('inc', 'linkedin'); + $fields = _linkedin_list_fields('auth'); + $options = array(); + foreach ($fields as $field) { + $options[$field] = $field; + } + $form['linkedin_profile']['user_page']['linkedin_profile_user_page_fields']['linkedin_profile_user_page_linkedin_fields'] = array( + '#type' => 'checkboxes', + '#default_value' => _linkedin_profile_vget_user_page_linkedin_fields(), + '#options' => $options, + ); + + $form['#submit'][] = 'linkedin_profile_admin_submit'; + return $form; +} + +/* + * Additionnal submit for Linkedin admin page. + * Rebuild menu router to avoid problems when switching display from/to tab + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_profile_admin_submit(&$form_state) { + menu_rebuild(); +} + +/* + * Implementation of hook_linkedin_user_settings_page + * Add our settings to user/%user/edit/linkedin + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_profile_linkedin_user_settings_page($account) { + $elems = array(); + if (variable_get('linkedin_profile_user_page_enabled', 0) > 0 && user_access('display LinkedIn profile')) { + $elems['linkedin_profile_user_page_enabled'] = array( + '#type' => 'checkbox', + '#default_value' => isset($account->data['linkedin_profile_user_page_enabled']) ? $account->data['linkedin_profile_user_page_enabled'] : 0, + '#title' => t('Display an abstract of your LinkedIn page on your current profile page'), + ); + return $elems; + } + return; +} + +/* + * Page callback for user profile linkedin tab + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_profile_display($account) { + $profile = $account->linkedin; + if (!isset($profile['error-code'])) { + return theme('linkedin_profile_user_page', array('profile' => $account->linkedin)); + } +} diff --git a/linkedin_profile/linkedin_profile.theme.inc b/linkedin_profile/linkedin_profile.theme.inc index 80d4adc..62b2f01 100644 --- a/linkedin_profile/linkedin_profile.theme.inc +++ b/linkedin_profile/linkedin_profile.theme.inc @@ -1,58 +1,58 @@ -'; - for ($i = 0; $i < count($item['value']['member-url']); $i++) { - $urls .= '
  • ' . l($item['value']['member-url'][$i]['name'], $item['value']['member-url'][$i]['url']) . '
  • '; - } - $urls .= ''; - $item['value'] = $urls; - } - else { - $item['value'] = l($item['value']['member-url']['name'], $item['value']['member-url']['url']); - } - break; - - case 'phone-numbers': - if ($item['value']['phone-number']['0']) { - $phones = '
      '; - for ($i = 0; $i < count($item['value']['phone-number']); $i++) { - $phones .= '
    • ' . $item['value']['phone-number'][$i]['phone-type'] . ': ' . $item['value']['member-url'][$i]['phone-number'] . '
    • '; - } - $phones .= '
    '; - $item['value'] = $phones; - } - else { - $item['value'] = $item['value']['phone-number']['phone-type'] . ': ' . $item['value']['phone-number']['phone-number']; - } - break; - } - $item['name'] = ucwords(str_replace('-', ' ', $item['name'])); - return $item; -} +'; + for ($i = 0; $i < count($item['value']['member-url']); $i++) { + $urls .= '
  • ' . l($item['value']['member-url'][$i]['name'], $item['value']['member-url'][$i]['url']) . '
  • '; + } + $urls .= ''; + $item['value'] = $urls; + } + else { + $item['value'] = l($item['value']['member-url']['name'], $item['value']['member-url']['url']); + } + break; + + case 'phone-numbers': + if ($item['value']['phone-number']['0']) { + $phones = '
      '; + for ($i = 0; $i < count($item['value']['phone-number']); $i++) { + $phones .= '
    • ' . $item['value']['phone-number'][$i]['phone-type'] . ': ' . $item['value']['member-url'][$i]['phone-number'] . '
    • '; + } + $phones .= '
    '; + $item['value'] = $phones; + } + else { + $item['value'] = $item['value']['phone-number']['phone-type'] . ': ' . $item['value']['phone-number']['phone-number']; + } + break; + } + $item['name'] = ucwords(str_replace('-', ' ', $item['name'])); + return $item; +} diff --git a/linkedin_status/README.txt b/linkedin_status/README.txt index 409905b..4fe0691 100644 --- a/linkedin_status/README.txt +++ b/linkedin_status/README.txt @@ -1,34 +1,34 @@ -=== LINKEDIN INTEGRATION === - -Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David -Landry (davad) Kyle Mathews (kyle_mathews) - -see http://drupal.org/node/919550 - -/********************************************* -Installation/initial configuration - - See http://drupal.org/node/919412. - - -/********************************************* -Configuration/Usage - -After enabling the module, go to admin/settings/linkedin. You can display the -"Login with LinkedIn" link under the standard login form page, under the -standard login form block, or as a stand-alone block. Note that if you choose -the stand-alone block, you still got to enable it at admin/build/block. Users -have to link their LinkedIn account to their local Drupal account from their -preferences at user/%user/edit/linkedin. If a visitor click on the link without -having tied the two accounts together, he will be asked to either login or -register as new user and redirected accordingly. - - -/********************************************* -Theming - -It provides the following theme function for the "Login with LinkedIn" link : - $display will be either -'drupal_login_page' 'drupal_login_block' 'linkedin_login_block', respectively -for standard login form page, standard login form block, and stand-alone block. +=== LINKEDIN INTEGRATION === + +Maintainers: Pascal Morin (bellesmanieres) Greg Harvey (greg.harvey) David +Landry (davad) Kyle Mathews (kyle_mathews) + +see http://drupal.org/node/919550 + +/********************************************* +Installation/initial configuration + + See http://drupal.org/node/919412. + + +/********************************************* +Configuration/Usage + +After enabling the module, go to admin/settings/linkedin. You can display the +"Login with LinkedIn" link under the standard login form page, under the +standard login form block, or as a stand-alone block. Note that if you choose +the stand-alone block, you still got to enable it at admin/build/block. Users +have to link their LinkedIn account to their local Drupal account from their +preferences at user/%user/edit/linkedin. If a visitor click on the link without +having tied the two accounts together, he will be asked to either login or +register as new user and redirected accordingly. + + +/********************************************* +Theming + +It provides the following theme function for the "Login with LinkedIn" link : + $display will be either +'drupal_login_page' 'drupal_login_block' 'linkedin_login_block', respectively +for standard login form page, standard login form block, and stand-alone block. diff --git a/linkedin_status/linkedin_status.css b/linkedin_status/linkedin_status.css index 58cb0cc..9c84430 100644 --- a/linkedin_status/linkedin_status.css +++ b/linkedin_status/linkedin_status.css @@ -1,13 +1,13 @@ - -div.linkedin-status { - margin-top:2em; - border-top:1px solid #eee; - font-weight:bold; - font-style:italic; -} -div.linkedin-status p.linkedin-submitted{ - font-weight:normal; - margin-bottom:0; - font-style:normal; - font-size:0.9em; + +div.linkedin-status { + margin-top:2em; + border-top:1px solid #eee; + font-weight:bold; + font-style:italic; +} +div.linkedin-status p.linkedin-submitted{ + font-weight:normal; + margin-bottom:0; + font-style:normal; + font-size:0.9em; } \ No newline at end of file diff --git a/linkedin_status/linkedin_status.info b/linkedin_status/linkedin_status.info index d64075c..1e03849 100644 --- a/linkedin_status/linkedin_status.info +++ b/linkedin_status/linkedin_status.info @@ -1,5 +1,5 @@ -name = "LinkedIn status update" -description = "Let users update their LinkedIn status message when creating nodes, leaving comments, ...." -package = "Linkedin" -core = 7.x +name = "LinkedIn status update" +description = "Let users update their LinkedIn status message when creating nodes, leaving comments, ...." +package = "Linkedin" +core = 7.x dependencies[] = "linkedin" \ No newline at end of file diff --git a/linkedin_status/linkedin_status.js b/linkedin_status/linkedin_status.js index 4de5e06..ae647f8 100644 --- a/linkedin_status/linkedin_status.js +++ b/linkedin_status/linkedin_status.js @@ -1,18 +1,18 @@ - -/* - * @file : hide the textfield on user posting form until enabled by checkbox. - */ -Drupal.behaviors.linkedin_status = function(context) { - - if (!$("#linkedin-status-posting").attr("checked")) { - $("#linkedin-status-textfield-wrapper").hide(); - } - $("#linkedin-status-posting").bind("click", function() { - if ($("#linkedin-status-posting").attr("checked")) { - $("#linkedin-status-textfield-wrapper").show(); - } - else { - $("#linkedin-status-textfield-wrapper").hide(); - } - }); -} + +/* + * @file : hide the textfield on user posting form until enabled by checkbox. + */ +Drupal.behaviors.linkedin_status = function(context) { + + if (!$("#linkedin-status-posting").attr("checked")) { + $("#linkedin-status-textfield-wrapper").hide(); + } + $("#linkedin-status-posting").bind("click", function() { + if ($("#linkedin-status-posting").attr("checked")) { + $("#linkedin-status-textfield-wrapper").show(); + } + else { + $("#linkedin-status-textfield-wrapper").hide(); + } + }); +} diff --git a/linkedin_status/linkedin_status.module b/linkedin_status/linkedin_status.module index 59c04ff..a406fe3 100644 --- a/linkedin_status/linkedin_status.module +++ b/linkedin_status/linkedin_status.module @@ -1,134 +1,134 @@ - array( - 'title' => t('update LinkedIn status'), - 'description' => t('Post to LInkedin on node edit/creation.'), - ), - 'use custom status text' => array( - 'title' => t('use custom status text'), - 'description' => t('Change the text sent to LinkedIn when posting.'), - ), - ); -} - -/* - * Implementation of hook_linkedin_user_edit_perms : - * Let Linkedin module know what permissions are available at user/%user/edit/linkedin - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_status_linkedin_user_edit_perms() { - return array('update LinkedIn status'); -} - -/* - * hook_form_alter() - * Call the user form when needed. - */ -function linkedin_status_form_alter(&$form, &$form_state, $form_id) { - //add posting form into nodes edit page and comments - if (isset($form['#node']) && user_access('update LinkedIn status')) { - if ($form['#node']->type . '_node_form' == $form_id && variable_get('linkedin_status_enabled_' . $form['#node']->type, 0) == 1) { - $node = $form['#node']; - } - elseif ('comment_node_' . $form['#node']->type . '_form' == $form_id && variable_get('linkedin_status_enabled_comment', 0) == 1) { - $node = node_load($form['nid']['#value']); - } - else { - return; - } - module_load_include('pages.inc', 'linkedin_status'); - global $user; - $array = array(); - $form['linkedin'] = linkedin_status_update_form_elements($node, $user); - array_unshift($form['#submit'], 'linkedin_status_update_form_submit'); - } -} - -/** - * Implements hook_node_insert(). - */ -function linkedin_status_node_insert($node) { - if ($node->linkedin_status['posting'] == '1' && !empty($node->linkedin_status['status'])) { - global $user; - linkedin_status_set_status($node->linkedin_status['status'], $node); - } -} - -/** - * Invokes hook_li_placeholders, hook_li_body, and hook_li_set_status - */ -function linkedin_status_set_status($status, $node) { - global $user; - $placeholders = module_invoke_all('li_placeholders', $node); - $body = module_invoke_all('li_body', $status, $placeholders); - drupal_alter('linkedin_status_set_status', $body, $node); - module_invoke_all('li_set_status', $user->uid, $body); -} - -/** - * Implements hook_li_placeholders(). - */ -function linkedin_status_li_placeholders($node) { - global $user; - global $base_url; - $placeholders = array( - '!title' => $node->title, - '!url' => url('node/' . $node->nid, array('absolute' => TRUE)), - '!user' => $user->name, - '!site' => variable_get('site_name', $base_url), - ); - return $placeholders; -} - -/** - * Implements hook_li_body(). - */ -function linkedin_status_li_body($status, $placeholders) { - global $user; - $body['comment'] = strtr($status, $placeholders); - $body['title'] = $placeholders['!title']; - $body['submitted-url'] = $placeholders['!url']; - return $body; -} - -/** - * Implements hook_li_set_status(). - */ -function linkedin_status_li_set_status($uid, $status) { - global $user; - linkedin_put_profile_field($user->uid, $status, 'shares'); - drupal_set_message(t('Posted to LinkedIn')); -} + array( + 'title' => t('update LinkedIn status'), + 'description' => t('Post to LInkedin on node edit/creation.'), + ), + 'use custom status text' => array( + 'title' => t('use custom status text'), + 'description' => t('Change the text sent to LinkedIn when posting.'), + ), + ); +} + +/* + * Implementation of hook_linkedin_user_edit_perms : + * Let Linkedin module know what permissions are available at user/%user/edit/linkedin + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_status_linkedin_user_edit_perms() { + return array('update LinkedIn status'); +} + +/* + * hook_form_alter() + * Call the user form when needed. + */ +function linkedin_status_form_alter(&$form, &$form_state, $form_id) { + //add posting form into nodes edit page and comments + if (isset($form['#node']) && user_access('update LinkedIn status')) { + if ($form['#node']->type . '_node_form' == $form_id && variable_get('linkedin_status_enabled_' . $form['#node']->type, 0) == 1) { + $node = $form['#node']; + } + elseif ('comment_node_' . $form['#node']->type . '_form' == $form_id && variable_get('linkedin_status_enabled_comment', 0) == 1) { + $node = node_load($form['nid']['#value']); + } + else { + return; + } + module_load_include('pages.inc', 'linkedin_status'); + global $user; + $array = array(); + $form['linkedin'] = linkedin_status_update_form_elements($node, $user); + array_unshift($form['#submit'], 'linkedin_status_update_form_submit'); + } +} + +/** + * Implements hook_node_insert(). + */ +function linkedin_status_node_insert($node) { + if ($node->linkedin_status['posting'] == '1' && !empty($node->linkedin_status['status'])) { + global $user; + linkedin_status_set_status($node->linkedin_status['status'], $node); + } +} + +/** + * Invokes hook_li_placeholders, hook_li_body, and hook_li_set_status + */ +function linkedin_status_set_status($status, $node) { + global $user; + $placeholders = module_invoke_all('li_placeholders', $node); + $body = module_invoke_all('li_body', $status, $placeholders); + drupal_alter('linkedin_status_set_status', $body, $node); + module_invoke_all('li_set_status', $user->uid, $body); +} + +/** + * Implements hook_li_placeholders(). + */ +function linkedin_status_li_placeholders($node) { + global $user; + global $base_url; + $placeholders = array( + '!title' => $node->title, + '!url' => url('node/' . $node->nid, array('absolute' => TRUE)), + '!user' => $user->name, + '!site' => variable_get('site_name', $base_url), + ); + return $placeholders; +} + +/** + * Implements hook_li_body(). + */ +function linkedin_status_li_body($status, $placeholders) { + global $user; + $body['comment'] = strtr($status, $placeholders); + $body['title'] = $placeholders['!title']; + $body['submitted-url'] = $placeholders['!url']; + return $body; +} + +/** + * Implements hook_li_set_status(). + */ +function linkedin_status_li_set_status($uid, $status) { + global $user; + linkedin_put_profile_field($user->uid, $status, 'shares'); + drupal_set_message(t('Posted to LinkedIn')); +} diff --git a/linkedin_status/linkedin_status.pages.inc b/linkedin_status/linkedin_status.pages.inc index 22d9397..03831c6 100644 --- a/linkedin_status/linkedin_status.pages.inc +++ b/linkedin_status/linkedin_status.pages.inc @@ -1,207 +1,207 @@ - t('Enable users to update their LinkedIn user status when performing following actions.'), - '#title' => t('Status update'), - '#type' => 'fieldset', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['linkedin_status']['node_types'] = array( - '#description' => t('Let users update their status when creating/editing nodes of these types.'), - '#title' => t('Node types'), - '#type' => 'fieldset', - ); - $types = node_type_get_types(); - foreach ($types as $type) { - $form['linkedin_status']['node_types']['linkedin_status_enabled_' . $type->type] = array( - '#type' => 'checkbox', - '#prefix' => '
    ', - '#suffix' => '
    ', - '#title' => $type->name, - '#default_value' => variable_get('linkedin_status_enabled_' . $type->type, '0'), - ); - $form['linkedin_status']['node_types']['linkedin_status_default_format_' . $type->type] = array( - '#type' => 'textfield', - '#prefix' => '
    ', - '#suffix' => '
    ', - '#title' => t('Default format string'), - '#maxlength' => 140, - '#description' => t('Text that will be posted to Linked In. You can use !url, !title, !user, and !site as replacement text.'), - '#default_value' => variable_get('linkedin_status_default_format_' . $type->type, 'Posted "!title" on !site'), - ); - } - if (module_exists('signup')) { - $form['linkedin_status']['event_signup'] = array( - '#description' => t('Let users update their status when signing up to events.'), - '#title' => t('Users signup'), - '#type' => 'fieldset', - ); - $form['linkedin_status']['event_signup']['linkedin_status_enabled_event_signup'] = array( - '#type' => 'checkbox', - '#title' => 'Enable', - '#default_value' => variable_get('linkedin_status_enabled_event_signup', '0'), - ); - $form['linkedin_status']['event_signup']['linkedin_status_default_format_event_signup'] = array( - '#type' => 'textfield', - '#title' => t('Default format string'), - '#maxlength' => 140, - '#description' => t('Text that will be posted to Linked In. You can use !url, !title, !user, and !site as replacement text.'), - '#default_value' => variable_get('linkedin_status_default_format_event_signup', 'Posted "!title" on !site'), - ); - } - - //Enable status update on comments - if (module_exists('comment')) { - $form['linkedin_status']['comment'] = array( - '#description' => t('Let users update their status when adding comments to a Linkedin enabled node.'), - '#title' => t('Comments'), - '#type' => 'fieldset', - ); - $form['linkedin_status']['comment']['linkedin_status_enabled_comment'] = array( - '#type' => 'checkbox', - '#title' => 'Enable', - '#default_value' => variable_get('linkedin_status_enabled_comment', '0'), - ); - $form['linkedin_status']['comment']['linkedin_status_default_format_comment'] = array( - '#type' => 'textfield', - '#title' => t('Default format string'), - '#maxlength' => 140, - '#description' => t('Text that will be posted to Linked In. You can use !url, !title, !user, and !site as replacement text.'), - '#default_value' => variable_get('linkedin_status_default_format_comment', 'Commented on "!title" on !site'), - ); - } - - return $form; -} - -/* - * Implementation of hook_linkedin_user_settings_page - * Add our settings to user/%user/edit/linkedin - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_status_linkedin_user_settings_page($account) { - $elems = array(); - if (user_access('update LinkedIn status')) { - //check if linkedin status update is enabled for at least one content type - $types = node_type_get_types(); - $type = new stdClass(); - //$type->type = 'event_signup'; - //$types[] = $type; - $type->type = 'comment'; - $types[] = $type; - foreach ($types as $type) { - if (variable_get('linkedin_status_enabled_' . $type->type, '0' == '1')) { - //if true add related option - $elems['linkedin_status_enabled_by_default'] = array( - '#type' => 'checkbox', - '#default_value' => isset($account->data['linkedin_status_enabled_by_default']) ? $account->data['linkedin_status_enabled_by_default'] : '0', - '#title' => t('By default, on actions such as posting content, update your LinkedIn status'), - '#description' => t('(You can always bypass this setting individually)'), - ); - return $elems; - } - } - } - return; -} - -/* - * Form that will appear on places where users can update their linkedin status (node edit, signup, ...) - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_status_update_form_elements($node, $user) { - // set up the state of the checkbox in the form - - if (isset($user->data['linkedin_status_enabled_by_default']) && $user->data['linkedin_status_enabled_by_default'] == 1 && !isset($node->nid)) { - $checked = 1; - } - else { - $checked = 0; - } - - //prepare the form base checkbox - $elems['linkedin_status'] = array( - '#type' => 'fieldset', - '#title' => t('Post to LinkedIn'), - '#tree' => TRUE, - ); - $elems['linkedin_status']['posting'] = array( - '#type' => 'checkbox', - '#id' => 'linkedin-status-posting', - '#default_value' => $checked, - ); - $elems['linkedin_status']['posting']['#title'] = t('Announce on LinkedIn'); - - //check if user can post to LinkedIn. No need to load all the following if the form is to be disabled anyway - $check = linkedin_get_profile_fields($user->uid, array('id')); - if (!isset($check['id'])) { //disabling form for users who have not yet authorised our site and link them to the right place - $elems['linkedin_status']['posting']['#disabled'] = TRUE; - $elems['linkedin_status']['posting']['#prefix'] = '

    ' . t('You must first authorize this feature in your user profile : !url', array('!url' => l($user->name, 'user/' . $user->uid . '/edit/linkedin'))) . '

    '; - } - else { //user can post - //add textfield is user has perm. - if (user_access('use custom status text')) { - // two lines of js for hiding the texfield if checkbox is unchecked. - drupal_add_js(drupal_get_path('module', 'linkedin_status') . '/linkedin_status.js'); - $elems['linkedin_status']['status'] = array( - '#type' => 'textfield', - '#default_value' => variable_get('linkedin_status_default_format_' . $node->type, ''), - '#description' => t('This text will be set as your current status on linkedin. You can use !title, !url, !user and !site as replacement text.'), - '#id' => 'linkedin-status-textfield', - ); - } - else { - $elems['linkedin_status']['status'] = array( - '#type' => 'hidden', - '#value' => variable_get('linkedin_status_default_format_' . $node->type, ''), - ); - } - } - return $elems; -} - -/* - * Submit for user posting their status - */ - -/** - * @todo Please document this function. - * @see http://drupal.org/node/1354 - */ -function linkedin_status_update_form_submit($form, &$form_state) { - //Check the node is published. - if ($form_state['values']['status'] != 1) { - $form_state['values']['linkedin_status']['posting'] = 0; - return; - } - if ( - $form_state['values']['linkedin_status']['posting'] == '1' && - !empty($form_state['values']['linkedin_status']['status']) && - user_access('update LinkedIn status') && - !empty($form_state['values']['nid']) - ) { - $node = node_load($form_state['values']['nid']); - linkedin_status_set_status($form_state['values']['linkedin_status']['status'], $node); - } -} + t('Enable users to update their LinkedIn user status when performing following actions.'), + '#title' => t('Status update'), + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['linkedin_status']['node_types'] = array( + '#description' => t('Let users update their status when creating/editing nodes of these types.'), + '#title' => t('Node types'), + '#type' => 'fieldset', + ); + $types = node_type_get_types(); + foreach ($types as $type) { + $form['linkedin_status']['node_types']['linkedin_status_enabled_' . $type->type] = array( + '#type' => 'checkbox', + '#prefix' => '
    ', + '#suffix' => '
    ', + '#title' => $type->name, + '#default_value' => variable_get('linkedin_status_enabled_' . $type->type, '0'), + ); + $form['linkedin_status']['node_types']['linkedin_status_default_format_' . $type->type] = array( + '#type' => 'textfield', + '#prefix' => '
    ', + '#suffix' => '
    ', + '#title' => t('Default format string'), + '#maxlength' => 140, + '#description' => t('Text that will be posted to Linked In. You can use !url, !title, !user, and !site as replacement text.'), + '#default_value' => variable_get('linkedin_status_default_format_' . $type->type, 'Posted "!title" on !site'), + ); + } + if (module_exists('signup')) { + $form['linkedin_status']['event_signup'] = array( + '#description' => t('Let users update their status when signing up to events.'), + '#title' => t('Users signup'), + '#type' => 'fieldset', + ); + $form['linkedin_status']['event_signup']['linkedin_status_enabled_event_signup'] = array( + '#type' => 'checkbox', + '#title' => 'Enable', + '#default_value' => variable_get('linkedin_status_enabled_event_signup', '0'), + ); + $form['linkedin_status']['event_signup']['linkedin_status_default_format_event_signup'] = array( + '#type' => 'textfield', + '#title' => t('Default format string'), + '#maxlength' => 140, + '#description' => t('Text that will be posted to Linked In. You can use !url, !title, !user, and !site as replacement text.'), + '#default_value' => variable_get('linkedin_status_default_format_event_signup', 'Posted "!title" on !site'), + ); + } + + //Enable status update on comments + if (module_exists('comment')) { + $form['linkedin_status']['comment'] = array( + '#description' => t('Let users update their status when adding comments to a Linkedin enabled node.'), + '#title' => t('Comments'), + '#type' => 'fieldset', + ); + $form['linkedin_status']['comment']['linkedin_status_enabled_comment'] = array( + '#type' => 'checkbox', + '#title' => 'Enable', + '#default_value' => variable_get('linkedin_status_enabled_comment', '0'), + ); + $form['linkedin_status']['comment']['linkedin_status_default_format_comment'] = array( + '#type' => 'textfield', + '#title' => t('Default format string'), + '#maxlength' => 140, + '#description' => t('Text that will be posted to Linked In. You can use !url, !title, !user, and !site as replacement text.'), + '#default_value' => variable_get('linkedin_status_default_format_comment', 'Commented on "!title" on !site'), + ); + } + + return $form; +} + +/* + * Implementation of hook_linkedin_user_settings_page + * Add our settings to user/%user/edit/linkedin + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_status_linkedin_user_settings_page($account) { + $elems = array(); + if (user_access('update LinkedIn status')) { + //check if linkedin status update is enabled for at least one content type + $types = node_type_get_types(); + $type = new stdClass(); + //$type->type = 'event_signup'; + //$types[] = $type; + $type->type = 'comment'; + $types[] = $type; + foreach ($types as $type) { + if (variable_get('linkedin_status_enabled_' . $type->type, '0' == '1')) { + //if true add related option + $elems['linkedin_status_enabled_by_default'] = array( + '#type' => 'checkbox', + '#default_value' => isset($account->data['linkedin_status_enabled_by_default']) ? $account->data['linkedin_status_enabled_by_default'] : '0', + '#title' => t('By default, on actions such as posting content, update your LinkedIn status'), + '#description' => t('(You can always bypass this setting individually)'), + ); + return $elems; + } + } + } + return; +} + +/* + * Form that will appear on places where users can update their linkedin status (node edit, signup, ...) + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_status_update_form_elements($node, $user) { + // set up the state of the checkbox in the form + + if (isset($user->data['linkedin_status_enabled_by_default']) && $user->data['linkedin_status_enabled_by_default'] == 1 && !isset($node->nid)) { + $checked = 1; + } + else { + $checked = 0; + } + + //prepare the form base checkbox + $elems['linkedin_status'] = array( + '#type' => 'fieldset', + '#title' => t('Post to LinkedIn'), + '#tree' => TRUE, + ); + $elems['linkedin_status']['posting'] = array( + '#type' => 'checkbox', + '#id' => 'linkedin-status-posting', + '#default_value' => $checked, + ); + $elems['linkedin_status']['posting']['#title'] = t('Announce on LinkedIn'); + + //check if user can post to LinkedIn. No need to load all the following if the form is to be disabled anyway + $check = linkedin_get_profile_fields($user->uid, array('id')); + if (!isset($check['id'])) { //disabling form for users who have not yet authorised our site and link them to the right place + $elems['linkedin_status']['posting']['#disabled'] = TRUE; + $elems['linkedin_status']['posting']['#prefix'] = '

    ' . t('You must first authorize this feature in your user profile : !url', array('!url' => l($user->name, 'user/' . $user->uid . '/edit/linkedin'))) . '

    '; + } + else { //user can post + //add textfield is user has perm. + if (user_access('use custom status text')) { + // two lines of js for hiding the texfield if checkbox is unchecked. + drupal_add_js(drupal_get_path('module', 'linkedin_status') . '/linkedin_status.js'); + $elems['linkedin_status']['status'] = array( + '#type' => 'textfield', + '#default_value' => variable_get('linkedin_status_default_format_' . $node->type, ''), + '#description' => t('This text will be set as your current status on linkedin. You can use !title, !url, !user and !site as replacement text.'), + '#id' => 'linkedin-status-textfield', + ); + } + else { + $elems['linkedin_status']['status'] = array( + '#type' => 'hidden', + '#value' => variable_get('linkedin_status_default_format_' . $node->type, ''), + ); + } + } + return $elems; +} + +/* + * Submit for user posting their status + */ + +/** + * @todo Please document this function. + * @see http://drupal.org/node/1354 + */ +function linkedin_status_update_form_submit($form, &$form_state) { + //Check the node is published. + if ($form_state['values']['status'] != 1) { + $form_state['values']['linkedin_status']['posting'] = 0; + return; + } + if ( + $form_state['values']['linkedin_status']['posting'] == '1' && + !empty($form_state['values']['linkedin_status']['status']) && + user_access('update LinkedIn status') && + !empty($form_state['values']['nid']) + ) { + $node = node_load($form_state['values']['nid']); + linkedin_status_set_status($form_state['values']['linkedin_status']['status'], $node); + } +} -- 2.1.2