Skip to content

Commit 6c3d83d

Browse files
committed
Initial commit
0 parents  commit 6c3d83d

11 files changed

+807
-0
lines changed

.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.idea/**/workspace.xml
2+
.idea/**/tasks.xml
3+
.idea/dictionaries
4+
.idea/**/dataSources/
5+
.idea/**/dataSources.ids
6+
.idea/**/dataSources.xml
7+
.idea/**/dataSources.local.xml
8+
.idea/**/sqlDataSources.xml
9+
.idea/**/dynamic.xml
10+
.idea/**/uiDesigner.xml
11+
.idea/**/gradle.xml
12+
.idea/**/libraries
13+
.idea/**/mongoSettings.xml
14+
*.iws
15+
/out/
16+
.idea_modules/
17+
atlassian-ide-plugin.xml
18+
com_crashlytics_export_strings.xml
19+
crashlytics.properties
20+
crashlytics-build.properties
21+
fabric.properties
22+
composer.phar
23+
/vendor/
24+
.env

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
PHP LinkedIn Client with OAuth 2 authorization
2+
==============================================
3+
4+
WIP
5+
6+

composer.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "zoonman/linkedin-client",
3+
"description": "Client for LinkedIn API v2",
4+
"type": "library",
5+
"require": {
6+
"php": ">=5.6",
7+
"ext-curl": "*",
8+
"guzzlehttp/guzzle": "^6.3"
9+
},
10+
"license": "MIT",
11+
"authors": [
12+
{
13+
"name": "Philipp Tkachev",
14+
"email": "[email protected]"
15+
}
16+
],
17+
"autoload": {
18+
"psr-4": {"LinkedIn\\": "src/"}
19+
},
20+
"require-dev": {
21+
"vlucas/phpdotenv": "~2.0",
22+
"phpunit/phpunit": "~4.0"
23+
},
24+
"autoload-dev": {}
25+
}

examples/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# How to run examples
2+
3+
First, clone repository.
4+
5+
Create `.env` file with linkedin credentials in the parent catalog (in the repository root) like this
6+
7+
```ini
8+
LINKEDIN_CLIENT_ID=111ClinetId111
9+
LINKEDIN_CLIENT_SECRET=222ClientSecret
10+
```
11+
12+
To get client and secret go to [LinkedIn Developers portal](https://developer.linkedin.com/) and create new app there.
13+
14+
After add to OAuth 2.0 Authorized Redirect URLs:
15+
```
16+
http://localhost:8901/
17+
```
18+
19+
Next, run PHP embedded server in the repository root:
20+
21+
```bash
22+
php -S localhost:8901 -t examples
23+
```
24+
25+
Navigate to http://localhost:8901/

examples/index.php

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
/**
3+
* linkedin-client
4+
* index.php
5+
*
6+
* PHP Version 5
7+
*
8+
* @category Production
9+
* @package Default
10+
* @author Philipp Tkachev <[email protected]>
11+
* @date 8/17/17 22:47
12+
* @license http://zoonman.com/license.txt linkedin-client License
13+
* @version GIT: 1.0
14+
* @link http://zoonman.com/projects/linkedin-client
15+
*/
16+
17+
// add Composer autoloader
18+
include_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
19+
20+
// import client class
21+
use LinkedIn\Client;
22+
23+
// import environment variables from the environment file
24+
$dotenv = new Dotenv\Dotenv(dirname(__DIR__));
25+
$dotenv->load();
26+
27+
// we need a session to keep intermediate results
28+
// you can use your own session persistence management
29+
// client doesn't depend on it
30+
session_start();
31+
32+
// instantiate the Linkedin client
33+
$client = new Client(
34+
getenv('LINKEDIN_CLIENT_ID'),
35+
getenv('LINKEDIN_CLIENT_SECRET')
36+
);
37+
38+
39+
if (isset($_GET['code'])) { // we are returning back from LinkedIn with the code
40+
if (isset($_GET['state']) && // and state parameter in place
41+
isset($_SESSION['state']) && // and we have have stored state
42+
$_GET['state'] === $_SESSION['state'] // and it is our request
43+
) {
44+
try {
45+
// you have to set initially used redirect url to be able
46+
// to retrieve access token
47+
$client->setRedirectUrl($_SESSION['redirect_url']);
48+
// retrieve access token using code provided by LinkedIn
49+
$accessToken = $client->getAccessToken($_GET['code']);
50+
echo 'Access token:';
51+
pp($accessToken); // print the access token content
52+
echo 'Profile:';
53+
// perform api call to get profile information
54+
$profile = $client->api(
55+
'people/~:(id,email-address,first-name,last-name)'
56+
);
57+
pp($profile); // print profile information
58+
} catch (\LinkedIn\Exception $exception) {
59+
// in case of failure, provide with details
60+
pp($exception);
61+
pp($_SESSION);
62+
}
63+
echo '<a href="/">Start over</a>';
64+
} else {
65+
// normally this shouldn't happen unless someone sits in the middle
66+
// and trying to override your state
67+
// or you are trying to change saved state during linking
68+
echo 'Invalid state!';
69+
pp($_GET);
70+
pp($_SESSION);
71+
echo '<a href="/">Start over</a>';
72+
}
73+
74+
} elseif (isset($_GET['error'])) {
75+
// if you cancel during linking
76+
// you will be redirected back with reason
77+
pp($_GET);
78+
echo '<a href="/">Start over</a>';
79+
} else {
80+
// define desired list of scopes
81+
$scopes = [
82+
'r_basicprofile',
83+
'r_emailaddress',
84+
'rw_company_admin',
85+
'w_share',
86+
];
87+
$loginUrl = $client->getLoginUrl(); // get url on LinkedIn to start linking
88+
$_SESSION['state'] = $client->getState(); // save state for future validation
89+
$_SESSION['redirect_url'] = $client->getRedirectUrl(); // save redirect url for future validation
90+
echo 'LoginUrl: <a href="'.$loginUrl.'">' . $loginUrl. '</a>';
91+
}
92+
93+
/**
94+
* Pretty print whatever passed in
95+
*
96+
* @param mixed $anything
97+
*/
98+
function pp($anything)
99+
{
100+
echo '<pre>' . print_r($anything, true) . '</pre>';
101+
}

phpunit.xml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<phpunit
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
4+
bootstrap="tests/bootstrap.php"
5+
backupGlobals="true"
6+
backupStaticAttributes="false"
7+
cacheTokens="false"
8+
colors="false"
9+
convertErrorsToExceptions="true"
10+
convertNoticesToExceptions="true"
11+
convertWarningsToExceptions="true"
12+
forceCoversAnnotation="false"
13+
mapTestClassNameToCoveredClassName="false"
14+
printerClass="PHPUnit_TextUI_ResultPrinter"
15+
processIsolation="false"
16+
stopOnError="false"
17+
stopOnFailure="false"
18+
stopOnIncomplete="false"
19+
stopOnSkipped="false"
20+
stopOnRisky="false"
21+
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
22+
timeoutForSmallTests="1"
23+
timeoutForMediumTests="10"
24+
timeoutForLargeTests="60"
25+
verbose="false">
26+
<testsuites>
27+
<testsuite name="client">
28+
<directory>tests</directory>
29+
</testsuite>
30+
</testsuites>
31+
</phpunit>

src/AccessToken.php

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
/**
3+
* linkedin-client
4+
* AccessToken.php
5+
*
6+
* PHP Version 5
7+
*
8+
* @category Production
9+
* @package Default
10+
* @author Philipp Tkachev <[email protected]>
11+
* @date 8/17/17 22:55
12+
* @license http://www.zoonman.com/projects/linkedin-client/license.txt linkedin-client License
13+
* @version GIT: 1.0
14+
* @link http://www.zoonman.com/projects/linkedin-client/
15+
*/
16+
17+
namespace LinkedIn;
18+
19+
/**
20+
* Class AccessToken
21+
*
22+
* @package LinkedIn
23+
*/
24+
class AccessToken
25+
{
26+
27+
/**
28+
* @var string
29+
*/
30+
protected $token;
31+
32+
/**
33+
* @var int
34+
*/
35+
protected $expiresIn;
36+
37+
/**
38+
* AccessToken constructor.
39+
*
40+
* @param string $token
41+
* @param int $expiresIn
42+
*/
43+
public function __construct($token = '', $expiresIn = 0)
44+
{
45+
$this->setToken($token);
46+
$this->setExpiresIn($expiresIn);
47+
}
48+
49+
/**
50+
* Get token string
51+
*
52+
* @return string
53+
*/
54+
public function getToken()
55+
{
56+
return $this->token;
57+
}
58+
59+
/**
60+
* Set token string
61+
*
62+
* @param string $token
63+
*
64+
* @return AccessToken
65+
*/
66+
public function setToken($token)
67+
{
68+
$this->token = $token;
69+
return $this;
70+
}
71+
72+
/**
73+
* Get token expiration
74+
*
75+
* @return int seconds
76+
*/
77+
public function getExpiresIn()
78+
{
79+
return $this->expiresIn;
80+
}
81+
82+
/**
83+
* Set token expiration time
84+
*
85+
* @param int $expiresIn seconds
86+
*
87+
* @return AccessToken
88+
*/
89+
public function setExpiresIn($expiresIn)
90+
{
91+
$this->expiresIn = $expiresIn;
92+
return $this;
93+
}
94+
95+
/**
96+
* Dynamically typecast token object into string
97+
*
98+
* @return string
99+
*/
100+
public function __toString()
101+
{
102+
return $this->getToken();
103+
}
104+
105+
/**
106+
* @param $responseArray
107+
*
108+
* @return \LinkedIn\AccessToken
109+
*/
110+
public static function fromResponseArray($responseArray)
111+
{
112+
if (!is_array($responseArray)) {
113+
throw new \InvalidArgumentException(
114+
'Argument is not array'
115+
);
116+
}
117+
if (!isset($responseArray['access_token'])) {
118+
throw new \InvalidArgumentException(
119+
'Access token is not available'
120+
);
121+
}
122+
if (!isset($responseArray['expires_in'])) {
123+
throw new \InvalidArgumentException(
124+
'Access token expiration date is not specified'
125+
);
126+
}
127+
return new static(
128+
$responseArray['access_token'],
129+
$responseArray['expires_in']
130+
);
131+
}
132+
}

0 commit comments

Comments
 (0)