Table Of Contents:

We have seen in Part one of LinkedIn API tutorial how to connect to LinkedIn API via OAuth protocol and how to retreive users profile.

In Part 2 we will enrich our PHP LinkedIn Class with:

  • An Update Status Capability
  • A Clear Status Capability
  • A Read Status Capability

Here is the Screencast followed by a written tutorial:

http://blip.tv/file/get/Formatix-LinkedInAPIPhpZendOAuthUpdateStatus851.mp4

Tutorial

Step 0. Using Oauth Authentication

This Step has been described in details in our first Screencast Connect to LinkedIn API using Oauth . I strongly recommend you watch it before starting this one.

This Step can be divided in 5 phases:

  1. Grabbing the LinkedIn Consumer Keys
  2. Grabbing Zend and Zend Incubator Librairies
  3. Include Zend_OAuth_Consumer Module
  4. Correct Zend_Oauth Module (This very new module has some bugs)
  5. Undertake the OAuth Handshake

Step 1. Add a GetStatus method

public function getStatus()
{
// Set LinkedIn's GetStatus URI
$this->client->setUri('http://api.linkedin.com/v1/people/~:(current-status)');

// Set HTTP Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::GET);

// Execute Request and get Response
$response = $this->client->request();

// Get the XML containing User's Status
$content =  $response->getBody();

// Use Php simplexml to transform XML to a PHP Object
$xml = simplexml_load_string($content);

// Store Status
$status = (string) $xml->{'current-status'};

// Return Status as result
return $status;

}

Step 2. Add a updateStatus method

public function updateStatus($status)
{
// Set LinkedIn's Set Status URI
$this->client->setUri('https://api.linkedin.com/v1/people/~/current-status');

// Set HTTP Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::PUT );

// Create XML String containing Users Status to be passed with the PUT
$xml = $this->createXmlStatus($status);

// Attach the XML String to the HTTP request
$this->client->setRawData($xml,'text/xml');

// Set the Content Type in the HTTP Header
$this->client->setHeaders('Content-Type', 'text/xml');

// Execute Request
$this->client->request();

}

Step 3. Add a clearStatus method

public function clearStatus()
{
// Set LinkedIn's Clear Status URI
$this->client->setUri('https://api.linkedin.com/v1/people/~/current-status');

// Set HTTP Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::DELETE );

// Execute Request
$this->client->request();

}

Step 4. Correct Zend_OAuth

As I’m doing this tutorial the very new Zend_OAuth Zend module still has some bugs which will probably be corrected when Zend_OAuth will officially join the Zend Framework that is to say in Zend Framework 1.10 .

In order to be able to do some HTTP “PUT” and “DELETE” we will have for now to modify 2 Zend_OAuth methods.

In the file incubator/library/Zend/Oauth/Client.php comment the if/else statement et call setRequestMethod regardless of $method value.

    public function setMethod($method = self::GET)
    {

        $this->setRequestMethod($method);

        //if ($method == self::GET) {
        //    $this->setRequestMethod(self::GET);
        //} elseif($method == self::POST) {
        //    $this->setRequestMethod(self::POST);
        //}
        return parent::setMethod($method);
    }

Then you will notice that setRequestMethod doesn’t support PUT nor DELETE either.

In file /incubator/library/Zend/Oauth/Config.php you will have to do something so that setRequestMethod will not trigger an error when given a PUT or a DELETE

You can make a quick and dirty workaround by commenting the control code as follows:

    public function setRequestMethod($method)
    {
        $method = strtoupper($method);
        //if (!in_array($method, array(Zend_Oauth::GET, Zend_Oauth::POST))) {
        //    require_once 'Zend/Oauth/Exception.php';
        //    throw new Zend_Oauth_Exception('Invalid method: '.$method);
        //}
        $this->_requestMethod = $method;
    }

Or do that nicely by adding PUT and DELETE to the control array:

    public function setRequestMethod($method)
    {
        $method = strtoupper($method);
        if (!in_array($method, array(Zend_Oauth::GET, Zend_Oauth::POST, Zend_Oauth::PUT, Zend_Oauth::DELETE))) {
            require_once 'Zend/Oauth/Exception.php';
            throw new Zend_Oauth_Exception('Invalid method: '.$method);
        }
        $this->_requestMethod = $method;
    }

Step 5. Test these new methods

The Test is divided in 3 phases

  • Instanciation of the LinkedIn Php Class
  • Connection and Authentication of the User
  • Calling the New Methods/li>

In our example we will

  • Get the LinkedIn user profile
    Display it
  • Get the users LinkedIn Status
    Display it
  • Update users LinkedIn Status with the following message << Testing LinkedIn Status Update using Zend OAuth >>
  • Get the users Status
    Display it in order to verify it has been correctly set
  • Clear the users status
  • Get the users status
    Display it in order to to see it has been correctly cleared
/*
*
* @abstract:  Test LinkedIn's Php Class
* @author: Christophe Fiat
* @copyright: FormatiX.EU
*
*/

// Set Parameters
$params = Array(    'consumerKey' => 'YOUR_CONSUMER_KEY',
'consumerSecret' => 'YOUR_CONSUMER_SECRET_KEY',
'localUrl' => 'YOUR_Local_URL',
'callbackUrl' => 'YOUR_Callback_URL',
'zendPath'	 => 'YOUR_Zend_Path',
'zendIncubatorPath'	 => 'YOUR_Zend_Incubator_Path'
);

// Create an Instance of LinkedIn's PHP Class
$linkedin = new linkedIn($params);

// Connect to LinkedIn API Via OAuth
$linkedin->connect();

// Call whoAmI method to Get User's profile
$profilInfo =$linkedin->whoAmI();

// Display User's profile
echo'<h2>Prenom: '.$profilInfo['firstName']. '</h2>';
echo'<h2>Nom: '.$profilInfo['lastName']. '</h2>';
echo'<h2>Fonction: '.$profilInfo['headline']. '</h2>';
echo'<h2><a href="'.$profilInfo['profilUrl'].'">profil LinkedIn </a></h2>';

// Get User's Status
$userStatus = $linkedin->getStatus();

// Display User's Status
if(!empty($userStatus))
{
echo"<h2>Statut Of  ".$profilInfo['firstName'] . ' ' . $profilInfo['lastName'] .":
$userStatus </h2>";
}
else
{
echo'<h2>No Status</h2>';
}

// Modify User's LinkedIn Status
$linkedin->updateStatus('Testing LinkedIn Status Update using Zend OAuth');

// Get The New Status
$userStatus = $linkedin->getStatus();

// Display User's LinkedIn Status
if(!empty($userStatus))
{
echo"<h2>Statut Of  ".$profilInfo['firstName'] . ' ' . $profilInfo['lastName'] .":
$userStatus </h2>";
}
else
{
echo'<h2>No Status</h2>';
}

// Clear User's LinkedIn Status
$linkedin->clearStatus();

// Get Status
$userStatus = $linkedin->getStatus();

// Display User's Status
if(!empty($userStatus))
{
echo"<h2>Statut Of  ".$profilInfo['firstName'] . ' ' . $profilInfo['lastName'] .":
$userStatus </h2>";
}
else
{
echo'<h2>No Status</h2>';
}

// The END! ;)

Step 6. Here is the Enriched PHP Class

<?php

/*
*
* @abstract: Cette Classe sert a accéder a l'API de LinkedIn en utilisant l'Authentification Oauth Authentication Protocol
* @author: Christophe Fiat
* @version: 0.2 2009-12-06
* @copyright: FormatiX.EU
*
*/

class linkedIn
{

private $options;
private $consumer;
private $client;
private $token;

public function __construct($params)
{
// Add Zend and Zend Incubator Paths to the Include Path
set_include_path( $params['zendPath'] . PATH_SEPARATOR .  $params['zendIncubatorPath'] . PATH_SEPARATOR . get_include_path() );

// Include Oauth Consumer class definition
require_once('Zend/Oauth/Consumer.php');

// Set Zend_Oauth_Consumer options
$this->options = array(
'version' => '1.0',
'localUrl' => $params['localUrl'],
'callbackUrl' => $params['callbackUrl'],
'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken',
'userAuthorisationUrl' => 'https://api.linkedin.com/uas/oauth/authorize',
'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken',
'consumerKey' => $params['consumerKey'],
'consumerSecret' => $params['consumerSecret']
);

// Instanciate Zend_Oauth_Consumer Class
$this->consumer = new Zend_Oauth_Consumer( $this->options );

}

public function connect()
{
// Start Session to be able to store Request Token and Access Token
session_start ();

if ( !isset ( $_SESSION ['ACCESS_TOKEN'] )) {
// We do not have any Access token Yet
if (! empty ( $_GET )) {
// But We have some parameters passed throw the URL

// Get the LinkedIn Access Token
$this->token = $this->consumer->getAccessToken ( $_GET, unserialize ( $_SESSION ['REQUEST_TOKEN'] ) );

// Store the LinkedIn Access Token
$_SESSION ['ACCESS_TOKEN'] = serialize ( $this->token );
} else {
// We have Nothing

// Start Requesting a LinkedIn Request Token
$this->token = $this->consumer->getRequestToken ();

// Store the LinkedIn Request Token
$_SESSION ['REQUEST_TOKEN'] = serialize ( $this->token );

// Redirect the Web User to LinkedIn Authentication Page
$this->consumer->redirect ();
}
} else {
// We've already Got a LinkedIn Access Token

// Restore The LinkedIn Access Token
$this->token = unserialize ( $_SESSION ['ACCESS_TOKEN'] );

}

// Use HTTP Client with built-in OAuth request handling
$this->client = $this->token->getHttpClient($this->options);

}

/*
* @abstract: This Method Grabs LinkedIn User Profile from LinkedIn API
*/
public function whoAmI()
{
// Set LinkedIn URI
$this->client->setUri('https://api.linkedin.com/v1/people/~');
// Set Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::GET);
// Execute Request and get Response
$response = $this->client->request();

// Get the XML containing User's Profile
$content =  $response->getBody();

// Uncomment Following Line To display XML result
// header('Content-Type: ' . $response->getHeader('Content-Type'));
// echo $content;
// exit;

// Use Php simplexml to transform XML to a PHP Object
$xml = simplexml_load_string($content);

// Uncomment Following Lines To display Simple XML Object Structure
// echo '<pre>';
// print_r($xml);
// echo'</pre>';

// Uncomment Following Lines To display LinkedIn User Profile
// echo 'First Name: ' . $xml->{'first-name'};
// echo '<br/>';
// echo 'Last Name: ' . $xml->{'last-name'};
// echo '<br/>';
// echo 'Headline: ' . $xml->{'headline'};

// Put the User Profile info in an Array
$info['firstName']  = (string) $xml->{'first-name'};
$info['lastName']   = (string) $xml->{'last-name'};
$info['headline']   = (string) $xml->{'headline'};
$info['profilUrl'] = (string) $xml->{'site-standard-profil-request'}->url;

// Return the Array as result
return $info;
}

/*
* @abstract: Creates THE XML string containing the User Status
*/
private function createXmlStatus($status)
{
$xml = '<?xml version="1.0" encoding="UTF-8"?><current-status>'.$status.'</current-status>';

return $xml;
}

/*
* @abstract: Gets the User's LinkedIn Status
*/
public function getStatus()
{
// Set LinkedIn's GetStatus URI
$this->client->setUri('http://api.linkedin.com/v1/people/~:(current-status)');

// Set HTTP Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::GET);

// Execute Request and get Response
$response = $this->client->request();

// Get the XML containing User's Status
$content =  $response->getBody();

// Use Php simplexml to transform XML to a PHP Object
$xml = simplexml_load_string($content);

// Store Status
$status = (string) $xml->{'current-status'};

// Return Status as result
return $status;

}
public function updateStatus($status)
{
// Set LinkedIn's Set Status URI
$this->client->setUri('https://api.linkedin.com/v1/people/~/current-status');

// Set HTTP Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::PUT );

// Create XML String containing Users Status to be passed with the PUT
$xml = $this->createXmlStatus($status);

// Attach the XML String to the HTTP request
$this->client->setRawData($xml,'text/xml');

// Set the Content Type in the HTTP Header
$this->client->setHeaders('Content-Type', 'text/xml');

// Execute Request
$this->client->request();

}

public function clearStatus()
{
// Set LinkedIn's Clear Status URI
$this->client->setUri('https://api.linkedin.com/v1/people/~/current-status');

// Set HTTP Method (GET, POST, PUT, or DELETE)
$this->client->setMethod(Zend_Http_Client::DELETE );

// Execute Request
$this->client->request();

}

} // Class End

/*
*
* @abstract:  Test LinkedIn's Php Class
* @author: Christophe Fiat
* @copyright: FormatiX.EU
*
*/

// Set Parameters
$params = Array(    'consumerKey' => 'YOUR_CONSUMER_KEY',
'consumerSecret' => 'YOUR_CONSUMER_SECRET_KEY',
'localUrl' => 'YOUR_Local_URL',
'callbackUrl' => 'YOUR_Callback_URL',
'zendPath'	 => 'YOUR_Zend_Path',
'zendIncubatorPath'	 => 'YOUR_Zend_Incubator_Path'
);

// Create an Instance of LinkedIn's PHP Class
$linkedin = new linkedIn($params);

// Connect to LinkedIn API Via OAuth
$linkedin->connect();

// Call whoAmI method to Get User's profile
$profilInfo =$linkedin->whoAmI();

// Display User's profile
echo'<h2>Prenom: '.$profilInfo['firstName']. '</h2>';
echo'<h2>Nom: '.$profilInfo['lastName']. '</h2>';
echo'<h2>Fonction: '.$profilInfo['headline']. '</h2>';
echo'<h2><a href="'.$profilInfo['profilUrl'].'">profil LinkedIn </a></h2>';

// Get User's Status
$userStatus = $linkedin->getStatus();

// Display User's Status
if(!empty($userStatus))
{
echo"<h2>Statut Of  ".$profilInfo['firstName'] . ' ' . $profilInfo['lastName'] .":
$userStatus </h2>";
}
else
{
echo'<h2>No Status</h2>';
}

// Modify User's LinkedIn Status
$linkedin->updateStatus('Testing LinkedIn Status Update using Zend OAuth');

// Get The New Status
$userStatus = $linkedin->getStatus();

// Display User's LinkedIn Status
if(!empty($userStatus))
{
echo"<h2>Statut Of  ".$profilInfo['firstName'] . ' ' . $profilInfo['lastName'] .":
$userStatus </h2>";
}
else
{
echo'<h2>No Status</h2>';
}

// Clear User's LinkedIn Status
$linkedin->clearStatus();

// Get Status
$userStatus = $linkedin->getStatus();

// Display User's Status
if(!empty($userStatus))
{
echo"<h2>Statut Of  ".$profilInfo['firstName'] . ' ' . $profilInfo['lastName'] .":
$userStatus </h2>";
}
else
{
echo'<h2>No Status</h2>';
}

// The END! ;)

?>

You can Download the LinkedIn Class.