├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── README.md ├── README.ru.md ├── composer.json ├── examples ├── README.md ├── demo.jpg └── index.php ├── phpunit.xml ├── src ├── AbstractEnum.php ├── AccessToken.php ├── Client.php ├── Exception.php ├── Http │ └── Method.php └── Scope.php └── tests ├── AccessTokenTest.php ├── ClientTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 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 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: php 3 | php: 4 | - 5.6 5 | - 7.1 6 | - 7.2 7 | - 7.3 8 | - 7.4 9 | - 7 10 | 11 | 12 | before_script: 13 | - composer update 14 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at philipp@zoonman.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 1. Make an issue 4 | 2. Create a pull request linked to this issue 5 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # What? Where? When? 2 | 3 | When you are going to report a new issue, include the following information 4 | 5 | 1. Environment 6 | 2. Steps to reproduce 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Philipp Tkachev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LinkedIn API Client with OAuth 2 authorization written on PHP 2 | ============================================================ 3 | [](https://travis-ci.org/zoonman/linkedin-api-php-client) [](https://codeclimate.com/github/zoonman/linkedin-api-php-client) [](https://packagist.org/packages/zoonman/linkedin-api-php-client) [](https://github.com/zoonman/linkedin-api-php-client/blob/master/LICENSE.md) 4 | 5 | 6 | 7 | See [complete example](examples/) inside [index.php](examples/index.php) to get started. 8 | 9 | 10 | ## Installation 11 | 12 | You will need at least PHP 7.3. We match [officially supported](https://www.php.net/supported-versions.php) versions of PHP. 13 | 14 | Use [composer](https://getcomposer.org/) package manager to install the lastest version of the package: 15 | 16 | ```bash 17 | composer require zoonman/linkedin-api-php-client 18 | ``` 19 | 20 | Or add this package as dependency to `composer.json`. 21 | 22 | If you have never used Composer, you should start [here](http://www.phptherightway.com/#composer_and_packagist) 23 | and install composer. 24 | 25 | 26 | ## Get Started 27 | 28 | Before you will get started, play visit to [LinkedIn API Documentation](https://docs.microsoft.com/en-us/linkedin/). 29 | This will save you a lot of time and prevent some silly questions. 30 | 31 | To start working with LinkedIn API, you will need to 32 | get application client id and secret. 33 | 34 | Go to [LinkedIn Developers portal](https://developer.linkedin.com/) 35 | and create new application in section My Apps. 36 | Save ClientId and ClientSecret, you will use them later. 37 | 38 | 39 | #### Bootstrapping autoloader and instantiating a client 40 | 41 | 42 | ```php 43 | // ... please, add composer autoloader first 44 | include_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; 45 | 46 | // import client class 47 | use LinkedIn\Client; 48 | 49 | // instantiate the Linkedin client 50 | $client = new Client( 51 | 'YOUR_LINKEDIN_APP_CLIENT_ID', 52 | 'YOUR_LINKEDIN_APP_CLIENT_SECRET' 53 | ); 54 | ``` 55 | 56 | #### Getting local redirect URL 57 | 58 | To start linking process you have to setup redirect url. 59 | You can set your own or use current one. 60 | SDK provides you a `getRedirectUrl()` helper for your convenience: 61 | 62 | ```php 63 | $redirectUrl = $client->getRedirectUrl(); 64 | ``` 65 | 66 | We recommend you to have it stored during the linking session 67 | because you will need to use it when you will be getting access token. 68 | 69 | #### Setting local redirect URL 70 | 71 | Set a custom redirect url use: 72 | 73 | ```php 74 | $client->setRedirectUrl('http://your.domain.tld/path/to/script/'); 75 | ``` 76 | 77 | #### Getting LinkedIn redirect URL 78 | 79 | In order of performing OAUTH 2.0 flow, you should get LinkedIn login URL. 80 | During this procedure you have to define scope of requested permissions. 81 | Use `Scope` enum class to get scope names. 82 | To get redirect url to LinkedIn, use the following approach: 83 | 84 | ```php 85 | use LinkedIn\Scope; 86 | 87 | // define scope 88 | $scopes = [ 89 | Scope::READ_LITE_PROFILE, 90 | Scope::READ_EMAIL_ADDRESS, 91 | Scope::SHARE_AS_USER, 92 | Scope::SHARE_AS_ORGANIZATION, 93 | ]; 94 | $loginUrl = $client->getLoginUrl($scopes); // get url on LinkedIn to start linking 95 | ``` 96 | 97 | Now you can take user to LinkedIn. You can use link or rely on Location HTTP header. 98 | 99 | #### Getting Access Token 100 | 101 | To get access token use (don't forget to set redirect url) 102 | 103 | ```php 104 | $accessToken = $client->getAccessToken($_GET['code']); 105 | ``` 106 | This method returns object of `LinkedIn\AccessToken` class. 107 | You can store this token in the file like this: 108 | ```php 109 | file_put_contents('token.json', json_encode($accessToken)); 110 | ``` 111 | This way of storing tokens is not recommended due to security concerns and used for demonstration purpose. 112 | Please, ensure that tokens are stored securely. 113 | 114 | #### Setting Access Token 115 | 116 | You can use method `setAccessToken()` for the `LinkedIn\Client` class to set token stored as string. You have to pass 117 | instance of `LinkedIn\AccessToken` to this method. 118 | 119 | ```php 120 | use LinkedIn\AccessToken; 121 | use LinkedIn\Client; 122 | 123 | // instantiate the Linkedin client 124 | $client = new Client( 125 | 'LINKEDIN_APP_CLIENT_ID', 126 | 'LINKEDIN_APP_CLIENT_SECRET' 127 | ); 128 | 129 | // load token from the file 130 | $tokenString = file_get_contents('token.json'); 131 | $tokenData = json_decode($tokenString, true); 132 | // instantiate access token object from stored data 133 | $accessToken = new AccessToken($tokenData['token'], $tokenData['expiresAt']); 134 | 135 | // set token for client 136 | $client->setAccessToken($accessToken); 137 | ``` 138 | 139 | #### Performing API calls 140 | 141 | All API calls can be called through simple method: 142 | 143 | ```php 144 | $profile = $client->api( 145 | 'ENDPOINT', 146 | ['parameter name' => 'its value here'], 147 | 'HTTP method like GET for example' 148 | ); 149 | ``` 150 | 151 | There are 3 helper methods: 152 | 153 | ```php 154 | // get method 155 | $client->get('ENDPOINT', ['param' => 'value']); 156 | 157 | //post 158 | $client->post('ENDPOINT', ['param' => 'value']); 159 | 160 | // delete 161 | $client->delete('ENDPOINT'); 162 | ``` 163 | 164 | #### Examples 165 | 166 | ##### Perform api call to get profile information 167 | 168 | ```php 169 | $profile = $client->get( 170 | 'me', 171 | ['fields' => 'id,firstName,lastName'] 172 | ); 173 | print_r($profile); 174 | ``` 175 | 176 | ##### List companies where you are an admin 177 | 178 | ```php 179 | $profile = $client->get( 180 | 'organizations', 181 | ['is-company-admin' => true] 182 | ); 183 | print_r($profile); 184 | ``` 185 | 186 | ##### Share content on a personal profile 187 | 188 | Make sure that image URL is available from the Internet (don't use localhost in the image url). 189 | 190 | ```php 191 | $share = $client->post( 192 | 'ugcPosts', 193 | [ 194 | 'author' => 'urn:li:person:' . $profile['id'], 195 | 'lifecycleState' => 'PUBLISHED', 196 | 'specificContent' => [ 197 | 'com.linkedin.ugc.ShareContent' => [ 198 | 'shareCommentary' => [ 199 | 'text' => 'Checkout this amazing PHP SDK for LinkedIn!' 200 | ], 201 | 'shareMediaCategory' => 'ARTICLE', 202 | 'media' => [ 203 | [ 204 | 'status' => 'READY', 205 | 'description' => [ 206 | 'text' => 'OAuth 2 flow, composer Package.' 207 | ], 208 | 'originalUrl' => 'https://github.com/zoonman/linkedin-api-php-client', 209 | 'title' => [ 210 | 'text' => 'PHP Client for LinkedIn API' 211 | ] 212 | ] 213 | ] 214 | ] 215 | ], 216 | 'visibility' => [ 217 | 'com.linkedin.ugc.MemberNetworkVisibility' => 'CONNECTIONS' 218 | ] 219 | ] 220 | ); 221 | print_r($share); 222 | ``` 223 | 224 | ##### Get Company page profile 225 | 226 | ```php 227 | $companyId = '123'; // use id of the company where you are an admin 228 | $companyInfo = $client->get('organizations/' . $companyId); 229 | print_r($companyInfo); 230 | ``` 231 | 232 | ##### Share content on a LinkedIn business page 233 | 234 | ```php 235 | // set sandboxed company page to work with 236 | // you can check updates at 237 | // https://www.linkedin.com/company/devtestco 238 | $companyId = '2414183'; 239 | 240 | $share = $client->post( 241 | 'ugcPosts', 242 | [ 243 | 'author' => 'urn:li:organization:' . $companyId, 244 | 'lifecycleState' => 'PUBLISHED', 245 | 'specificContent' => [ 246 | 'com.linkedin.ugc.ShareContent' => [ 247 | 'shareCommentary' => [ 248 | 'text' => 'Checkout this amazing PHP SDK for LinkedIn!' 249 | ], 250 | 'shareMediaCategory' => 'ARTICLE', 251 | 'media' => [ 252 | [ 253 | 'status' => 'READY', 254 | 'description' => [ 255 | 'text' => 'OAuth 2 flow, composer Package.' 256 | ], 257 | 'originalUrl' => 'https://github.com/zoonman/linkedin-api-php-client', 258 | 'title' => [ 259 | 'text' => 'PHP Client for LinkedIn API' 260 | ] 261 | ] 262 | ] 263 | ] 264 | ], 265 | 'visibility' => [ 266 | 'com.linkedin.ugc.MemberNetworkVisibility' => 'PUBLIC' 267 | ] 268 | ] 269 | ); 270 | print_r($share); 271 | ``` 272 | 273 | ##### Setup custom API request headers 274 | 275 | Change different headers sent to LinkedIn API. 276 | 277 | ```php 278 | $client->setApiHeaders([ 279 | 'Content-Type' => 'application/json', 280 | 'x-li-format' => 'json', 281 | 'X-Restli-Protocol-Version' => '2.0.0', // use protocol v2 282 | 'x-li-src' => 'msdk' // set a src header to "msdk" to mimic a mobile SDK 283 | ]); 284 | ``` 285 | 286 | ##### Change default API root 287 | 288 | Some private API access there. 289 | 290 | ```php 291 | $client->setApiRoot('https://api.linkedin.com/v2/'); 292 | ``` 293 | 294 | ##### ~Image Upload~ 295 | 296 | I assume you have to be LinkedIn partner or something like that. 297 | 298 | Try to upload image to LinkedIn. See [Rich Media Shares](https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/rich-media-shares) 299 | (returns "Not enough permissions to access media resource" for me). 300 | 301 | ```php 302 | $filename = '/path/to/image.jpg'; 303 | $client->setApiRoot('https://api.linkedin.com/'); 304 | $mp = $client->upload($filename); 305 | ``` 306 | 307 | ## Contributing 308 | 309 | Please, open PR with your changes linked to an GitHub issue. 310 | You code must follow [PSR](http://www.php-fig.org/psr/) standards and have PHPUnit tests. 311 | 312 | ## License 313 | 314 | [MIT](LICENSE.md) 315 | -------------------------------------------------------------------------------- /README.ru.md: -------------------------------------------------------------------------------- 1 | Клиент для работы с LinkedIn API с авторизацией через OAuth 2 написанный на PHP 2 | ============================================================ 3 | [](https://travis-ci.org/zoonman/linkedin-api-php-client) [](https://codeclimate.com/github/zoonman/linkedin-api-php-client) [](https://packagist.org/packages/zoonman/linkedin-api-php-client) [](https://github.com/zoonman/linkedin-api-php-client/blob/master/LICENSE.md) 4 | 5 | 6 | 7 | Чтобы быстрее вникнуть, смотри [пример использования](examples/) внутри [index.php](examples/index.php). 8 | 9 | 10 | ## Установка 11 | 12 | Установка делается через composer следующей командой 13 | 14 | ```bash 15 | composer require zoonman/linkedin-api-php-client 16 | ``` 17 | 18 | Также можно добавить `composer.json`. 19 | 20 | Если вы никогда им не пользовались, познакомьтесь на [этой страничке](http://www.phptherightway.com/#composer_and_packagist) 21 | и установите composer. 22 | 23 | 24 | ## Использование клиента 25 | 26 | Чтобы начать работать с LinkedIn API, потребуется раздобыть идентификатор клиента (client id) и его секретный ключ (secret). 27 | 28 | Получить их можно на [Портале разработчиков](https://developer.linkedin.com/), для этого зайдите в секцию мои приложения 29 | (My Apps). 30 | 31 | 32 | #### Подключение к проекту 33 | 34 | Установите пакет, там появится каталог vendor, в котором будет autoload.php - это автозагрузчик. 35 | 36 | ```php 37 | // ... подлкючить автозагрузчик 38 | include_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; 39 | 40 | // сделать класс доступным 41 | use LinkedIn\Client; 42 | 43 | // создать новый объект 44 | $client = new Client( 45 | 'LINKEDIN_APP_CLIENT_ID', 46 | 'LINKEDIN_APP_CLIENT_SECRET' 47 | ); 48 | ``` 49 | 50 | #### Получение локального адреса для перенаправления 51 | 52 | Чтобы начать процесс аутентификации вам необходимо установить адрес для перенаправления. 53 | Вы можете вызвать метод `getRedirectUrl()`, 54 | 55 | ```php 56 | $redirectUrl = $client->getRedirectUrl(); 57 | ``` 58 | 59 | Вам нужно будет сохранить этот адрес во временное хранилище для текущей сессии. 60 | Вам потребуется этот адрес снова, когда вы будете получать токен. 61 | 62 | ```php 63 | $_SESSION['linkedin_redirect_url'] = $redirectUrl; 64 | ``` 65 | 66 | #### Установка собственного адреса возврата 67 | 68 | Вы также можете использовать `setRedirectUrl()`, чтобы установить свой обратный адрес. 69 | Не забудьте указать этот адрес в параметрах приложения. 70 | 71 | ```php 72 | $client->setRedirectUrl('http://your.domain.tld/path/to/script/'); 73 | ``` 74 | 75 | #### Получение адреса для аутентификации 76 | 77 | Для того, чтобы пройти аутентификацию, вам необходимо получить адрес в LinkedIn, 78 | на который нужно перенаправить пользователя. 79 | Этот тот самый адрес, на котором пользователя спрашивают о подтвердении 80 | запрашиваемых прав доступа для приложения. 81 | 82 | ```php 83 | // определить области доступа 84 | $scopes = [ 85 | 'r_basicprofile', 86 | 'r_emailaddress', 87 | 'rw_company_admin', 88 | 'w_share', 89 | ]; 90 | $loginUrl = $client->getLoginUrl($scopes); // получить адрес 91 | ``` 92 | 93 | Теперь нужно перенаправить пользователя на полученный адрес. 94 | 95 | 96 | #### Получение токена 97 | 98 | Чтобы получить токен или маркер доступа, как его иногда называют, 99 | нужно установить обратный адрес ($redirectUrl), который вы сохранили в сессии. 100 | 101 | А затем вызвать получение токена 102 | 103 | ```php 104 | $accessToken = $client->getAccessToken($_GET['code']); 105 | ``` 106 | 107 | #### Вызов API 108 | 109 | All API calls can be called through simple method: 110 | Вызовы API происходят с помощью простого метода api(), 111 | который принимает 3 параметра: путь вызова, параметры и метод. 112 | 113 | ```php 114 | $profile = $client->api( 115 | 'ENDPOINT', 116 | ['parameter name' => 'its value here'], 117 | 'HTTP method like GET for example' 118 | ); 119 | ``` 120 | 121 | Есть два упрощенных вызова: 122 | 123 | ```php 124 | // метод get 125 | $client->get('путь', ['имя параметра' => 'значение']); 126 | 127 | // метод post 128 | $client->post('ENDPOINT', ['param' => 'value']); 129 | ``` 130 | #### Примеры 131 | 132 | Получить информацию о профиле 133 | 134 | ```php 135 | $profile = $client->get( 136 | 'people/~:(id,email-address,first-name,last-name)' 137 | ); 138 | print_r($profile); 139 | ``` 140 | 141 | Получить список компаний, в которой владелец токена - администратор. 142 | 143 | ```php 144 | $profile = $client->get( 145 | 'companies', 146 | ['is-company-admin' => true] 147 | ); 148 | print_r($profile); 149 | ``` 150 | 151 | Опубликовать сообщение у себя на странице профиля 152 | 153 | ```php 154 | $share = $client->post( 155 | 'people/~/shares', 156 | [ 157 | 'comment' => 'Посмотри, какая классная библиотека для работы с LinkedIn!', 158 | 'content' => [ 159 | 'title' => 'PHP Client for LinkedIn API', 160 | 'description' => 'OAuth 2 flow, composer Package', 161 | 'submitted-url' => 'https://github.com/zoonman/linkedin-api-php-client', 162 | 'submitted-image-url' => 'https://github.com/fluidicon.png', 163 | ], 164 | 'visibility' => [ 165 | 'code' => 'anyone' 166 | ] 167 | ] 168 | ); 169 | ``` 170 | 171 | Поделиться контентом на тестовой странице компаний 172 | 173 | ```php 174 | // Вы можете увидеть сообщение на этой странице 175 | // https://www.linkedin.com/company/devtestco 176 | $companyId = '2414183'; // идентификатор страницы 177 | 178 | $share = $client->post( 179 | 'companies/' . $companyId . '/shares', 180 | [ 181 | 'comment' => 'Checkout this amazing PHP SDK for LinkedIn!', 182 | 'content' => [ 183 | 'title' => 'PHP Client for LinkedIn API', 184 | 'description' => 'OAuth 2 flow, composer Package', 185 | 'submitted-url' => 'https://github.com/zoonman/linkedin-api-php-client', 186 | 'submitted-image-url' => 'https://github.com/fluidicon.png', 187 | ], 188 | 'visibility' => [ 189 | 'code' => 'anyone' 190 | ] 191 | ] 192 | ); 193 | ``` 194 | 195 | Установить заголовки по умолчанию 196 | 197 | ```php 198 | $client->setApiHeaders([ 199 | 'Content-Type' => 'application/json', 200 | 'x-li-format' => 'json', 201 | 'x-li-src' => 'msdk' // например отправить "msdk" чтобы симулировать мобильное SDK 202 | ]); 203 | ``` 204 | 205 | Изменить корневой адрес для API вызовов 206 | 207 | ```php 208 | $client->setApiRoot('https://api.linkedin.com/v2/'); 209 | ``` 210 | 211 | ## Помощь проекту 212 | 213 | Если вы нашли ошибку и исправили ее, вы всегда можете открыть Pull Request. 214 | У нас есть небольшое требование к качеству кода. 215 | Пожалуйста, следуйте стандарту [PSR](http://www.php-fig.org/psr/) и пишите тесты PHPUnit для вносимых изменений. 216 | 217 | ## Лицензия 218 | 219 | [MIT](LICENSE.md) - вы имеете право использовать библиотеку без каких-либо отчислений. 220 | Пожалуйста, указывайте ссылку на данный проекта в своих приложениях. 221 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zoonman/linkedin-api-php-client", 3 | "description": "LinkedIn API PHP SDK with OAuth 2.0 & CSRF support. Can be used for social sign in or sharing on LinkedIn. Examples. Documentation.", 4 | "type": "library", 5 | "keywords": [ 6 | "linkedin", "linkedin-client", "linkedin-api", "linkedin-signin", 7 | "linkedin-sdk", "linkedin-login", "linked in", "linkedin.com", "php-linkedin", 8 | "oauth", "oauth2", "oauth2-client", "oauth2-authentication", "authentication", 9 | "social", "rest", "api", "client", "social network", "auth", "authorization", 10 | "wrapper", "integration", "platform" 11 | ], 12 | "homepage": "https://github.com/zoonman/linkedin-api-php-client", 13 | "require": { 14 | "php": ">=5.6", 15 | "ext-curl": "*", 16 | "guzzlehttp/guzzle": "^6.3" 17 | }, 18 | "license": "MIT", 19 | "authors": [ 20 | { 21 | "name": "Philipp Tkachev", 22 | "email": "philipp@zoonman.com", 23 | "homepage": "http://www.zoonman.com/", 24 | "role": "Developer" 25 | }, 26 | { 27 | "name": "Aleksey Salnikov", 28 | "email": "me@iamsalnikov.ru", 29 | "homepage": "http://iamsalnikov.ru/", 30 | "role": "Developer" 31 | }, 32 | { 33 | "name": "Daniel J. Post", 34 | "homepage": "http://danieljpost.info/", 35 | "role": "Developer" 36 | } 37 | ], 38 | "support": { 39 | "docs": "https://www.zoonman.com/projects/linkedin-client/", 40 | "source": "https://github.com/zoonman/linkedin-api-php-client", 41 | "issues": "https://github.com/zoonman/linkedin-api-php-client/issues", 42 | "wiki": "https://github.com/zoonman/linkedin-api-php-client/wiki" 43 | }, 44 | "autoload": { 45 | "psr-4": {"LinkedIn\\": "src/"} 46 | }, 47 | "require-dev": { 48 | "vlucas/phpdotenv": "~2.0", 49 | "phpunit/phpunit": "~4.0", 50 | "phpmd/phpmd": "@stable", 51 | "squizlabs/php_codesniffer": "@stable" 52 | }, 53 | "archive": { 54 | "exclude": [ 55 | "examples", 56 | "tests", 57 | ".env", 58 | ".travis.yml", 59 | "phpunit.xml" 60 | ] 61 | }, 62 | "autoload-dev": {} 63 | } 64 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # How to run examples 2 | 3 | First, [clone](https://help.github.com/articles/cloning-a-repository/) repository. 4 | 5 | ```bash 6 | git clone https://github.com/zoonman/linkedin-api-php-client 7 | ``` 8 | Change dir to the repo 9 | ```bash 10 | cd linkedin-api-php-client 11 | ``` 12 | 13 | Install dependencies: 14 | 15 | ```bash 16 | composer install [-d /path/to/repository/root] 17 | ``` 18 | If you don't have composer, you can get it [here](https://getcomposer.org/doc/00-intro.md). 19 | Parameters in brackets are optional. 20 | 21 | Create `.env` file with linkedin credentials in the parent catalog (in the repository root) like this 22 | 23 | ```ini 24 | LINKEDIN_CLIENT_ID=111ClientId111 25 | LINKEDIN_CLIENT_SECRET=222ClientSecret 26 | ``` 27 | 28 | The simplest way to do that to run the following commands: 29 | ```bash 30 | echo 'LINKEDIN_CLIENT_ID=111ClientId111' >> .env 31 | echo 'LINKEDIN_CLIENT_SECRET=222ClientSecret' >> .env 32 | ``` 33 | 34 | To get client and secret go to [LinkedIn Developers portal](https://developer.linkedin.com/) and create new app there. 35 | 36 | After add to OAuth 2.0 Authorized Redirect URLs: 37 | ``` 38 | http://localhost:8901/ 39 | ``` 40 | 41 | Next, run PHP embedded server in the repository root: 42 | 43 | ```bash 44 | php -S localhost:8901 -t examples 45 | ``` 46 | 47 | Navigate to http://localhost:8901/ 48 | 49 | If you will see error like `Class 'Dotenv\Dotenv' not found...` install DotEnv using the following command: 50 | ```bash 51 | composer require vlucas/phpdotenv 52 | ``` 53 | -------------------------------------------------------------------------------- /examples/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zoonman/linkedin-api-php-client/d06531c48d5efc8aaf7dc074a5320f5ba3f906c9/examples/demo.jpg -------------------------------------------------------------------------------- /examples/index.php: -------------------------------------------------------------------------------- 1 | 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 | use LinkedIn\Scope; 23 | 24 | // import environment variables from the environment file 25 | // you need a .env file in the parent folder 26 | // read this document to learn how to create that file 27 | // https://github.com/zoonman/linkedin-api-php-client/blob/master/examples/README.md 28 | // 29 | $dotenv = new Dotenv\Dotenv(dirname(__DIR__)); 30 | $dotenv->load(); 31 | 32 | // we need a session to keep intermediate results 33 | // you can use your own session persistence management 34 | // client doesn't depend on it 35 | session_start(); 36 | 37 | // instantiate the Linkedin client 38 | // you can setup keys using 39 | $client = new Client( 40 | getenv('LINKEDIN_CLIENT_ID'), 41 | getenv('LINKEDIN_CLIENT_SECRET') 42 | ); 43 | 44 | 45 | if (isset($_GET['code'])) { // we are returning back from LinkedIn with the code 46 | if (isset($_GET['state']) && // and state parameter in place 47 | isset($_SESSION['state']) && // and we have have stored state 48 | $_GET['state'] === $_SESSION['state'] // and it is our request 49 | ) { 50 | try { 51 | // you have to set initially used redirect url to be able 52 | // to retrieve access token 53 | $client->setRedirectUrl($_SESSION['redirect_url']); 54 | // retrieve access token using code provided by LinkedIn 55 | $accessToken = $client->getAccessToken($_GET['code']); 56 | h1('Access token'); 57 | pp($accessToken); // print the access token content 58 | h1('Profile'); 59 | // perform api call to get profile information 60 | $profile = $client->get( 61 | 'me', 62 | ['fields' => 'id,firstName,lastName'] 63 | ); 64 | pp($profile); // print profile information 65 | 66 | $emailInfo = $email = $client->get('emailAddress', ['q' => 'members', 'projection' => '(elements*(handle~))']); 67 | pp($emailInfo); 68 | 69 | $share = $client->post( 70 | 'ugcPosts', 71 | [ 72 | 'author' => 'urn:li:person:' . $profile['id'], 73 | 'lifecycleState' => 'PUBLISHED', 74 | 'specificContent' => [ 75 | 'com.linkedin.ugc.ShareContent' => [ 76 | 'shareCommentary' => [ 77 | 'text' => 'Checkout this amazing PHP SDK for LinkedIn!' 78 | ], 79 | 'shareMediaCategory' => 'ARTICLE', 80 | 'media' => [ 81 | [ 82 | 'status' => 'READY', 83 | 'description' => [ 84 | 'text' => 'OAuth 2 flow, composer Package.' 85 | ], 86 | 'originalUrl' => 'https://github.com/zoonman/linkedin-api-php-client', 87 | 'title' => [ 88 | 'text' => 'PHP Client for LinkedIn API' 89 | ] 90 | ] 91 | ] 92 | ] 93 | ], 94 | 'visibility' => [ 95 | 'com.linkedin.ugc.MemberNetworkVisibility' => 'CONNECTIONS' 96 | ] 97 | ] 98 | ); 99 | pp($share); 100 | 101 | // set sandboxed company page id to work with 102 | // https://www.linkedin.com/company/devtestco 103 | /* TODO! 104 | $companyId = '2414183'; 105 | 106 | h1('Company information'); 107 | $companyInfo = $client->get('companies/' . $companyId . ':(id,name,num-followers,description)'); 108 | pp($companyInfo); 109 | 110 | h1('Sharing on company page'); 111 | $companyShare = $client->post( 112 | 'companies/' . $companyId . '/shares', 113 | [ 114 | 'comment' => 115 | sprintf( 116 | '%s %s just tried this amazing PHP SDK for LinkedIn!', 117 | $profile['firstName'], 118 | $profile['lastName'] 119 | ), 120 | 'content' => [ 121 | 'title' => 'PHP Client for LinkedIn API', 122 | 'description' => 'OAuth 2 flow, composer Package', 123 | 'submitted-url' => 'https://github.com/zoonman/linkedin-api-php-client', 124 | 'submitted-image-url' => 'https://github.com/fluidicon.png', 125 | ], 126 | 'visibility' => [ 127 | 'code' => 'anyone' 128 | ] 129 | ] 130 | ); 131 | pp($companyShare); 132 | */ 133 | 134 | /* 135 | // Returns {"serviceErrorCode":100,"message":"Not enough permissions to access media resource","status":403} 136 | // You have to be whitelisted or so by LinkedIn 137 | $filename = './demo.jpg'; 138 | $client->setApiRoot('https://api.linkedin.com/'); 139 | $mp = $client->upload($filename); 140 | */ 141 | } catch (\LinkedIn\Exception $exception) { 142 | // in case of failure, provide with details 143 | pp($exception); 144 | pp($_SESSION); 145 | } 146 | echo 'Start over'; 147 | } else { 148 | // normally this shouldn't happen unless someone sits in the middle 149 | // and trying to override your state 150 | // or you are trying to change saved state during linking 151 | echo 'Invalid state!'; 152 | pp($_GET); 153 | pp($_SESSION); 154 | echo 'Start over'; 155 | } 156 | 157 | } elseif (isset($_GET['error'])) { 158 | // if you cancel during linking 159 | // you will be redirected back with reason 160 | pp($_GET); 161 | echo 'Start over'; 162 | } else { 163 | // define desired list of scopes 164 | $scopes = [ 165 | Scope::READ_LITE_PROFILE, 166 | Scope::READ_EMAIL_ADDRESS, 167 | Scope::SHARE_AS_USER, 168 | ]; 169 | $loginUrl = $client->getLoginUrl($scopes); // get url on LinkedIn to start linking 170 | $_SESSION['state'] = $client->getState(); // save state for future validation 171 | $_SESSION['redirect_url'] = $client->getRedirectUrl(); // save redirect url for future validation 172 | echo 'LoginUrl: ' . $loginUrl. ''; 173 | } 174 | 175 | /** 176 | * Pretty print whatever passed in 177 | * 178 | * @param mixed $anything 179 | */ 180 | function pp($anything) 181 | { 182 | echo '
' . print_r($anything, true) . ''; 183 | } 184 | 185 | /** 186 | * Add header 187 | * 188 | * @param string $h 189 | */ 190 | function h1($h) { 191 | echo '