diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e35b4d7..fd8943c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,19 +3,22 @@ on: pull_request: branches: - master + - develop push: + branches: + - master jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: - php: [ '7.3', '7.4', '8.0', '8.1', '8.2', '8.3' ] + php: [ '8.1', '8.2', '8.3', '8.4' ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: mkdir -p build/logs - name: Test PHP uses: shivammathur/setup-php@v2 with: php-version: ${{matrix.php}} - run: composer install - - run: php vendor/bin/phpunit --exclude-group integration + - run: php vendor/bin/phpunit diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 85e2f80..0000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: php - -php: - - 7.3 - - 7.4 - - 8.0 - -dist: - xenial -os: - linux - -cache: - directories: - - $HOME/.composer/cache - -before_install: - - travis_retry composer self-update - -install: - - travis_retry composer install --prefer-dist --no-interaction - -script: - - vendor/bin/phpunit --coverage-text --exclude-group integration diff --git a/CHANGELOG.md b/CHANGELOG.md index c6291ff..5e25d34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,221 +1,316 @@ # CHANGELOG +## 8.x (UNOFFICIAL) + +- 8.0.0-rc.1 + - Requires PHP 8.1. + - Defaults to Facebook Graph v20.0, instead of v2.10 which is no longer accessible. + - Added a few more objects/types. Please open a PR if you want to add more types. + - `GraphAgeRange` + - `GraphApplicationEventsConfig` + - `GraphApplicationObjectStoreURLs` + - `GraphApplicationRestrictions` + - `GraphArchivedAd` + - `GraphEngagement` + - `GraphExperience` + - `GraphInsightsRangeValue` + - `GraphMailingAddress` + - `GraphPhoto` + - `GraphPlace` + - `GraphPlatformImageSource` + - `GraphVideo` + - `GraphVideoFormat` + - Removed integration tests as Facebook's API does not support it anymore anyway. + - Deleted the entire `docs` folder as it's too much work to maintain and was full of outdated examples. For + documentation, see https://developers.facebook.com/docs/graph-api. + - Removed the custom `autoload.php` file. Please autoload with composer. + - Removed all `mcrypt` implementations as it was removed in PHP 7.2: + - Removed `mcrypt` as option for `createPseudoRandomStringGenerator`. + - Removed `McryptPseudoRandomStringGenerator`. + - Removed deprecated classes: + - `GraphList` + - `GraphObject` + - `GraphObjectFactory` + - Methods that return `bool|null` now always return `bool` and default to `false` instead. + - `AccessTokenMetaData`: + - Removed deprecated `getProperty()` function. Use `getField()`. + - `Collection`: + - Removed deprecated `getProperty()` function. Use `getField()`. + - Removed deprecated `getPropertyNames()` function. Use `getFieldNames()`. + - `FacebookResponse`: + - Removed deprecated `getGraphList()` function. Use `getGraphEdge()`. + - `FacebookApp`: + - If PHP runs in 32 bit mode, you *must* provide your app ID as a string. + - `GraphNodeFactory`: + - Removed convenience methods as they would require a method per node/object. Use `makeGraphNode()` + instead and pass in a subclass of `GraphNode`. + - `makeGraphAchievment()` + - `makeGraphAlbum()` + - `makeGraphPage()` + - `makeGraphSessionInfo()` + - `makeGraphUser()` + - `makeGraphEvent()` + - `makeGraphGroup()` + - `castAsGraphNodeOrGraphEdge()` is now private. + - `safelyMakeGraphEdge()` is now private. + - `safelyMakeGraphNode()` is now private. + - `validateResponseAsArray()` is now private. + - All random string generators now type-check their `length` parameter instead of relying on a validation method and + user-land exception. + - `GraphAlbum`: + - `getPlace()` now correctly returns a `GraphPlace` instead of a `GraphPage`. + - `GraphEvent`: + - Removed `getPicture()`. Use `getCover()` instead. + - `GraphGroup`: + - Removed `getLink()`. + - Removed `getVenue()`. + - `GraphNode`: + - `castToBirthday()` is now private. + - `castToDateTime()` is now private. + - Removed `isIso8601DateString()`. If a date/time field cannot be parsed as a `DateTime`, it will be omitted + instead as this would be incompatible with types added to these fields. + - `GraphPage`: + - Removed `getGlobalBrandParentPage()`. + - Removed `getPerms()`. + - `GraphAchievement`: + - Removed entirely. See https://developers.facebook.com/docs/graph-api/reference/user/achievements. + - `FacebookResponse`: + - Removed these type-casting methods. Use `getGraphNode()` instead. This is similar to the changes made to + `GraphNodeFactory` for the same reason. + - `getGraphAchivement()` + - `getGraphAlbum()` + - `getGraphPage()` + - `getGraphSessionInfo()` + - `getGraphUser()` + - `getGraphEvent()` + - `getGraphGroup()` + ## 7.x (UNOFFICIAL) - - 7.0.1 - - Add `conflict` section to `composer.json` to prevent incompatible versions of Guzzle. - - 7.0.0 (:warning: Removed from packagist because it was missing the conflict change from 7.0.1) - - Guzzle now takes priority over cURL as the HTTP client, if available. - - Removed support for Guzzle 5. Guzzle 6 or 7 is now required if using Guzzle. - - Fixed additional deprecation warnings on PHP 8.1. - - Removed deprecated or skipped tests for PHP < 7.3. + +- 7.0.1 + - Add `conflict` section to `composer.json` to prevent incompatible versions of Guzzle. +- 7.0.0 (:warning: Removed from packagist because it was missing the conflict change from 7.0.1) + - Guzzle now takes priority over cURL as the HTTP client, if available. + - Removed support for Guzzle 5. Guzzle 6 or 7 is now required if using Guzzle. + - Fixed additional deprecation warnings on PHP 8.1. + - Removed deprecated or skipped tests for PHP < 7.3. + ## 6.x (UNOFFICIAL) - - 6.0.3 - - Fixed deprecation warnings for PHP 8.1 - - 6.0.2 - - Removed PHP 5 polyfills - - Updated `phpunit.xml` - - Added GitHub Actions - - Test against PHP 8.1 - - 6.0.1 - - Added `replace` property to `composer.json` - - 6.0.0 - - Works with PHP 8. + +- 6.0.3 + - Fixed deprecation warnings for PHP 8.1 +- 6.0.2 + - Removed PHP 5 polyfills + - Updated `phpunit.xml` + - Added GitHub Actions + - Test against PHP 8.1 +- 6.0.1 + - Added `replace` property to `composer.json` +- 6.0.0 + - Works with PHP 8. ## 5.x -Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes loaded with lots of new features and a friendlier API. +Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes loaded with lots of new features and a +friendlier API. - 5.7.1 (2018-XX-XX) - 5.7.0 (2018-12-12) - - Add `joined` to list of fields to be cast to `\DateTime` (#950) - - Add `GraphPage::getFanCount()` to get the number of people who like the page (#815) - - Fixed HTTP/2 support (#1079) - - Fixed resumable upload error (#1001) - - Strip 'enforce_https' param (#1084) - - Conserve id when next to data key, resolves #700 (#1034) + - Add `joined` to list of fields to be cast to `\DateTime` (#950) + - Add `GraphPage::getFanCount()` to get the number of people who like the page (#815) + - Fixed HTTP/2 support (#1079) + - Fixed resumable upload error (#1001) + - Strip 'enforce_https' param (#1084) + - Conserve id when next to data key, resolves #700 (#1034) - 5.6.3 (2018-07-01) - - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) + - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) - - Strip 'code' param (#913) + - Strip 'code' param (#913) - 5.6.1 (2017-08-16) - - Fixed doc block syntax that interfered with Doctrine (#844) + - Fixed doc block syntax that interfered with Doctrine (#844) - 5.6.0 (2017-07-23) - - Bump Graph API version to v2.10 (#829) + - Bump Graph API version to v2.10 (#829) - 5.5.0 (2017-04-20) - - Added support for batch options (#713) - - Bump Graph API version to v2.9. + - Added support for batch options (#713) + - Bump Graph API version to v2.9. - 5.4.4 (2017-01-19) - - Added the `application/octet-stream` MIME type for SRT files (#734) + - Added the `application/octet-stream` MIME type for SRT files (#734) - 5.4.3 (2016-12-30) - - Fixed a bug that would throw a type error in `GraphEdge` in some cases (#715) + - Fixed a bug that would throw a type error in `GraphEdge` in some cases (#715) - 5.4.2 (2016-11-15) - - Added check for [PHP 7 CSPRNG](http://php.net/manual/en/function.random-bytes.php) first to keep mcrypt deprecation messages from appearing in PHP 7.1 (#692) + - Added check for [PHP 7 CSPRNG](http://php.net/manual/en/function.random-bytes.php) first to keep mcrypt + deprecation messages from appearing in PHP 7.1 (#692) - 5.4.1 (2016-10-18) - - Fixed a bug that was not properly parsing response headers when they contained the colon `:` character. (#679) + - Fixed a bug that was not properly parsing response headers when they contained the colon `:` character. (#679) - 5.4.0 (2016-10-12) - - Bump Graph API version to v2.8. - - Auto-cast `cover` field to `GraphCoverPhoto` and `picture` field to `GraphPicture` in `GraphPage`. (#655) - - Added `getCover()` and `getPicture()` to `GraphPage`. (#655) + - Bump Graph API version to v2.8. + - Auto-cast `cover` field to `GraphCoverPhoto` and `picture` field to `GraphPicture` in `GraphPage`. (#655) + - Added `getCover()` and `getPicture()` to `GraphPage`. (#655) - 5.3.1 - - Fixed a bug where the `polyfills.php` file wasn't being included properly when using the built-in auto loader (#633) + - Fixed a bug where the `polyfills.php` file wasn't being included properly when using the built-in auto loader ( + #633) - 5.3.0 - - Bump Graph API version to v2.7. + - Bump Graph API version to v2.7. - 5.2.1 - - Fix notice that is raised in `FacebookUrlDetectionHandler` (#626) - - Fix bug in `FacebookRedirectLoginHelper::getLoginUrl()` where the CSRF token gets overwritten in certain scenarios (#613) - - Fix bug with polyfills not getting loaded when installing the Facebook PHP SDK manually (#599) + - Fix notice that is raised in `FacebookUrlDetectionHandler` (#626) + - Fix bug in `FacebookRedirectLoginHelper::getLoginUrl()` where the CSRF token gets overwritten in certain + scenarios (#613) + - Fix bug with polyfills not getting loaded when installing the Facebook PHP SDK manually (#599) - 5.2.0 - - Added new Birthday class to handle Graph API response variations - - Bumped Graph version to v2.6 - - Added better error checking for app IDs that are cast as int when they are greater than PHP_INT_MAX + - Added new Birthday class to handle Graph API response variations + - Bumped Graph version to v2.6 + - Added better error checking for app IDs that are cast as int when they are greater than PHP_INT_MAX - 5.1.5 - - Removed mbstring extension dependency - - Updated required PHP version syntax in composer.json + - Removed mbstring extension dependency + - Updated required PHP version syntax in composer.json - 5.1.4 - - Breaking changes - - Changes the serialization method of FacebookApp - - FacebookApps serialized by versions prior 5.1.4 cannot be unserialized by this version - - Fixed redirect_uri injection vulnerability + - Breaking changes + - Changes the serialization method of FacebookApp + - FacebookApps serialized by versions prior 5.1.4 cannot be unserialized by this version + - Fixed redirect_uri injection vulnerability - 5.0 (2015-07-09) - - New features - - Added the `Facebook\Facebook` super service for an easier API - - Improved "reauthentication" and "rerequest" support - - Requests/Responses - - Added full batch support - - Added full file upload support for videos & photos - - Added methods to make pagination easier - - Added "deep" pagination support so that Graph edges embedded in a Graph node can be paginated over easily - - Beta support at `graph.beta.facebook.com` - - Added `getMetaData()` to `GraphEdge` to obtain all the metadata associated with a list of Graph nodes - - Full nested param support - - Many improvements to the Graph node subtypes - - New injectable interfaces - - Added a `PersistentDataInterface` for custom persistent data handling - - Added a `PseudoRandomStringGeneratorInterface` for customizable CSPRNG's - - Added a `UrlDetectionInterface` for custom URL-detection logic - - Codebase changes - - Moved exception classes to `Exception\*` directory - - Moved response collection objects to `GraphNodes\*` directory - - Moved helpers to `Helpers\*` directory - - Killed `FacebookSession` in favor of the `AccessToken` entity - - Added `FacebookClient` service - - Renamed `FacebookRequestException` to `FacebookResponseException` - - Renamed `FacebookHttpable` to `FacebookHttpClientInterface` - - Added `FacebookApp` entity that contains info about the Facebook app - - Updated the API for the helpers - - Added `HttpClients`, `PersistentData` and `PseudoRandomString` factories to reduce main class' complexity - - Tests - - Added namespaces to the tests - - Grouped functional tests under `functional` group - - Other changes - - Made PSR-2 compliant - - Adopted SemVer - - Completely refactored request/response handling - - Refactored the OAuth 2.0 logic - - Added `ext-mbstring` to composer require - - Added this CHANGELOG. Hi! :) + - New features + - Added the `Facebook\Facebook` super service for an easier API + - Improved "reauthentication" and "rerequest" support + - Requests/Responses + - Added full batch support + - Added full file upload support for videos & photos + - Added methods to make pagination easier + - Added "deep" pagination support so that Graph edges embedded in a Graph node can be paginated over easily + - Beta support at `graph.beta.facebook.com` + - Added `getMetaData()` to `GraphEdge` to obtain all the metadata associated with a list of Graph nodes + - Full nested param support + - Many improvements to the Graph node subtypes + - New injectable interfaces + - Added a `PersistentDataInterface` for custom persistent data handling + - Added a `PseudoRandomStringGeneratorInterface` for customizable CSPRNG's + - Added a `UrlDetectionInterface` for custom URL-detection logic + - Codebase changes + - Moved exception classes to `Exception\*` directory + - Moved response collection objects to `GraphNodes\*` directory + - Moved helpers to `Helpers\*` directory + - Killed `FacebookSession` in favor of the `AccessToken` entity + - Added `FacebookClient` service + - Renamed `FacebookRequestException` to `FacebookResponseException` + - Renamed `FacebookHttpable` to `FacebookHttpClientInterface` + - Added `FacebookApp` entity that contains info about the Facebook app + - Updated the API for the helpers + - Added `HttpClients`, `PersistentData` and `PseudoRandomString` factories to reduce main class' complexity + - Tests + - Added namespaces to the tests + - Grouped functional tests under `functional` group + - Other changes + - Made PSR-2 compliant + - Adopted SemVer + - Completely refactored request/response handling + - Refactored the OAuth 2.0 logic + - Added `ext-mbstring` to composer require + - Added this CHANGELOG. Hi! :) ## 4.1-dev -Since the Facebook PHP SDK didn't follow SemVer in version 4.x, the master branch was going to be released as 4.1. However, the SDK switched to SemVer in v5.0. So any references on the internet to version 4.1 can be assumed to be an alias to version `5.0.0` +Since the Facebook PHP SDK didn't follow SemVer in version 4.x, the master branch was going to be released as 4.1. +However, the SDK switched to SemVer in v5.0. So any references on the internet to version 4.1 can be assumed to be an +alias to version `5.0.0` ## 4.0.x -Version 4.0 of the Facebook PHP SDK did not follow [SemVer](http://semver.org/). The versioning format used was as follows: `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions were squashed together. +Version 4.0 of the Facebook PHP SDK did not follow [SemVer](http://semver.org/). The versioning format used was as +follows: `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions were squashed together. - 4.0.23 (2015-04-03) - - Added support for new JSON response types in Graph v2.3 when requesting access tokens + - Added support for new JSON response types in Graph v2.3 when requesting access tokens - 4.0.22 (2015-04-02) - - Fixed issues related to multidimensional params - - **Bumped default fallback Graph version to `v2.3`** + - Fixed issues related to multidimensional params + - **Bumped default fallback Graph version to `v2.3`** - 4.0.21 (2015-03-31) - - Added a `FacebookPermissions` class to reference all the Facebook permissions + - Added a `FacebookPermissions` class to reference all the Facebook permissions - 4.0.20 (2015-03-02) - - Fixed a bug introduced in `4.0.19` related to CSRF comparisons + - Fixed a bug introduced in `4.0.19` related to CSRF comparisons - 4.0.19 (2015-03-02) - - Added stricter CSRF comparison checks to `SignedRequest` and `FacebookRedirectLoginHelper` + - Added stricter CSRF comparison checks to `SignedRequest` and `FacebookRedirectLoginHelper` - 4.0.18 (2015-02-24) - - [`FacebookHttpable`] Reverted a breaking change from `4.0.17` that changed the method signatures + - [`FacebookHttpable`] Reverted a breaking change from `4.0.17` that changed the method signatures - 4.0.17 (2015-02-19) - - [`FacebookRedirectLoginHelper`] Added multiple auth types to `getLoginUrl()` - - [`GraphUser`] Added `getTimezone()` - - [`FacebookCurl`] Additional fix for `curl_init()` handling - - Added support for https://graph-video.facebook.com when path ends with `/videos` + - [`FacebookRedirectLoginHelper`] Added multiple auth types to `getLoginUrl()` + - [`GraphUser`] Added `getTimezone()` + - [`FacebookCurl`] Additional fix for `curl_init()` handling + - Added support for https://graph-video.facebook.com when path ends with `/videos` - 4.0.16 (2015-02-03) - - [`FacebookRedirectLoginHelper`] Added "reauthenticate" functionality to `getLoginUrl()` - - [`FacebookCurl`] Fixed `curl_init()` issue + - [`FacebookRedirectLoginHelper`] Added "reauthenticate" functionality to `getLoginUrl()` + - [`FacebookCurl`] Fixed `curl_init()` issue - 4.0.15 (2015-01-06) - - [`FacebookRedirectLoginHelper`] Added guard against accidental exposure of app secret via the logout link + - [`FacebookRedirectLoginHelper`] Added guard against accidental exposure of app secret via the logout link - 4.0.14 (2014-12-29) - - [`GraphUser`] Added `getGender()` - - [`FacebookRedirectLoginHelper`] Added CSRF protection for rerequest links - - [`GraphAlbum`] Fixed bugs in getter methods + - [`GraphUser`] Added `getGender()` + - [`FacebookRedirectLoginHelper`] Added CSRF protection for rerequest links + - [`GraphAlbum`] Fixed bugs in getter methods - 4.0.13 (2014-12-12) - - [`FacebookRedirectLoginHelper`] Added `$displayAsPopup` param to `getLoginUrl()` - - [`FacebookResponse`] Fixed minor pagination bug - - Removed massive cert bundle and replaced with `DigiCertHighAssuranceEVRootCA` for peer verification + - [`FacebookRedirectLoginHelper`] Added `$displayAsPopup` param to `getLoginUrl()` + - [`FacebookResponse`] Fixed minor pagination bug + - Removed massive cert bundle and replaced with `DigiCertHighAssuranceEVRootCA` for peer verification - 4.0.12 (2014-10-30) - - **Updated default fallback Graph version to `v2.2`** - - Fixed potential duplicate `type` param in URL's - - [`FacebookRedirectLoginHelper`] Added `getReRequestUrl()` - - [`GraphUser`] Added `getEmail()` + - **Updated default fallback Graph version to `v2.2`** + - Fixed potential duplicate `type` param in URL's + - [`FacebookRedirectLoginHelper`] Added `getReRequestUrl()` + - [`GraphUser`] Added `getEmail()` - 4.0.11 (2014-08-25) - - [`FacebookCurlHttpClient`] Added a method to disable IPv6 resolution + - [`FacebookCurlHttpClient`] Added a method to disable IPv6 resolution - 4.0.10 (2014-08-12) - - [`GraphObject`] Fixed improper usage of `stdClass` - - Fixed warnings when `open_basedir` directive set - - Fixed long lived sessions forgetting the signed request - - [`CanvasLoginHelper`] Removed GET processing - - Updated visibility on `FacebookSession::useAppSecretProof` + - [`GraphObject`] Fixed improper usage of `stdClass` + - Fixed warnings when `open_basedir` directive set + - Fixed long lived sessions forgetting the signed request + - [`CanvasLoginHelper`] Removed GET processing + - Updated visibility on `FacebookSession::useAppSecretProof` - 4.0.9 (2014-06-27) - - [`FacebookPageTabHelper`] Added ability to fetch `app_data` - - Added `GraphUserPage` Graph node collection - - Cleaned up test files - - Decoupled signed request handling - - Added some stronger type hinting - - Explicitly added separator in `http_build_query()` - - [`FacebookCurlHttpClient`] Updated the calculation of the request body size - - Decoupled access token handling - - [`FacebookRedirectLoginHelper`] Implemented better CSPRNG - - Added autoloader for those poor non-composer peeps + - [`FacebookPageTabHelper`] Added ability to fetch `app_data` + - Added `GraphUserPage` Graph node collection + - Cleaned up test files + - Decoupled signed request handling + - Added some stronger type hinting + - Explicitly added separator in `http_build_query()` + - [`FacebookCurlHttpClient`] Updated the calculation of the request body size + - Decoupled access token handling + - [`FacebookRedirectLoginHelper`] Implemented better CSPRNG + - Added autoloader for those poor non-composer peeps - 4.0.8 (2014-06-10) - - Enabled `appsecret_proof` by default - - Added stream wrapper and Guzzle HTTP client implementations + - Enabled `appsecret_proof` by default + - Added stream wrapper and Guzzle HTTP client implementations - 4.0.7 (2014-05-31) - - Improved testing environment - - Added `FacebookPageTabHelper` - - [`FacebookSession`] Fixed issue where `validateSessionInfo()` would return incorrect results + - Improved testing environment + - Added `FacebookPageTabHelper` + - [`FacebookSession`] Fixed issue where `validateSessionInfo()` would return incorrect results - 4.0.6 (2014-05-24) - - Added feature to inject custom HTTP clients - - [`FacebookCanvasLoginHelper`] Fixed bug that would throw when logging out - - Removed appToken from test credentials file - - [`FacebookRequest`] Added `appsecret_proof` handling + - Added feature to inject custom HTTP clients + - [`FacebookCanvasLoginHelper`] Fixed bug that would throw when logging out + - Removed appToken from test credentials file + - [`FacebookRequest`] Added `appsecret_proof` handling - 4.0.5 (2014-05-19) - - Fixed bug in cURL where proxy headers are not included in header_size - - Added internal SDK error codes for thrown exceptions - - Added stream wrapper fallback for hosting environments without cURL - - Added getter methods for signed requests - - Fixed warning that showed up in tests - - Changed SDK error code for stream failure - - Added `GraphAlbum` Graph node collection + - Fixed bug in cURL where proxy headers are not included in header_size + - Added internal SDK error codes for thrown exceptions + - Added stream wrapper fallback for hosting environments without cURL + - Added getter methods for signed requests + - Fixed warning that showed up in tests + - Changed SDK error code for stream failure + - Added `GraphAlbum` Graph node collection - 4.0.4 (2014-05-15) - - Added more error codes to accommodate more Graph error responses - - [`JavaScriptLoginHelper`] Fixed bug that would try to get a new access token when one already existed + - Added more error codes to accommodate more Graph error responses + - [`JavaScriptLoginHelper`] Fixed bug that would try to get a new access token when one already existed - 4.0.3 (2014-05-14) - - Fixed bug for "Missing client_id parameter" error - - Fixed bug for eTag support when "Network is unreachable" error occurs - - Fixed pagination issue related to `sdtClass` + - Fixed bug for "Missing client_id parameter" error + - Fixed bug for eTag support when "Network is unreachable" error occurs + - Fixed pagination issue related to `sdtClass` - 4.0.2 (2014-05-07) - - [`composer.json`] Upgraded to use PSR-4 autoloading instead of Composer's `classmap` - - [`FacebookCanvasLoginHelper`] Abstracted access to super globals - - [`FacebookRequest`] Fixed bug that blindly appended params to a url - - [`FacebookRequest`] Added support for `DELETE` and `PUT` methods - - Added eTag support to Graph requests + - [`composer.json`] Upgraded to use PSR-4 autoloading instead of Composer's `classmap` + - [`FacebookCanvasLoginHelper`] Abstracted access to super globals + - [`FacebookRequest`] Fixed bug that blindly appended params to a url + - [`FacebookRequest`] Added support for `DELETE` and `PUT` methods + - Added eTag support to Graph requests - 4.0.1 (2014-05-05) - - All exceptions are now extend from `FacebookSDKException` - - [`FacebookSession`] Signed request parsing will throw on malformed signed request input - - Excluded test credentials from tests - - [`FacebookRedirectLoginHelper`] Changed scope on `$state` property - - [`phpunit.xml`] Normalized + - All exceptions are now extend from `FacebookSDKException` + - [`FacebookSession`] Signed request parsing will throw on malformed signed request input + - Excluded test credentials from tests + - [`FacebookRedirectLoginHelper`] Changed scope on `$state` property + - [`phpunit.xml`] Normalized - 4.0.0 (2014-04-30) - - Initial release. Yay! + - Initial release. Yay! diff --git a/README.md b/README.md index c54cd2c..846c4fa 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ [![Build Status](https://github.com/nickdnk/php-graph-sdk/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/nickdnk/php-graph-sdk/actions/workflows/test.yml) [![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-7.0.1-blue.svg)](https://packagist.org/packages/nickdnk/graph-sdk) [![Downloads](https://img.shields.io/packagist/dt/nickdnk/graph-sdk?label=Downloads)](https://packagist.org/packages/nickdnk/graph-sdk) -### This is an unofficial version of Facebook's PHP SDK designed for PHP 7/8+. It is being maintained and tested against the newest PHP versions. You can use this in place of version `5.x` of Facebook's deprecated `facebook/graph-sdk` package. +### This is an unofficial version of Facebook's PHP SDK designed for PHP 8+. It is being maintained and tested against the newest PHP versions. You can use this in place of version `5.x` of Facebook's deprecated `facebook/graph-sdk` package. -## PHP 7.3 is required. +### PHP 8.1 is required. This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. @@ -20,7 +20,7 @@ composer require nickdnk/graph-sdk By default, the request will be made via a `Facebook\HttpClients\FacebookHttpClientInterface`. The default implementation depends on the available PHP extension/packages. In order of priority: -1. Package `guzzlehttp/guzzle` (version 6 or 7): `Facebook\HttpClients\FacebookGuzzleHttpClient` +1. Package `guzzlehttp/guzzle` (v6 and v7 only): `Facebook\HttpClients\FacebookGuzzleHttpClient` 2. ext-curl: `Facebook\HttpClients\FacebookCurlHttpClient` 3. Fallback: `Facebook\HttpClients\FacebookStreamHttpClient` @@ -29,12 +29,17 @@ implementation depends on the available PHP extension/packages. In order of prio Simple GET example of a user's profile. ```php -require_once __DIR__ . '/vendor/autoload.php'; // change path as needed +require_once __DIR__ . '/vendor/autoload.php'; -$fb = new \Facebook\Facebook([ +use Facebook\Facebook; +use Facebook\GraphNodes\GraphUser; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; + +$fb = new Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', + 'default_graph_version' => 'v20.0', //'default_access_token' => '{access-token}', // optional ]); @@ -45,45 +50,41 @@ $fb = new \Facebook\Facebook([ // $helper = $fb->getPageTabHelper(); try { - // Get the \Facebook\GraphNodes\GraphUser object for the current user. + // If you provided a 'default_access_token', the '{access-token}' is optional. $response = $fb->get('/me', '{access-token}'); -} catch(\Facebook\Exceptions\FacebookResponseException $e) { + + // To decode the response to a PHP class, provide the class of the root node in the response. You will have to match + // this manually based on the endpoint you requested. Please do open a pull request if you want to add more types. + + /** @var GraphUser $me */ + $me = $response->getGraphNode(GraphUser::class); + echo 'Logged in as ' . $me->getName() . PHP_EOL; + echo 'User email is ' . $me->getEmail() . PHP_EOL; + +} catch (FacebookResponseException $e) { + // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(\Facebook\Exceptions\FacebookSDKException $e) { + +} catch (FacebookSDKException $e) { + // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; + } - -$me = $response->getGraphUser(); -echo 'Logged in as ' . $me->getName(); ``` -Complete documentation, installation instructions, and examples are available [here](docs/). - ## Tests 1. [Composer](https://getcomposer.org/) is a prerequisite for running the tests. Install composer globally, then run `composer install` to install required files. -2. Create a test app on [Facebook Developers](https://developers.facebook.com), then - create `tests/FacebookTestCredentials.php` from `tests/FacebookTestCredentials.php.dist` and edit it to add your - credentials. -3. The tests can be executed by running this command from the root directory: +2. The tests can be executed by running this command from the root directory: ```bash $ ./vendor/bin/phpunit ``` -By default, the tests will send live HTTP requests to the Graph API. If you are without an internet connection you can -skip these tests by excluding the `integration` group. - -```bash -$ ./vendor/bin/phpunit --exclude-group integration -``` - ## License Please see the [license file](https://github.com/facebook/php-graph-sdk/blob/master/LICENSE) for more information. diff --git a/composer.json b/composer.json index 99e2c67..8d615c6 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "nickdnk/graph-sdk", - "description": "Facebook SDK for PHP compatible with PHP8", + "description": "Facebook SDK for PHP 8+", "keywords": ["facebook", "sdk"], "type": "library", "homepage": "https://github.com/nickdnk/php-graph-sdk", @@ -12,12 +12,12 @@ } ], "require": { - "php": "^7.3 || ^8.0" + "php": "^8.1" }, "require-dev": { - "phpunit/phpunit": "~9.5", - "mockery/mockery": "~1.5.1", - "guzzlehttp/guzzle": "^6.5.0 | ^7.5.0" + "phpunit/phpunit": "^9.5", + "mockery/mockery": "^1.6.12", + "guzzlehttp/guzzle": "^7.9.2" }, "conflict": { "guzzlehttp/guzzle": "<6.0" diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 229a2d7..0000000 --- a/docs/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Facebook SDK for PHP - -The Facebook SDK for PHP is a library with powerful features that enable PHP developers to easily integrate Facebook login and make requests to the Graph API. It also plays well with the [Facebook SDK for JavaScript](https://developers.facebook.com/docs/javascript) to give the front-end user the best possible user experience. But it doesn't end there, the Facebook SDK for PHP makes it easy to upload photos and videos and send batch requests to the Graph API among other things. And SDK for PHP has many extensibility points giving PHP developers full control of how the SDK for PHP interacts with their specific hosting environment and web framework. - -Whether you're developing a website with Facebook login, creating a Facebook Canvas app or Page tab, the Facebook SDK for PHP does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. - -For installation & implementation instructions, look through the [Getting Started with the Facebook SDK for PHP](./getting_started.md) guide, and then check out some of the examples below. - ---- - -## Examples - -The following examples demonstrate how you would accomplish common tasks with the Facebook SDK for PHP. - -- **Authentication & Signed Requests** - - [Facebook Login (OAuth 2.0)](./examples/facebook_login.md) - - [Obtaining an access token from the SDK for JavaScript](./examples/access_token_from_javascript.md) - - [Obtaining an access token within a Facebook Canvas context](./examples/access_token_from_canvas.md) - - [Obtaining an access token within a Facebook Page tab context](./examples/access_token_from_page_tab.md) -- **User profile** - - [Retrieve a user's profile](./examples/retrieve_user_profile.md) - - [Post a link to a user's feed](./examples/post_links.md) -- **File Uploads** - - [Upload a photo to a user's profile](./examples/upload_photo.md) - - [Upload a video to a user's profile](./examples/upload_video.md) -- **Batch Requests** - - [Sending requests in a batch](./examples/batch_request.md) - - [Uploading files in a batch](./examples/batch_upload.md) -- **Pagination** - - [Basic pagination](./examples/pagination_basic.md) - -## API Reference - -For a full list of classes, see the API [reference page](./reference.md). diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md deleted file mode 100644 index 447582f..0000000 --- a/docs/examples/access_token_from_canvas.md +++ /dev/null @@ -1,41 +0,0 @@ -# Get Access Token From App Canvas Example - -This example covers obtaining an access token and signed request from within the context of an app canvas with the Facebook SDK for PHP. - -## Example - -A signed request will be sent to your app via the HTTP POST method within the context of app canvas. The PHP SDK provides a helper to easily obtain, validate & decode the signed request. If the proper OAuth data exists in the signed request payload data, an attempt can be made to obtain an access token from the Graph API. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$helper = $fb->getCanvasHelper(); - -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (! isset($accessToken)) { - echo 'No OAuth data could be obtained from the signed request. User has not authorized your app yet.'; - exit; -} - -// Logged in -echo '

Signed Request

'; -var_dump($helper->getSignedRequest()); - -echo '

Access Token

'; -var_dump($accessToken->getValue()); -``` diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md deleted file mode 100644 index f67ab5a..0000000 --- a/docs/examples/access_token_from_javascript.md +++ /dev/null @@ -1,86 +0,0 @@ -# Getting Access Token From The JavaScript SDK Example - -This example covers obtaining an access token and signed request from the Facebook JavaScript SDK with the Facebook SDK for PHP. - -## Example - -In order to have the JavaScript SDK set a cookie containing a signed request (which contains information about the logged in user), you must first initialize the JavaScript SDK with the `{cookie: true}` option. - -```html - - - -

Log In with the JavaScript SDK

- - - - -``` - -After the user successfully logs in, redirect the user (or make an AJAX request) to a PHP script that obtains an access token from the signed request that exists in the cookie. - -```php -# /js-login.php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$helper = $fb->getJavaScriptHelper(); - -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (! isset($accessToken)) { - echo 'No cookie set or no OAuth data could be obtained from cookie.'; - exit; -} - -// Logged in -echo '

Access Token

'; -var_dump($accessToken->getValue()); - -$_SESSION['fb_access_token'] = (string) $accessToken; - -// User is logged in! -// You can redirect them to a members-only page. -//header('Location: https://example.com/members.php'); -``` diff --git a/docs/examples/access_token_from_page_tab.md b/docs/examples/access_token_from_page_tab.md deleted file mode 100644 index 2674833..0000000 --- a/docs/examples/access_token_from_page_tab.md +++ /dev/null @@ -1,47 +0,0 @@ -# Get Access Token From Page Tab Example - -This example covers obtaining an access token and signed request from within the context of a page tab with the Facebook SDK for PHP. - -## Example - -Page tabs behave much like the app canvas. The PHP SDK provides a helper for page tabs that delivers specific methods unique to page tabs. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$helper = $fb->getPageTabHelper(); - -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (! isset($accessToken)) { - echo 'No OAuth data could be obtained from the signed request. User has not authorized your app yet.'; - exit; -} - -// Logged in -echo '

Page ID

'; -var_dump($helper->getPageId()); - -echo '

User is admin of page

'; -var_dump($helper->isAdmin()); - -echo '

Signed Request

'; -var_dump($helper->getSignedRequest()); - -echo '

Access Token

'; -var_dump($accessToken->getValue()); -``` diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md deleted file mode 100644 index 64b296e..0000000 --- a/docs/examples/batch_request.md +++ /dev/null @@ -1,278 +0,0 @@ -# Batch Request Example - -This example covers sending a batch request with the Facebook SDK for PHP. - -## Example - -The following example assumes we have the following permissions granted from the user: `user_likes`, `user_events`, `user_photos`, `publish_actions`. The example makes use of [JSONPath to reference specific batch operations](https://developers.facebook.com/docs/graph-api/making-multiple-requests/#operations). - -```php - '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', -]); - -// Since all the requests will be sent on behalf of the same user, -// we'll set the default fallback access token here. -$fb->setDefaultAccessToken('user-access-token'); - -/** - * Generate some requests and then send them in a batch request. - */ - -// Get the name of the logged in user -$requestUserName = $fb->request('GET', '/me?fields=id,name'); - -// Get user likes -$requestUserLikes = $fb->request('GET', '/me/likes?fields=id,name&limit=1'); - -// Get user events -$requestUserEvents = $fb->request('GET', '/me/events?fields=id,name&limit=2'); - -// Post a status update with reference to the user's name -$message = 'My name is {result=user-profile:$.name}.' . "\n\n"; -$message .= 'I like this page: {result=user-likes:$.data.0.name}.' . "\n\n"; -$message .= 'My next 2 events are {result=user-events:$.data.*.name}.'; -$statusUpdate = ['message' => $message]; -$requestPostToFeed = $fb->request('POST', '/me/feed', $statusUpdate); - -// Get user photos -$requestUserPhotos = $fb->request('GET', '/me/photos?fields=id,source,name&limit=2'); - -$batch = [ - 'user-profile' => $requestUserName, - 'user-likes' => $requestUserLikes, - 'user-events' => $requestUserEvents, - 'post-to-feed' => $requestPostToFeed, - 'user-photos' => $requestUserPhotos, - ]; - -echo '

Make a batch request

' . "\n\n"; - -try { - $responses = $fb->sendBatchRequest($batch); -} catch (Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch (Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($responses as $key => $response) { - if ($response->isError()) { - $e = $response->getThrownException(); - echo '

Error! Facebook SDK Said: ' . $e->getMessage() . "\n\n"; - echo '

Graph Said: ' . "\n\n"; - var_dump($e->getResponse()); - } else { - echo "

(" . $key . ") HTTP status code: " . $response->getHttpStatusCode() . "
\n"; - echo "Response: " . $response->getBody() . "

\n\n"; - echo "
\n\n"; - } -} - -``` - -There five requests being made in this batch requests. - -- Get the user's full `name` and `id`. -- Get one thing the user likes (which is a [Page node](https://developers.facebook.com/docs/graph-api/reference/page)). -- Get two events the user has been invited to (which are [Event nodes](https://developers.facebook.com/docs/graph-api/reference/event)). -- Compose a message using the data obtained from the 3 requests above and post it on the user's timeline. -- Get two photos from the user. - -If the request was successful, the user should have a new status update similar to this: - -``` -My name is Foo User. - -I like this page: Facebook Developers. - -My next 2 events are House Warming Party,Some Foo Event. -``` - -It should also contain a response containing two photos from the user. - -> **Warning:** The response object should return a `null` response for any request that was pointed to with JSONPath as is [the behaviour of the batch functionality of the Graph API](https://developers.facebook.com/docs/graph-api/making-multiple-requests/#operations). If we want to receive the response anyway we have to set the `omit_response_on_success` option to `false`. [See the example below](#force-response-example). - -## Force Response Example - -The following example is a subset of the [first example](#example). We will only use the `user-events` and `post-to-feed` requests of the [first example](#example), but in this case we will force the server to return the response of the `user-events` request. - -```php - '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', -]); - -// Since all the requests will be sent on behalf of the same user, -// we'll set the default fallback access token here. -$fb->setDefaultAccessToken('user-access-token'); - -// Get user events -$requestUserEvents = $fb->request('GET', '/me/events?fields=id,name&limit=2'); - -// Post a status update with reference to the user's events -$message = 'My next 2 events are {result=user-events:$.data.*.name}.'; -$statusUpdate = ['message' => $message]; -$requestPostToFeed = $fb->request('POST', '/me/feed', $statusUpdate); - -// Create an empty batch request -$batch = $fb->newBatchRequest(); - -// Populate the batch request -// Set the 'omit_response_on_success' option to false to force the server return the response -$batch->add($requestUserEvents, [ - "name" => "user-events", - "omit_response_on_success" => false -]); -$batch->add($requestPostToFeed, "post-to-feed"); - -// Send the batch request -try { - $responses = $fb->getClient()->sendBatchRequest($batch); -} catch (Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch (Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($responses as $key => $response) { - if ($response->isError()) { - $e = $response->getThrownException(); - echo '

Error! Facebook SDK Said: ' . $e->getMessage() . "\n\n"; - echo '

Graph Said: ' . "\n\n"; - var_dump($e->getResponse()); - } else { - echo "

(" . $key . ") HTTP status code: " . $response->getHttpStatusCode() . "
\n"; - echo "Response: " . $response->getBody() . "

\n\n"; - echo "
\n\n"; - } -} - -``` - -## Explicit Dependency Example - -In the following example we will make two requests. -* One to post a status update on the user's feed -* and one to receive the last post of the user (which should be the one that we posted with first request). - -Since we want the second request to be executed after the first one is completed, we have to set the `depends_on` option of the second request to point to the name of the first request. We assume that we have the following options granted from the user: `user_posts`, `publish_actions`. - -```php - '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', -]); - -// Since all the requests will be sent on behalf of the same user, -// we'll set the default fallback access token here. -$fb->setDefaultAccessToken('user-access-token'); - -// Post a status update to the user's feed -$message = 'Random status update'; -$statusUpdate = ['message' => $message]; -$requestPostToFeed = $fb->request('POST', '/me/feed', $statusUpdate); - -// Get last post of the user -$requestLastPost = $fb->request('GET', '/me/feed?limit=1'); - -// Create an empty batch request -$batch = $fb->newBatchRequest(); - -// Populate the batch request -$batch->add($requestPostToFeed, "post-to-feed"); - -// Set the 'depends_on' property to point to the first request -$batch->add($requestLastPost, [ - "name" => "last-post", - "depends_on" => "post-to-feed" -]); - -// Send the batch request -try { - $responses = $fb->getClient()->sendBatchRequest($batch); -} catch (Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch (Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($responses as $key => $response) { - if ($response->isError()) { - $e = $response->getThrownException(); - echo '

Error! Facebook SDK Said: ' . $e->getMessage() . "\n\n"; - echo '

Graph Said: ' . "\n\n"; - var_dump($e->getResponse()); - } else { - echo "

(" . $key . ") HTTP status code: " . $response->getHttpStatusCode() . "
\n"; - echo "Response: " . $response->getBody() . "

\n\n"; - echo "
\n\n"; - } -} -``` - -> **Warning:** The response object should return a `null` response for any request that was pointed to with the `depends_on` option as is [the behaviour of the batch functionality of the Graph API](https://developers.facebook.com/docs/graph-api/making-multiple-requests/#operations). If we want to receive the response anyway we have to set the `omit_response_on_success` option to `false`. [See example](#force-response-example). - -## Multiple User Example - -Since the requests sent in a batch are unrelated by default, we can make requests on behalf of multiple users and pages in the same batch request. - -```php - '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', -]); - -$batch = [ - $fb->request('GET', '/me?fields=id,name', 'user-access-token-one'), - $fb->request('GET', '/me?fields=id,name', 'user-access-token-two'), - $fb->request('GET', '/me?fields=id,name', 'page-access-token-one'), - $fb->request('GET', '/me?fields=id,name', 'page-access-token-two'), -]; - -try { - $responses = $fb->sendBatchRequest($batch); -} catch (Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch (Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($responses as $key => $response) { - if ($response->isError()) { - $e = $response->getThrownException(); - echo '

Error! Facebook SDK Said: ' . $e->getMessage() . "\n\n"; - echo '

Graph Said: ' . "\n\n"; - var_dump($e->getResponse()); - } else { - echo "

(" . $key . ") HTTP status code: " . $response->getHttpStatusCode() . "
\n"; - echo "Response: " . $response->getBody() . "

\n\n"; - echo "
\n\n"; - } -} -``` diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md deleted file mode 100644 index 25dc874..0000000 --- a/docs/examples/batch_upload.md +++ /dev/null @@ -1,62 +0,0 @@ -# Batch File Upload Example - -This example covers uploading files in a batch request with the Facebook SDK for PHP. - -## Example - -The Graph API supports [file uploads in batch requests](https://developers.facebook.com/docs/graph-api/making-multiple-requests#binary) and the Facebook PHP SDK does all the heavy lifting to make it super easy to upload photos and videos in a batch request. - -The following example will upload two photos and one video. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -// Since all the requests will be sent on behalf of the same user, -// we'll set the default fallback access token here. -$fb->setDefaultAccessToken('user-access-token'); - -$batch = [ - 'photo-one' => $fb->request('POST', '/me/photos', [ - 'message' => 'Foo photo', - 'source' => $fb->fileToUpload('/path/to/photo-one.jpg'), - ]), - 'photo-two' => $fb->request('POST', '/me/photos', [ - 'message' => 'Bar photo', - 'source' => $fb->fileToUpload('/path/to/photo-two.jpg'), - ]), - 'video-one' => $fb->request('POST', '/me/videos', [ - 'title' => 'Baz video', - 'description' => 'My neat baz video', - 'source' => $fb->videoToUpload('/path/to/video-one.mp4'), - ]), -]; - -try { - $responses = $fb->sendBatchRequest($batch); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($responses as $key => $response) { - if ($response->isError()) { - $e = $response->getThrownException(); - echo '

Error! Facebook SDK Said: ' . $e->getMessage() . "\n\n"; - echo '

Graph Said: ' . "\n\n"; - var_dump($e->getResponse()); - } else { - echo "

(" . $key . ") HTTP status code: " . $response->getHttpStatusCode() . "
\n"; - echo "Response: " . $response->getBody() . "

\n\n"; - echo "
\n\n"; - } -} -``` diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md deleted file mode 100644 index d1a6a34..0000000 --- a/docs/examples/facebook_login.md +++ /dev/null @@ -1,101 +0,0 @@ -# Facebook Login Example - -This example covers Facebook Login with the Facebook SDK for PHP. - -## Example - -Although it's common to see examples of Facebook Login being implemented in one PHP script, is best to use two separate PHP scripts for more separation and more control over the responses. - -In this example, the PHP script that generates the login link is called `/login.php`. The callback URL that Facebook redirects the user to after login dialog is called `/fb-callback.php`. - -## /login.php - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$helper = $fb->getRedirectLoginHelper(); - -$permissions = ['email']; // Optional permissions -$loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permissions); - -echo 'Log in with Facebook!'; -``` - -## /fb-callback.php - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$helper = $fb->getRedirectLoginHelper(); - -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (! isset($accessToken)) { - if ($helper->getError()) { - header('HTTP/1.0 401 Unauthorized'); - echo "Error: " . $helper->getError() . "\n"; - echo "Error Code: " . $helper->getErrorCode() . "\n"; - echo "Error Reason: " . $helper->getErrorReason() . "\n"; - echo "Error Description: " . $helper->getErrorDescription() . "\n"; - } else { - header('HTTP/1.0 400 Bad Request'); - echo 'Bad request'; - } - exit; -} - -// Logged in -echo '

Access Token

'; -var_dump($accessToken->getValue()); - -// The OAuth 2.0 client handler helps us manage access tokens -$oAuth2Client = $fb->getOAuth2Client(); - -// Get the access token metadata from /debug_token -$tokenMetadata = $oAuth2Client->debugToken($accessToken); -echo '

Metadata

'; -var_dump($tokenMetadata); - -// Validation (these will throw FacebookSDKException's when they fail) -$tokenMetadata->validateAppId($config['app_id']); -// If you know the user ID this access token belongs to, you can validate it here -//$tokenMetadata->validateUserId('123'); -$tokenMetadata->validateExpiration(); - -if (! $accessToken->isLongLived()) { - // Exchanges a short-lived access token for a long-lived one - try { - $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken); - } catch (Facebook\Exceptions\FacebookSDKException $e) { - echo "

Error getting long-lived access token: " . $e->getMessage() . "

\n\n"; - exit; - } - - echo '

Long-lived

'; - var_dump($accessToken->getValue()); -} - -$_SESSION['fb_access_token'] = (string) $accessToken; - -// User is logged in with a long-lived access token. -// You can redirect them to a members-only page. -//header('Location: https://example.com/members.php'); -``` diff --git a/docs/examples/pagination_basic.md b/docs/examples/pagination_basic.md deleted file mode 100644 index 635798f..0000000 --- a/docs/examples/pagination_basic.md +++ /dev/null @@ -1,44 +0,0 @@ -# Pagination Example - -This example covers basic cursor pagination with the Facebook SDK for PHP. - -## Example - -The Graph API supports [several methods to paginate over response data](https://developers.facebook.com/docs/graph-api/using-graph-api/#paging). The PHP SDK supports cursor-based pagination out of the box. It does all the heavy lifting of managing page cursors for you. - -In this example we'll pull five entries from a user's feed (assuming the user approved the `read_stream` permission for your app). Then we'll use the `next()` method to grab the next page of results. Naturally you'd provide some sort of pagination navigation in your app, but this is just an example to get you started. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -try { - // Requires the "read_stream" permission - $response = $fb->get('/me/feed?fields=id,message&limit=5'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -// Page 1 -$feedEdge = $response->getGraphEdge(); - -foreach ($feedEdge as $status) { - var_dump($status->asArray()); -} - -// Page 2 (next 5 results) -$nextFeed = $fb->next($feedEdge); - -foreach ($nextFeed as $status) { - var_dump($status->asArray()); -} -``` diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md deleted file mode 100644 index 29cd09b..0000000 --- a/docs/examples/post_links.md +++ /dev/null @@ -1,39 +0,0 @@ -# Post Links Using the Graph API - -This example covers posting a link to the current user's timeline using the Graph API and Facebook SDK for PHP. - -It assumes that you've already obtained an access token from one of the helpers found [here](../reference.md). The access token must have the `publish_actions` permission for this to work. - -For more information, see the documentation for [`Facebook\Facebook`](../reference/Facebook.md), [`Facebook\FacebookResponse`](../reference/FacebookResponse.md), [`Facebook\GraphNodes\GraphNode`](../reference/GraphNode.md), [`Facebook\Exceptions\FacebookSDKException`](../reference/FacebookSDKException.md) and [`Facebook\Exceptions\FacebookResponseException`](../reference/FacebookResponseException.md). - -## Example - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$linkData = [ - 'link' => 'http://www.example.com', - 'message' => 'User provided message', - ]; - -try { - // Returns a `Facebook\FacebookResponse` object - $response = $fb->post('/me/feed', $linkData, '{access-token}'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Posted with id: ' . $graphNode['id']; -``` - -Note that the 'message' field must come from the user, as pre-filled content is forbidden by the [Platform Policies](https://developers.intern.facebook.com/policy/#control) (2.3). diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md deleted file mode 100644 index 6df0d8a..0000000 --- a/docs/examples/retrieve_user_profile.md +++ /dev/null @@ -1,34 +0,0 @@ -# Retrieve User Profile via the Graph API - -This example covers getting profile information for the current user and printing their name, using the Graph API and the Facebook SDK for PHP. - -It assumes that you've already obtained an access token from one of the helpers found [here](../reference.md). - -For more information, see the documentation for [`Facebook\Facebook`](../reference/Facebook.md), [`Facebook\FacebookResponse`](../reference/FacebookResponse.md), [`Facebook\GraphNodes\GraphUser`](../reference/GraphNode.md#graphuser-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](../reference/FacebookSDKException.md) and [`Facebook\Exceptions\FacebookResponseException`](../reference/FacebookResponseException.md). - -## Example - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -try { - // Returns a `Facebook\FacebookResponse` object - $response = $fb->get('/me?fields=id,name', '{access-token}'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -$user = $response->getGraphUser(); - -echo 'Name: ' . $user['name']; -// OR -// echo 'Name: ' . $user->getName(); -``` diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md deleted file mode 100644 index 6b60419..0000000 --- a/docs/examples/upload_photo.md +++ /dev/null @@ -1,39 +0,0 @@ -# Upload Photos to a User's Profile - -This example covers uploading a photo to the current User's profile using the Graph API and the Facebook SDK for PHP. - -It assumes that you've already acquired an access token using one of the helper classes found [here](../reference.md). The access token must have the `publish_actions` permission for this to work. - -For more information, see the documentation for [`Facebook\Facebook`](../reference/Facebook.md), [`Facebook\FileUpload\FacebookFile`](../reference/FacebookFile.md), [`Facebook\FacebookResponse`](../reference/FacebookResponse.md), [`Facebook\GraphNodes\GraphNode`](../reference/GraphNode.md), [`Facebook\Exceptions\FacebookSDKException`](../reference/FacebookSDKException.md) and [`Facebook\Exceptions\FacebookResponseException`](../reference/FacebookResponseException.md). - -## Example - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$data = [ - 'message' => 'My awesome photo upload example.', - 'source' => $fb->fileToUpload('/path/to/photo.jpg'), -]; - -try { - // Returns a `Facebook\FacebookResponse` object - $response = $fb->post('/me/photos', $data, '{access-token}'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Photo ID: ' . $graphNode['id']; -``` - -Note that the `message` field must come from the user, as pre-filled content is forbidden by the [Platform Policies](https://developers.intern.facebook.com/policy/#control) (2.3). diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md deleted file mode 100644 index 2aea43e..0000000 --- a/docs/examples/upload_video.md +++ /dev/null @@ -1,66 +0,0 @@ -# Video Upload Example - -This example covers uploading & posting a video to a user's timeline with the Facebook SDK for PHP. - -## Example - -> **Warning:** Before you upload, check out the [video publishing options & requirements](https://developers.facebook.com/docs/graph-api/reference/video#publishing) for the specific video endpoint you want to publish to. - -The following example will upload a video in chunks using the [resumable upload](https://developers.facebook.com/docs/graph-api/video-uploads#resumable) feature added in Graph v2.3. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); - -$data = [ - 'title' => 'My Foo Video', - 'description' => 'This video is full of foo and bar action.', -]; - -try { - $response = $fb->uploadVideo('me', '/path/to/foo_bar.mp4', $data, '{user-access-token}'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -echo 'Video ID: ' . $response['video_id']; -``` - -See more about the [`uploadVideo()` method](../reference/Facebook.md#uploadvideo). - -For versions of Graph before v2.3, videos had to be uploaded in one request. - -```php -$fb = new Facebook\Facebook([/* . . . */]); - -$data = [ - 'title' => 'My Foo Video', - 'description' => 'This video is full of foo and bar action.', - 'source' => $fb->videoToUpload('/path/to/foo_bar.mp4'), -]; - -try { - $response = $fb->post('/me/videos', $data, 'user-access-token'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Video ID: ' . $graphNode['id']; -``` diff --git a/docs/getting_started.md b/docs/getting_started.md deleted file mode 100644 index 57b816f..0000000 --- a/docs/getting_started.md +++ /dev/null @@ -1,267 +0,0 @@ -# Getting started with the Facebook SDK for PHP - -Whether you're developing a website with Facebook login, creating a Facebook Canvas app or Page tab, the Facebook SDK for PHP does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. - -## Autoloading & namespaces - -The Facebook SDK for PHP v5 is coded in compliance with [PSR-4](http://www.php-fig.org/psr/psr-4/). This means it relies heavily on namespaces so that class files can be loaded for you automatically. - -It would be advantageous to familiarize yourself with the concepts of [namespacing](http://php.net/manual/en/language.namespaces.rationale.php) and [autoloading](http://php.net/manual/en/function.spl-autoload-register.php) if you are not already acquainted with them. - -## System requirements - -- PHP 5.4 or greater -- [Composer](https://getcomposer.org/) *(optional)* - -## Installing the Facebook SDK for PHP - -There are two methods to install the Facebook SDK for PHP. The recommended installation method is by using [Composer](#installing-with-composer-recommended). If are unable to use Composer for your project, you can still [install the SDK manually](#manually-installing-if-you-really-have-to) by downloading the source files and including the autoloader. - -## Installing with Composer (recommended) - -[Composer](https://getcomposer.org/) is the recommended way to install the Facebook SDK for PHP. Simply run the following in the root of your project. - -``` -composer require facebook/graph-sdk -``` - -> The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer. - -Once you do this, composer will edit your `composer.json` file and download the latest version of the SDK and put it in the `/vendor/` directory. - -Make sure to include the Composer autoloader at the top of your script. - -```php -require_once __DIR__ . '/vendor/autoload.php'; -``` - -## Manually installing (if you really have to) - -First, download the source code and unzip it wherever you like in your project. - -[Download the SDK for PHP v5](https://github.com/facebook/php-graph-sdk/archive/5.7.zip) - -Then include the autoloader provided in the SDK at the top of your script. - -```php -require_once __DIR__ . '/path/to/php-graph-sdk/src/Facebook/autoload.php'; -``` - -The autoloader should be able to auto-detect the proper location of the source code. - -### Keeping things tidy - -The source code includes myriad files that aren't necessary for use in a production environment. If you'd like to strip out everything except the core files, follow this example. - -> For this example we'll assume the root of your website is `/var/html`. - -After downloading the source code with the button above, extract the files in a temporary directory. - -Move the folder `src/Facebook` to the root of your website installation or where ever you like to put third-party code. For this example we'll rename the `Facebook` directory to `facebook-sdk-v5`. - -The path the the core SDK files should now be located in `/var/html/facebook-sdk-v5` and inside will also be the `autoload.php` file. - -Assuming we have a script called `index.php` in the root of our web project, we need to include the autoloader at the top of our script. - -```php -require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; -``` - -If the autoloader is having trouble detecting the path to the source files, we can define the location of the source code before the `require_once` statement. - -```php -define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v5/'); -require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; -``` - -## Configuration and setup - -> **Warning:** This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](https://developers.facebook.com/apps). - -Before we can send requests to the Graph API, we need to load our app configuration into the `Facebook\Facebook` service. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - ]); -``` - -You'll need to replace the `{app-id}` and `{app-secret}` with your Facebook app's ID and secret which can be obtained from the [app settings tab](https://developers.facebook.com/apps). - -> **Warning:** It's important that you specify a `default_graph_version` value as this will give you more control over which version of Graph you want to use. If you don't specify a `default_graph_version`, the SDK for PHP will choose one for you and it might not be one that is compatible with your app. - -The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](reference/Facebook.md). - -## Authentication and authorization - -The SDK can be used to support logging a Facebook user into your site using Facebook Login which is based on OAuth 2.0. - -Most all request made to the Graph API require an access token. We can obtain user access tokens with the SDK using the [helper classes](reference.md). - -### Obtaining an access token from redirect - -For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper`](reference/FacebookRedirectLoginHelper.md) to generate a login URL with the `getLoginUrl()` method. The link will take the user to an app authorization screen and upon approval, will redirect them back to a URL that you specified. On the redirect callback page we can obtain the user access token as an [`AccessToken`](reference/AccessToken.md) entity. - -> For this example we'll assume `login.php` will present the login link and the user will be redirected to `login-callback.php` where we will obtain the access token. - -```php -# login.php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getRedirectLoginHelper(); -$permissions = ['email', 'user_likes']; // optional -$loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions); - -echo 'Log in with Facebook!'; -``` - -> **Warning:** The `FacebookRedirectLoginHelper` makes use of sessions to store a [CSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) value. You need to make sure you have sessions enabled before invoking the `getLoginUrl()` method. This is usually done automatically in most web frameworks, but if you're not using a web framework you can add [`session_start();`](http://php.net/session_start) to the top of your `login.php` & `login-callback.php` scripts. - -```php -# login-callback.php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getRedirectLoginHelper(); -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (isset($accessToken)) { - // Logged in! - $_SESSION['facebook_access_token'] = (string) $accessToken; - - // Now you can redirect to another page and use the - // access token from $_SESSION['facebook_access_token'] -} -``` - -### Obtaining an access token from a Facebook Canvas context - -If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](reference/FacebookCanvasHelper.md) to get an [`AccessToken`](reference/AccessToken.md) entity for the user. - -> **Warning:** The `FacebookCanvasHelper` will detect a [signed request](reference.md#signed-requests) for you and attempt to obtain an access token using the payload data from the signed request. The signed request will only contain the data needed to obtain an access token if the user has already authorized your app sometime in the past. If they have not yet authorized your app the `getAccessToken()` will return `null` and you will need to log the user in with either the [redirect method](#obtaining-an-access-token-from-redirect) or by using the [SDK for JavaScript](https://developers.facebook.com/docs/javascript) and then use the SDK for PHP to [obtain the access token from the cookie](#obtaining-an-access-token-from-the-sdk-for-javascript) the SDK for JavaScript set. - -```php -# example-canvas-app.php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getCanvasHelper(); -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (isset($accessToken)) { - // Logged in. -} -``` - -> If your app exists within the context of a Page tab, you can obtain an access token using the example above since a Page tab is very similar to a Facebook Canvas app. But if you'd like to use a Page-tab-specific helper, you can use the [`Facebook\Helpers\FacebookPageTabHelper`](reference/FacebookPageTabHelper.md) - -### Obtaining an access token from the SDK for JavaScript - -If you're already using the Facebook SDK for JavaScript to authenticate users, you can obtain the access token with PHP by using the [FacebookJavaScriptHelper](reference/FacebookJavaScriptHelper.md). The `getAccessToken()` method will return an [`AccessToken`](reference/AccessToken.md) entity. - -```php -# example-obtain-from-js-cookie-app.php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getJavaScriptHelper(); -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (isset($accessToken)) { - // Logged in -} -``` - -> **Warning:** Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](https://developers.facebook.com/docs/javascript/reference/FB.init/v2.10). This will make the SDK for JavaScript set a cookie on your domain containing information about the user in the form of a signed request. - -## Extending the access token - -When a user first logs into your app, the access token your app receives will be a short-lived access token that lasts about 2 hours. It's generally a good idea to exchange the short-lived access token for a long-lived access token that lasts about 60 days. - -To extend an access token, you can make use of the [`OAuth2Client`](reference/Facebook.md#getoauth2client). - -```php -// OAuth 2.0 client handler -$oAuth2Client = $fb->getOAuth2Client(); - -// Exchanges a short-lived access token for a long-lived one -$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken('{access-token}'); -``` - -[See more about long-lived and short-lived access tokens](https://developers.facebook.com/docs/facebook-login/access-tokens#usertokens). - -## Making Requests to the Graph API - -Once you have an instance of the `Facebook\Facebook` service and obtained an access token, you can begin making calls to the Graph API. - -In this example we will send a GET request to the Graph API endpoint `/me`. The `/me` endpoint is a special alias to the [user node endpoint](https://developers.facebook.com/docs/graph-api/reference/user) that references the user or Page making the request. - -```php -$fb = new Facebook\Facebook([/* . . . */]); - -// Sets the default fallback access token so we don't have to pass it to each request -$fb->setDefaultAccessToken('{access-token}'); - -try { - $response = $fb->get('/me'); - $userNode = $response->getGraphUser(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -echo 'Logged in as ' . $userNode->getName(); -``` - -The `get()` method will return a [`Facebook\FacebookResponse`](reference/FacebookResponse.md) which is an entity that represents an HTTP response from the Graph API. - -To get the response in the form of a nifty collection, we call `getGraphUser()` which returns a [`Facebook\GraphNodes\GraphUser`](reference/GraphNode.md#graphuser-instance-methods) entity which represents a user node. - -If you don't care about fancy collections and just want the response as a plain-old array, you can call the `getDecodedBody()` method on the `FacebookResponse` entity. - -```php -try { - $response = $fb->get('/me'); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // . . . - exit; -} - -$plainOldArray = $response->getDecodedBody(); -``` - -For a full list of all of the components that make up the SDK for PHP, see the [SDK for PHP reference page](reference.md). diff --git a/docs/reference.md b/docs/reference.md deleted file mode 100644 index a98acfc..0000000 --- a/docs/reference.md +++ /dev/null @@ -1,91 +0,0 @@ -# Facebook SDK for PHP Reference (v5) - -Below is the API reference for the Facebook SDK for PHP. - -# Core API - -These classes are at the core of the Facebook SDK for PHP. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\Facebook`](reference/Facebook.md) | The main service object that helps tie all the SDK components together. | -| [`Facebook\FacebookApp`](reference/FacebookApp.md) | An entity that represents a Facebook app and is required to send requests to Graph. | - -# Authentication - -These classes facilitate authenticating a Facebook user with OAuth 2.0. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\Helpers\FacebookRedirectLoginHelper`](reference/FacebookRedirectLoginHelper.md) | An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link. | -| [`Facebook\Authentication\AccessToken`](reference/AccessToken.md) | An entity that represents an access token. | -| `Facebook\Authentication\AccessTokenMetadata` | An entity that represents metadata from an access token. | -| `Facebook\Authentication\OAuth2Client` | An OAuth 2.0 client that sends and receives HTTP requests related to user authentication. | - -# Requests and Responses - -These classes are used in a Graph API request/response cycle. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\FacebookRequest`](reference/FacebookRequest.md) | An entity that represents an HTTP request to be sent to Graph. | -| [`Facebook\FacebookResponse`](reference/FacebookResponse.md) | An entity that represents an HTTP response from Graph. | -| [`Facebook\FacebookBatchRequest`](reference/FacebookBatchRequest.md) | An entity that represents an HTTP batch request to be sent to Graph. | -| [`Facebook\FacebookBatchResponse`](reference/FacebookBatchResponse.md) | An entity that represents an HTTP response from Graph after sending a batch request. | -| [`Facebook\FacebookClient`](reference/FacebookClient.md) | A service object that sends HTTP requests and receives HTTP responses to and from the Graph API. | - -# Signed Requests - -Classes to help obtain and manage signed requests. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\Helpers\FacebookJavaScriptHelper`](reference/FacebookJavaScriptHelper.md) | Used to obtain an access token or signed request from the cookie set by the JavaScript SDK. | -| [`Facebook\Helpers\FacebookCanvasHelper`](reference/FacebookCanvasHelper.md) | Used to obtain an access token or signed request from within the context of an app canvas. | -| [`Facebook\Helpers\FacebookPageTabHelper`](reference/FacebookPageTabHelper.md) | Used to obtain an access token or signed request from within the context of a page tab. | -| [`Facebook\SignedRequest`](reference/SignedRequest.md) | An entity that represents a signed request. | - -# Core Exceptions - -These are the core exceptions that the SDK will throw when an error occurs. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\Exceptions\FacebookSDKException`](reference/FacebookSDKException.md) | The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error. | -| [`Facebook\Exceptions\FacebookResponseException`](reference/FacebookResponseException.md) | The base exception to all Graph error responses. This exception is never thrown directly. | - -# Graph Nodes and Edges - -Graph nodes are collections that represent nodes returned by the Graph API. And Graph edges are a collection of nodes returned from an edge on the Graph API. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\GraphNodes\GraphNode`](reference/GraphNode.md) | The base collection object that represents a generic node. | -| [`Facebook\GraphNodes\GraphEdge`](reference/GraphEdge.md) | A collection of GraphNode\'s with special methods to help paginate over the edge. | -| [`Facebook\GraphNodes\GraphAchievement`](reference/GraphNode.md#graphachievement-instance-methods) | A collection that represents an Achievement node. | -| [`Facebook\GraphNodes\GraphAlbum`](reference/GraphNode.md#graphalbum-instance-methods) | A collection that represents an Album node. | -| [`Facebook\GraphNodes\GraphLocation`](reference/GraphNode.md#graphlocation-instance-methods) | A collection that represents a Location node. | -| [`Facebook\GraphNodes\GraphPage`](reference/GraphNode.md#graphpage-instance-methods) | A collection that represents a Page node. | -| [`Facebook\GraphNodes\GraphPicture`](reference/GraphNode.md#graphpicture-instance-methods) | A collection that represents a Picture node. | -| [`Facebook\GraphNodes\GraphUser`](reference/GraphNode.md#graphuser-instance-methods) | A collection that represents a User node. | - -# File Uploads - -These are entities that represent files to be uploaded with a Graph request. - -| Class name | Description | -| ------------- | ------------- | -| [`Facebook\FileUpload\FacebookFile`](reference/FacebookFile.md) | Represents a generic file to be uploaded to the Graph API. | -| [`Facebook\FileUpload\FacebookVideo`](reference/FacebookVideo.md) | Represents a video file to be uploaded to the Graph API. | - -# Extensibility - -You can overwrite certain functionality of the SDK by coding to an interface and injecting an instance of your custom functionality. - -| Interface name | Description | -| ------------- | ------------- | -| `Facebook\HttpClients\ FacebookHttpClientInterface` | An interface to code your own HTTP client implementation. | -| `Facebook\Http\GraphRawResponse` | An entity that is returned from an instance of a `FacebookHttpClientInterface` that represents a raw HTTP response from the Graph API. | -| [`Facebook\PersistentData\PersistentDataInterface`](reference/PersistentDataInterface.md) | An interface to code your own persistent data storage implementation. | -| [`Facebook\Url\UrlDetectionInterface`](reference/UrlDetectionInterface.md) | An interface to code your own URL detection logic. | -| [`Facebook\PseudoRandomString\ PseudoRandomStringGeneratorInterface`](reference/PseudoRandomStringGeneratorInterface.md) | An interface to code your own cryptographically secure pseudo-random string generator. | diff --git a/docs/reference/AccessToken.md b/docs/reference/AccessToken.md deleted file mode 100644 index ec45390..0000000 --- a/docs/reference/AccessToken.md +++ /dev/null @@ -1,56 +0,0 @@ -# AccessToken for the Facebook SDK for PHP - -Requests to the Graph API need to have an access token sent with them to identify the app, user and/or page that is making the request. The `Facebook\Authentication\AccessToken` entity represents an access token. - -## Facebook\Authentication\AccessToken - -Whenever you use the PHP SDK to obtain an access token, the access token will be returned as an instance of `AccessToken`. The `AccessToken` entity contains a number of methods that make it easier to handle access tokens. - -### getValue() -```php -public string getValue() -``` -Returns the access token as a string. The `AccessToken` entity also makes use of the [magic method `__toString()`](http://php.net/manual/en/language.oop5.magic.php#object.tostring) so you can cast an `AccessToken` entity to a string with: `$token = (string) $accessTokenEntity;` - -### getExpiresAt() -```php -public \DateTime|null getExpiresAt() -``` -If the expiration date was provided when the `AccessToken` entity was instantiated, the `getExpiresAt()` method will return the access token expiration date as a [`DateTime` entity](http://php.net/manual/en/class.datetime.php). If the expiration date was not originally provided, the method will return `null`. - -### isExpired() -```php -public boolean|null isExpired() -``` -If the expiration date was provided when the `AccessToken` entity was instantiated, the `isExpired()` method will return `true` if the access token has expired. If the access token is still active, the method will return `false`. If the expiration date was not -originally provided, the method will return `null`. - -### isLongLived() -```php -public boolean|null isLongLived() -``` -If the expiration date was provided when the `AccessToken` entity was instantiated, the `isLongLived()` method will return `true` if the access token is long-lived. If the token is short-lived, the method will return `false`. If the expiration date was not -originally provided, the method will return `false`. [See more about long-lived and short-lived access tokens](https://developers.facebook.com/docs/facebook-login/access-tokens#extending). - -### isAppAccessToken() -```php -public boolean isAppAccessToken() -``` -Since app access tokens contain the app secret in plain-text, it's very important that app access tokens aren't used in client-side contexts where someone might be able to grab the app secret. For this reason you should do a check on the access token to ensure it is not an app access token before using it on the client-side. The `isAppAccessToken()` will return `true` if the access token is an app access token and `false` if it is not. - -### getAppSecretProof() -```php -public string getAppSecretProof(string $appSecret) -``` -For better security, all requests to the Graph API should be [signed with an app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof) and your app settings should enable the app secret proof requirement for all requests. The PHP SDK will generate the app secret proof for each request automatically, but if you need to generate one, pass your app secret to the `getAppSecretProof()` method and it will return the HMAC hash that is the app secret proof. - -## Making an entity from a string - -If you already have an access token in the form of a string (from a session or database for example), you can make an `AccessToken` entity with it by passing the access token string as the first argument in the `AccessToken` the constructor. - -You can optionally pass an expiration date in the form of timestamp as the second argument. - -```php -$expires = time() + 60 * 60 * 2; -$accessToken = new Facebook\Authentication\AccessToken('{example-access-token}', $expires); -``` diff --git a/docs/reference/Birthday.md b/docs/reference/Birthday.md deleted file mode 100644 index 20901da..0000000 --- a/docs/reference/Birthday.md +++ /dev/null @@ -1,55 +0,0 @@ -# Birthday for the Facebook SDK for PHP - -Extends `\DateTime` and represents a user's birthday returned from the Graph API which can be returned omitting certain information. - -Users may opt not to share birth day or month, or may not share birth year. Possible returns: - -* MM/DD/YYYY -* MM/DD -* YYYY - -## Facebook\GraphNodes\Birthday - -After retrieving a GraphUser from the Graph API, the `getBirthday()` method will return the birthday in the form of a `Facebook\GraphNodes\Birthday` entity which indicates which aspects of the birthday the user opted to share. - -The `Facebook\GraphNodes\Birthday` entity extends `DateTime` so `format` may be used to present the information appropriately depending on what information it contains. - -Usage: - -```php -$fb = new Facebook\Facebook(\* *\); -// Returns a `Facebook\FacebookResponse` object -$response = $fb->get('/me'); - -// Get the response typed as a GraphUser -$user = $response->getGraphUser(); - -// Gets birthday value, assume Graph return was format MM/DD -$birthday = $user->getBirthday(); - -var_dump($birthday); -// class Facebook\GraphNodes\Birthday ... - -var_dump($birthday->hasDate()); -// true - -var_dump($birthday->hasYear()); -// false - -var_dump($birthday->format('m/d')); -// 03/21 -``` - -## Instance Methods - -### hasDate() -```php -public boolean hasDate() -``` -Returns whether or not the birthday object contains the day and month of birth. - -### hasYear() -```php -public boolean hasYear() -``` -Returns whether or not the birthday object contains the year of birth. diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md deleted file mode 100644 index 732f9ab..0000000 --- a/docs/reference/Facebook.md +++ /dev/null @@ -1,562 +0,0 @@ -# Facebook service class for the Facebook SDK for PHP - -The Facebook SDK for PHP is made up of many components. The `Facebook\Facebook` service class provides an easy interface for working with all the components of the SDK. - -## Facebook\Facebook - -To instantiate a new `Facebook\Facebook` service, pass an array of configuration options to the constructor. - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.10', - // . . . - ]); -``` - -Usage: - -```php -// Send a GET request -$response = $fb->get('/me'); - -// Send a POST request -$response = $fb->post('/me/feed', ['message' => 'Foo message']); - -// Send a DELETE request -$response = $fb->delete('/{node-id}'); -``` - -If you don't provide a `default_access_token` in the configuration options, or you wish to use a different access token than the default, you can explicitly pass the access token as an argument to the `get()`, `post()`, and `delete()` methods. - -```php -$res = $fb->get('/me', '{access-token}'); -$res = $fb->post('/me/feed', ['foo' => 'bar'], '{access-token}'); -$res = $fb->delete('/{node-id}', '{access-token}'); -``` - -## Configuration options - -Although the `Facebook\Facebook` service tries to make the SDK as easy as possible to use, it also makes it easy to customize with configuration options. - -Full configuration options list: - -```php -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - 'default_access_token' => '{access-token}', - 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.10', - 'http_client_handler' => 'guzzle', - 'persistent_data_handler' => 'memory', - 'url_detection_handler' => new MyUrlDetectionHandler(), - 'pseudo_random_string_generator' => new MyPseudoRandomStringGenerator(), -]); -``` - -### `app_id` -The ID of your Facebook app (required). - -### `app_secret` -The secret of your Facebook app (required). - -### `default_access_token` -The default fallback access token to use if one is not explicitly provided. The value can be of type `string` or `Facebook\AccessToken`. If any other value is provided an `InvalidArgumentException` will be thrown. Defaults to `null`. - -### `enable_beta_mode` -Enable [beta mode](https://developers.facebook.com/docs/apps/beta-tier) so that request are made to the [https://graph.beta.facebook.com](https://graph.beta.facebook.com/) endpoint. Set to boolean `true` to enable or `false` to disable. Defaults to `false`. - -### `default_graph_version` -Allows you to overwrite the default Graph version number set in `Facebook\Facebook::DEFAULT_GRAPH_VERSION`. Set this as a string as it would appear in the Graph url, e.g. `v2.10`. Defaults to the [latest version of Graph](https://developers.facebook.com/docs/apps/changelog). - -### `http_client_handler` -Allows you to overwrite the default HTTP client. - -By default, the SDK will try to use cURL as the HTTP client. If a cURL implementation cannot be found, it will fallback to a stream wrapper HTTP client. You can force either HTTP client implementations by setting this value to `curl` or `stream`. - -If you wish to use Guzzle, you can set this value to `guzzle`, but it requires that you [install Guzzle](http://docs.guzzlephp.org/en/latest/) with composer. - -If you wish to write your own HTTP client, you can code your HTTP client to the `Facebook\HttpClients\FacebookHttpClientInterface` and set this value to an instance of your custom client. - -```php -$fb = new Facebook([ - 'http_client_handler' => new MyCustomHttpClient(), -]); -``` - -If any other value is provided an `InvalidArgumentException` will be thrown. - -### `persistent_data_handler` -Allows you to overwrite the default persistent data store. - -By default, the SDK will try to use the native PHP session for the persistent data store. There is also an in-memory persistent data handler which is useful when running your script from the command line for example. You can force either implementation by setting this value to `session` or `memory`. - -If you wish to write your own persistent data handler, you can code your persistent data handler to the [`Facebook\PersistentData\PersistentDataInterface`](PersistentDataInterface.md) and set the value of `persistent_data_handler` to an instance of your custom handler. - -```php -$fb = new Facebook([ - 'persistent_data_handler' => new MyCustomPersistentDataHandler(), -]); -``` - -If any other value is provided an `InvalidArgumentException` will be thrown. - -### `url_detection_handler` -Allows you to overwrite the default URL detection logic. - -The SDK will do its best to detect the proper current URL but this can sometimes get tricky if you have a very customized environment. You can write your own URL detection logic that implements the ['Facebook\Url\UrlDetectionInterface'](UrlDetectionInterface.md)` and set the value of `url_detection_handler` to an instance of your custom URL detector. - -```php -$fb = new Facebook([ - 'url_detection_handler' => new MyUrlDetectionHandler(), -]); -``` - -If any other value is provided an `InvalidArgumentException` will be thrown. - -### `pseudo_random_string_generator` -Allows you to overwrite the default cryptographically secure pseudo-random string generator. - -Generating random strings in PHP is easy but generating _cryptographically secure_ random strings is another matter. By default the SDK will attempt to detect a suitable to cryptographically secure random string generator for you. If a cryptographically secure method cannot be detected, a `Facebook\Exceptions\FacebookSDKException` will be thrown. - -You can force a specific implementation of the CSPRSG's provided in the SDK by setting `pseudo_random_string_generator` to one of the following methods: `mcrypt`, `openssl` and `urandom`. - -```php -$fb = new Facebook([ - 'pseudo_random_string_generator' => 'openssl', -]); -``` - -You can write your own CSPRSG that implements the [`Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface`](PseudoRandomStringGeneratorInterface.md) and set the value of `pseudo_random_string_generator` to an instance of your custom generator. - -```php -$fb = new Facebook([ - 'pseudo_random_string_generator' => new MyPseudoRandomStringGenerator(), -]); -``` - -If any other value is provided an `InvalidArgumentException` will be thrown. - -## Environment variables fallback - -The only required configuration options are `app_id` and `app_secret`. However, the SDK will look to environment variables for the app ID and app secret. - -To take advantage of this feature, simply set an environment variable named `FACEBOOK_APP_ID` with your Facebook app ID and set an environment variable named `FACEBOOK_APP_SECRET` with your Facebook app secret and you will be able to instantiate the `Facebook\Facebook` service without setting any configuration in the constructor. - -```php -$fb = new Facebook\Facebook(); -``` - -# Instance Methods - -## getApp() -```php -public FacebookApp getApp() -``` -Returns the instance of `Facebook\FacebookApp` for the instantiated service. - -## getClient() -```php -public Facebook\FacebookClient getClient() -``` -Returns the instance of [`Facebook\FacebookClient`](FacebookClient.md) for the instantiated service. - -## getOAuth2Client() -```php -public Facebook\Authentication\OAuth2Client getOAuth2Client() -``` -Returns an instance of `Facebook\Authentication\OAuth2Client`. - -## getLastResponse() -```php -public Facebook\FacebookResponse|Facebook\FacebookBatchResponse|null getLastResponse() -``` -Returns the last response received from the Graph API in the form of a `Facebook\FacebookResponse` or `Facebook\FacebookBatchResponse`. - -## getUrlDetectionHandler() -```php -public Facebook\Url\UrlDetectionInterface getUrlDetectionHandler() -``` -Returns an instance of [`Facebook\Url\UrlDetectionInterface`](UrlDetectionInterface.md). - -## getDefaultAccessToken() -```php -public Facebook\Authentication\AccessToken|null getDefaultAccessToken() -``` -Returns the default fallback [`AccessToken`](AccessToken.md) entity that is being used with every request to Graph. This value can be set with the configuration option `default_access_token` or by using `setDefaultAccessToken()`. - -## setDefaultAccessToken() -```php -public setDefaultAccessToken(string|Facebook\AccessToken $accessToken) -``` -Sets the default fallback access token to be use with all requests sent to Graph. The access token can be a string or an instance of [`AccessToken`](AccessToken.md). - -```php -$fb->setDefaultAccessToken('{my-access-token}'); - -// . . . OR . . . - -$accessToken = new Facebook\Authentication\AccessToken('{my-access-token}'); -$fb->setDefaultAccessToken($accessToken); -``` - -This setting will overwrite the value from `default_access_token` option if it was passed to the `Facebook\Facebook` constructor. - -## getDefaultGraphVersion() -```php -public string getDefaultGraphVersion() -``` -Returns the default version of Graph. If the `default_graph_version` configuration option was not set, this will default to `Facebook\Facebook::DEFAULT_GRAPH_VERSION`. - -## get() -```php -public Facebook\FacebookResponse get( - string $endpoint, - string|AccessToken|null $accessToken, - string|null $eTag, - string|null $graphVersion -) -``` - -Sends a GET request to Graph and returns a `Facebook\FacebookResponse`. - -`$endpoint` -The url to send to Graph without the version prefix (required). - -```php -$fb->get('/me'); -``` - -`$accessToken` -The access token (as a string or `AccessToken` entity) to use for the request. If none is provided, the SDK will assume the value from the `default_access_token` configuration option if it was set. - -`$eTag` -[Graph supports eTags](https://developers.facebook.com/docs/marketing-api/etags). Set this to the eTag from a previous request to get a `304 Not Modified` response if the data has not changed. - -`$graphVersion` -This will overwrite the Graph version that was set in the `default_graph_version` configuration option. - -## post() -```php -public Facebook\FacebookResponse post( - string $endpoint, - array $params, - string|AccessToken|null $accessToken, - string|null $eTag, - string|null $graphVersion -) -``` - -Sends a POST request to Graph and returns a `Facebook\FacebookResponse`. - -The arguments are the same as `get()` above with the exception of `$params`. - -`$params` -The associative array of params you want to send in the body of the POST request. - -```php -$response = $fb->post('/me/feed', ['message' => 'Foo message']); -``` - -## delete() -```php -public Facebook\FacebookResponse delete( - string $endpoint, - array $params, - string|AccessToken|null $accessToken, - string|null $eTag, - string|null $graphVersion -) -``` - -Sends a DELETE request to Graph and returns a `Facebook\FacebookResponse`. - -The arguments are the same as `post()` above. - -```php -$response = $fb->delete('/{node-id}', ['object' => '1234']); -``` - -## request() -```php -public Facebook\FacebookRequest request( - string $method, - string $endpoint, - array $params, - string|AccessToken|null $accessToken, - string|null $eTag, - string|null $graphVersion -) -``` - -Instantiates a new `Facebook\FacebookRequest` entity **but does not send the request to Graph**. This is useful for creating a number of requests to be sent later in a batch request (see `sendBatchRequest()` below). - -The arguments are the same as `post()` above with the exception of `$method`. - -`$method` -The HTTP request verb to use for this request. This can be set to any verb that the `$graphVersion` of Graph supports, e.g. `GET`, `POST`, `DELETE`, etc. - -```php -$request = $fb->request('GET', '/{node-id}'); -``` - -## sendRequest() -```php -public Facebook\FacebookResponse sendRequest( - string $method, - string $endpoint, - array $params, - string|AccessToken|null $accessToken, - string|null $eTag, - string|null $graphVersion -) -``` - -Sends a request to the Graph API. - -```php -$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.10'); -``` - -## sendBatchRequest() -```php -public Facebook\FacebookBatchResponse sendBatchRequest( - array $requests, - string|AccessToken|null $accessToken, - string|null $graphVersion -) -``` - -Sends an array of `Facebook\FacebookRequest` entities as a batch request to Graph. - -The `$accessToken` and `$graphVersion` arguments are the same as `get()` above. - -`$requests` -An array of `Facebook\FacebookRequest` entities. This can be a numeric or associative array but every value of the array has to be an instance of `Facebook\FacebookRequest`. - -If the requests are sent as an associative array, the key will be used as the `name` of the request so that it can be referenced by another request. See more on [batch request naming and using JSONPath](https://developers.facebook.com/docs/graph-api/making-multiple-requests). - -```php -$requests = [ - 'me' => $fb->request('GET', '/me'), - 'you' => $fb->request('GET', '/1337', [], '{user-b-access-token}'), - 'my_post' => $fb->request('POST', '/1337/feed', ['message' => 'Hi!']), -]; -$batchResponse = $fb->sendBatchRequest($requests); -``` - -[See a full batch example](../examples/batch_request.md). - -## newBatchRequest() -```php -public Facebook\FacebookBatchRequest newBatchRequest( - string|AccessToken|null $accessToken, - string|null $graphVersion -) -``` - -Instantiates an empty `Facebook\FacebookBatchRequest`. -To populate it use the [`Facebook\FacebookBatchRequest::add()`](FacebookBatchRequest.md#add) method. - -The `$accessToken` and `$graphVersion` arguments are the same as `get()` above. -If any of the requests contained in the batch request does not have either the `$accessToken` or the `$graphVersion` set, -it fallbacks to the values provided in the instantiation of the batch request. - -[See a full batch example](../examples/batch_request.md). - -## getRedirectLoginHelper() -```php -public Facebook\Helpers\FacebookRedirectLoginHelper getRedirectLoginHelper() -``` - -Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](FacebookRedirectLoginHelper.md) which is used to generate a "Login with Facebook" link and obtain an access token from a redirect. - -```php -$helper = $fb->getRedirectLoginHelper(); -``` - -## getJavaScriptHelper() -```php -public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() -``` - -Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](FacebookJavaScriptHelper.md) which is used to access the signed request stored in the cookie set by the SDK for JavaScript. - -```php -$helper = $fb->getJavaScriptHelper(); -``` - -## getCanvasHelper() -```php -public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() -``` - -Returns a [`Facebook\Helpers\FacebookCanvasHelper`](FacebookCanvasHelper.md) which is used to access the signed request that is `POST`ed to canvas apps. - -```php -$helper = $fb->getCanvasHelper(); -``` - -## getPageTabHelper() -```php -public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() -``` - -Returns a [`Facebook\Helpers\FacebookPageTabHelper`](FacebookPageTabHelper.md) which is used to access the signed request that is `POST`ed to canvas apps and provides a number of helper methods useful for apps living in a page tab context. - -```php -$helper = $fb->getPageTabHelper(); -``` - -## next() -```php -public Facebook\GraphNodes\GraphEdge|null next(Facebook\GraphNodes\GraphEdge $graphEdge) -``` - -Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphEdge`](GraphEdge.md) collection. If the next page returns no results, `null` will be returned. - -```php -// Iterate over 5 pages max -$maxPages = 5; - -// Get a list of photo nodes from the /photos edge -$response = $fb->get('/me/photos?fields=id,source,likes&limit=5'); - -$photosEdge = $response->getGraphEdge(); - -if (count($photosEdge) > 0) { - $pageCount = 0; - do { - foreach ($photosEdge as $photo) { - var_dump($photo->asArray()); - - // Deep pagination is supported on child GraphEdge's - $likes = $photo['likes']; - do { - echo '

Likes:

' . "\n\n"; - var_dump($likes->asArray()); - } while ($likes = $fb->next($likes)); - } - $pageCount++; - } while ($pageCount < $maxPages && $photosEdge = $fb->next($photosEdge)); -} -``` - -## previous() -```php -public Facebook\GraphNodes\GraphEdge|null previous(Facebook\GraphNodes\GraphEdge $graphEdge) -``` - -Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphEdge` collection. Functions just like `next()` above, but in the opposite direction of pagination. - -## fileToUpload() -```php -public Facebook\FileUpload\FacebookFile fileToUpload(string $pathToFile) -``` - -When a valid path to a local or remote file is provided, `fileToUpload()` will returns a `FacebookFile` entity that can be used in the params in a POST request to Graph. - -```php -// Upload a photo for a user -$data = [ - 'message' => 'A neat photo upload example. Neat.', - 'source' => $fb->fileToUpload('/path/to/photo.jpg'), -]; - -try { - $response = $fb->post('/me/photos', $data); -} catch(FacebookSDKException $e) { - echo 'Error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Photo ID: ' . $graphNode['id']; -``` - -## videoToUpload() -```php -public Facebook\FileUpload\FacebookVideo videoToUpload(string $pathToVideoFile) -``` - -Uploading videos to Graph requires that you send the request to `https://graph-video.facebook.com` instead of the normal `https://graph.facebook.com` host name. When you use `videoToUpload()` to upload a video, the SDK for PHP will automatically point the request to the `graph-video.facebook.com` host name for you. - -```php -// Upload a video for a user -$data = [ - 'title' => 'My awesome video', - 'description' => 'More info about my awesome video.', - 'source' => $fb->videoToUpload('/path/to/video.mp4'), -]; - -try { - $response = $fb->post('/me/videos', $data); -} catch(FacebookSDKException $e) { - echo 'Error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Video ID: ' . $graphNode['id']; -``` - -## uploadVideo() -```php -public array videoToUpload( - string $target, - string $pathToFile, - array $metadata = [], - string|Facebook\AccessToken $accessToken = null, - int $maxTransferTries = 5, - string $graphVersion = null - ) -``` - -Functionality to [upload video files in chunks](https://developers.facebook.com/docs/graph-api/video-uploads#resumable) was added to the Graph API in v2.3. The `uploadVideo()` method provides an easy API to take advantage of this new feature. - -### Parameters - -`$target` -The ID or alias of the target node. This can be a user ID, page ID, event ID, group ID or `me`. - -`$pathToFile` -The absolute or relative path to the video file to upload. - -`$metadata` -All the metadata associated with the [Video node](https://developers.facebook.com/docs/graph-api/reference/video). - -`$accessToken` -The access token to use for this request. Falls back to the default access token if one exists. - -`$maxTransferTries` -During the [transfer phase](https://developers.facebook.com/docs/graph-api/video-uploads#transfer) an upload can fail for a number of reasons. If the Graph API responds with an error that is resumable, the PHP SDK will retry uploading the chunk automatically. By default the PHP SDK will try to upload each chunk five times before throwing a `FacebookResponseException`. - -`$graphVersion` -The version of the Graph API to use. The resumable upload feature did not become available until Graph v2.3. - -### Return Value - -The array that is returned will contain two keys; `video_id` with the ID of the video node, and `success` with a boolean value that represents a successful or failed transfer. - -### Example - -```php -// Upload a video for a user (chunked) -$data = [ - 'title' => 'My awesome video', - 'description' => 'More info about my awesome video.', -]; - -try { - $response = $fb->uploadVideo('me', '/path/to/video.mp4', $data, '{user-access-token}'); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Error: ' . $e->getMessage(); - exit; -} - -echo 'Video ID: ' . $response['video_id']; -``` diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md deleted file mode 100644 index 2506fd3..0000000 --- a/docs/reference/FacebookApp.md +++ /dev/null @@ -1,57 +0,0 @@ -# FacebookApp for the Facebook SDK for PHP - -In order to make requests to the Graph API, you need to [create a Facebook app](https://developers.facebook.com/apps) and obtain the app ID and the app secret. The `Facebook\FacebookApp` entity represents the Facebook app that is making the requests to the Graph API. - -> **Warning:** It is quite uncommon to work with the `FacebookApp` entity directly since the `Facebook\Facebook` service handles injecting it into the required classes for you. - -## Facebook\FacebookApp - -To instantiate a new `Facebook\FacebookApp` entity, pass the app ID and app secret to the constructor. - -```php -$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); -``` - -Alternatively you can obtain the `Facebook\FacebookApp` entity from the [`Facebook\Facebook`](Facebook.md) super service class. - -```php -$fb = new Facebook\Facebook([/* . . . */]); -$fbApp = $fb->getApp(); -``` - -You'll rarely be using the `FacebookApp` entity directly unless you're doing some extreme customizations of the SDK for PHP. But this entity plays an important role in the internal workings of the SDK for PHP. - -## Instance Methods - -## getAccessToken() -```php -public Facebook\Authentication\AccessToken getAccessToken() -``` -Returns an app access token in the form of an [`AccessToken`](AccessToken.md) entity. - -## getId() -```php -public string getId() -``` -Returns the app id. - -## getSecret() -```php -public string getSecret() -``` -Returns the app secret. - -## Serialization - -The `Facebook\FacebookApp` entity can be serialized and unserialized. - -```php -$fbApp = new Facebook\FacebookApp('foo-app-id', 'foo-app-secret'); - -$serializedFacebookApp = serialize($fbApp); -// C:29:"Facebook\\FacebookApp":54:{a:2:{i:0;s:10:"foo-app-id";i:1;s:14:"foo-app-secret";}} - -$unserializedFacebookApp = unserialize($serializedFacebookApp); -echo $unserializedFacebookApp->getAccessToken(); -// foo-app-id|foo-app-secret -``` diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md deleted file mode 100644 index c3d40dc..0000000 --- a/docs/reference/FacebookBatchRequest.md +++ /dev/null @@ -1,98 +0,0 @@ -# FacebookBatchRequest for the Facebook SDK for PHP - -Represents a batch request that will be sent to the Graph API. - -## Facebook\FacebookBatchRequest - -You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor or -by using the [`Facebook\Facebook::newBatchRequest()`](Facebook.md#newBatchRequest) factory method. - -```php -use Facebook\FacebookBatchRequest; - -$request = new FacebookBatchRequest( - Facebook\FacebookApp $app, - array $requests, - string|null $accessToken, - string|null $graphVersion -); -``` - -The `$requests` array is an array of [`Facebook\FacebookRequest`'s](FacebookRequest.md) to be sent as a batch request. - -The `FacebookBatchRequest` entity does not actually make any calls to the Graph API, but instead just represents a batch request that can be sent to the Graph API later. The batch request can be sent by using [`Facebook\Facebook::sendBatchRequest()`](Facebook.md#sendbatchrequest) or [`Facebook\FacebookClient::sendBatchRequest()`](FacebookClient.md#sendbatchrequest.md). - -Usage: - -```php -$fb = new Facebook\Facebook(/* . . . */); - -$requests = [ - $fb->request('GET', '/me'), - $fb->request('POST', '/me/feed', [/* */]), -]; - -// Send the batch request to Graph -try { - $batchResponse = $fb->sendBatchRequest($requests, '{access-token}'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($batchResponse as $key => $response) { - if ($response->isError()) { - $error = $response->getThrownException(); - echo $key . ' error: ' . $error->getMessage(); - } else { - // Success - } -} -``` - -## Instance Methods - -Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](FacebookRequest.md) entity, all the methods are inherited. - -### add() -```php -public add( - array|Facebook\FacebookBatchRequest $request, - string|null $name -) -``` -Adds a request to be sent in the batch request. The `$request` can be a single [`Facebook\FacebookRequest`](FacebookRequest.md) or an array of `Facebook\FacebookRequest`'s. - -The `$name` argument is optional and is used to identify the request in the batch. - -### getRequests() -```php -public array getRequests() -``` -Returns the array of [`Facebook\FacebookRequest`'s](FacebookRequest.md) to be sent in the batch request. - -## Array Access - -Since `Facebook\FacebookBatchRequest` implements `\IteratorAggregate` and `\ArrayAccess`, the requests can be accessed via array syntax and can also be iterated over. - -```php -$fb = new Facebook\Facebook(/* . . . */); -$requests = [ - 'foo' => $fb->request('GET', '/me'), - 'bar' => $fb->request('POST', '/me/feed', [/* */]), -]; -$batchRequest = new Facebook\FacebookBatchRequest($fb->getApp(), $requests, '{access-token}'); - -var_dump($batchRequest[0]); -/* -array(2) { - 'name' => string(3) "foo" - 'request' => class Facebook\FacebookRequest - . . . -*/ -``` diff --git a/docs/reference/FacebookBatchResponse.md b/docs/reference/FacebookBatchResponse.md deleted file mode 100644 index e71b24f..0000000 --- a/docs/reference/FacebookBatchResponse.md +++ /dev/null @@ -1,76 +0,0 @@ -# FacebookBatchResponse for the Facebook SDK for PHP - -Represents a batch response returned from the Graph API. - -## Facebook\FacebookBatchResponse - -After sending a batch request to the Graph API, the response will be returned in the form of a `Facebook\FacebookBatchResponse` entity. - -Usage: - -```php -$fb = new Facebook\Facebook(/* . . . */); -$requests = [ - $fb->request('GET', '/me'), - $fb->request('POST', '/me/feed', [/* */]), -]; - -// Send the batch request to Graph -try { - $batchResponse = $fb->sendBatchRequest($requests, '{access-token}'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -foreach ($batchResponse as $key => $response) { - if ($response->isError()) { - $error = $response->getThrownException(); - echo $key . ' error: ' . $error->getMessage(); - } else { - // Success - } -} - -var_dump($batchResponse); -// class Facebook\FacebookBatchResponse . . . -``` - -## Instance Methods - -Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](FacebookResponse.md) entity, all the methods are inherited. - -### getResponses() -```php -public array getResponses() -``` -Returns the array of [`Facebook\FacebookResponse`](FacebookResponse.md) entities that were returned from Graph. - -## Array Access - -Since `Facebook\FacebookBatchResponse` implements `\IteratorAggregate` and `\ArrayAccess`, the responses can be accessed via array syntax and can also be iterated over. - -```php -$requests = [ - 'foo' => $fb->request('GET', '/me'), - 'bar' => $fb->request('POST', '/me/feed', [/* */]), -]; -$batchResponse = $fb->sendBatchRequest($requests); - -foreach ($batchResponse as $key => $response) { - if ($response->isError()) { - $error = $response->getThrownException(); - echo $key . ' error: ' . $error->getMessage(); - } else { - // Success - } -} - -var_dump($batchResponse['foo']); -// class Facebook\FacebookResponse . . . -``` diff --git a/docs/reference/FacebookCanvasHelper.md b/docs/reference/FacebookCanvasHelper.md deleted file mode 100644 index 1862457..0000000 --- a/docs/reference/FacebookCanvasHelper.md +++ /dev/null @@ -1,103 +0,0 @@ -# Facebook\Helpers\FacebookCanvasHelper - -The `FacebookCanvasHelper` is used to obtain an access token or signed request when working within the context of an [app canvas](https://developers.facebook.com/docs/games/canvas). - -```php -Facebook\Helpers\FacebookCanvasHelper( Facebook\FacebookApp $facebookApp ) -``` - -## Usage - -If your app is loaded through Canvas, Facebook sends a POST request to your app with a signed request. This helper will handle validating and decrypting the signed request. - -```php -$fb = new Facebook\Facebook([/* */]); -$canvasHelper = $fb->getCanvasHelper(); -$signedRequest = $canvasHelper->getSignedRequest(); - -if ($signedRequest) { - $payload = $signedRequest->getPayload(); - var_dump($payload); -} -``` - -If a user has already authenticated your app, you can also obtain an access token. - -```php -$fb = new Facebook\Facebook([/* */]); -$canvasHelper = $fb->getCanvasHelper(); - -try { - $accessToken = $canvasHelper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); -} - -if (isset($accessToken)) { - // Logged in. -} -``` - -The `$accessToken` will be `null` if the signed request did not contain any OAuth 2.0 data to obtain the access token. - -## Instance Methods - -### __construct() -```php -public FacebookCanvasHelper __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) -``` -Upon instantiation, `FacebookCanvasHelper` validates and decrypts the signed request that was sent via POST if present. - -### getAccessToken() -```php -public Facebook\AccessToken|null getAccessToken() -``` -Checks the signed request for authentication data and tries to obtain an access token access token. - -### getUserId() -```php -public string|null getUserId() -``` -A convenience method for obtaining a user's ID from the signed request if present. This will only return the user's ID if a valid signed request can be obtained and decrypted and the user has already authorized the app. - -```php -$userId = $canvasHelper->getUserId(); - -if ($userId) { - // User is logged in -} -``` - -This is equivalent to accessing the user ID from the signed request entity. - -```php -$signedRequest = $canvasHelper->getSignedRequest(); - -if ($signedRequest) { - $userId = $signedRequest->getUserId(); - // OR - $userId = $signedRequest->get('user_id'); -} -``` - -### getAppData() -```php -public string|null getAppData() -``` -Gets the value that is set in the `app_data` property if present. - -### getSignedRequest() -```php -public Facebook\SignedRequest|null getSignedRequest() -``` -Returns the signed request as an instance of [`Facebook\SignedRequest`](SignedRequest.md) if present. - -### getRawSignedRequest() -```php -public string|null getRawSignedRequest() -``` -Returns the raw encoded signed request as a `string` if present in the POST variables or `null`. diff --git a/docs/reference/FacebookClient.md b/docs/reference/FacebookClient.md deleted file mode 100644 index 91e4be8..0000000 --- a/docs/reference/FacebookClient.md +++ /dev/null @@ -1,72 +0,0 @@ -# FacebookClient service class for the Facebook SDK for PHP - -The `Facebook\FacebookClient` service class juggles the dependencies needed to make requests to the Graph API. - -## Facebook\FacebookClient - -You most likely won't be working with the `Facebook\FacebookClient` service directly if you're using the `Facebook\Facebook` super service class, but if you have a highly customized environment, you might need to send requests with an instance of `Facebook\FacebookClient`. - -You can grab an instance of a `Facebook\FacebookClient` service, from the `Facebook\Facebook` super service class. - -```php -$fb = new Facebook\Facebook([/* */]); -$fbClient = $fb->getClient(); -``` - -Alternatively you could instantiate a new `Facebook\FacebookClient` service directly. - -```php -$fbClient = new Facebook\FacebookClient($httpClientHandler, $enableBeta = false); -``` - -The Graph API has a number of different base URL's based on what request you want to send. For example, if you wanted to send requests to the beta version of Graph, you'd need to send requests to [https://graph.beta.facebook.com](https://graph.beta.facebook.com) instead [https://graph.facebook.com](https://graph.facebook.com). And if you wanted to upload a video, that request would need to be sent to [https://graph-video.facebook.com](https://graph-video.facebook.com). - -The `Facebook\FacebookClient` service takes the guess-work out of managing those base URL's by automatically sending your requests to the proper URL. - -## Instance Methods - -### getHttpClientHandler() -```php -public Facebook\HttpClients\FacebookHttpClientInterface getHttpClientHandler() -``` -Returns the instance of `Facebook\HttpClients\FacebookHttpClientInterface` that the service is using. - -### setHttpClientHandler() -```php -public setHttpClientHandler(Facebook\HttpClients\FacebookHttpClientInterface $client) -``` -If you've coded your own HTTP client to the `Facebook\HttpClients\FacebookHttpClientInterface`, you can inject it into the service using this method. - -### enableBetaMode() -```php -public enableBetaMode(boolean $enable = true) -``` -Tells the service to send requests to the beta URL's which include [https://graph.beta.facebook.com](https://graph.beta.facebook.com) and [https://graph-video.beta.facebook.com](https://graph-video.beta.facebook.com). - -### sendRequest() -```php -public Facebook\FacebookResponse sendRequest(Facebook\FacebookRequest $request) -``` -Sends a non-batch request to Graph. - -Takes a [`Facebook\FacebookRequest`](FacebookRequest.md) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. - -Returns the response from Graph in the form of a [`Facebook\FacebookResponse`](FacebookResponse.md). - -If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](FacebookSDKException.md) will be thrown. - -If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](FacebookResponseException.md) will be thrown. - -### sendBatchRequest() -```php -public Facebook\FacebookBatchResponse sendBatchRequest(Facebook\FacebookBatchRequest $batchRequest) -``` -Sends a batch request to Graph. - -Takes a [`Facebook\FacebookBatchRequest`](FacebookBatchRequest.md) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. - -Returns the response from Graph in the form of a [`Facebook\FacebookBatchResponse`](FacebookBatchResponse.md). - -If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](FacebookSDKException.md) will be thrown. - -If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](FacebookResponseException.md) will be thrown. diff --git a/docs/reference/FacebookFile.md b/docs/reference/FacebookFile.md deleted file mode 100644 index 3046995..0000000 --- a/docs/reference/FacebookFile.md +++ /dev/null @@ -1,61 +0,0 @@ -# File Uploading with the Facebook SDK for PHP - -Uploading files to the Graph API is made a breeze with the Facebook SDK for PHP. - -## Facebook\FileUpload\FacebookFile(string $pathToFile, int $maxLength = -1, int $offset = -1) - -The `FacebookFile` entity represents a local or remote file to be uploaded with a request to Graph. - -There are two ways to instantiate a `FacebookFile` entity. One way is to instantiate it directly: - -```php -use Facebook\FileUpload\FacebookFile; - -$myFileToUpload = new FacebookFile('/path/to/file.jpg'); -``` - -Alternatively, you can use the `fileToUpload()` factory on the `Facebook\Facebook` super service to instantiate a new `FacebookFile` entity. - -```php -$fb = new Facebook\Facebook(/* . . . */); - -$myFileToUpload = $fb->fileToUpload('/path/to/file.jpg'); -``` - -Partial file uploads are possible using the `$maxLength` and `$offset` parameters which provide the same functionality as the `$maxlen` and `$offset` parameters on the [`stream_get_contents()` PHP function](http://php.net/stream_get_contents). - -## Usage - -The following example uploads a photo for a user. - -```php -$data = [ - 'message' => 'My awesome photo upload example.', - 'source' => $fb->fileToUpload('/path/to/photo.jpg'), - // Or you can provide a remote file location - //'source' => $fb->fileToUpload('https://example.com/photo.jpg'), -]; - -try { - $response = $fb->post('/me/photos', $data); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Photo ID: ' . $graphNode['id']; -``` - -> **Note:** Although you can use `fileToUpload()` to upload a remote file, it is more efficient to just point the Graph request to the the remote file with the `url` param. - -```php -// Upload a remote photo for a user without using the FacebookFile entity -$data = [ - 'message' => 'A neat photo upload example. Neat.', - 'url' => 'https://example.com/photo.jpg', -]; - -$response = $fb->post('/me/photos', $data); -``` diff --git a/docs/reference/FacebookJavaScriptHelper.md b/docs/reference/FacebookJavaScriptHelper.md deleted file mode 100644 index d9520c7..0000000 --- a/docs/reference/FacebookJavaScriptHelper.md +++ /dev/null @@ -1,93 +0,0 @@ -# Facebook\Helpers\FacebookJavaScriptHelper - -If you're using the [JavaScript SDK](https://developers.facebook.com/docs/javascript) on your site, information on the logged in user is stored in a cookie. Use the `FacebookJavaScriptHelper` to obtain an access token or signed request from the cookie. - -## Usage - -This helper will handle validating and decode the signed request from the cookie set by the JavaScript SDK. - -```php -$fb = new Facebook\Facebook([/* */]); -$jsHelper = $fb->getJavaScriptHelper(); -$signedRequest = $jsHelper->getSignedRequest(); - -if ($signedRequest) { - $payload = $signedRequest->getPayload(); - var_dump($payload); -} -``` - -If a user has already authenticated your app, you can also obtain an access token. - -```php -$fb = new Facebook\Facebook([/* */]); -$jsHelper = $fb->getJavaScriptHelper(); - -try { - $accessToken = $jsHelper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); -} - -if (isset($accessToken)) { - // Logged in. -} -``` - -You will likely want to make an Ajax request when the login state changes in the Facebook SDK for JavaScript. Information about that here: [FB.event.subscribe](https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/#events) - -## Instance Methods - -### __construct() -```php -public FacebookJavaScriptHelper __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) -``` -Upon instantiation, `FacebookJavaScriptHelper` validates and decodes the signed request that exists in the cookie set by the JavaScript SDK if present. - -### getAccessToken() -```php -public Facebook\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) -``` -Checks the signed request for authentication data and tries to obtain an access token access token. - -### getUserId() -```php -public string|null getUserId() -``` -A convenience method for obtaining a user's ID from the signed request if present. This will only return the user's ID if a valid signed request can be obtained and decoded and the user has already authorized the app. - -```php -$userId = $jsHelper->getUserId(); - -if ($userId) { - // User is logged in -} -``` - -This is equivalent to accessing the user ID from the signed request entity. - -```php -$signedRequest = $jsHelper->getSignedRequest(); - -if ($signedRequest) { - $userId = $signedRequest->getUserId(); - // OR - $userId = $signedRequest->get('user_id'); -} -``` - -### getSignedRequest() -```php -public Facebook\SignedRequest|null getSignedRequest() -``` -Returns the signed request as a [`Facebook\SignedRequest`](SignedRequest.md) entity if present. - -### getRawSignedRequest() -```php -public string|null getRawSignedRequest() -``` -Returns the raw encoded signed request as a `string` or `null`. diff --git a/docs/reference/FacebookPageTabHelper.md b/docs/reference/FacebookPageTabHelper.md deleted file mode 100644 index 3666a8c..0000000 --- a/docs/reference/FacebookPageTabHelper.md +++ /dev/null @@ -1,59 +0,0 @@ -# Facebook\Helpers\FacebookPageTabHelper - -Page tabs are similar to the context to app canvases but are treated slightly differently. Use the `FacebookPageTabHelper` to obtain an access token or signed request within the context of a page tab. - -## Usage - -The usage of the `FacebookPageTabHelper` is exactly the same as [`FacebookCanvasHelper`](FacebookCanvasHelper.md) with additional methods to obtain the `page` data from the signed request. - -```php -$fb = new Facebook\Facebook([/* */]); -$pageHelper = $fb->getPageTabHelper(); -$signedRequest = $pageHelper->getSignedRequest(); - -if ($signedRequest) { - $payload = $signedRequest->getPayload(); - var_dump($payload); -} -``` - -If a user has already authenticated your app, you can also obtain an access token. - -```php -$fb = new Facebook\Facebook([/* */]); -$pageHelper = $fb->getPageTabHelper(); - -try { - $accessToken = $pageHelper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); -} - -if (isset($accessToken)) { - // Logged in. -} -``` - -## Instance Methods - -### getPageData() -```php -public string|null getPageData($key, $default = null) -``` -Gets a value from the `page` property if present. - -### isAdmin() -```php -public boolean isAdmin() -``` -Returns `true` is the user has authenticated your app and is an admin of the parent page. - -### getPageId() -```php -public string|null getPageId() -``` -Returns the ID of the parent page if it can be obtained from the `page` property in the signed request. diff --git a/docs/reference/FacebookRedirectLoginHelper.md b/docs/reference/FacebookRedirectLoginHelper.md deleted file mode 100644 index 5639177..0000000 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ /dev/null @@ -1,130 +0,0 @@ -# Facebook\Helpers\FacebookRedirectLoginHelper - -The most commonly used helper is the `FacebookRedirectLoginHelper` which allows you to obtain a user access token from a redirect using a "Log in with Facebook" link. - -## Usage - -Facebook Login is achieved via OAuth 2.0. But you don't really have to know much about OAuth 2.0 since the SDK for PHP does all the heavy lifting for you. - -### Obtaining an instance of FacebookRedirectLoginHelper - -You can obtain an instance of the `FacebookRedirectLoginHelper` from the `getRedirectLoginHelper()` method on the `Facebook\Facebook` service. - -```php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getRedirectLoginHelper(); -``` - -### Login with Facebook - -The basic login flow goes like this: - -1. A user is presented with a unique "log in with Facebook" link that was generated by the `FacebookRedirectLoginHelper`. -2. Once the user clicks on the link they will be taken to Facebook's website and presented with an app authorization modal. -3. After the user confirms or denies the app authorization, they will be redirected to a specific callback URL on your website. -4. In your callback URL you can analyse the response to obtain a user access token or display an error if the user denied the request. - -```php -# login.php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getRedirectLoginHelper(); -$permissions = ['email', 'user_likes']; // optional -$loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions); - -echo 'Log in with Facebook!'; -``` - -> **Warning:** The `FacebookRedirectLoginHelper` makes use of sessions to store a [CSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) value. You need to make sure you have sessions enabled before invoking the `getLoginUrl()` method. This is usually done automatically in most web frameworks, but if you're not using a web framework you can add [`session_start();`](http://php.net/session_start) to the top of your `login.php` & `login-callback.php` scripts. You can overwrite the default session handling - see [extensibility points](#extensibility-points) below. - -Then, in your callback page (at the redirect url) when Facebook sends the user back: - -```php -# login-callback.php -$fb = new Facebook\Facebook([/* . . . */]); - -$helper = $fb->getRedirectLoginHelper(); -try { - $accessToken = $helper->getAccessToken(); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -if (isset($accessToken)) { - // Logged in! - $_SESSION['facebook_access_token'] = (string) $accessToken; - - // Now you can redirect to another page and use the - // access token from $_SESSION['facebook_access_token'] -} elseif ($helper->getError()) { - // The user denied the request - exit; -} -``` - -## Instance Methods - -### getLoginUrl() -```php -public string getLoginUrl(string $redirectUrl, array $scope = [], string $separator = '&') -``` -Generates an authorization URL to ask a user for access to their profile on behalf of your app. - -#### Arguments -- `$redirectUrl` (_Required_) The callback URL that the user will be redirected to after being presented with the app authorization modal. -- `$scope` (_Optional_) A numeric array of permissions to ask the user for. -- `$separator` (_Optional_) The URL parameter separator. When working with XML documents, you can set this to `&` for example. - -### getReRequestUrl() -```php -public string getReRequestUrl(string $redirectUrl, array $scope = [], string $separator = '&') -``` -Generates a URL to rerequest permissions from a user. The arguments are the same as the `getLoginUrl()` method above. - -### getReAuthenticationUrl() -```php -public string getReAuthenticationUrl(string $redirectUrl, array $scope = [], string $separator = '&') -``` -Generates a URL to ask the user to reauthenticate. The arguments are the same as the `getLoginUrl()` method above. - -### getLogoutUrl() -```php -public string getLogoutUrl(string $accessToken, string $next, string $separator = '&') -``` -Generates the URL log a user out of Facebook. This will throw an `FacebookSDKException` if you try to use an app access token. - -### getAccessToken() -```php -public Facebook\Authentication\AccessToken|null getAccessToken(string $redirectUrl = null) -``` -Attempts to obtain an access token from an authorization code. This method will make a request to the Graph API and return a response. If there was an error in that process a `FacebookSDKException` will be thrown. A `FacebookSDKException` will also be thrown if the CSRF validation fails. - -If no authorization code could be found from the `code` param in the URL, this method will return `null`. - -#### Arguments -- `$redirectUrl` (_Optional_) The URL of the callback that the user is currently on. This should be the same as the one used when creating the login URL. If no URL is provided, it will be detected automatically. - -## Extensibility Points - -The `FacebookRedirectLoginHelper` has to orchestrate a number of components from the hosting environment to make the OAuth 2.0 authorization process as easy as possible to integrate. Out of the box it auto-detects all the things it needs, but sometimes you'll want to control these components. - -### Sessions (persistent data) - -In order to prevent [CSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)'s, a unique value is generated with each login link and stored in a session. - -Most modern web frameworks have custom session handlers that allow you to manage your sessions with something other than the default flat-file storage. You can integrate your framework's custom session handling by coding to the [`PersistentDataInterface`](PersistentDataInterface.md). - -### CSPRNG - -The CSRF value that the `getLoginUrl()`, `getReRequestUrl()`, and `getReAuthenticationUrl()` methods generate are all _cryptographically secure_ random strings. PHP's native support of CSPRNG's is spotty at best. The PHP SDK goes to great lengths to to detect a suitable CSPRNG but in rare cases, it might not find a suitable one. The [`PseudoRandomStringGeneratorInterface`](PseudoRandomStringGeneratorInterface.md) allows you to inject your own custom CSPRNG. - -### URL detection - -In order to not make you pass the callback URL to the `getAccessToken()` method, the SDK will do its best to detect the callback's URL for you. Most modern web frameworks have URL detection built-in. You can code your specific web framework's URL detection logic by coding to the [`UrlDetectionInterface`](UrlDetectionInterface.md). diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md deleted file mode 100644 index cc8b7b2..0000000 --- a/docs/reference/FacebookRequest.md +++ /dev/null @@ -1,180 +0,0 @@ -# FacebookRequest for the Facebook SDK for PHP - -Represents a request that will be sent to the Graph API. - -## Facebook\FacebookRequest - -You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. - -```php -use Facebook\FacebookRequest; - -$request = new FacebookRequest( - Facebook\FacebookApp $app, - string $accessToken, - string $method, - string $endpoint, - array $params, - string $eTag, - string $graphVersion -); -``` - -Alternatively, you can make use of the [`request()` factory provided by `Facebook\Facebook`](Facebook.md#request) to create new `FacebookRequest` instances. - -The `FacebookRequest` entity does not actually make any calls to the Graph API, but instead just represents a request that can be sent to the Graph API later. This is most useful for making batch requests using [`Facebook\Facebook::sendBatchRequest()`](Facebook.md#sendbatchrequest) or [`Facebook\FacebookClient::sendBatchRequest()`](FacebookClient.md#sendbatchrequest). - -Usage: - -```php -$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); -$request = new Facebook\FacebookRequest($fbApp, '{access-token}', 'GET', '/me'); - -// OR - -$fb = new Facebook\Facebook(/* . . . */); -$request = $fb->request('GET', '/me'); - -// Send the request to Graph -try { - $response = $fb->getClient()->sendRequest($request); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'User name: ' . $graphNode['name']; -``` - -## Instance Methods - -### setAccessToken() -```php -public setAccessToken(string|Facebook\AccessToken $accessToken) -``` -Sets the access token to be used for the request. - -### getAccessToken() -```php -public string getAccessToken() -``` -Returns the access token to be used for the request in the form of a string. - -### setApp() -```php -public setApp(Facebook\FacebookApp $app) -``` -Sets the [`Facebook\FacebookApp`](FacebookApp.md) entity used with this request. - -### getApp() -```php -public Facebook\FacebookApp getApp() -``` -Returns the [`Facebook\FacebookApp`](FacebookApp.md) entity used with this request. - -### getAppSecretProof() -```php -public string getAppSecretProof() -``` -Returns the [app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests/#appsecret_proof) to sign the request. - -### setMethod() -```php -public setMethod(string $method) -``` -Sets the HTTP verb to use for the request. - -### getMethod() -```php -public string setMethod() -``` -Returns the HTTP verb to use for the request. - -### setEndpoint() -```php -public setEndpoint(string $endpoint) -``` -Sets the Graph URL endpoint to be used with the request. The endpoint must be excluding the host name and Graph version number prefix. - -```php -$request->setEndpoint('/me'); -``` - -### getEndpoint() -```php -public string getEndpoint() -``` -Returns the Graph URL endpoint to be used with the request. - -### setHeaders() -```php -public setHeaders(array $headers) -``` -Sets additional request headers to be use with the request. The supplied headers will be merged with the existing headers. The headers should be sent as an associative array with the key being the header name and the value being the header value. - -```php -$request->setHeaders([ - 'X-foo-header' => 'Something', -]); -``` - -### getHeaders() -```php -public array getHeaders() -``` -Returns the request headers that will be sent with the request. The eTag headers `If-None-Match` are appended automatically. - -### setETag() -```php -public setETag(string $eTag) -``` -Sets the eTag that will be using for matching the `If-None-Match` header. - -### setParams() -```php -public setParams(array $params) -``` -For `GET` requests, the array of params will be converted to a query string and appended to the URL. - -```php -$request->setParams([ - 'foo' => 'bar', - 'limit' => 10, -]); -// /endpoint?foo=bar&limit=10 -``` - -For `POST` requests, the array of params will be sent in the `POST` body encoded as `application/x-www-form-urlencoded` for most request. If the request includes a file upload the params will be encoded as `multipart/form-data`. - -### getParams() -```php -public array getParams() -``` -Returns an array of params to be sent with the request. The `access_token` and `appsecret_proof` params will be automatically appended to the array of params. - -### getGraphVersion() -```php -public string getGraphVersion() -``` -Returns the Graph version prefix to be used with the request. - -### getUrl() -```php -public string getUrl() -``` -Returns the endpoint of the Graph URL for the request. This will include the Graph version prefix but will not include the host name. The host name is determined after the request is sent to [`Facebook\FacebookClient`](FacebookClient.md). - -```php -$fb = new Facebook\Facebook(/* . . . */); -$request = $fb->request('GET', '/me', ['fields' => 'id,name']); - -$url = $request->getUrl(); -// /v2.10/me?fields=id,name&access_token=token&appsecret_proof=proof -``` diff --git a/docs/reference/FacebookResponse.md b/docs/reference/FacebookResponse.md deleted file mode 100644 index 8a60a76..0000000 --- a/docs/reference/FacebookResponse.md +++ /dev/null @@ -1,161 +0,0 @@ -# FacebookResponse for the Facebook SDK for PHP - -Represents a response from the Graph API. - -## Facebook\FacebookResponse - -After sending a request to the Graph API, the response will be returned in the form of a `Facebook\FacebookResponse` entity. - -Usage: - -```php -$fb = new Facebook\Facebook(/* . . . */); - -// Send the request to Graph -try { - $response = $fb->get('/me'); -} catch(Facebook\Exceptions\FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); - exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); - exit; -} - -var_dump($response); -// class Facebook\FacebookResponse . . . -``` - -## Instance Methods - -### getRequest() -```php -public Facebook\FacebookRequest getRequest() -``` -Returns the original [`Facebook\FacebookRequest`](FacebookRequest.md) entity that was used to solicit this response. - -### getAccessToken() -```php -public string getAccessToken() -``` -Returns the access token that was used for the original request in the form of a string. - -### getApp() -```php -public Facebook\FacebookApp getApp() -``` -Returns the [`Facebook\FacebookApp`](FacebookApp.md) entity that was used with the original request. - -### getHttpStatusCode() -```php -public int getHttpStatusCode() -``` -Returns the HTTP response code for this response. - -### getHeaders() -```php -public array getHeaders() -``` -Returns the response headers that were returned. - -### getBody() -```php -public string getBody() -``` -Returns the raw, unparsed body of the response as a string. - -### getDecodedBody() -```php -public array getDecodedBody() -``` -Returns the parsed body of the response as an array. - -### getAppSecretProof() -```php -public string getAppSecretProof() -``` -Returns the original [app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests/#appsecret_proof) that was used with the original request. - -### getETag() -```php -public string getETag() -``` -Returns the `ETag` response header if it exists. If the header does not exist in the response headers, `null` will be returned instead. - -### getGraphVersion() -```php -public string getGraphVersion() -``` -Returns the Graph version that was used by returning the value from the `Facebook-API-Version` response header if it exists. If the header does not exist in the response headers, `null` will be returned instead. - -### isError() -```php -public boolean isError() -``` -If the Graph API returned an error response `isError()` will return `true`. If a successful response was returned, `isError()` will return `false`. - -### throwException() -```php -public throwException() -``` -Throws the [`Facebook\Exceptions\FacebookResponseException`](FacebookResponseException.md) that was generated by an error response from Graph. - -### getThrownException() -```php -public Facebook\Exceptions\FacebookResponseException getThrownException() -``` -Returns the [`Facebook\Exceptions\FacebookResponseException`](FacebookResponseException.md) that was generated by an error response from Graph. This is mainly useful for dealing with [responses to batch requests](FacebookBatchResponse.md). - -### getGraphNode() -```php -public Facebook\GraphNodes\GraphNode getGraphNode() -``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](GraphNode.md) collection. - -### getGraphAlbum() -```php -public Facebook\GraphNodes\GraphAlbum getGraphAlbum() -``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](GraphNode.md#graphalbum-instance-methods) collection. - -### getGraphPage() -```php -public Facebook\GraphNodes\GraphPage getGraphPage() -``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](GraphNode.md#graphpage-instance-methods) collection. - -### getGraphSessionInfo() -```php -public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() -``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](GraphNode.md) collection. - -### getGraphUser() -```php -public Facebook\GraphNodes\GraphUser getGraphUser() -``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](GraphNode.md#graphuser-instance-methods) collection. - -### getGraphEdge() -```php -public Facebook\GraphNodes\GraphEdge getGraphEdge( - string|null $subclassName, - boolean $auto_prefix) -``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphEdge`](GraphEdge.md) collection. - -`$subclassName` -The `Facebook\GraphNodes\GraphNode` subclass to cast list items to. If none is provided, default is `Facebook\GraphNodes\GraphNode`. - -`$auto_prefix` -Toggle to auto-prefix the subclass name. If none is provided, default is `true`. - -```php -$res = $fb->get('/{facebook-page}/events', '{access-token}'); -$events = $res->getGraphEdge("GraphEvent"); -foreach ($events as $event) { - // . . . -} -``` diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md deleted file mode 100644 index 6fe777c..0000000 --- a/docs/reference/FacebookResponseException.md +++ /dev/null @@ -1,57 +0,0 @@ -# FacebookResponseException for the Facebook SDK for PHP - -Represents an error response from the Graph API. - -## Facebook\Exceptions\FacebookResponseException - -Whenever a `FacebookResponseException` is thrown, you can access it's previous exception with the `getPrevious()` method to get more information on the specific type of error response that the Graph API returned. - -```php -try { - // Some request to the Graph API -} catch (Facebook\Exceptions\FacebookResponseException $e) { - echo 'Message: ' . $e->getMessage(); - $previousException = $e->getPrevious(); - // Do some further processing on $previousException - exit; -} -``` - -| Class name | Description | -| ------------- | ------------- | -| `Facebook\Exceptions\FacebookAuthenticationException` | Thrown when Graph returns an authentication error. | -| `Facebook\Exceptions\FacebookAuthorizationException` | Thrown when Graph returns a user permissions error. | -| `Facebook\Exceptions\FacebookClientException` | Thrown when Graph returns a duplicate post error. | -| `Facebook\Exceptions\FacebookOtherException` | Thrown when Graph returns an error that is unknown to the SDK. | -| `Facebook\Exceptions\FacebookServerException` | Thrown when Graph returns a server error. | -| `Facebook\Exceptions\FacebookThrottleException` | Thrown when Graph returns a throttle error. | - -These exceptions are derived from the [error responses from the Graph API](https://developers.facebook.com/docs/graph-api/using-graph-api#errors). - -## Instance Methods - -`FacebookResponseException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. - -### getHttpStatusCode -`getHttpStatusCode()` -Returns the HTTP status code returned with this exception. - -### getSubErrorCode -`getSubErrorCode()` -Returns the numeric sub-error code returned from the Graph API. - -### getErrorType -`getErrorType()` -Returns the type of error as a string. - -### getResponseData -`getResponseData()` -Returns the decoded response body used to create the exception as an array. - -### getRawResponse -`getRawResponse()` -Returns the raw response body used to create the exception as a string. - -### getResponse -`getResponse()` -Returns the `FacebookResponse` entity which represents the HTTP response. diff --git a/docs/reference/FacebookSDKException.md b/docs/reference/FacebookSDKException.md deleted file mode 100644 index 2166ec1..0000000 --- a/docs/reference/FacebookSDKException.md +++ /dev/null @@ -1,13 +0,0 @@ -# FacebookSDKException for the Facebook SDK for PHP - -Represents an exception thrown by the SDK. - -## Facebook\Exceptions\FacebookSDKException - -A `FacebookSDKException` is thrown when something goes wrong. For example if an invalid signed request is sent to the `Facebook\SignedRequest` entity, it will throw an `FacebookSDKException`. - -When an error response is returned from the Graph API, it will be thrown as a `FacebookSDKException` subtype called a [Facebook\Exceptions\FacebookResponseException](FacebookResponseException.md). - -## Instance Methods - -`FacebookSDKException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. diff --git a/docs/reference/FacebookVideo.md b/docs/reference/FacebookVideo.md deleted file mode 100644 index df7e424..0000000 --- a/docs/reference/FacebookVideo.md +++ /dev/null @@ -1,68 +0,0 @@ -# Video Uploading with the Facebook SDK for PHP - -Uploading video files to the Graph API is made a breeze with the SDK for PHP. - -## Facebook\FileUpload\FacebookVideo(string $pathToVideoFile, int $maxLength = -1, int $offset = -1) - -The `FacebookVideo` entity represents a local or remote video file to be uploaded with a request to Graph. - -There are two ways to instantiate a `FacebookVideo` entity. One way is to instantiate it directly: - -```php -use Facebook\FileUpload\FacebookVideo; - -$myVideoFileToUpload = new FacebookVideo('/path/to/video-file.mp4'); -``` - -Alternatively, you can use the `videoToUpload()` factory on the `Facebook\Facebook` super service to instantiate a new `FacebookVideo` entity. - -```php -$fb = new Facebook\Facebook(/* . . . */); - -$myVideoFileToUpload = $fb->videoToUpload('/path/to/video-file.mp4'), -``` - -Partial file uploads are possible using the `$maxLength` and `$offset` parameters which provide the same functionality as the `$maxlen` and `$offset` parameters on the [`stream_get_contents()` PHP function](http://php.net/stream_get_contents). - -## Usage - -In Graph v2.3, functionality was added to [upload video files in chunks](https://developers.facebook.com/docs/graph-api/video-uploads#resumable). The PHP SDK provides a handy API to easily upload video files in chunks via the [`uploadVideo()` method](Facebook.md#uploadvideo). - -```php -// Upload a video for a user (chunked) -$data = [ - 'title' => 'My awesome video', - 'description' => 'More info about my awesome video.', -]; - -try { - $response = $fb->uploadVideo('me', '/path/to/video.mp4', $data, '{user-access-token}'); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Error: ' . $e->getMessage(); - exit; -} - -echo 'Video ID: ' . $response['video_id']; -``` - -For versions of Graph before v2.3, videos had to be uploaded in one request. - -```php -// Upload a video for a user -$data = [ - 'title' => 'My awesome video', - 'description' => 'More info about my awesome video.', - 'source' => $fb->videoToUpload('/path/to/video.mp4'), -]; - -try { - $response = $fb->post('/me/videos', $data); -} catch(Facebook\Exceptions\FacebookSDKException $e) { - echo 'Error: ' . $e->getMessage(); - exit; -} - -$graphNode = $response->getGraphNode(); - -echo 'Video ID: ' . $graphNode['id']; -``` diff --git a/docs/reference/GraphEdge.md b/docs/reference/GraphEdge.md deleted file mode 100644 index 30508d3..0000000 --- a/docs/reference/GraphEdge.md +++ /dev/null @@ -1,114 +0,0 @@ -# GraphEdge for the Facebook SDK for PHP - -When a list of nodes is returned from a Graph request, it can be cast as a `GraphEdge` which provides convenient ways of interacting with the data which includes pagination. - -## Facebook\GraphNodes\GraphEdge - -You can grab a `GraphEdge` from a response from Graph. - -```php -$graphEdge = $request->getGraphEdge(); -``` - -Usage: - -```php -// Iterate over all the GraphNode's returned from the edge -foreach ($graphEdge as $graphNode) { - // . . . -} -``` - -## Pagination - -With the help of the `Facebook\Facebook` super service class, the `GraphEdge` collection can grab the next and previous sets of data. - -```php -$albumsEdge = $response->getGraphEdge(); - -// Get the next page of results -$nextPageOfAlbums = $fb->next($albumsEdge); -// Or the previous page of results -$previousPageOfAlbums = $fb->previous($previousOfAlbums); -``` - -When the next or previous page returns no results, `$fb->next()` will return `null`. - -## Deep Pagination - -Sometimes Graph will return a list of nodes within a node. Paginating on these sub lists can be non-trivial. Fortunately, the `GraphEdge` collection takes the guesswork out and allows you to paginate deeply within a `GraphEdge`. - -The following example paginates over the first 5 pages of a list of Facebook pages. For each page it paginates over all the likes for that page. - -```php -$pagesEdge = $response->getGraphEdge(); -// Only grab 5 pages -$maxPages = 5; -$pageCount = 0; - -do { - echo '

Page #' . $pageCount . ':

' . "\n\n"; - - foreach ($pagesEdge as $page) { - var_dump($page->asArray()); - - $likes = $page['likes']; - do { - echo '

Likes:

' . "\n\n"; - var_dump($likes->asArray()); - } while ($likes = $fb->next($likes)); - } - $pageCount++; -} while ($pageCount < $maxPages && $pagesEdge = $fb->next($pagesEdge)); -``` - -## Method Reference - -### getMetaData() -```php -public array getMetaData() -``` - -Sometimes Graph will return additional data associated with an edge. You can access this raw data as an array with `getMetaData()`. - -```php -$metaData = $graphEdge->getMetaData(); -``` - -### getNextCursor() -```php -public string|null getNextCursor() -``` - -Returns the `$.paging.cursors.after` value if it exists or `null` if it does not exist. Since cursors are sort of like bookmarks for paginating over an edge, it is sometimes handy to store the last cursor used so that you can revisit the exact position at a later time. - -```php -$nextCursor = $graphEdge->getNextCursor(); -// Returns: MMAyDDM5NjA0OTEyMDc0OTM= -``` - -### getPreviousCursor() -```php -public string|null getPreviousCursor() -``` - -Returns the `$.paging.cursors.before` value if it exists or `null` if it does not exist. - -```php -$previousCursor = $graphEdge->getPreviousCursor(); -// Returns: ODOxMTUzMjQzNTg5zzU5 -``` - -### getTotalCount() -```php -public int|null getTotalCount() -``` - -Some endpoints and edges of Graph support a summary of data. If the `summary=true` modifier was sent with a request on a supported endpoint or edge, Graph will return the total count of results in the meta data under `$.summary.total_count`. `getTotalCount()` will return that value or `null` if it does not exist. - -```php -$response = $fb->get('/{post-id}/likes?summary=true'); -$likesEdge = $response->getGraphEdge(); -$totalCount = $likesEdge->getTotalCount(); -// Returns: 10 -``` diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md deleted file mode 100644 index a609402..0000000 --- a/docs/reference/GraphNode.md +++ /dev/null @@ -1,591 +0,0 @@ -# GraphNode for the Facebook SDK for PHP - -A `Facebook\GraphNodes\GraphNode` is a collection that represents a node returned by the Graph API. - -## Facebook\GraphNodes\GraphNode - -This base class has several subclasses: - -[__GraphUser__](#graphuser-instance-methods) -[__GraphPage__](#graphpage-instance-methods) -[__GraphAlbum__](#graphalbum-instance-methods) -[__GraphLocation__](#graphlocation-instance-methods) -[__GraphPicture__](#graphpicture-instance-methods) -[__GraphAchievement__](#graphachievement-instance-methods) - -`GraphNode`s are obtained from a [`Facebook\FacebookResponse`](FacebookResponse.md) object which represents an HTTP response from the Graph API. - -Usage: - -```php -$fb = new Facebook\Facebook(\* *\); -// Returns a `Facebook\FacebookResponse` object -$response = $fb->get('/something'); - -// Get the base class GraphNode from the response -$graphNode = $response->getGraphNode(); - -// Get the response typed as a GraphUser -$user = $response->getGraphUser(); - -// Get the response typed as a GraphPage -$page = $response->getGraphPage(); - -// User example -echo $graphNode->getField('name'); // From GraphNode -echo $user->getName(); // From GraphUser - -// Location example -echo $graphNode->getField('country'); // From GraphNode -echo $location->getCountry(); // From GraphLocation -``` - -## SPL Libraries - -The `GraphNode` collection and its subclasses implement several [SPL](http://php.net/manual/en/book.spl.php) libraries and [predefined PHP interfaces and classes](http://php.net/manual/en/reserved.interfaces.php) which make it convenient to work with the object in PHP. The supported libraries are `ArrayAccess`, `ArrayIterator`, `Countable`, and `IteratorAggregate`. - -All of the following operations are possible on a `GraphNode`. - -```php -$graphNode = $response->getGraphNode(); - -// Array access -$id = $graphNode['id']; - -// Iteration -foreach ($graphNode as $key => $value) { - // . . . -} - -// Counting -$total = count($graphNode); -``` - -## GraphNode Instance Methods - -### asArray -`asArray()` -Returns the raw representation (associative arrays, nested) of the node's underlying data. - -### asJson -`asJson()` -Returns the data as a JSON string. - -### getField -`getField(string $name, string $default = 'foo')` -Gets the value from the field of a Graph node. If the value is a scalar (string, number, etc.) it will be returned. If it's an associative array, it will be returned as a GraphNode. - -The second argument lets you define a default value to return if the field doesn't exist. - -### getFieldNames -`getFieldNames()` -Returns an array with the names of all fields present on the graph node. - -### map -`map(Closure $callback)` -Provides a way to map over the data within the collection just like `array_map()`. - -## GraphUser Instance Methods - -The `GraphUser` collection represents a [User](https://developers.facebook.com/docs/graph-api/reference/user) Graph node. - -### Auto-cast properties - -The following properties on the `GraphUser` collection will get automatically cast as `GraphNode` subtypes: - -| Property | GraphNode subtype | -| ------------- | ------------- | -| `hometown` | [`Facebook\GraphNodes\GraphPage`](#graphpage-instance-methods) | -| `location` | [`Facebook\GraphNodes\GraphPage`](#graphpage-instance-methods) | -| `significant_other` | [`Facebook\GraphNodes\GraphUser`](#graphuser-instance-methods) | - -All getter methods return `null` if the property does not exist on the node. - -### getId() -```php -public string|null getId() -``` -Returns the `id` property for the user as a string if present. - -### getName() -```php -public string|null getName() -``` -Returns the `name` property for the user as a string if present. - -### getFirstName() -```php -public string|null getFirstName() -``` -Returns the `first_name` property for the user as a string if present. - -### getMiddleName() -```php -public string|null getMiddleName() -``` -Returns the `middle_name` property for the user as a string if present. - -### getLastName() -```php -public string|null getLastName() -``` -Returns the `last_name` property for the user as a string if present. - -### getLink() -```php -public string|null getLink() -``` -Returns the `link` property for the user as a string if present. - -### getBirthday() -```php -public \Facebook\GraphNodes\Birthday|null getBirthday() -``` -Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](Birthday.md) if present. - -### getLocation() -```php -public Facebook\GraphNodes\GraphPage|null getLocation() -``` -Returns the `location` property for the user as a `Facebook\GraphNodes\GraphPage` if present. - -### getHometown() -```php -public Facebook\GraphNodes\GraphPage|null getHometown() -``` -Returns the `hometown` property for the user as a `Facebook\GraphNodes\GraphPage` if present. - -### getSignificantOther() -```php -public Facebook\GraphNodes\GraphUser|null getSignificantOther() -``` -Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. - -## GraphPage Instance Methods - -The `GraphPage` collection represents a [Page](https://developers.facebook.com/docs/graph-api/reference/page) Graph node. - -### Auto-cast properties - -The following properties on the `GraphPage` collection will get automatically cast as `GraphNode` subtypes: - -| Property | GraphNode subtype | -| ------------- | ------------- | -| `best_page` | [`Facebook\GraphNodes\GraphPage`](#graphpage-instance-methods) | -| `global_brand_parent_page` | [`Facebook\GraphNodes\GraphPage`](graph#page-instance-methods) | -| `location` | [`Facebook\GraphNodes\GraphLocation`](#graphlocation-instance-methods) | - -All getter methods return `null` if the property does not exist on the node. - -### getId() -```php -public string|null getId() -``` -Returns the `id` property for the page as a string if present. - -### getName() -```php -public string|null getName() -``` -Returns the `name` property for the page as a string if present. - -### getCategory() -```php -public string|null getCategory() -``` -Returns the `category` property for the page as a string if present. - -### getBestPage() -```php -public Facebook\GraphNodes\GraphPage|null getBestPage() -``` -Returns the `best_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. - -### getGlobalBrandParentPage() -```php -public Facebook\GraphNodes\GraphPage|null getGlobalBrandParentPage() -``` -Returns the `global_brand_parent_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. - -### getLocation() -```php -public Facebook\GraphNodes\GraphLocation|null getLocation() -``` -Returns the `location` property for the page as a `Facebook\GraphNodes\GraphLocation` if present. - -### getAccessToken() -```php -public string|null getAccessToken() -``` -Returns the `access_token` property for the page if present. (Only available in the `/me/accounts` context.) - -### getPerms() -```php -public array|null getAccessToken() -``` -Returns the `perms` property for the page as an `array` if present. (Only available in the `/me/accounts` context.) - -## GraphAlbum Instance Methods - -The `GraphAlbum` collection represents an [Album](https://developers.facebook.com/docs/graph-api/reference/album) Graph node. - -### Auto-cast properties - -The following properties on the `GraphAlbum` collection will get automatically cast as `GraphNode` subtypes: - -| Property | GraphNode subtype | -| ------------- | ------------- | -| `from` | [`Facebook\GraphNodes\GraphUser`](#graphuser-instance-methods) | -| `place` | [`Facebook\GraphNodes\GraphPage`](#graphpage-instance-methods) | - -All getter methods return `null` if the property does not exist on the node. - -### getId() -```php -public string|null getId() -``` -Returns the `id` property for the album as a string if present. - -### getName() -```php -public string|null getName() -``` -Returns the `name` property for the album as a string if present. - -### getCanUpload() -```php -public boolean|null getCanUpload() -``` -Returns the `can_upload` property for the album as a boolean if present. - -### getCount() -```php -public int|null getCount() -``` -Returns the `count` property for the album as an integer if present. - -### getCoverPhoto() -```php -public string|null getCoverPhoto() -``` -Returns the `cover_photo` property for the album as a string if present. - -### getCreatedTime() -```php -public \DateTime|null getCreatedTime() -``` -Returns the `created_time` property for the album as a `\DateTime` if present. - -### getUpdatedTime() -```php -public \DateTime|null getUpdatedTime() -``` -Returns the `updated_time` property for the album as a `\DateTime` if present. - -### getDescription() -```php -public string|null getDescription() -``` -Returns the `description` property for the album as a string if present. - -### getFrom() -```php -public Facebook\GraphNodes\GraphUser|null getFrom() -``` -Returns the `from` property for the album as a `Facebook\GraphNodes\GraphUser` if present. - -### getPlace() -```php -public Facebook\GraphNodes\GraphPage|null getPlace() -``` -Returns the `place` property for the album as a `Facebook\GraphNodes\GraphPage` if present. - -### getLink() -```php -public string|null getLink() -``` -Returns the `link` property for the album as a string if present. - -### getLocation() -```php -public Facebook\GraphNodes\GraphNode|string|null getLocation() -``` -Returns the `location` property for the album as a `Facebook\GraphNodes\GraphNode` or string if present. - -### getPrivacy() -```php -public string|null getPrivacy() -``` -Returns the `privacy` property for the album as a string if present. - -### getType() -```php -public string|null getType() -``` -Returns the `type` property for the album as a string (`profile`, `mobile`, `wall`, `normal` or `album`) if present. - -## GraphLocation Instance Methods - -All getter methods return `null` if the property does not exist on the node. - -### getStreet() -```php -public string|null getStreet() -``` -Returns the `street` property for the location as a string if present. - -### getCity() -```php -public string|null getCity() -``` -Returns the `city` property for the location as a string if present. - -### getCountry() -```php -public string|null getCountry() -``` -Returns the `country` property for the location as a string if present. - -### getZip() -```php -public string|null getZip() -``` -Returns the `zip` property for the location as a string if present. - -### getLatitude() -```php -public float|null getLatitude() -``` -Returns the `latitude` property for the location as a float if present. - -### getLongitude() -```php -public float|null getLongitude() -``` -Returns the `longitude` property for the location as a float if present. - -## GraphPicture Instance Methods - -All getter methods return `null` if the property does not exist on the node. - -### getUrl() -```php -public string|null getUrl() -``` -Returns the `url` property for the picture as a string if present. - -## GraphAchievement Instance Methods - -All getter methods return `null` if the property does not exist on the node. - -### getId() -```php -public string|null getId() -``` -Returns the `id` property for the achievement as a string if present. - -## GraphEvent Instance Methods - -All getter methods return `null` if the property does not exist on the node. - -### getId() -```php -public string|null getId() -``` -Returns the `id` property (The event ID) for the event as a string if present. - -### getCover() -```php -public GraphCoverPhoto|null getCover() -``` -Returns the `cover` property (Cover picture) for the event as a GraphCoverPhoto if present. - -### getDescription() -```php -public string|null getDescription() -``` -Returns the `description` property (Long-form description) for the event as a string if present. - -### getEndTime() -```php -public DateTime|null getEndTime() -``` -Returns the `end_time` property (End time, if one has been set) for the event as a DateTime if present. - -### getIsDateOnly() -```php -public bool|null getIsDateOnly() -``` -Returns the `is_date_only` property (Whether the event only has a date specified, but no time) for the event as a bool if present. - -### getName() -```php -public string|null getName() -``` -Returns the `name` property (Event name) for the event as a string if present. - -### getOwner() -```php -public GraphNode|null getOwner() -``` -Returns the `owner` property (The profile that created the event) for the event as a GraphNode if present. - -### getParentGroup() -```php -public GraphGroup|null getParentGroup() -``` -Returns the `parent_group` property (The group the event belongs to) for the event as a GraphGroup if present. - -### getPlace() -```php -public GraphPage|null getPlace() -``` -Returns the `place` property (Event Place information) for the event as a GraphPage if present. - -### getPrivacy() -```php -public string|null getPrivacy() -``` -Returns the `privacy` property (Who can see the event) for the event as a string if present. - -### getStartTime() -```php -public DateTime|null getStartTime() -``` -Returns the `start_time` property (Start time) for the event as a DateTime if present. - -### getTicketUri() -```php -public string|null getTicketUri() -``` -Returns the `ticket_uri` property (The link users can visit to buy a ticket to this event) for the event as a string if present. - -### getTimezone() -```php -public string|null getTimezone() -``` -Returns the `timezone` property (Timezone) for the event as a string if present. - -### getUpdatedTime() -```php -public DateTime|null getUpdatedTime() -``` -Returns the `updated_time` property (Last update time) for the event as a DateTime if present. - -### getPicture() -```php -public GraphPicture|null getPicture() -``` -Returns the `picture` property (Event picture) for the event as a GraphPicture if present. - -### getAttendingCount() -```php -public int|null getAttendingCount() -``` -Returns the `attending_count` property (Number of people attending the event) for the event as a int if present. - -### getDeclinedCount() -```php -public int|null getDeclinedCount() -``` -Returns the `declined_count` property (Number of people who declined the event) for the event as a int if present. - -### getMaybeCount() -```php -public int|null getMaybeCount() -``` -Returns the `maybe_count` property (Number of people who maybe going to the event) for the event as a int if present. - -### getNoreplyCount() -```php -public int|null getNoreplyCount() -``` -Returns the `noreply_count` property (Number of people who did not reply to the event) for the event as a int if present. - -### getInvitedCount() -```php -public int|null getInvitedCount() -``` -Returns the `invited_count` property (Number of people invited to the event) for the event as a int if present. - -## GraphGroup Instance Methods - -All getter methods return `null` if the field does not exist on the node. - -### getId() -```php -public string|null getId() -``` -Returns the `id` field (The Group ID) for the group as a string if present. - -### getCover() -```php -public GraphCoverPhoto|null getCover() -``` -Returns the `cover` field (The cover photo of the Group) for the group as a GraphCoverPhoto if present. - -### getDescription() -```php -public string|null getDescription() -``` -Returns the `description` field (A brief description of the Group) for the group as a string if present. - -### getEmail() -```php -public string|null getEmail() -``` -Returns the `email` field (The email address to upload content to the Group. Only current members of the Group can use this) for the group as a string if present. - -### getIcon() -```php -public string|null getIcon() -``` -Returns the `icon` field (The URL for the Group's icon) for the group as a string if present. - -### getLink() -```php -public string|null getLink() -``` -Returns the `link` field (The Group's website) for the group as a string if present. - -### getName() -```php -public string|null getName() -``` -Returns the `name` field (The name of the Group) for the group as a string if present. - -### getMemberRequestCount() -```php -public int|null getMemberRequestCount() -``` -Returns the `member_request_count` field (Number of people asking to join the group.) for the group as a int if present. - -### getOwner() -```php -public GraphNode|null getOwner() -``` -Returns the `owner` field (The profile that created this Group) for the group as a GraphNode if present. - -### getParent() -```php -public GraphNode|null getParent() -``` -Returns the `parent` field (The parent Group of this Group, if it exists) for the group as a GraphNode if present. - -### getPrivacy() -```php -public string|null getPrivacy() -``` -Returns the `privacy` field (The privacy setting of the Group) for the group as a string if present. - -### getUpdatedTime() -```php -public DateTime|null getUpdatedTime() -``` -Returns the `updated_time` field (The last time the Group was updated (this includes changes in the Group's properties and changes in posts and comments if user can see them)) for the group as a DateTime if present. - -### getVenue() -```php -public GraphLocation|null getVenue() -``` -Returns the `venue` field (The location for the Group) for the group as a GraphLocation if present. diff --git a/docs/reference/PersistentDataInterface.md b/docs/reference/PersistentDataInterface.md deleted file mode 100644 index 9f22839..0000000 --- a/docs/reference/PersistentDataInterface.md +++ /dev/null @@ -1,70 +0,0 @@ -# The persistent data handler interface for the Facebook SDK for PHP - -The persistent data handler interface stores values in a persistent data store. By default the SDK for PHP uses native PHP sessions to store the persistent data. You can overwrite this behavior by coding to the `Facebook\PersistentData\PersistentDataInterface`. - -## Facebook\PersistentData\PersistentDataInterface - -If you're using a web framework that handles persistent data for you, you might want to code a custom persistent data handler to ensure that your persistent storage is being handled consistently. - -For example if you are using Laravel, a custom handler might look like this: - -```php -use Facebook\PersistentData\PersistentDataInterface; - -class MyLaravelPersistentDataHandler implements PersistentDataInterface -{ - /** - * @var string Prefix to use for session variables. - */ - protected $sessionPrefix = 'FBRLH_'; - - /** - * @inheritdoc - */ - public function get($key) - { - return \Session::get($this->sessionPrefix . $key); - } - - /** - * @inheritdoc - */ - public function set($key, $value) - { - \Session::put($this->sessionPrefix . $key, $value); - } -} -``` - -To enable your custom persistent data handler implementation in the SDK, you can set an instance of the handler to the `persistent_data_handler` config of the `Facebook\Facebook` super service. - -```php -$fb = new Facebook\Facebook([ - // . . . - 'persistent_data_handler' => new MyLaravelPersistentDataHandler(), - // . . . - ]); -``` - -Alternatively, if you're working with the `Facebook\Helpers\FacebookRedirectLoginHelper` directly, you can inject your custom handler via the constructor. - -```php -use Facebook\Helpers\FacebookRedirectLoginHelper; - -$myPersistentDataHandler = new MyLaravelPersistentDataHandler(); -$helper = new FacebookRedirectLoginHelper($fbApp, $myPersistentDataHandler); -``` - -## Method Reference - -### get() -```php -public mixed get(string $key) -``` -Returns a value from the persistent data store or `null` if the value does not exist. - -### set() -```php -public void set(string $key, mixed $value) -``` -Sets a value to the persistent data store. diff --git a/docs/reference/PseudoRandomStringGeneratorInterface.md b/docs/reference/PseudoRandomStringGeneratorInterface.md deleted file mode 100644 index a6409ed..0000000 --- a/docs/reference/PseudoRandomStringGeneratorInterface.md +++ /dev/null @@ -1,59 +0,0 @@ -# The cryptographically secure pseudo-random string generator interface for the Facebook SDK for PHP - -The cryptographically secure pseudo-random string generator interface allows you to overwrite the default CSPRSG logic by coding to the `Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface`. - -## Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface - -By default the SDK will attempt to generate a cryptographically secure random string using a number of methods. If a cryptographically secure method is not detected, a `Facebook\Exceptions\FacebookSDKException` will be thrown. - -If your hosting environment does not support any of the CSPRSG methods used by the SDK or if you have preferred CSPRSG, you can provide your own CSPRSG to the SDK using this interface. - -> **Caution:** Although it is popular to use `rand()`, `mt_rand()` and `uniqid()` to generate random strings in PHP, these methods are not cryptographically secure. Since the pseudo-random string generator is used to validate against Cross-Site Request Forgery (CSRF) attacks, the random strings _must_ be cryptographically secure. Only overwrite this functionality if your custom pseudo-random string generator is a cryptographically strong one. - -An example of implementing a custom CSPRSG: - -```php -use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; - -class MyCustomPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface -{ - /** - * @inheritdoc - */ - public function getPseudoRandomString($length) - { - $randomString = ''; - - // . . . Do CSPRSG logic here . . . - - return $randomString; - } -} -``` - -To enable your custom CSPRSG implementation in the SDK, you can set an instance of the generator to the `pseudo_random_string_generator` config of the `Facebook\Facebook` super service. - -```php -$fb = new Facebook\Facebook([ - // . . . - 'pseudo_random_string_generator' => new MyCustomPseudoRandomStringGenerator(), - // . . . - ]); -``` - -Alternatively, if you're working with the `Facebook\Helpers\FacebookRedirectLoginHelper` directly, you can inject your custom generator via the constructor. - -```php -use Facebook\Helpers\FacebookRedirectLoginHelper; - -$myPseudoRandomStringGenerator = new MyCustomPseudoRandomStringGenerator(); -$helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStringGenerator); -``` - -## Method Reference - -### getPseudoRandomString() -```php -public string getPseudoRandomString(int $length) -``` -Returns a cryptographically secure pseudo-random string that is `$length` characters long. diff --git a/docs/reference/SignedRequest.md b/docs/reference/SignedRequest.md deleted file mode 100644 index 70539f6..0000000 --- a/docs/reference/SignedRequest.md +++ /dev/null @@ -1,85 +0,0 @@ -# SignedRequest entity for the Facebook SDK for PHP - -The `Facebook\SignedRequest` entity represents a signed request. - -## Facebook\SignedRequest - -[Signed requests](https://developers.facebook.com/docs/games/gamesonfacebook/login#detectingloginstatus) contain payloads of data that can be validated against a hash signature to ensure it is from Facebook. The `Facebook\SignedRequest` entity can validate a signed request signature and decode the payload. - -To instantiate a new `Facebook\SignedRequest` entity, pass the [`Facebook\FacebookApp`](FacebookApp.md) entity and raw signed request to the constructor. - -```php -$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); -$signedRequest = new Facebook\SignedRequest($fbApp, 'raw.signed_request'); -``` - -Usually `Facebook\SignedRequest` entities are obtained using one of the [helpers](../reference.md). - -```php -$fb = new Facebook\Facebook([/* . . . */]); - -// Obtain a signed request entity from the cookie set by the JavaScript SDK -$helper = $fb->getJavaScriptHelper(); -$signedRequest = $helper->getSignedRequest(); - -// Obtain a signed request entity from a canvas app -$helper = $fb->getCanvasHelper(); -$signedRequest = $helper->getSignedRequest(); - -// Obtain a signed request entity from a page tab -$helper = $fb->getPageTabHelper(); -$signedRequest = $helper->getSignedRequest(); -``` - -## Instance Methods - -### getRawSignedRequest() -```php -public string|null getRawSignedRequest() -``` -Returns the original raw encoded signed request in the form of a string. - -### getPayload() -```php -public array|null getPayload() -``` -Returns the [signed request payload](https://developers.facebook.com/docs/reference/login/signed-request/) in the form of an array. - -### get() -```php -public string|null get(string $key, string|null $default) -``` -Returns a [field from the signed request payload](https://developers.facebook.com/docs/reference/login/signed-request) or `$default` if the value does not exist. - -### getUserId() -```php -public string|null getUserId() -``` -Returns the `user_id` field from the signed request payload if it exists or `null` if it does not exists. - -### hasOAuthData() -```php -public boolean hasOAuthData() -``` -Returns `true` if the payload data contains either an `oauth_token` or `code` field. Returns `false` if neither value exists. - -### make() -```php -public string make(array $payload) -``` -Generates a valid raw signed request as a string that contains the data from the `$payload` array. The signature is signed using the app secret from the `Facebook\FacebookApp` entity. This can be useful for testing purposes. - -```php -$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); -$signedRequest = new Facebook\SignedRequest($fbApp); - -$payload = [ - 'algorithm' => 'HMAC-SHA256', - 'issued_at' => time(), - 'foo' => 'bar', - ]; -$rawSignedRequest = $signedRequest->make($payload); - -var_dump($rawSignedRequest); -// string(129) "c9RNpwW4vGYTGc7_E-_XQu5aoEQrWrx_KDOdz3x9Ec0=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQxODE4MjI1NSwiZm9vIjoiYmFyIn0=" -``` diff --git a/docs/reference/UrlDetectionInterface.md b/docs/reference/UrlDetectionInterface.md deleted file mode 100644 index 7e14b24..0000000 --- a/docs/reference/UrlDetectionInterface.md +++ /dev/null @@ -1,51 +0,0 @@ -# The URL detection interface for the Facebook SDK for PHP - -The URL detection interface allows you to overwrite the default URL detection logic by coding to the `Facebook\Url\UrlDetectionInterface`. - -## Facebook\Url\UrlDetectionInterface - -If you're using a web framework that handles routes and URL generation for you, you might want to code a custom URL detection handler to ensure that your URL's are being generated consistently. - -For example if you are using Laravel, a custom handler might look like this: - -```php -use Facebook\Url\UrlDetectionInterface; - -class MyLaravelUrlDetectionHandler implements UrlDetectionInterface -{ - /** - * @inheritdoc - */ - public function getCurrentUrl() - { - return \Request::url(); - } -} -``` - -To enable your custom URL detection implementation in the SDK, you can set an instance of the handler to the `url_detection_handler` config of the `Facebook\Facebook` super service. - -```php -$fb = new Facebook\Facebook([ - // . . . - 'url_detection_handler' => new MyLaravelUrlDetectionHandler(), - // . . . - ]); -``` - -Alternatively, if you're working with the `Facebook\Helpers\FacebookRedirectLoginHelper` directly, you can inject your custom handler via the constructor. - -```php -use Facebook\Helpers\FacebookRedirectLoginHelper; - -$myUrlDetectionHandler = new MyLaravelUrlDetectionHandler(); -$helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); -``` - -## Method Reference - -### getCurrentUrl() -```php -public string getCurrentUrl() -``` -Returns the full and currently active URL. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8fe6c52..ceb55ad 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,7 @@ diff --git a/src/Facebook/Authentication/AccessToken.php b/src/Facebook/Authentication/AccessToken.php index 5d70073..13f2510 100644 --- a/src/Facebook/Authentication/AccessToken.php +++ b/src/Facebook/Authentication/AccessToken.php @@ -23,6 +23,8 @@ */ namespace Facebook\Authentication; +use DateTime; + /** * Class AccessToken * @@ -35,22 +37,19 @@ class AccessToken * * @var string */ - protected $value = ''; + protected string $value = ''; /** * Date when token expires. * - * @var \DateTime|null + * @var DateTime|null */ - protected $expiresAt; + protected ?DateTime $expiresAt = null; /** * Create a new access token entity. - * - * @param string $accessToken - * @param int $expiresAt */ - public function __construct($accessToken, $expiresAt = 0) + public function __construct(string $accessToken, int $expiresAt = 0) { $this->value = $accessToken; if ($expiresAt) { @@ -65,7 +64,7 @@ public function __construct($accessToken, $expiresAt = 0) * * @return string */ - public function getAppSecretProof($appSecret) + public function getAppSecretProof(string $appSecret): string { return hash_hmac('sha256', $this->value, $appSecret); } @@ -73,21 +72,19 @@ public function getAppSecretProof($appSecret) /** * Getter for expiresAt. * - * @return \DateTime|null + * @return DateTime|null */ - public function getExpiresAt() + public function getExpiresAt(): ?DateTime { return $this->expiresAt; } /** * Determines whether or not this is an app access token. - * - * @return bool */ - public function isAppAccessToken() + public function isAppAccessToken(): bool { - return strpos($this->value, '|') !== false; + return str_contains($this->value, '|'); } /** @@ -95,43 +92,33 @@ public function isAppAccessToken() * * @return bool */ - public function isLongLived() + public function isLongLived(): bool { if ($this->expiresAt) { return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); } - if ($this->isAppAccessToken()) { - return true; - } + return $this->isAppAccessToken(); - return false; } /** * Checks the expiration of the access token. - * - * @return boolean|null */ - public function isExpired() + public function isExpired(): bool { - if ($this->getExpiresAt() instanceof \DateTime) { + if ($this->getExpiresAt() instanceof DateTime) { return $this->getExpiresAt()->getTimestamp() < time(); } - if ($this->isAppAccessToken()) { - return false; - } + return false; - return null; } /** * Returns the access token as a string. - * - * @return string */ - public function getValue() + public function getValue(): string { return $this->value; } @@ -146,14 +133,9 @@ public function __toString() return $this->getValue(); } - /** - * Setter for expires_at. - * - * @param int $timeStamp - */ - protected function setExpiresAtFromTimeStamp($timeStamp) + protected function setExpiresAtFromTimeStamp(int $timeStamp): void { - $dt = new \DateTime(); + $dt = new DateTime(); $dt->setTimestamp($timeStamp); $this->expiresAt = $dt; } diff --git a/src/Facebook/Authentication/AccessTokenMetadata.php b/src/Facebook/Authentication/AccessTokenMetadata.php index 165433c..e8eb02d 100644 --- a/src/Facebook/Authentication/AccessTokenMetadata.php +++ b/src/Facebook/Authentication/AccessTokenMetadata.php @@ -23,6 +23,7 @@ */ namespace Facebook\Authentication; +use DateTime; use Facebook\Exceptions\FacebookSDKException; /** @@ -31,7 +32,7 @@ * Represents metadata from an access token. * * @package Facebook - * @see https://developers.facebook.com/docs/graph-api/reference/debug_token + * @link https://developers.facebook.com/docs/graph-api/reference/debug_token */ class AccessTokenMetadata { @@ -40,14 +41,14 @@ class AccessTokenMetadata * * @var array */ - protected $metadata = []; + protected array $metadata = []; /** * Properties that should be cast as DateTime objects. * * @var array */ - protected static $dateProperties = ['expires_at', 'issued_at']; + protected static array $dateProperties = ['expires_at', 'issued_at']; /** * @param array $metadata @@ -73,7 +74,7 @@ public function __construct(array $metadata) * * @return mixed */ - public function getField($field, $default = null) + public function getField(string $field, mixed $default = null): mixed { if (isset($this->metadata[$field])) { return $this->metadata[$field]; @@ -82,32 +83,14 @@ public function getField($field, $default = null) return $default; } - /** - * Returns a value from the metadata. - * - * @param string $field The property to retrieve. - * @param mixed $default The default to return if the property doesn't exist. - * - * @return mixed - * - * @deprecated 5.0.0 getProperty() has been renamed to getField() - * @todo v6: Remove this method - */ - public function getProperty($field, $default = null) - { - return $this->getField($field, $default); - } - /** * Returns a value from a child property in the metadata. * * @param string $parentField The parent property. * @param string $field The property to retrieve. * @param mixed $default The default to return if the property doesn't exist. - * - * @return mixed */ - public function getChildProperty($parentField, $field, $default = null) + public function getChildProperty(string $parentField, string $field, mixed $default = null): mixed { if (!isset($this->metadata[$parentField])) { return $default; @@ -125,10 +108,8 @@ public function getChildProperty($parentField, $field, $default = null) * * @param string $field The property to retrieve. * @param mixed $default The default to return if the property doesn't exist. - * - * @return mixed */ - public function getErrorProperty($field, $default = null) + public function getErrorProperty(string $field, mixed $default = null): mixed { return $this->getChildProperty('error', $field, $default); } @@ -138,30 +119,24 @@ public function getErrorProperty($field, $default = null) * * @param string $field The property to retrieve. * @param mixed $default The default to return if the property doesn't exist. - * - * @return mixed */ - public function getMetadataProperty($field, $default = null) + public function getMetadataProperty(string $field, mixed $default = null): mixed { return $this->getChildProperty('metadata', $field, $default); } /** * The ID of the application this access token is for. - * - * @return string|null */ - public function getAppId() + public function getAppId(): ?string { return $this->getField('app_id'); } /** * Name of the application this access token is for. - * - * @return string|null */ - public function getApplication() + public function getApplication(): ?string { return $this->getField('application'); } @@ -169,10 +144,8 @@ public function getApplication() /** * Any error that a request to the graph api * would return due to the access token. - * - * @return bool|null */ - public function isError() + public function isError(): bool { return $this->getField('error') !== null; } @@ -182,49 +155,41 @@ public function isError() * * @return int|null */ - public function getErrorCode() + public function getErrorCode(): ?int { return $this->getErrorProperty('code'); } /** * The error message for the error. - * - * @return string|null */ - public function getErrorMessage() + public function getErrorMessage(): ?string { return $this->getErrorProperty('message'); } /** * The error subcode for the error. - * - * @return int|null */ - public function getErrorSubcode() + public function getErrorSubcode(): ?int { return $this->getErrorProperty('subcode'); } /** * DateTime when this access token expires. - * - * @return \DateTime|null */ - public function getExpiresAt() + public function getExpiresAt(): ?DateTime { return $this->getField('expires_at'); } /** * Whether the access token is still valid or not. - * - * @return boolean|null */ - public function getIsValid() + public function getIsValid(): bool { - return $this->getField('is_valid'); + return $this->getField('is_valid') ?? false; } /** @@ -234,10 +199,8 @@ public function getIsValid() * for short-lived access tokens. * * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug - * - * @return \DateTime|null */ - public function getIssuedAt() + public function getIssuedAt(): ?DateTime { return $this->getField('issued_at'); } @@ -245,40 +208,32 @@ public function getIssuedAt() /** * General metadata associated with the access token. * Can contain data like 'sso', 'auth_type', 'auth_nonce'. - * - * @return array|null */ - public function getMetadata() + public function getMetadata(): ?array { return $this->getField('metadata'); } /** * The 'sso' child property from the 'metadata' parent property. - * - * @return string|null */ - public function getSso() + public function getSso(): ?string { return $this->getMetadataProperty('sso'); } /** * The 'auth_type' child property from the 'metadata' parent property. - * - * @return string|null */ - public function getAuthType() + public function getAuthType(): ?string { return $this->getMetadataProperty('auth_type'); } /** * The 'auth_nonce' child property from the 'metadata' parent property. - * - * @return string|null */ - public function getAuthNonce() + public function getAuthNonce(): ?string { return $this->getMetadataProperty('auth_nonce'); } @@ -286,10 +241,8 @@ public function getAuthNonce() /** * For impersonated access tokens, the ID of * the page this token contains. - * - * @return string|null */ - public function getProfileId() + public function getProfileId(): ?string { return $this->getField('profile_id'); } @@ -297,20 +250,16 @@ public function getProfileId() /** * List of permissions that the user has granted for * the app in this access token. - * - * @return array */ - public function getScopes() + public function getScopes(): array { return $this->getField('scopes'); } /** * The ID of the user this access token is for. - * - * @return string|null */ - public function getUserId() + public function getUserId(): ?string { return $this->getField('user_id'); } @@ -319,11 +268,9 @@ public function getUserId() * Ensures the app ID from the access token * metadata is what we expect. * - * @param string $appId - * * @throws FacebookSDKException */ - public function validateAppId($appId) + public function validateAppId(string $appId): void { if ($this->getAppId() !== $appId) { throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401); @@ -334,11 +281,9 @@ public function validateAppId($appId) * Ensures the user ID from the access token * metadata is what we expect. * - * @param string $userId - * * @throws FacebookSDKException */ - public function validateUserId($userId) + public function validateUserId(string $userId): void { if ($this->getUserId() !== $userId) { throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401); @@ -350,9 +295,9 @@ public function validateUserId($userId) * * @throws FacebookSDKException */ - public function validateExpiration() + public function validateExpiration(): void { - if (!$this->getExpiresAt() instanceof \DateTime) { + if (!$this->getExpiresAt() instanceof DateTime) { return; } @@ -363,14 +308,10 @@ public function validateExpiration() /** * Converts a unix timestamp into a DateTime entity. - * - * @param int $timestamp - * - * @return \DateTime */ - private function convertTimestampToDateTime($timestamp) + private function convertTimestampToDateTime(int $timestamp): DateTime { - $dt = new \DateTime(); + $dt = new DateTime(); $dt->setTimestamp($timestamp); return $dt; @@ -379,7 +320,7 @@ private function convertTimestampToDateTime($timestamp) /** * Casts the unix timestamps as DateTime entities. */ - private function castTimestampsToDateTime() + private function castTimestampsToDateTime(): void { foreach (static::$dateProperties as $key) { if (isset($this->metadata[$key]) && $this->metadata[$key] !== 0) { diff --git a/src/Facebook/Authentication/OAuth2Client.php b/src/Facebook/Authentication/OAuth2Client.php index 3ba05d8..a394ab4 100644 --- a/src/Facebook/Authentication/OAuth2Client.php +++ b/src/Facebook/Authentication/OAuth2Client.php @@ -48,35 +48,35 @@ class OAuth2Client * * @var FacebookApp */ - protected $app; + protected FacebookApp $app; /** * The Facebook client. * * @var FacebookClient */ - protected $client; + protected FacebookClient $client; /** * The version of the Graph API to use. * * @var string */ - protected $graphVersion; + protected string $graphVersion; /** * The last request sent to Graph. * * @var FacebookRequest|null */ - protected $lastRequest; + protected ?FacebookRequest $lastRequest; /** * @param FacebookApp $app * @param FacebookClient $client * @param string|null $graphVersion The version of the Graph API to use. */ - public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) + public function __construct(FacebookApp $app, FacebookClient $client, ?string $graphVersion = null) { $this->app = $app; $this->client = $client; @@ -89,7 +89,7 @@ public function __construct(FacebookApp $app, FacebookClient $client, $graphVers * * @return FacebookRequest|null */ - public function getLastRequest() + public function getLastRequest(): ?FacebookRequest { return $this->lastRequest; } @@ -100,8 +100,9 @@ public function getLastRequest() * @param AccessToken|string $accessToken The access token to debug. * * @return AccessTokenMetadata + * @throws FacebookSDKException */ - public function debugToken($accessToken) + public function debugToken(AccessToken|string $accessToken): AccessTokenMetadata { $accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; $params = ['input_token' => $accessToken]; @@ -125,22 +126,20 @@ public function debugToken($accessToken) * Generates an authorization URL to begin the process of authenticating a user. * * @param string $redirectUrl The callback URL to redirect to. - * @param string $state The CSPRNG-generated CSRF value. - * @param array $scope An array of permissions to request. - * @param array $params An array of parameters to generate URL. - * @param string $separator The separator to use in http_build_query(). - * - * @return string + * @param string $state The CSPRNG-generated CSRF value. + * @param array $scope An array of permissions to request. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). */ - public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], array $params = [], $separator = '&') + public function getAuthorizationUrl(string $redirectUrl, string $state, array $scope = [], array $params = [], string $separator = '&'): string { $params += [ - 'client_id' => $this->app->getId(), - 'state' => $state, + 'client_id' => $this->app->getId(), + 'state' => $state, 'response_type' => 'code', - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope) + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) ]; return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, '', $separator); @@ -149,17 +148,12 @@ public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], arr /** * Get a valid access token from a code. * - * @param string $code - * @param string $redirectUri - * - * @return AccessToken - * * @throws FacebookSDKException */ - public function getAccessTokenFromCode($code, $redirectUri = '') + public function getAccessTokenFromCode(string $code, string $redirectUri = ''): AccessToken { $params = [ - 'code' => $code, + 'code' => $code, 'redirect_uri' => $redirectUri, ]; @@ -169,17 +163,13 @@ public function getAccessTokenFromCode($code, $redirectUri = '') /** * Exchanges a short-lived access token with a long-lived access token. * - * @param AccessToken|string $accessToken - * - * @return AccessToken - * * @throws FacebookSDKException */ - public function getLongLivedAccessToken($accessToken) + public function getLongLivedAccessToken(AccessToken|string $accessToken): AccessToken { $accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; $params = [ - 'grant_type' => 'fb_exchange_token', + 'grant_type' => 'fb_exchange_token', 'fb_exchange_token' => $accessToken, ]; @@ -189,14 +179,9 @@ public function getLongLivedAccessToken($accessToken) /** * Get a valid code from an access token. * - * @param AccessToken|string $accessToken - * @param string $redirectUri - * - * @return AccessToken - * * @throws FacebookSDKException */ - public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') + public function getCodeFromLongLivedAccessToken(AccessToken|string $accessToken, string $redirectUri = ''): string { $params = [ 'redirect_uri' => $redirectUri, @@ -215,13 +200,9 @@ public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') /** * Send a request to the OAuth endpoint. * - * @param array $params - * - * @return AccessToken - * * @throws FacebookSDKException */ - protected function requestAnAccessToken(array $params) + protected function requestAnAccessToken(array $params): AccessToken { $response = $this->sendRequestWithClientParams('/oauth/access_token', $params); $data = $response->getDecodedBody(); @@ -250,15 +231,16 @@ protected function requestAnAccessToken(array $params) /** * Send a request to Graph with an app access token. * - * @param string $endpoint - * @param array $params + * @param string $endpoint + * @param array $params * @param AccessToken|string|null $accessToken * * @return FacebookResponse * * @throws FacebookResponseException + * @throws FacebookSDKException */ - protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null) + protected function sendRequestWithClientParams(string $endpoint, array $params, AccessToken|string|null $accessToken = null): FacebookResponse { $params += $this->getClientParams(); @@ -279,13 +261,11 @@ protected function sendRequestWithClientParams($endpoint, array $params, $access /** * Returns the client_* params for OAuth requests. - * - * @return array */ - protected function getClientParams() + protected function getClientParams(): array { return [ - 'client_id' => $this->app->getId(), + 'client_id' => $this->app->getId(), 'client_secret' => $this->app->getSecret(), ]; } diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index e51f1c8..8376d95 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -35,20 +35,20 @@ class FacebookResponseException extends FacebookSDKException /** * @var FacebookResponse The response that threw the exception. */ - protected $response; + protected FacebookResponse $response; /** - * @var array Decoded response. + * @var array|null Decoded response. */ - protected $responseData; + protected ?array $responseData; /** * Creates a FacebookResponseException. * - * @param FacebookResponse $response The response that threw the exception. - * @param FacebookSDKException $previousException The more detailed exception. + * @param FacebookResponse $response The response that threw the exception. + * @param FacebookSDKException|null $previousException The more detailed exception. */ - public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) + public function __construct(FacebookResponse $response, ?FacebookSDKException $previousException = null) { $this->response = $response; $this->responseData = $response->getDecodedBody(); @@ -66,7 +66,7 @@ public function __construct(FacebookResponse $response, FacebookSDKException $pr * * @return FacebookResponseException */ - public static function create(FacebookResponse $response) + public static function create(FacebookResponse $response): FacebookResponseException { $data = $response->getDecodedBody(); @@ -74,8 +74,8 @@ public static function create(FacebookResponse $response) $data = ['error' => $data]; } - $code = isset($data['error']['code']) ? $data['error']['code'] : null; - $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; + $code = $data['error']['code'] ?? null; + $message = $data['error']['message'] ?? 'Unknown error from Graph.'; if (isset($data['error']['error_subcode'])) { switch ($data['error']['error_subcode']) { @@ -97,10 +97,10 @@ public static function create(FacebookResponse $response) case 1363037: $previousException = new FacebookResumableUploadException($message, $code); - $startOffset = isset($data['error']['error_data']['start_offset']) ? (int) $data['error']['error_data']['start_offset'] : null; + $startOffset = isset($data['error']['error_data']['start_offset']) ? (int)$data['error']['error_data']['start_offset'] : null; $previousException->setStartOffset($startOffset); - $endOffset = isset($data['error']['error_data']['end_offset']) ? (int) $data['error']['error_data']['end_offset'] : null; + $endOffset = isset($data['error']['error_data']['end_offset']) ? (int)$data['error']['error_data']['end_offset'] : null; $previousException->setEndOffset($endOffset); return new static($response, $previousException); @@ -148,13 +148,8 @@ public static function create(FacebookResponse $response) /** * Checks isset and returns that or a default value. - * - * @param string $key - * @param mixed $default - * - * @return mixed */ - private function get($key, $default = null) + private function get(string $key, mixed $default = null) { if (isset($this->responseData['error'][$key])) { return $this->responseData['error'][$key]; @@ -165,50 +160,40 @@ private function get($key, $default = null) /** * Returns the HTTP status code - * - * @return int */ - public function getHttpStatusCode() + public function getHttpStatusCode(): ?int { return $this->response->getHttpStatusCode(); } /** * Returns the sub-error code - * - * @return int */ - public function getSubErrorCode() + public function getSubErrorCode(): int { return $this->get('error_subcode', -1); } /** * Returns the error type - * - * @return string */ - public function getErrorType() + public function getErrorType(): string { return $this->get('type', ''); } /** * Returns the raw response used to create the exception. - * - * @return string */ - public function getRawResponse() + public function getRawResponse(): ?string { return $this->response->getBody(); } /** * Returns the decoded response used to create the exception. - * - * @return array */ - public function getResponseData() + public function getResponseData(): ?array { return $this->responseData; } @@ -218,7 +203,7 @@ public function getResponseData() * * @return FacebookResponse */ - public function getResponse() + public function getResponse(): FacebookResponse { return $this->response; } diff --git a/src/Facebook/Exceptions/FacebookResumableUploadException.php b/src/Facebook/Exceptions/FacebookResumableUploadException.php index 6d41c63..d80fb24 100644 --- a/src/Facebook/Exceptions/FacebookResumableUploadException.php +++ b/src/Facebook/Exceptions/FacebookResumableUploadException.php @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\Exceptions; /** @@ -30,38 +31,24 @@ */ class FacebookResumableUploadException extends FacebookSDKException { - protected $startOffset; - - protected $endOffset; + protected ?int $startOffset = null, $endOffset = null; - /** - * @return int|null - */ - public function getStartOffset() + public function getStartOffset(): ?int { return $this->startOffset; } - /** - * @param int|null $startOffset - */ - public function setStartOffset($startOffset) + public function setStartOffset(?int $startOffset): void { $this->startOffset = $startOffset; } - /** - * @return int|null - */ - public function getEndOffset() + public function getEndOffset(): ?int { return $this->endOffset; } - /** - * @param int|null $endOffset - */ - public function setEndOffset($endOffset) + public function setEndOffset(?int $endOffset): void { $this->endOffset = $endOffset; } diff --git a/src/Facebook/Exceptions/FacebookSDKException.php b/src/Facebook/Exceptions/FacebookSDKException.php index d8bef1a..4e9e805 100644 --- a/src/Facebook/Exceptions/FacebookSDKException.php +++ b/src/Facebook/Exceptions/FacebookSDKException.php @@ -23,11 +23,13 @@ */ namespace Facebook\Exceptions; +use Exception; + /** * Class FacebookSDKException * * @package Facebook */ -class FacebookSDKException extends \Exception +class FacebookSDKException extends Exception { } diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 03a5234..723ad91 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -42,6 +42,7 @@ use Facebook\Helpers\FacebookPageTabHelper; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\Exceptions\FacebookSDKException; +use InvalidArgumentException; /** * Class Facebook @@ -53,12 +54,12 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.7.0'; + const VERSION = '8.0.0'; /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.10'; + const DEFAULT_GRAPH_VERSION = 'v20.0'; /** * @const string The name of the environment variable that contains the app ID. @@ -73,53 +74,50 @@ class Facebook /** * @var FacebookApp The FacebookApp entity. */ - protected $app; + protected FacebookApp $app; /** * @var FacebookClient The Facebook client service. */ - protected $client; + protected FacebookClient $client; /** - * @var OAuth2Client The OAuth 2.0 client service. + * @var OAuth2Client|null The OAuth 2.0 client service. */ - protected $oAuth2Client; + protected ?OAuth2Client $oAuth2Client = null; /** - * @var UrlDetectionInterface|null The URL detection handler. + * @var UrlDetectionInterface The URL detection handler. */ - protected $urlDetectionHandler; + protected UrlDetectionInterface $urlDetectionHandler; /** - * @var PseudoRandomStringGeneratorInterface|null The cryptographically secure pseudo-random string generator. + * @var PseudoRandomStringGeneratorInterface The cryptographically secure pseudo-random string generator. */ - protected $pseudoRandomStringGenerator; + protected PseudoRandomStringGeneratorInterface $pseudoRandomStringGenerator; /** * @var AccessToken|null The default access token to use with requests. */ - protected $defaultAccessToken; + protected AccessToken|null $defaultAccessToken; /** * @var string|null The default Graph version we want to use. */ - protected $defaultGraphVersion; + protected string|null $defaultGraphVersion; /** - * @var PersistentDataInterface|null The persistent data handler. + * @var PersistentDataInterface The persistent data handler. */ - protected $persistentDataHandler; + protected PersistentDataInterface $persistentDataHandler; /** * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. */ - protected $lastResponse; + protected FacebookResponse|FacebookBatchResponse|null $lastResponse; /** * Instantiates a new Facebook super-class object. - * - * @param array $config - * * @throws FacebookSDKException */ public function __construct(array $config = []) @@ -156,41 +154,38 @@ public function __construct(array $config = []) ); if (isset($config['default_access_token'])) { + $t = $config['default_access_token']; + if (!is_string($t) && !($t instanceof AccessToken)) { + throw new InvalidArgumentException('Access token must be of type string or ' . AccessToken::class . '.'); + } $this->setDefaultAccessToken($config['default_access_token']); } - // @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set $this->defaultGraphVersion = $config['default_graph_version']; } /** * Returns the FacebookApp entity. - * - * @return FacebookApp */ - public function getApp() + public function getApp(): FacebookApp { return $this->app; } /** * Returns the FacebookClient service. - * - * @return FacebookClient */ - public function getClient() + public function getClient(): FacebookClient { return $this->client; } /** * Returns the OAuth 2.0 client service. - * - * @return OAuth2Client */ - public function getOAuth2Client() + public function getOAuth2Client(): OAuth2Client { - if (!$this->oAuth2Client instanceof OAuth2Client) { + if (!$this->oAuth2Client) { $app = $this->getApp(); $client = $this->getClient(); $this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion); @@ -201,40 +196,32 @@ public function getOAuth2Client() /** * Returns the last response returned from Graph. - * - * @return FacebookResponse|FacebookBatchResponse|null */ - public function getLastResponse() + public function getLastResponse(): FacebookResponse|FacebookBatchResponse|null { return $this->lastResponse; } /** * Returns the URL detection handler. - * - * @return UrlDetectionInterface */ - public function getUrlDetectionHandler() + public function getUrlDetectionHandler(): ?UrlDetectionInterface { return $this->urlDetectionHandler; } /** * Changes the URL detection handler. - * - * @param UrlDetectionInterface $urlDetectionHandler */ - private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler) + private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler): void { $this->urlDetectionHandler = $urlDetectionHandler; } /** * Returns the default AccessToken entity. - * - * @return AccessToken|null */ - public function getDefaultAccessToken() + public function getDefaultAccessToken(): ?AccessToken { return $this->defaultAccessToken; } @@ -242,11 +229,9 @@ public function getDefaultAccessToken() /** * Sets the default access token to use with requests. * - * @param AccessToken|string $accessToken The access token to save. - * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ - public function setDefaultAccessToken($accessToken) + public function setDefaultAccessToken(AccessToken|string $accessToken): void { if (is_string($accessToken)) { $this->defaultAccessToken = new AccessToken($accessToken); @@ -260,25 +245,15 @@ public function setDefaultAccessToken($accessToken) return; } - throw new \InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken'); + throw new InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken'); } - /** - * Returns the default Graph version. - * - * @return string - */ - public function getDefaultGraphVersion() + public function getDefaultGraphVersion(): string { return $this->defaultGraphVersion; } - /** - * Returns the redirect login helper. - * - * @return FacebookRedirectLoginHelper - */ - public function getRedirectLoginHelper() + public function getRedirectLoginHelper(): FacebookRedirectLoginHelper { return new FacebookRedirectLoginHelper( $this->getOAuth2Client(), @@ -288,32 +263,17 @@ public function getRedirectLoginHelper() ); } - /** - * Returns the JavaScript helper. - * - * @return FacebookJavaScriptHelper - */ - public function getJavaScriptHelper() + public function getJavaScriptHelper(): FacebookJavaScriptHelper { return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion); } - /** - * Returns the canvas helper. - * - * @return FacebookCanvasHelper - */ - public function getCanvasHelper() + public function getCanvasHelper(): FacebookCanvasHelper { return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion); } - /** - * Returns the page tab helper. - * - * @return FacebookPageTabHelper - */ - public function getPageTabHelper() + public function getPageTabHelper(): FacebookPageTabHelper { return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion); } @@ -321,21 +281,21 @@ public function getPageTabHelper() /** * Sends a GET request to Graph and returns the result. * - * @param string $endpoint + * @param string $endpoint * @param AccessToken|string|null $accessToken - * @param string|null $eTag - * @param string|null $graphVersion + * @param string|null $eTag + * @param string|null $graphVersion * * @return FacebookResponse * * @throws FacebookSDKException */ - public function get($endpoint, $accessToken = null, $eTag = null, $graphVersion = null) + public function get(string $endpoint, AccessToken|string|null $accessToken = null, ?string $eTag = null, ?string $graphVersion = null): FacebookResponse { return $this->sendRequest( 'GET', $endpoint, - $params = [], + [], $accessToken, $eTag, $graphVersion @@ -355,7 +315,7 @@ public function get($endpoint, $accessToken = null, $eTag = null, $graphVersion * * @throws FacebookSDKException */ - public function post($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + public function post(string $endpoint, array $params = [], AccessToken|string|null $accessToken = null, ?string $eTag = null, ?string $graphVersion = null): FacebookResponse { return $this->sendRequest( 'POST', @@ -380,7 +340,7 @@ public function post($endpoint, array $params = [], $accessToken = null, $eTag = * * @throws FacebookSDKException */ - public function delete($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + public function delete(string $endpoint, array $params = [], AccessToken|string|null $accessToken = null, ?string $eTag = null, ?string $graphVersion = null): FacebookResponse { return $this->sendRequest( 'DELETE', @@ -401,7 +361,7 @@ public function delete($endpoint, array $params = [], $accessToken = null, $eTag * * @throws FacebookSDKException */ - public function next(GraphEdge $graphEdge) + public function next(GraphEdge $graphEdge): ?GraphEdge { return $this->getPaginationResults($graphEdge, 'next'); } @@ -415,7 +375,7 @@ public function next(GraphEdge $graphEdge) * * @throws FacebookSDKException */ - public function previous(GraphEdge $graphEdge) + public function previous(GraphEdge $graphEdge): ?GraphEdge { return $this->getPaginationResults($graphEdge, 'previous'); } @@ -430,7 +390,7 @@ public function previous(GraphEdge $graphEdge) * * @throws FacebookSDKException */ - public function getPaginationResults(GraphEdge $graphEdge, $direction) + public function getPaginationResults(GraphEdge $graphEdge, string $direction): ?GraphEdge { $paginationRequest = $graphEdge->getPaginationRequest($direction); if (!$paginationRequest) { @@ -441,7 +401,7 @@ public function getPaginationResults(GraphEdge $graphEdge, $direction) // Keep the same GraphNode subclass $subClassName = $graphEdge->getSubClassName(); - $graphEdge = $this->lastResponse->getGraphEdge($subClassName, false); + $graphEdge = $this->lastResponse->getGraphEdge($subClassName); return count($graphEdge) > 0 ? $graphEdge : null; } @@ -460,7 +420,7 @@ public function getPaginationResults(GraphEdge $graphEdge, $direction) * * @throws FacebookSDKException */ - public function sendRequest($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + public function sendRequest(string $method, string $endpoint, array $params = [], AccessToken|string|null $accessToken = null, ?string $eTag = null, ?string $graphVersion = null): FacebookResponse { $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; @@ -480,7 +440,7 @@ public function sendRequest($method, $endpoint, array $params = [], $accessToken * * @throws FacebookSDKException */ - public function sendBatchRequest(array $requests, $accessToken = null, $graphVersion = null) + public function sendBatchRequest(array $requests, AccessToken|string|null $accessToken = null, ?string $graphVersion = null): FacebookBatchResponse { $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; @@ -502,7 +462,7 @@ public function sendBatchRequest(array $requests, $accessToken = null, $graphVer * @param string|null $graphVersion The Graph API version to use. * @return FacebookBatchRequest */ - public function newBatchRequest($accessToken = null, $graphVersion = null) + public function newBatchRequest(AccessToken|string|null $accessToken = null, ?string $graphVersion = null): FacebookBatchRequest { $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; @@ -517,19 +477,9 @@ public function newBatchRequest($accessToken = null, $graphVersion = null) /** * Instantiates a new FacebookRequest entity. - * - * @param string $method - * @param string $endpoint - * @param array $params - * @param AccessToken|string|null $accessToken - * @param string|null $eTag - * @param string|null $graphVersion - * - * @return FacebookRequest - * * @throws FacebookSDKException */ - public function request($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + public function request(string $method, string $endpoint, array $params = [], AccessToken|string|null $accessToken = null, ?string $eTag = null, ?string $graphVersion = null): FacebookRequest { $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; @@ -547,28 +497,18 @@ public function request($method, $endpoint, array $params = [], $accessToken = n /** * Factory to create FacebookFile's. - * - * @param string $pathToFile - * - * @return FacebookFile - * * @throws FacebookSDKException */ - public function fileToUpload($pathToFile) + public function fileToUpload(string $pathToFile): FacebookFile { return new FacebookFile($pathToFile); } /** - * Factory to create FacebookVideo's. - * - * @param string $pathToFile - * - * @return FacebookVideo - * + * Factory to create FacebookVideo * @throws FacebookSDKException */ - public function videoToUpload($pathToFile) + public function videoToUpload(string $pathToFile): FacebookVideo { return new FacebookVideo($pathToFile); } @@ -576,18 +516,16 @@ public function videoToUpload($pathToFile) /** * Upload a video in chunks. * - * @param int $target The id of the target node before the /videos edge. + * @param string $target The id of the target node before the /videos edge. * @param string $pathToFile The full path to the file. * @param array $metadata The metadata associated with the video file. * @param string|null $accessToken The access token. * @param int $maxTransferTries The max times to retry a failed upload chunk. * @param string|null $graphVersion The Graph API version to use. * - * @return array - * * @throws FacebookSDKException */ - public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = null, $maxTransferTries = 5, $graphVersion = null) + public function uploadVideo(string $target, string $pathToFile, array $metadata = [], ?string $accessToken = null, int $maxTransferTries = 5, ?string $graphVersion = null): array { $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; @@ -619,7 +557,7 @@ public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = * * @throws FacebookSDKException */ - private function maxTriesTransfer(FacebookResumableUploader $uploader, $endpoint, FacebookTransferChunk $chunk, $retryCountdown) + private function maxTriesTransfer(FacebookResumableUploader $uploader, string $endpoint, FacebookTransferChunk $chunk, int $retryCountdown): FacebookTransferChunk { $newChunk = $uploader->transfer($endpoint, $chunk, $retryCountdown < 1); diff --git a/src/Facebook/FacebookApp.php b/src/Facebook/FacebookApp.php index f3f3e50..6faa080 100644 --- a/src/Facebook/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -31,89 +31,76 @@ class FacebookApp implements \Serializable /** * @var string The app ID. */ - protected $id; + protected string $id; /** * @var string The app secret. */ - protected $secret; + protected string $secret; /** - * @param string $id + * @param string|int $id * @param string $secret * * @throws FacebookSDKException */ - public function __construct($id, $secret) + public function __construct(string|int $id, string $secret) { - if (!is_string($id) - // Keeping this for BC. Integers greater than PHP_INT_MAX will make is_int() return false - && !is_int($id)) { - throw new FacebookSDKException('The "app_id" must be formatted as a string since many app ID\'s are greater than PHP_INT_MAX on some systems.'); + if (!is_string($id) && PHP_INT_SIZE === 4) { + throw new FacebookSDKException('The "app_id" must be formatted as a string when PHP is running in 32 bit mode.'); } - // We cast as a string in case a valid int was set on a 64-bit system and this is unserialised on a 32-bit system $this->id = (string) $id; $this->secret = $secret; } /** * Returns the app ID. - * - * @return string */ - public function getId() + public function getId(): string { return $this->id; } /** * Returns the app secret. - * - * @return string */ - public function getSecret() + public function getSecret(): string { return $this->secret; } /** * Returns an app access token. - * - * @return AccessToken */ - public function getAccessToken() + public function getAccessToken(): AccessToken { return new AccessToken($this->id . '|' . $this->secret); } /** * Serializes the FacebookApp entity as a string. - * - * @return string */ - public function serialize() + public function serialize(): string { return implode('|', [$this->id, $this->secret]); } - public function __serialize() + public function __serialize(): array { return ['id' => $this->id, 'secret' => $this->secret]; } /** * Unserializes a string as a FacebookApp entity. - * - * @param string $serialized */ - public function unserialize($serialized) + public function unserialize(string $serialized): void { list($id, $secret) = explode('|', $serialized); $this->__construct($id, $secret); } - public function __unserialize($data) + public function __unserialize($data): void { $this->__construct($data['id'], $data['secret']); } diff --git a/src/Facebook/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php index a2c5a50..2e7480a 100644 --- a/src/Facebook/FacebookBatchRequest.php +++ b/src/Facebook/FacebookBatchRequest.php @@ -21,9 +21,11 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook; use ArrayIterator; +use InvalidArgumentException; use IteratorAggregate; use ArrayAccess; use Facebook\Authentication\AccessToken; @@ -39,22 +41,18 @@ class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, /** * @var array An array of FacebookRequest entities to send. */ - protected $requests = []; - - /** - * @var array An array of files to upload. - */ - protected $attachedFiles; + protected array $requests = []; /** * Creates a new Request entity. * - * @param FacebookApp|null $app - * @param array $requests + * @param FacebookApp|null $app + * @param FacebookRequest[] $requests * @param AccessToken|string|null $accessToken - * @param string|null $graphVersion + * @param string|null $graphVersion + * @throws FacebookSDKException */ - public function __construct(FacebookApp $app = null, array $requests = [], $accessToken = null, $graphVersion = null) + public function __construct(?FacebookApp $app = null, array $requests = [], AccessToken|string|null $accessToken = null, ?string $graphVersion = null) { parent::__construct($app, $accessToken, 'POST', '', [], null, $graphVersion); @@ -64,15 +62,15 @@ public function __construct(FacebookApp $app = null, array $requests = [], $acce /** * Adds a new request to the array. * - * @param FacebookRequest|array $request - * @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'. + * @param FacebookRequest|FacebookRequest[] $request + * @param array|string|null $options Array of batch request options e.g. 'name', 'omit_response_on_success'. * If a string is given, it is the value of the 'name' option. * * @return FacebookBatchRequest * - * @throws \InvalidArgumentException + * @throws FacebookSDKException */ - public function add($request, $options = null) + public function add(array|FacebookRequest $request, int|array|string|null $options = null): self { if (is_array($request)) { foreach ($request as $key => $req) { @@ -83,7 +81,7 @@ public function add($request, $options = null) } if (!$request instanceof FacebookRequest) { - throw new \InvalidArgumentException('Argument for add() must be of type array or FacebookRequest.'); + throw new InvalidArgumentException('Argument for add() must be of type array or FacebookRequest.'); } if (null === $options) { @@ -97,14 +95,14 @@ public function add($request, $options = null) // File uploads $attachedFiles = $this->extractFileAttachments($request); - $name = isset($options['name']) ? $options['name'] : null; + $name = $options['name'] ?? null; unset($options['name']); $requestToAdd = [ - 'name' => $name, - 'request' => $request, - 'options' => $options, + 'name' => $name, + 'request' => $request, + 'options' => $options, 'attached_files' => $attachedFiles, ]; @@ -116,11 +114,9 @@ public function add($request, $options = null) /** * Ensures that the FacebookApp and access token fall back when missing. * - * @param FacebookRequest $request - * * @throws FacebookSDKException */ - public function addFallbackDefaults(FacebookRequest $request) + public function addFallbackDefaults(FacebookRequest $request): void { if (!$request->getApp()) { $app = $this->getApp(); @@ -141,14 +137,8 @@ public function addFallbackDefaults(FacebookRequest $request) /** * Extracts the files from a request. - * - * @param FacebookRequest $request - * - * @return string|null - * - * @throws FacebookSDKException */ - public function extractFileAttachments(FacebookRequest $request) + public function extractFileAttachments(FacebookRequest $request): ?string { if (!$request->containsFileUploads()) { return null; @@ -171,22 +161,23 @@ public function extractFileAttachments(FacebookRequest $request) /** * Return the FacebookRequest entities. * - * @return array + * @return FacebookRequest[] */ - public function getRequests() + public function getRequests(): array { return $this->requests; } /** * Prepares the requests to be sent as a batch request. + * @throws FacebookSDKException */ - public function prepareRequestsForBatch() + public function prepareRequestsForBatch(): void { $this->validateBatchRequestCount(); $params = [ - 'batch' => $this->convertRequestsToJson(), + 'batch' => $this->convertRequestsToJson(), 'include_headers' => true, ]; $this->setParams($params); @@ -194,10 +185,9 @@ public function prepareRequestsForBatch() /** * Converts the requests into a JSON(P) string. - * - * @return string + * @throws FacebookSDKException */ - public function convertRequestsToJson() + public function convertRequestsToJson(): string { $requests = []; foreach ($this->requests as $request) { @@ -220,7 +210,7 @@ public function convertRequestsToJson() * * @throws FacebookSDKException */ - public function validateBatchRequestCount() + public function validateBatchRequestCount(): void { $batchCount = count($this->requests); if ($batchCount === 0) { @@ -234,14 +224,13 @@ public function validateBatchRequestCount() /** * Converts a Request entity into an array that is batch-friendly. * - * @param FacebookRequest $request The request entity to convert. - * @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'. + * @param FacebookRequest $request The request entity to convert. + * @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'. * If a string is given, it is the value of the 'name' option. - * @param string|null $attachedFiles Names of files associated with the request. - * - * @return array + * @param string|null $attachedFiles Names of files associated with the request. + * @throws FacebookSDKException */ - public function requestEntityToBatchArray(FacebookRequest $request, $options = null, $attachedFiles = null) + public function requestEntityToBatchArray(FacebookRequest $request, array|string|null $options = null, ?string $attachedFiles = null): array { if (null === $options) { @@ -257,8 +246,8 @@ public function requestEntityToBatchArray(FacebookRequest $request, $options = n } $batch = [ - 'headers' => $compiledHeaders, - 'method' => $request->getMethod(), + 'headers' => $compiledHeaders, + 'method' => $request->getMethod(), 'relative_url' => $request->getUrl(), ]; @@ -283,17 +272,16 @@ public function requestEntityToBatchArray(FacebookRequest $request, $options = n * * @return ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): ArrayIterator { return new ArrayIterator($this->requests); } /** * @inheritdoc + * @throws FacebookSDKException */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->add($value, $offset); } @@ -301,8 +289,7 @@ public function offsetSet($offset, $value) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->requests[$offset]); } @@ -310,8 +297,7 @@ public function offsetExists($offset) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->requests[$offset]); } @@ -319,9 +305,8 @@ public function offsetUnset($offset) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { - return isset($this->requests[$offset]) ? $this->requests[$offset] : null; + return $this->requests[$offset] ?? null; } } diff --git a/src/Facebook/FacebookBatchResponse.php b/src/Facebook/FacebookBatchResponse.php index d0e65a3..38b45ca 100644 --- a/src/Facebook/FacebookBatchResponse.php +++ b/src/Facebook/FacebookBatchResponse.php @@ -37,12 +37,12 @@ class FacebookBatchResponse extends FacebookResponse implements IteratorAggregat /** * @var FacebookBatchRequest The original entity that made the batch request. */ - protected $batchRequest; + protected FacebookBatchRequest $batchRequest; /** * @var array An array of FacebookResponse entities. */ - protected $responses = []; + protected array $responses = []; /** * Creates a new Response entity. @@ -66,10 +66,8 @@ public function __construct(FacebookBatchRequest $batchRequest, FacebookResponse /** * Returns an array of FacebookResponse entities. - * - * @return array */ - public function getResponses() + public function getResponses(): array { return $this->responses; } @@ -77,10 +75,8 @@ public function getResponses() /** * The main batch response will be an array of requests so * we need to iterate over all the responses. - * - * @param array $responses */ - public function setResponses(array $responses) + public function setResponses(array $responses): void { $this->responses = []; @@ -91,19 +87,15 @@ public function setResponses(array $responses) /** * Add a response to the list. - * - * @param int $key - * @param array|null $response */ - public function addResponse($key, $response) + public function addResponse(int $key, ?array $response): void { $originalRequestName = isset($this->batchRequest[$key]['name']) ? $this->batchRequest[$key]['name'] : $key; $originalRequest = isset($this->batchRequest[$key]['request']) ? $this->batchRequest[$key]['request'] : null; - $httpResponseBody = isset($response['body']) ? $response['body'] : null; - $httpResponseCode = isset($response['code']) ? $response['code'] : null; - // @TODO With PHP 5.5 support, this becomes array_column($response['headers'], 'value', 'name') - $httpResponseHeaders = isset($response['headers']) ? $this->normalizeBatchHeaders($response['headers']) : []; + $httpResponseBody = $response['body'] ?? null; + $httpResponseCode = $response['code'] ?? null; + $httpResponseHeaders = isset($response['headers']) ? array_column($response['headers'], 'value', 'name') : []; $this->responses[$originalRequestName] = new FacebookResponse( $originalRequest, @@ -116,8 +108,7 @@ public function addResponse($key, $response) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): ArrayIterator { return new ArrayIterator($this->responses); } @@ -125,8 +116,7 @@ public function getIterator() /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->addResponse($offset, $value); } @@ -134,8 +124,7 @@ public function offsetSet($offset, $value) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->responses[$offset]); } @@ -143,8 +132,7 @@ public function offsetExists($offset) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->responses[$offset]); } @@ -152,28 +140,8 @@ public function offsetUnset($offset) /** * @inheritdoc */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { - return isset($this->responses[$offset]) ? $this->responses[$offset] : null; - } - - /** - * Converts the batch header array into a standard format. - * @TODO replace with array_column() when PHP 5.5 is supported. - * - * @param array $batchHeaders - * - * @return array - */ - private function normalizeBatchHeaders(array $batchHeaders) - { - $headers = []; - - foreach ($batchHeaders as $header) { - $headers[$header['name']] = $header['value']; - } - - return $headers; + return $this->responses[$offset] ?? null; } } diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index f362f28..dba878a 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -74,25 +74,22 @@ class FacebookClient /** * @var bool Toggle to use Graph beta url. */ - protected $enableBetaMode = false; + protected bool $enableBetaMode = false; /** * @var FacebookHttpClientInterface HTTP client handler. */ - protected $httpClientHandler; + protected FacebookHttpClientInterface $httpClientHandler; /** * @var int The number of calls that have been made to Graph. */ - public static $requestCount = 0; + public static int $requestCount = 0; /** * Instantiates a new FacebookClient object. - * - * @param FacebookHttpClientInterface|null $httpClientHandler - * @param boolean $enableBeta */ - public function __construct(FacebookHttpClientInterface $httpClientHandler = null, $enableBeta = false) + public function __construct(?FacebookHttpClientInterface $httpClientHandler = null, bool $enableBeta = false) { $this->httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler(); $this->enableBetaMode = $enableBeta; @@ -100,30 +97,24 @@ public function __construct(FacebookHttpClientInterface $httpClientHandler = nul /** * Sets the HTTP client handler. - * - * @param FacebookHttpClientInterface $httpClientHandler */ - public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler) + public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler): void { $this->httpClientHandler = $httpClientHandler; } /** * Returns the HTTP client handler. - * - * @return FacebookHttpClientInterface */ - public function getHttpClientHandler() + public function getHttpClientHandler(): FacebookHttpClientInterface { return $this->httpClientHandler; } /** * Detects which HTTP client handler to use. - * - * @return FacebookHttpClientInterface */ - public function detectHttpClientHandler() + public function detectHttpClientHandler(): FacebookHttpClientInterface { if (class_exists('GuzzleHttp\Client')) { return new FacebookGuzzleHttpClient(); @@ -136,7 +127,7 @@ public function detectHttpClientHandler() * * @param boolean $betaMode */ - public function enableBetaMode($betaMode = true) + public function enableBetaMode(bool $betaMode = true): void { $this->enableBetaMode = $betaMode; } @@ -145,10 +136,8 @@ public function enableBetaMode($betaMode = true) * Returns the base Graph URL. * * @param boolean $postToVideoUrl Post to the video API if videos are being uploaded. - * - * @return string */ - public function getBaseGraphUrl($postToVideoUrl = false) + public function getBaseGraphUrl(bool $postToVideoUrl = false): string { if ($postToVideoUrl) { return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL; @@ -160,11 +149,9 @@ public function getBaseGraphUrl($postToVideoUrl = false) /** * Prepares the request for sending to the client handler. * - * @param FacebookRequest $request - * - * @return array + * @throws FacebookSDKException */ - public function prepareRequestMessage(FacebookRequest $request) + public function prepareRequestMessage(FacebookRequest $request): array { $postToVideoUrl = $request->containsVideoUploads(); $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl(); @@ -193,15 +180,11 @@ public function prepareRequestMessage(FacebookRequest $request) /** * Makes the request to Graph and returns the result. * - * @param FacebookRequest $request - * - * @return FacebookResponse - * * @throws FacebookSDKException */ - public function sendRequest(FacebookRequest $request) + public function sendRequest(FacebookRequest $request): FacebookResponse { - if (get_class($request) === 'Facebook\FacebookRequest') { + if (get_class($request) === FacebookRequest::class) { $request->validateAccessToken(); } @@ -238,13 +221,9 @@ public function sendRequest(FacebookRequest $request) /** * Makes a batched request to Graph and returns the result. * - * @param FacebookBatchRequest $request - * - * @return FacebookBatchResponse - * * @throws FacebookSDKException */ - public function sendBatchRequest(FacebookBatchRequest $request) + public function sendBatchRequest(FacebookBatchRequest $request): FacebookBatchResponse { $request->prepareRequestsForBatch(); $facebookResponse = $this->sendRequest($request); diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index de801a6..33a9033 100644 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -39,62 +39,55 @@ class FacebookRequest { /** - * @var FacebookApp The Facebook app entity. + * @var FacebookApp|null The Facebook app entity. */ - protected $app; + protected FacebookApp|null $app; /** * @var string|null The access token to use for this request. */ - protected $accessToken; + protected string|null $accessToken; /** - * @var string The HTTP method for this request. + * @var string|null The HTTP method for this request. */ - protected $method; + protected ?string $method; /** - * @var string The Graph endpoint for this request. + * @var string|null The Graph endpoint for this request. */ - protected $endpoint; + protected ?string $endpoint; /** * @var array The headers to send with this request. */ - protected $headers = []; + protected array $headers = []; /** * @var array The parameters to send with this request. */ - protected $params = []; + protected array $params = []; /** - * @var array The files to send with this request. + * @var FacebookFile[] The files to send with this request. */ - protected $files = []; + protected array $files = []; /** - * @var string ETag to send with this request. + * @var string|null ETag to send with this request. */ - protected $eTag; + protected ?string $eTag; /** * @var string Graph version to use for this request. */ - protected $graphVersion; + protected string $graphVersion; /** * Creates a new Request entity. - * - * @param FacebookApp|null $app - * @param AccessToken|string|null $accessToken - * @param string|null $method - * @param string|null $endpoint - * @param array|null $params - * @param string|null $eTag - * @param string|null $graphVersion + * @throws FacebookSDKException */ - public function __construct(FacebookApp $app = null, $accessToken = null, $method = null, $endpoint = null, array $params = [], $eTag = null, $graphVersion = null) + public function __construct(?FacebookApp $app = null, AccessToken|string|null $accessToken = null, ?string $method = null, ?string $endpoint = null, ?array $params = [], ?string $eTag = null, ?string $graphVersion = null) { $this->setApp($app); $this->setAccessToken($accessToken); @@ -107,12 +100,8 @@ public function __construct(FacebookApp $app = null, $accessToken = null, $metho /** * Set the access token for this request. - * - * @param AccessToken|string|null - * - * @return FacebookRequest */ - public function setAccessToken($accessToken) + public function setAccessToken(AccessToken|string|null $accessToken): self { $this->accessToken = $accessToken; if ($accessToken instanceof AccessToken) { @@ -131,7 +120,7 @@ public function setAccessToken($accessToken) * * @throws FacebookSDKException */ - public function setAccessTokenFromParams($accessToken) + public function setAccessTokenFromParams(string $accessToken): self { $existingAccessToken = $this->getAccessToken(); if (!$existingAccessToken) { @@ -148,7 +137,7 @@ public function setAccessTokenFromParams($accessToken) * * @return string|null */ - public function getAccessToken() + public function getAccessToken(): ?string { return $this->accessToken; } @@ -158,7 +147,7 @@ public function getAccessToken() * * @return AccessToken|null */ - public function getAccessTokenEntity() + public function getAccessTokenEntity(): ?AccessToken { return $this->accessToken ? new AccessToken($this->accessToken) : null; } @@ -168,27 +157,23 @@ public function getAccessTokenEntity() * * @param FacebookApp|null $app */ - public function setApp(FacebookApp $app = null) + public function setApp(?FacebookApp $app = null): void { $this->app = $app; } /** * Return the FacebookApp entity used for this request. - * - * @return FacebookApp */ - public function getApp() + public function getApp(): ?FacebookApp { return $this->app; } /** * Generate an app secret proof to sign this request. - * - * @return string|null */ - public function getAppSecretProof() + public function getAppSecretProof(): ?string { if (!$accessTokenEntity = $this->getAccessTokenEntity()) { return null; @@ -202,7 +187,7 @@ public function getAppSecretProof() * * @throws FacebookSDKException */ - public function validateAccessToken() + public function validateAccessToken(): void { $accessToken = $this->getAccessToken(); if (!$accessToken) { @@ -212,23 +197,17 @@ public function validateAccessToken() /** * Set the HTTP method for this request. - * - * @param string */ - public function setMethod($method) + public function setMethod(?string $method): void { - if (!is_string($method)) { - return; - } - $this->method = strtoupper($method); + + $this->method = $method ? strtoupper($method) : null; } /** * Return the HTTP method for this request. - * - * @return string */ - public function getMethod() + public function getMethod(): ?string { return $this->method; } @@ -238,7 +217,7 @@ public function getMethod() * * @throws FacebookSDKException */ - public function validateMethod() + public function validateMethod(): void { if (!$this->method) { throw new FacebookSDKException('HTTP method not specified.'); @@ -252,14 +231,14 @@ public function validateMethod() /** * Set the endpoint for this request. * - * @param string - * - * @return FacebookRequest - * * @throws FacebookSDKException */ - public function setEndpoint($endpoint) + public function setEndpoint(?string $endpoint): self { + if (!$endpoint) { + $this->endpoint = null; + return $this; + } // Harvest the access token from the endpoint to keep things in sync $params = FacebookUrlManipulator::getParamsAsArray($endpoint); if (isset($params['access_token'])) { @@ -275,10 +254,8 @@ public function setEndpoint($endpoint) /** * Return the endpoint for this request. - * - * @return string */ - public function getEndpoint() + public function getEndpoint(): ?string { // For batch requests, this will be empty return $this->endpoint; @@ -286,10 +263,8 @@ public function getEndpoint() /** * Generate and return the headers for this request. - * - * @return array */ - public function getHeaders() + public function getHeaders(): array { $headers = static::getDefaultHeaders(); @@ -302,20 +277,16 @@ public function getHeaders() /** * Set the headers for this request. - * - * @param array $headers */ - public function setHeaders(array $headers) + public function setHeaders(array $headers): void { $this->headers = array_merge($this->headers, $headers); } /** * Sets the eTag value. - * - * @param string $eTag */ - public function setETag($eTag) + public function setETag(?string $eTag): void { $this->eTag = $eTag; } @@ -323,13 +294,9 @@ public function setETag($eTag) /** * Set the params for this request. * - * @param array $params - * - * @return FacebookRequest - * * @throws FacebookSDKException */ - public function setParams(array $params = []) + public function setParams(array $params = []): self { if (isset($params['access_token'])) { $this->setAccessTokenFromParams($params['access_token']); @@ -348,12 +315,8 @@ public function setParams(array $params = []) /** * Set the params for this request without filtering them first. - * - * @param array $params - * - * @return FacebookRequest */ - public function dangerouslySetParams(array $params = []) + public function dangerouslySetParams(array $params = []): self { $this->params = array_merge($this->params, $params); @@ -362,12 +325,8 @@ public function dangerouslySetParams(array $params = []) /** * Iterate over the params and pull out the file uploads. - * - * @param array $params - * - * @return array */ - public function sanitizeFileParams(array $params) + public function sanitizeFileParams(array $params): array { foreach ($params as $key => $value) { if ($value instanceof FacebookFile) { @@ -381,11 +340,8 @@ public function sanitizeFileParams(array $params) /** * Add a file to be uploaded. - * - * @param string $key - * @param FacebookFile $file */ - public function addFile($key, FacebookFile $file) + public function addFile(string $key, FacebookFile $file): void { $this->files[$key] = $file; } @@ -393,37 +349,32 @@ public function addFile($key, FacebookFile $file) /** * Removes all the files from the upload queue. */ - public function resetFiles() + public function resetFiles(): void { $this->files = []; } /** * Get the list of files to be uploaded. - * - * @return array + * @return FacebookFile[] */ - public function getFiles() + public function getFiles(): array { return $this->files; } /** * Let's us know if there is a file upload with this request. - * - * @return boolean */ - public function containsFileUploads() + public function containsFileUploads(): bool { return !empty($this->files); } /** * Let's us know if there is a video upload with this request. - * - * @return boolean */ - public function containsVideoUploads() + public function containsVideoUploads(): bool { foreach ($this->files as $file) { if ($file instanceof FacebookVideo) { @@ -436,10 +387,8 @@ public function containsVideoUploads() /** * Returns the body of the request as multipart/form-data. - * - * @return RequestBodyMultipart */ - public function getMultipartBody() + public function getMultipartBody(): RequestBodyMultipart { $params = $this->getPostParams(); @@ -448,10 +397,8 @@ public function getMultipartBody() /** * Returns the body of the request as URL-encoded. - * - * @return RequestBodyUrlEncoded */ - public function getUrlEncodedBody() + public function getUrlEncodedBody(): RequestBodyUrlEncoded { $params = $this->getPostParams(); @@ -460,10 +407,8 @@ public function getUrlEncodedBody() /** * Generate and return the params for this request. - * - * @return array */ - public function getParams() + public function getParams(): array { $params = $this->params; @@ -478,10 +423,8 @@ public function getParams() /** * Only return params on POST requests. - * - * @return array */ - public function getPostParams() + public function getPostParams(): array { if ($this->getMethod() === 'POST') { return $this->getParams(); @@ -492,20 +435,17 @@ public function getPostParams() /** * The graph version used for this request. - * - * @return string */ - public function getGraphVersion() + public function getGraphVersion(): string { return $this->graphVersion; } /** * Generate and return the URL for this request. - * - * @return string + * @throws FacebookSDKException */ - public function getUrl() + public function getUrl(): string { $this->validateMethod(); @@ -524,10 +464,8 @@ public function getUrl() /** * Return the default headers that every request should use. - * - * @return array */ - public static function getDefaultHeaders() + public static function getDefaultHeaders(): array { return [ 'User-Agent' => 'fb-php-' . Facebook::VERSION, diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index d283fbe..23e9048 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -21,8 +21,11 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook; +use Facebook\GraphNodes\GraphEdge; +use Facebook\GraphNodes\GraphNode; use Facebook\GraphNodes\GraphNodeFactory; use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; @@ -35,44 +38,39 @@ class FacebookResponse { /** - * @var int The HTTP status code response from Graph. + * @var int|null The HTTP status code response from Graph. */ - protected $httpStatusCode; + protected ?int $httpStatusCode; /** * @var array The headers returned from Graph. */ - protected $headers; + protected array $headers; /** - * @var string The raw body of the response from Graph. + * @var string|null The raw body of the response from Graph. */ - protected $body; + protected ?string $body; /** - * @var array The decoded body of the Graph response. + * @var array|null The decoded body of the Graph response. */ - protected $decodedBody = []; + protected ?array $decodedBody = null; /** * @var FacebookRequest The original request that returned this response. */ - protected $request; + protected FacebookRequest $request; /** - * @var FacebookSDKException The exception thrown by this request. + * @var FacebookResponseException|null The exception thrown by this request. */ - protected $thrownException; + protected ?FacebookResponseException $thrownException; /** * Creates a new Response entity. - * - * @param FacebookRequest $request - * @param string|null $body - * @param int|null $httpStatusCode - * @param array|null $headers */ - public function __construct(FacebookRequest $request, $body = null, $httpStatusCode = null, array $headers = []) + public function __construct(FacebookRequest $request, ?string $body = null, ?int $httpStatusCode = null, array $headers = []) { $this->request = $request; $this->body = $body; @@ -87,107 +85,87 @@ public function __construct(FacebookRequest $request, $body = null, $httpStatusC * * @return FacebookRequest */ - public function getRequest() + public function getRequest(): FacebookRequest { return $this->request; } /** * Return the FacebookApp entity used for this response. - * - * @return FacebookApp */ - public function getApp() + public function getApp(): ?FacebookApp { return $this->request->getApp(); } /** * Return the access token that was used for this response. - * - * @return string|null */ - public function getAccessToken() + public function getAccessToken(): ?string { return $this->request->getAccessToken(); } /** * Return the HTTP status code for this response. - * - * @return int */ - public function getHttpStatusCode() + public function getHttpStatusCode(): ?int { return $this->httpStatusCode; } /** * Return the HTTP headers for this response. - * - * @return array */ - public function getHeaders() + public function getHeaders(): array { return $this->headers; } /** * Return the raw body response. - * - * @return string */ - public function getBody() + public function getBody(): ?string { return $this->body; } /** * Return the decoded body response. - * - * @return array */ - public function getDecodedBody() + public function getDecodedBody(): ?array { return $this->decodedBody; } /** * Get the app secret proof that was used for this response. - * - * @return string|null */ - public function getAppSecretProof() + public function getAppSecretProof(): ?string { return $this->request->getAppSecretProof(); } /** * Get the ETag associated with the response. - * - * @return string|null */ - public function getETag() + public function getETag(): ?string { - return isset($this->headers['ETag']) ? $this->headers['ETag'] : null; + return $this->headers['ETag'] ?? null; } /** * Get the version of Graph that returned this response. - * - * @return string|null */ - public function getGraphVersion() + public function getGraphVersion(): ?string { - return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null; + return $this->headers['Facebook-API-Version'] ?? null; } /** * Returns true if Graph returned an error message. - * - * @return boolean */ - public function isError() + public function isError(): bool { return isset($this->decodedBody['error']); } @@ -195,7 +173,7 @@ public function isError() /** * Throws the exception. * - * @throws FacebookSDKException + * @throws FacebookResponseException */ public function throwException() { @@ -205,7 +183,7 @@ public function throwException() /** * Instantiates an exception to be thrown later. */ - public function makeException() + public function makeException(): void { $this->thrownException = FacebookResponseException::create($this); } @@ -215,7 +193,7 @@ public function makeException() * * @return FacebookResponseException|null */ - public function getThrownException() + public function getThrownException(): ?FacebookResponseException { return $this->thrownException; } @@ -231,27 +209,23 @@ public function getThrownException() * a short-lived access token for a long-lived access token * - And sometimes nothing :/ but that'd be a bug. */ - public function decodeBody() + public function decodeBody(): void { if ($this->body === null) { return; } - $this->decodedBody = json_decode($this->body, true); - if ($this->decodedBody === null) { + $decoded = json_decode($this->body, true); + + if ($decoded === null) { $this->decodedBody = []; parse_str($this->body, $this->decodedBody); - } elseif (is_bool($this->decodedBody)) { - // Backwards compatibility for Graph < 2.1. - // Mimics 2.1 responses. - // @TODO Remove this after Graph 2.0 is no longer supported - $this->decodedBody = ['success' => $this->decodedBody]; - } elseif (is_numeric($this->decodedBody)) { + } elseif (is_numeric($decoded)) { $this->decodedBody = ['id' => $this->decodedBody]; - } - - if (!is_array($this->decodedBody)) { + } elseif (!is_array($decoded)) { $this->decodedBody = []; + } else { + $this->decodedBody = $decoded; } if ($this->isError()) { @@ -259,155 +233,31 @@ public function decodeBody() } } - /** - * Instantiate a new GraphObject from response. - * - * @param string|null $subclassName The GraphNode subclass to cast to. - * - * @return \Facebook\GraphNodes\GraphObject - * - * @throws FacebookSDKException - * - * @deprecated 5.0.0 getGraphObject() has been renamed to getGraphNode() - * @todo v6: Remove this method - */ - public function getGraphObject($subclassName = null) - { - return $this->getGraphNode($subclassName); - } - /** * Instantiate a new GraphNode from response. * * @param string|null $subclassName The GraphNode subclass to cast to. * - * @return \Facebook\GraphNodes\GraphNode - * * @throws FacebookSDKException */ - public function getGraphNode($subclassName = null) + public function getGraphNode(?string $subclassName = null): GraphNode { $factory = new GraphNodeFactory($this); return $factory->makeGraphNode($subclassName); } - /** - * Convenience method for creating a GraphAlbum collection. - * - * @return \Facebook\GraphNodes\GraphAlbum - * - * @throws FacebookSDKException - */ - public function getGraphAlbum() - { - $factory = new GraphNodeFactory($this); - - return $factory->makeGraphAlbum(); - } - - /** - * Convenience method for creating a GraphPage collection. - * - * @return \Facebook\GraphNodes\GraphPage - * - * @throws FacebookSDKException - */ - public function getGraphPage() - { - $factory = new GraphNodeFactory($this); - - return $factory->makeGraphPage(); - } - - /** - * Convenience method for creating a GraphSessionInfo collection. - * - * @return \Facebook\GraphNodes\GraphSessionInfo - * - * @throws FacebookSDKException - */ - public function getGraphSessionInfo() - { - $factory = new GraphNodeFactory($this); - - return $factory->makeGraphSessionInfo(); - } - - /** - * Convenience method for creating a GraphUser collection. - * - * @return \Facebook\GraphNodes\GraphUser - * - * @throws FacebookSDKException - */ - public function getGraphUser() - { - $factory = new GraphNodeFactory($this); - - return $factory->makeGraphUser(); - } - - /** - * Convenience method for creating a GraphEvent collection. - * - * @return \Facebook\GraphNodes\GraphEvent - * - * @throws FacebookSDKException - */ - public function getGraphEvent() - { - $factory = new GraphNodeFactory($this); - - return $factory->makeGraphEvent(); - } - - /** - * Convenience method for creating a GraphGroup collection. - * - * @return \Facebook\GraphNodes\GraphGroup - * - * @throws FacebookSDKException - */ - public function getGraphGroup() - { - $factory = new GraphNodeFactory($this); - - return $factory->makeGraphGroup(); - } - - /** - * Instantiate a new GraphList from response. - * - * @param string|null $subclassName The GraphNode subclass to cast list items to. - * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. - * - * @return \Facebook\GraphNodes\GraphList - * - * @throws FacebookSDKException - * - * @deprecated 5.0.0 getGraphList() has been renamed to getGraphEdge() - * @todo v6: Remove this method - */ - public function getGraphList($subclassName = null, $auto_prefix = true) - { - return $this->getGraphEdge($subclassName, $auto_prefix); - } - /** * Instantiate a new GraphEdge from response. * * @param string|null $subclassName The GraphNode subclass to cast list items to. - * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. - * - * @return \Facebook\GraphNodes\GraphEdge * * @throws FacebookSDKException */ - public function getGraphEdge($subclassName = null, $auto_prefix = true) + public function getGraphEdge(?string $subclassName = null): GraphEdge { $factory = new GraphNodeFactory($this); - return $factory->makeGraphEdge($subclassName, $auto_prefix); + return $factory->makeGraphEdge($subclassName); } } diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php index 3c1536d..51e5342 100644 --- a/src/Facebook/FileUpload/FacebookFile.php +++ b/src/Facebook/FileUpload/FacebookFile.php @@ -35,17 +35,17 @@ class FacebookFile /** * @var string The path to the file on the system. */ - protected $path; + protected string $path; /** * @var int The maximum bytes to read. Defaults to -1 (read all the remaining buffer). */ - private $maxLength; + private int $maxLength; /** * @var int Seek to the specified offset before reading. If this number is negative, no seeking will occur and reading will start from the current position. */ - private $offset; + private int $offset; /** * @var resource The stream pointing to the file. @@ -55,13 +55,9 @@ class FacebookFile /** * Creates a new FacebookFile entity. * - * @param string $filePath - * @param int $maxLength - * @param int $offset - * * @throws FacebookSDKException */ - public function __construct($filePath, $maxLength = -1, $offset = -1) + public function __construct(string $filePath, int $maxLength = -1, int $offset = -1) { $this->path = $filePath; $this->maxLength = $maxLength; @@ -82,7 +78,7 @@ public function __destruct() * * @throws FacebookSDKException */ - public function open() + public function open(): void { if (!$this->isRemoteFile($this->path) && !is_readable($this->path)) { throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to read resource: ' . $this->path . '.'); @@ -98,7 +94,7 @@ public function open() /** * Stops the file stream. */ - public function close() + public function close(): void { if (is_resource($this->stream)) { fclose($this->stream); @@ -108,61 +104,48 @@ public function close() /** * Return the contents of the file. * - * @return string */ - public function getContents() + public function getContents(): false|string { return stream_get_contents($this->stream, $this->maxLength, $this->offset); } /** * Return the name of the file. - * - * @return string */ - public function getFileName() + public function getFileName(): string { return basename($this->path); } /** * Return the path of the file. - * - * @return string */ - public function getFilePath() + public function getFilePath(): string { return $this->path; } /** * Return the size of the file. - * - * @return int */ - public function getSize() + public function getSize(): int { return filesize($this->path); } /** * Return the mimetype of the file. - * - * @return string */ - public function getMimetype() + public function getMimetype(): string { return Mimetypes::getInstance()->fromFilename($this->path) ?: 'text/plain'; } /** * Returns true if the path to the file is remote. - * - * @param string $pathToFile - * - * @return boolean */ - protected function isRemoteFile($pathToFile) + protected function isRemoteFile(string $pathToFile): bool { return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1; } diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 46a2727..de2131a 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\FileUpload; use Facebook\Authentication\AccessToken; @@ -38,33 +39,19 @@ */ class FacebookResumableUploader { - /** - * @var FacebookApp - */ - protected $app; - - /** - * @var string - */ - protected $accessToken; - - /** - * @var FacebookClient The Facebook client service. - */ - protected $client; - /** - * @var string Graph version to use for this request. - */ - protected $graphVersion; + protected FacebookApp $app; + protected AccessToken|string|null $accessToken; + protected FacebookClient $client; + protected string $graphVersion; /** - * @param FacebookApp $app - * @param FacebookClient $client + * @param FacebookApp $app + * @param FacebookClient $client * @param AccessToken|string|null $accessToken - * @param string $graphVersion + * @param string $graphVersion */ - public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $graphVersion) + public function __construct(FacebookApp $app, FacebookClient $client, AccessToken|string|null $accessToken, string $graphVersion) { $this->app = $app; $this->client = $client; @@ -82,11 +69,11 @@ public function __construct(FacebookApp $app, FacebookClient $client, $accessTok * * @throws FacebookSDKException */ - public function start($endpoint, FacebookFile $file) + public function start(string $endpoint, FacebookFile $file): FacebookTransferChunk { $params = [ 'upload_phase' => 'start', - 'file_size' => $file->getSize(), + 'file_size' => $file->getSize(), ]; $response = $this->sendUploadRequest($endpoint, $params); @@ -103,14 +90,15 @@ public function start($endpoint, FacebookFile $file) * @return FacebookTransferChunk * * @throws FacebookResponseException + * @throws FacebookSDKException */ - public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow = false) + public function transfer(string $endpoint, FacebookTransferChunk $chunk, bool $allowToThrow = false): FacebookTransferChunk { $params = [ - 'upload_phase' => 'transfer', + 'upload_phase' => 'transfer', 'upload_session_id' => $chunk->getUploadSessionId(), - 'start_offset' => $chunk->getStartOffset(), - 'video_file_chunk' => $chunk->getPartialFile(), + 'start_offset' => $chunk->getStartOffset(), + 'video_file_chunk' => $chunk->getPartialFile(), ]; try { @@ -145,14 +133,13 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow * @param string $uploadSessionId * @param array $metadata The metadata associated with the file. * - * @return boolean - * + * @return bool * @throws FacebookSDKException */ - public function finish($endpoint, $uploadSessionId, $metadata = []) + public function finish(string $endpoint, string $uploadSessionId, array $metadata = []): bool { $params = array_merge($metadata, [ - 'upload_phase' => 'finish', + 'upload_phase' => 'finish', 'upload_session_id' => $uploadSessionId, ]); $response = $this->sendUploadRequest($endpoint, $params); @@ -166,9 +153,9 @@ public function finish($endpoint, $uploadSessionId, $metadata = []) * @param string $endpoint The endpoint to POST to. * @param array $params The params to send with the request. * - * @return array + * @throws FacebookSDKException */ - private function sendUploadRequest($endpoint, $params = []) + private function sendUploadRequest(string $endpoint, array $params = []): ?array { $request = new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion); diff --git a/src/Facebook/FileUpload/FacebookTransferChunk.php b/src/Facebook/FileUpload/FacebookTransferChunk.php index 99ea775..a4973b4 100644 --- a/src/Facebook/FileUpload/FacebookTransferChunk.php +++ b/src/Facebook/FileUpload/FacebookTransferChunk.php @@ -23,6 +23,8 @@ */ namespace Facebook\FileUpload; +use Facebook\Exceptions\FacebookSDKException; + /** * Class FacebookTransferChunk * @@ -33,36 +35,29 @@ class FacebookTransferChunk /** * @var FacebookFile The file to chunk during upload. */ - private $file; + private FacebookFile $file; /** * @var int The ID of the upload session. */ - private $uploadSessionId; + private int $uploadSessionId; /** * @var int Start byte position of the next file chunk. */ - private $startOffset; + private int $startOffset; /** * @var int End byte position of the next file chunk. */ - private $endOffset; + private int $endOffset; /** * @var int The ID of the video. */ - private $videoId; + private int $videoId; - /** - * @param FacebookFile $file - * @param int $uploadSessionId - * @param int $videoId - * @param int $startOffset - * @param int $endOffset - */ - public function __construct(FacebookFile $file, $uploadSessionId, $videoId, $startOffset, $endOffset) + public function __construct(FacebookFile $file, int $uploadSessionId, int $videoId, int $startOffset, int $endOffset) { $this->file = $file; $this->uploadSessionId = $uploadSessionId; @@ -76,65 +71,43 @@ public function __construct(FacebookFile $file, $uploadSessionId, $videoId, $sta * * @return FacebookFile */ - public function getFile() + public function getFile(): FacebookFile { return $this->file; } /** * Return a FacebookFile entity with partial content. - * - * @return FacebookFile + * @throws FacebookSDKException */ - public function getPartialFile() + public function getPartialFile(): FacebookFile { $maxLength = $this->endOffset - $this->startOffset; return new FacebookFile($this->file->getFilePath(), $maxLength, $this->startOffset); } - /** - * Return upload session Id - * - * @return int - */ - public function getUploadSessionId() + public function getUploadSessionId(): int { return $this->uploadSessionId; } - /** - * Check whether is the last chunk - * - * @return bool - */ - public function isLastChunk() + public function isLastChunk(): bool { return $this->startOffset === $this->endOffset; } - /** - * @return int - */ - public function getStartOffset() + public function getStartOffset(): int { return $this->startOffset; } - /** - * @return int - */ - public function getEndOffset() + public function getEndOffset(): int { return $this->endOffset; } - /** - * Get uploaded video Id - * - * @return int - */ - public function getVideoId() + public function getVideoId(): int { return $this->videoId; } diff --git a/src/Facebook/FileUpload/Mimetypes.php b/src/Facebook/FileUpload/Mimetypes.php index 95d3992..f9b4ce8 100644 --- a/src/Facebook/FileUpload/Mimetypes.php +++ b/src/Facebook/FileUpload/Mimetypes.php @@ -34,11 +34,11 @@ */ class Mimetypes { - /** @var self */ - protected static $instance; + + protected static ?Mimetypes $instance = null; /** @var array Mapping of extension to mimetype */ - protected $mimetypes = [ + protected array $mimetypes = [ '3dml' => 'text/vnd.in3d.3dml', '3g2' => 'video/3gpp2', '3gp' => 'video/3gpp', @@ -951,7 +951,7 @@ class Mimetypes * @return self * @codeCoverageIgnore */ - public static function getInstance() + public static function getInstance(): self { if (!self::$instance) { self::$instance = new self(); @@ -967,11 +967,10 @@ public static function getInstance() * * @return string|null */ - public function fromExtension($extension) + public function fromExtension(string $extension): ?string { - $extension = strtolower($extension); - return isset($this->mimetypes[$extension]) ? $this->mimetypes[$extension] : null; + return $this->mimetypes[strtolower($extension)] ?? null; } /** @@ -981,7 +980,7 @@ public function fromExtension($extension) * * @return string|null */ - public function fromFilename($filename) + public function fromFilename(string $filename): ?string { return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); } diff --git a/src/Facebook/GraphNodes/Birthday.php b/src/Facebook/GraphNodes/Birthday.php index 4338b65..c7c4a1b 100644 --- a/src/Facebook/GraphNodes/Birthday.php +++ b/src/Facebook/GraphNodes/Birthday.php @@ -32,15 +32,8 @@ */ class Birthday extends DateTime { - /** - * @var bool - */ - private $hasDate = false; - /** - * @var bool - */ - private $hasYear = false; + private bool $hasDate, $hasYear; /** * Parses Graph birthday format to set indication flags, possible values: @@ -50,35 +43,30 @@ class Birthday extends DateTime * YYYY * * @link https://developers.facebook.com/docs/graph-api/reference/user - * - * @param string $date */ - public function __construct($date) + public function __construct(string $date) { $parts = explode('/', $date); + $count = count($parts); - $this->hasYear = count($parts) === 3 || count($parts) === 1; - $this->hasDate = count($parts) === 3 || count($parts) === 2; + $this->hasYear = $count === 3 || $count === 1; + $this->hasDate = $count === 3 || $count === 2; parent::__construct($date); } /** * Returns whether date object contains birth day and month - * - * @return bool */ - public function hasDate() + public function hasDate(): bool { return $this->hasDate; } /** * Returns whether date object contains birth year - * - * @return bool */ - public function hasYear() + public function hasYear(): bool { return $this->hasYear; } diff --git a/src/Facebook/GraphNodes/Collection.php b/src/Facebook/GraphNodes/Collection.php index 39823da..11a6110 100644 --- a/src/Facebook/GraphNodes/Collection.php +++ b/src/Facebook/GraphNodes/Collection.php @@ -33,6 +33,7 @@ use ArrayAccess; use ArrayIterator; +use Closure; use Countable; use IteratorAggregate; @@ -43,7 +44,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate * * @var array */ - protected $items = []; + protected array $items = []; /** * Create a new collection. @@ -63,7 +64,7 @@ public function __construct(array $items = []) * * @return mixed */ - public function getField($name, $default = null) + public function getField(string $name, mixed $default = null): mixed { if (isset($this->items[$name])) { return $this->items[$name]; @@ -72,61 +73,26 @@ public function getField($name, $default = null) return $default; } - /** - * Gets the value of the named property for this graph object. - * - * @param string $name The property to retrieve. - * @param mixed $default The default to return if the property doesn't exist. - * - * @return mixed - * - * @deprecated 5.0.0 getProperty() has been renamed to getField() - * @todo v6: Remove this method - */ - public function getProperty($name, $default = null) - { - return $this->getField($name, $default); - } - /** * Returns a list of all fields set on the object. - * - * @return array */ - public function getFieldNames() + public function getFieldNames(): array { return array_keys($this->items); } - /** - * Returns a list of all properties set on the object. - * - * @return array - * - * @deprecated 5.0.0 getPropertyNames() has been renamed to getFieldNames() - * @todo v6: Remove this method - */ - public function getPropertyNames() - { - return $this->getFieldNames(); - } - /** * Get all of the items in the collection. - * - * @return array */ - public function all() + public function all(): array { return $this->items; } /** * Get the collection of items as a plain array. - * - * @return array */ - public function asArray() + public function asArray(): array { return array_map(function ($value) { return $value instanceof Collection ? $value->asArray() : $value; @@ -135,113 +101,76 @@ public function asArray() /** * Run a map over each of the items. - * - * @param \Closure $callback - * - * @return static */ - public function map(\Closure $callback) + public function map(Closure $callback): static { return new static(array_map($callback, $this->items, array_keys($this->items))); } /** * Get the collection of items as JSON. - * - * @param int $options - * - * @return string */ - public function asJson($options = 0) + public function asJson(int $options = 0): string { return json_encode($this->asArray(), $options); } /** * Count the number of items in the collection. - * - * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return count($this->items); } /** * Get an iterator for the items. - * - * @return ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): ArrayIterator { return new ArrayIterator($this->items); } /** * Determine if an item exists at an offset. - * - * @param mixed $key - * - * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists(mixed $offset): bool { - return array_key_exists($key, $this->items); + return array_key_exists($offset, $this->items); } /** * Get an item at a given offset. - * - * @param mixed $key - * - * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet(mixed $offset): mixed { - return $this->items[$key]; + return $this->items[$offset] ?? null; } /** * Set the item at a given offset. - * - * @param mixed $key - * @param mixed $value - * - * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet(mixed $offset, mixed $value): void { - if (is_null($key)) { + if (is_null($offset)) { $this->items[] = $value; } else { - $this->items[$key] = $value; + $this->items[$offset] = $value; } } /** * Unset the item at a given offset. - * - * @param string $key - * - * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset(mixed $offset): void { - unset($this->items[$key]); + unset($this->items[$offset]); } /** * Convert the collection to its string representation. - * - * @return string */ - public function __toString() + public function __toString(): string { return $this->asJson(); } diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php deleted file mode 100644 index 31508ee..0000000 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ /dev/null @@ -1,112 +0,0 @@ - '\Facebook\GraphNodes\GraphUser', - 'application' => '\Facebook\GraphNodes\GraphApplication', - ]; - - /** - * Returns the ID for the achievement. - * - * @return string|null - */ - public function getId() - { - return $this->getField('id'); - } - - /** - * Returns the user who achieved this. - * - * @return GraphUser|null - */ - public function getFrom() - { - return $this->getField('from'); - } - - /** - * Returns the time at which this was achieved. - * - * @return \DateTime|null - */ - public function getPublishTime() - { - return $this->getField('publish_time'); - } - - /** - * Returns the app in which the user achieved this. - * - * @return GraphApplication|null - */ - public function getApplication() - { - return $this->getField('application'); - } - - /** - * Returns information about the achievement type this instance is connected with. - * - * @return array|null - */ - public function getData() - { - return $this->getField('data'); - } - - /** - * Returns the type of achievement. - * - * @see https://developers.facebook.com/docs/graph-api/reference/achievement - * - * @return string - */ - public function getType() - { - return 'game.achievement'; - } - - /** - * Indicates whether gaining the achievement published a feed story for the user. - * - * @return boolean|null - */ - public function isNoFeedStory() - { - return $this->getField('no_feed_story'); - } -} diff --git a/src/Facebook/GraphNodes/GraphAgeRange.php b/src/Facebook/GraphNodes/GraphAgeRange.php new file mode 100644 index 0000000..b15f011 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphAgeRange.php @@ -0,0 +1,19 @@ +getField('max'); + } + + public function getMin(): ?int + { + return $this->getField('min'); + } +} diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index 52f19b5..4a09e7b 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -21,163 +21,107 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; +use DateTime; + /** * Class GraphAlbum * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/album/ */ - class GraphAlbum extends GraphNode { - /** - * @var array Maps object key names to Graph object types. - */ - protected static $graphObjectMap = [ - 'from' => '\Facebook\GraphNodes\GraphUser', - 'place' => '\Facebook\GraphNodes\GraphPage', + + protected static array $graphObjectMap = [ + 'from' => GraphUser::class, + 'place' => GraphPlace::class, + 'event' => GraphEvent::class, + 'cover_photo' => GraphPhoto::class, ]; - /** - * Returns the ID for the album. - * - * @return string|null - */ - public function getId() + public function getId(): ?string { return $this->getField('id'); } - /** - * Returns whether the viewer can upload photos to this album. - * - * @return boolean|null - */ - public function getCanUpload() + public function getBackdatedTime(): ?DateTime { - return $this->getField('can_upload'); + return $this->getField('backdated_time'); } - /** - * Returns the number of photos in this album. - * - * @return int|null - */ - public function getCount() + public function getCanUpload(): bool + { + return (bool)$this->getField('can_upload'); + } + + public function getCount(): ?int { return $this->getField('count'); } - /** - * Returns the ID of the album's cover photo. - * - * @return string|null - */ - public function getCoverPhoto() + public function getCoverPhoto(): ?GraphPhoto { return $this->getField('cover_photo'); } - /** - * Returns the time the album was initially created. - * - * @return \DateTime|null - */ - public function getCreatedTime() + public function getCreatedTime(): ?DateTime { return $this->getField('created_time'); } - /** - * Returns the time the album was updated. - * - * @return \DateTime|null - */ - public function getUpdatedTime() + public function getUpdatedTime(): ?DateTime { return $this->getField('updated_time'); } - /** - * Returns the description of the album. - * - * @return string|null - */ - public function getDescription() + public function getDescription(): ?string { return $this->getField('description'); } - /** - * Returns profile that created the album. - * - * @return GraphUser|null - */ - public function getFrom() + public function getFrom(): ?GraphUser { return $this->getField('from'); } - /** - * Returns profile that created the album. - * - * @return GraphPage|null - */ - public function getPlace() + public function getPlace(): ?GraphPlace { return $this->getField('place'); } - /** - * Returns a link to this album on Facebook. - * - * @return string|null - */ - public function getLink() + public function getLink(): ?string { return $this->getField('link'); } - /** - * Returns the textual location of the album. - * - * @return string|null - */ - public function getLocation() + public function getLocation(): ?string { return $this->getField('location'); } - /** - * Returns the title of the album. - * - * @return string|null - */ - public function getName() + public function getName(): ?string { return $this->getField('name'); } - /** - * Returns the privacy settings for the album. - * - * @return string|null - */ - public function getPrivacy() + public function getPrivacy(): ?string { return $this->getField('privacy'); } /** - * Returns the type of the album. - * - * enum{ profile, mobile, wall, normal, album } - * - * @return string|null + * One of `album`, `app`, `cover`, `profile`, `mobile`, `normal` or `wall`. */ - public function getType() + public function getType(): ?string { return $this->getField('type'); } + + public function getEvent(): ?GraphEvent + { + return $this->getField('event'); + } } diff --git a/src/Facebook/GraphNodes/GraphApplication.php b/src/Facebook/GraphNodes/GraphApplication.php index aa07c82..ed90b7d 100644 --- a/src/Facebook/GraphNodes/GraphApplication.php +++ b/src/Facebook/GraphNodes/GraphApplication.php @@ -21,23 +21,412 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; +use DateTime; + /** * Class GraphApplication * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/application/ */ - class GraphApplication extends GraphNode { + + protected static array $graphObjectMap = [ + 'object_store_urls' => GraphApplicationObjectStoreURLs::class, + 'restrictions' => GraphApplicationRestrictions::class, + 'app_events_config' => GraphApplicationEventsConfig::class + ]; + /** * Returns the ID for the application. - * - * @return string|null */ - public function getId() + public function getId(): ?string { return $this->getField('id'); } + + public function getAamRules(): ?string + { + return $this->getField('aam_rules'); + } + + public function getAnAdSpaceLimit(): ?int + { + return $this->getField('an_ad_space_limit'); + } + + /** + * @return ?string[] + */ + public function getAppDomains(): ?array + { + return $this->getField('app_domains'); + } + + public function getAppEventsConfig(): ?GraphApplicationEventsConfig + { + return $this->getField('app_events_config'); + } + + public function isAppInstallTracked(): bool + { + return (bool)$this->getField('app_install_tracked'); + } + + public function getAppName(): ?string + { + return $this->getField('app_name'); + } + + public function getAppType(): ?int + { + return $this->getField('app_type'); + } + + public function getAuthDialogDataHelpUrl(): ?string + { + return $this->getField('auth_dialog_data_help_url'); + } + + public function getAuthDialogHeadline(): ?string + { + return $this->getField('auth_dialog_headline'); + } + + public function getAuthDialoguePermissionsExplanation(): ?string + { + return $this->getField('auth_dialog_perms_explanation'); + } + + public function getAuthReferralDefaultActivityPrivacy(): ?string + { + return $this->getField('auth_referral_default_activity_privacy'); + } + + public function isAuthReferralEnabled(): bool + { + return (bool)$this->getField('auth_referral_enabled'); + } + + /** + * @return ?string[] + */ + public function getAuthReferralExtendedPermissions(): ?array + { + return $this->getField('auth_referral_extended_perms'); + } + + /** + * @return ?string[] + */ + public function getAuthReferralFriendPermissions(): ?array + { + return $this->getField('auth_referral_friend_perms'); + } + + public function getAuthReferralResponseType(): ?string + { + return $this->getField('auth_referral_response_type'); + } + + /** + * @return ?string[] + */ + public function getAuthReferralUserPermissions(): ?array + { + return $this->getField('auth_referral_user_perms'); + } + + public function isCanvasFluidHeight(): bool + { + return (bool)$this->getField('canvas_fluid_height'); + } + + public function getCanvasFluidWidth(): ?int + { + return $this->getField('canvas_fluid_width'); + } + + public function getCanvasUrl(): ?string + { + return $this->getField('canvas_url'); + } + + public function getCategory(): ?string + { + return $this->getField('category'); + } + + public function getClientConfig(): ?array + { + return $this->getField('client_config'); + } + + public function getCompany(): ?string + { + return $this->getField('company'); + } + + public function isConfigurediOSSSO(): bool + { + return (bool)$this->getField('configured_ios_sso'); + } + + public function getContactEmail(): ?string + { + return $this->getField('contact_email'); + } + + public function getCreatedTime(): ?DateTime + { + return $this->getField('created_time'); + } + + public function getCreatorUid(): ?string + { + return $this->getField('creator_uid'); + } + + public function getDailyActiveUsers(): ?string + { + return $this->getField('daily_active_users'); + } + + public function getDailyActiveUsersRank(): ?int + { + return $this->getField('daily_active_users_rank'); + } + + public function getDeauthCallbackUrl(): ?string + { + return $this->getField('deauth_callback_url'); + } + + public function getDefaultShareMode(): ?string + { + return $this->getField('default_share_mode'); + } + + public function getDescription(): ?string + { + return $this->getField('description'); + } + + public function getFinancialId(): ?string + { + return $this->getField('financial_id'); + } + + public function getHostingUrl(): ?string + { + return $this->getField('hosting_url'); + } + + public function getIconUrl(): ?string + { + return $this->getField('icon_url'); + } + + /** + * @return ?string[] + */ + public function getiOSBundleIds(): ?array + { + return $this->getField('ios_bundle_id'); + } + + public function iOSSupportsNativeProxyAuthFlow(): bool + { + return (bool)$this->getField('ios_supports_native_proxy_auth_flow'); + } + + public function iOSSupportsSystemAuth(): bool + { + return (bool)$this->getField('ios_supports_system_auth'); + } + + public function getiPadAppStoreId(): ?string + { + return $this->getField('ipad_app_store_id'); + } + + public function getiPhoneAppStoreId(): ?string + { + return $this->getField('iphone_app_store_id'); + } + + public function getLink(): ?string + { + return $this->getField('link'); + } + + public function getLoggingToken(): ?string + { + return $this->getField('logging_token'); + } + + public function getLogoUrl(): ?string + { + return $this->getField('logo_url'); + } + + public function getMobileProfileSectionUrl(): ?string + { + return $this->getField('mobile_profile_section_url'); + } + + public function getMobileWebUrl(): ?string + { + return $this->getField('mobile_web_url'); + } + + public function getMonthlyActiveUsers(): ?string + { + return $this->getField('monthly_active_users'); + } + + public function getMonthlyActiveUsersRank(): ?int + { + return $this->getField('monthly_active_users_rank'); + } + + /** + * Seems to be identical to `getAppName()`. + */ + public function getName(): ?string + { + return $this->getField('name'); + } + + public function getNamespace(): ?string + { + return $this->getField('namespace'); + } + + public function getObjectStoreUrls(): ?GraphApplicationObjectStoreURLs + { + return $this->getField('object_store_urls'); + } + + public function getPageTabDefaultName(): ?string + { + return $this->getField('page_tab_default_name'); + } + + public function getPageTabUrl(): ?string + { + return $this->getField('page_tab_url'); + } + + public function getPhotoUrl(): ?string + { + return $this->getField('photo_url'); + } + + public function getPrivacyPolicyUrl(): ?string + { + return $this->getField('privacy_policy_url'); + } + + public function getProfileSectionUrl(): ?string + { + return $this->getField('profile_section_url'); + } + + public function getPropertyId(): ?string + { + return $this->getField('property_id'); + } + + /** + * @return ?string[] + */ + public function getRealTimeModeDevices(): ?array + { + return $this->getField('real_time_mode_devices'); + } + + public function getRestrictions(): ?GraphApplicationRestrictions + { + return $this->getField('restrictions'); + } + + public function getRestrictiveDataFilterParams(): ?string + { + return $this->getField('restrictive_data_filter_params'); + } + + public function getSecureCanvasUrl(): ?string + { + return $this->getField('secure_canvas_url'); + } + + public function getSecurePageTabUrl(): ?string + { + return $this->getField('secure_page_tab_url'); + } + + public function getServerIPWhitelist(): ?string + { + return $this->getField('server_ip_whitelist'); + } + + public function isSocialDiscovery(): bool + { + return (bool)$this->getField('social_discovery'); + } + + public function getSubcategory(): ?string + { + return $this->getField('subcategory'); + } + + public function getSuggestedEventSettings(): ?string + { + return $this->getField('suggested_event_settings'); + } + + /** + * Array of: `WEB`,`CANVAS`,`MOBILE_WEB`,`IPHONE`,`IPAD`,`ANDROID`,`WINDOWS`,`AMAZON`,`SUPPLEMENTARY_IMAGES`, + * `GAMEROOM`,`INSTANT_GAME`,`OCULUS`,`SAMSUNG`,`XIAOMI`. + * @return ?string[] + */ + public function getSupportedPlatforms(): ?array + { + return $this->getField('supported_platforms'); + } + + public function getTermsOfServiceUrl(): ?string + { + return $this->getField('terms_of_service_url'); + } + + public function getUrlSchemeSuffix(): ?string + { + return $this->getField('url_scheme_suffix'); + } + + public function getUserSupportEmail(): ?string + { + return $this->getField('user_support_email'); + } + + public function getUserSupportUrl(): ?string + { + return $this->getField('user_support_url'); + } + + public function getWebsiteUrl(): ?string + { + return $this->getField('website_url'); + } + + public function getWeeklyActiveUsers(): ?string + { + return $this->getField('weekly_active_users'); + } } diff --git a/src/Facebook/GraphNodes/GraphApplicationEventsConfig.php b/src/Facebook/GraphNodes/GraphApplicationEventsConfig.php new file mode 100644 index 0000000..a07c228 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphApplicationEventsConfig.php @@ -0,0 +1,22 @@ +getField('default_ate_status'); + } + + public function isAdvertiserIdCollectionEnabled(): bool + { + return (bool)$this->getField('advertiser_id_collection_enabled'); + } + + public function isEventCollectionEnabled(): bool + { + return (bool)$this->getField('event_collection_enabled'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphApplicationObjectStoreURLs.php b/src/Facebook/GraphNodes/GraphApplicationObjectStoreURLs.php new file mode 100644 index 0000000..69fb3d4 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphApplicationObjectStoreURLs.php @@ -0,0 +1,50 @@ +getField('amazon_app_store'); + } + + public function getFBCanvas(): ?string + { + return $this->getField('fb_canvas'); + } + + public function getFBGameRoom(): ?string + { + return $this->getField('fb_gameroom'); + } + + public function getGooglePlay(): ?string + { + return $this->getField('google_play'); + } + + public function getInstantGame(): ?string + { + return $this->getField('instant_game'); + } + + public function getItunes(): ?string + { + return $this->getField('itunes'); + } + + public function getItunesIpad(): ?string + { + return $this->getField('itunes_ipad'); + } + + public function getWindows10Store(): ?string + { + return $this->getField('windows_10_store'); + } +} diff --git a/src/Facebook/GraphNodes/GraphApplicationRestrictions.php b/src/Facebook/GraphNodes/GraphApplicationRestrictions.php new file mode 100644 index 0000000..4943526 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphApplicationRestrictions.php @@ -0,0 +1,29 @@ +getField('age'); + } + + public function getAgeDistribution(): ?string + { + return $this->getField('age_distribution'); + } + + public function getLocation(): ?string + { + return $this->getField('location'); + } + + public function getType(): ?string + { + return $this->getField('type'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphArchivedAd.php b/src/Facebook/GraphNodes/GraphArchivedAd.php new file mode 100644 index 0000000..cf8ae2b --- /dev/null +++ b/src/Facebook/GraphNodes/GraphArchivedAd.php @@ -0,0 +1,154 @@ + GraphInsightsRangeValue::class, + 'impressions' => GraphInsightsRangeValue::class, + 'spend' => GraphInsightsRangeValue::class, + ]; + + public function getId(): ?string + { + return $this->getField('id'); + } + + public function getAdCreationTime(): ?DateTime + { + return $this->getField('ad_creation_time'); + } + + /** + * @return ?string[] + */ + public function getAdCreativeBodies(): ?array + { + return $this->getField('ad_creative_bodies'); + } + + /** + * @return ?string[] + */ + public function getAdCreativeLinkCaptions(): ?array + { + return $this->getField('ad_creative_link_captions'); + } + + /** + * @return ?string[] + */ + public function getAdCreativeLinkDescriptions(): ?array + { + return $this->getField('ad_creative_link_descriptions'); + } + + /** + * @return ?string[] + */ + public function getAdCreativeLinkTitles(): ?array + { + return $this->getField('ad_creative_link_titles'); + } + + public function getAdDeliveryStartTime(): ?DateTime + { + return $this->getField('ad_delivery_start_time'); + } + + public function getAdDeliveryStopTime(): ?DateTime + { + return $this->getField('ad_delivery_stop_time'); + } + + public function getAdSnapshotUrl(): ?string + { + return $this->getField('ad_snapshot_url'); + } + + public function getBrTotalReach(): ?int + { + return $this->getField('br_total_reach'); + } + + public function getBylines(): ?string + { + return $this->getField('bylines'); + } + + public function getCurrency(): ?string + { + return $this->getField('currency'); + } + + public function getEstimatedAudienceSize(): ?GraphInsightsRangeValue + { + return $this->getField('estimated_audience_size'); + } + + public function getEUTotalReach(): ?int + { + return $this->getField('eu_total_reach'); + } + + public function getImpressions(): ?GraphInsightsRangeValue + { + return $this->getField('impressions'); + } + + /** + * @return ?string[] + */ + public function getLanguages(): ?array + { + return $this->getField('languages'); + } + + public function getPageId(): ?string + { + return $this->getField('page_id'); + } + + public function getPageName(): ?string + { + return $this->getField('page_name'); + } + + /** + * @return ?string[] + */ + public function getPublisherPlatforms(): ?array + { + return $this->getField('publisher_platforms'); + } + + public function getSpend(): ?GraphInsightsRangeValue + { + return $this->getField('spend'); + } + + /** + * @return ?string[] + */ + public function getTargetAges(): ?array + { + return $this->getField('target_ages'); + } + + /** + * @return ?string[] + */ + public function getTargetGenders(): ?array + { + return $this->getField('target_genders'); + } + +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphCoverPhoto.php b/src/Facebook/GraphNodes/GraphCoverPhoto.php index 824275b..51bcf38 100644 --- a/src/Facebook/GraphNodes/GraphCoverPhoto.php +++ b/src/Facebook/GraphNodes/GraphCoverPhoto.php @@ -21,51 +21,34 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; /** * Class GraphCoverPhoto * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/cover-photo/ */ class GraphCoverPhoto extends GraphNode { - /** - * Returns the id of cover if it exists - * - * @return int|null - */ - public function getId() + + public function getId(): ?string { return $this->getField('id'); } - - /** - * Returns the source of cover if it exists - * - * @return string|null - */ - public function getSource() + + public function getSource(): ?string { return $this->getField('source'); } - /** - * Returns the offset_x of cover if it exists - * - * @return int|null - */ - public function getOffsetX() + public function getOffsetX(): ?float { return $this->getField('offset_x'); } - /** - * Returns the offset_y of cover if it exists - * - * @return int|null - */ - public function getOffsetY() + public function getOffsetY(): ?float { return $this->getField('offset_y'); } diff --git a/src/Facebook/GraphNodes/GraphEdge.php b/src/Facebook/GraphNodes/GraphEdge.php index f6f4970..b8b9b40 100644 --- a/src/Facebook/GraphNodes/GraphEdge.php +++ b/src/Facebook/GraphNodes/GraphEdge.php @@ -23,6 +23,7 @@ */ namespace Facebook\GraphNodes; +use Closure; use Facebook\FacebookRequest; use Facebook\Url\FacebookUrlManipulator; use Facebook\Exceptions\FacebookSDKException; @@ -37,22 +38,22 @@ class GraphEdge extends Collection /** * @var FacebookRequest The original request that generated this data. */ - protected $request; + protected FacebookRequest $request; /** * @var array An array of Graph meta data like pagination, etc. */ - protected $metaData = []; + protected array $metaData = []; /** * @var string|null The parent Graph edge endpoint that generated the list. */ - protected $parentEdgeEndpoint; + protected ?string $parentEdgeEndpoint; /** * @var string|null The subclass of the child GraphNode's. */ - protected $subclassName; + protected ?string $subclassName; /** * Init this collection of GraphNode's. @@ -63,7 +64,7 @@ class GraphEdge extends Collection * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. * @param string|null $subclassName The subclass of the child GraphNode's. */ - public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) + public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], ?string $parentEdgeEndpoint = null, ?string $subclassName = null) { $this->request = $request; $this->metaData = $metaData; @@ -78,7 +79,7 @@ public function __construct(FacebookRequest $request, array $data = [], array $m * * @return string|null */ - public function getParentGraphEdge() + public function getParentGraphEdge(): ?string { return $this->parentEdgeEndpoint; } @@ -88,7 +89,7 @@ public function getParentGraphEdge() * * @return string|null */ - public function getSubClassName() + public function getSubClassName(): ?string { return $this->subclassName; } @@ -98,7 +99,7 @@ public function getSubClassName() * * @return array */ - public function getMetaData() + public function getMetaData(): array { return $this->metaData; } @@ -108,7 +109,7 @@ public function getMetaData() * * @return string|null */ - public function getNextCursor() + public function getNextCursor(): ?string { return $this->getCursor('after'); } @@ -118,7 +119,7 @@ public function getNextCursor() * * @return string|null */ - public function getPreviousCursor() + public function getPreviousCursor(): ?string { return $this->getCursor('before'); } @@ -130,7 +131,7 @@ public function getPreviousCursor() * * @return string|null */ - public function getCursor($direction) + public function getCursor(string $direction): ?string { if (isset($this->metaData['paging']['cursors'][$direction])) { return $this->metaData['paging']['cursors'][$direction]; @@ -148,7 +149,7 @@ public function getCursor($direction) * * @throws FacebookSDKException */ - public function getPaginationUrl($direction) + public function getPaginationUrl(string $direction): ?string { $this->validateForPagination(); @@ -167,7 +168,7 @@ public function getPaginationUrl($direction) * * @throws FacebookSDKException */ - public function validateForPagination() + public function validateForPagination(): void { if ($this->request->getMethod() !== 'GET') { throw new FacebookSDKException('You can only paginate on a GET request.', 720); @@ -179,11 +180,9 @@ public function validateForPagination() * * @param string $direction The direction of the page: next|previous * - * @return FacebookRequest|null - * * @throws FacebookSDKException */ - public function getPaginationRequest($direction) + public function getPaginationRequest(string $direction): FacebookRequest|null { $pageUrl = $this->getPaginationUrl($direction); if (!$pageUrl) { @@ -199,11 +198,9 @@ public function getPaginationRequest($direction) /** * Gets the request object needed to make a "next" page request. * - * @return FacebookRequest|null - * * @throws FacebookSDKException */ - public function getNextPageRequest() + public function getNextPageRequest(): ?FacebookRequest { return $this->getPaginationRequest('next'); } @@ -211,11 +208,9 @@ public function getNextPageRequest() /** * Gets the request object needed to make a "previous" page request. * - * @return FacebookRequest|null - * * @throws FacebookSDKException */ - public function getPreviousPageRequest() + public function getPreviousPageRequest(): ?FacebookRequest { return $this->getPaginationRequest('previous'); } @@ -224,22 +219,16 @@ public function getPreviousPageRequest() * The total number of results according to Graph if it exists. * * This will be returned if the summary=true modifier is present in the request. - * - * @return int|null */ - public function getTotalCount() + public function getTotalCount(): ?int { - if (isset($this->metaData['summary']['total_count'])) { - return $this->metaData['summary']['total_count']; - } - - return null; + return $this->metaData['summary']['total_count'] ?? null; } /** * @inheritDoc */ - public function map(\Closure $callback) + public function map(Closure $callback): static { return new static( $this->request, diff --git a/src/Facebook/GraphNodes/GraphEngagement.php b/src/Facebook/GraphNodes/GraphEngagement.php new file mode 100644 index 0000000..e5e4c5f --- /dev/null +++ b/src/Facebook/GraphNodes/GraphEngagement.php @@ -0,0 +1,46 @@ +getField('count'); + } + + public function getCountString(): ?string + { + return $this->getField('count_string'); + } + + public function getCountStringWithLike(): ?string + { + return $this->getField('count_string_with_like'); + } + + public function getCountStringWithoutLike(): ?string + { + return $this->getField('count_string_without_like'); + } + + public function getSocialSentence(): ?string + { + return $this->getField('social_sentence'); + } + + public function getSocialSentenceWithLike(): ?string + { + return $this->getField('social_sentence_with_like'); + } + + public function getSocialSentenceWithoutLike(): ?string + { + return $this->getField('social_sentence_without_like'); + } + +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphEvent.php b/src/Facebook/GraphNodes/GraphEvent.php index a470d89..181900b 100644 --- a/src/Facebook/GraphNodes/GraphEvent.php +++ b/src/Facebook/GraphNodes/GraphEvent.php @@ -21,211 +21,168 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; +use DateTime; + /** * Class GraphEvent * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/event */ class GraphEvent extends GraphNode { /** * @var array Maps object key names to GraphNode types. */ - protected static $graphObjectMap = [ - 'cover' => '\Facebook\GraphNodes\GraphCoverPhoto', - 'place' => '\Facebook\GraphNodes\GraphPage', - 'picture' => '\Facebook\GraphNodes\GraphPicture', - 'parent_group' => '\Facebook\GraphNodes\GraphGroup', + protected static array $graphObjectMap = [ + 'cover' => GraphCoverPhoto::class, + 'place' => GraphPage::class, + 'parent_group' => GraphGroup::class, ]; /** * Returns the `id` (The event ID) as string if present. - * - * @return string|null */ - public function getId() + public function getId(): ?string { return $this->getField('id'); } /** * Returns the `cover` (Cover picture) as GraphCoverPhoto if present. - * - * @return GraphCoverPhoto|null */ - public function getCover() + public function getCover(): ?GraphCoverPhoto { return $this->getField('cover'); } /** * Returns the `description` (Long-form description) as string if present. - * - * @return string|null */ - public function getDescription() + public function getDescription(): ?string { return $this->getField('description'); } /** * Returns the `end_time` (End time, if one has been set) as DateTime if present. - * - * @return \DateTime|null */ - public function getEndTime() + public function getEndTime(): ?DateTime { return $this->getField('end_time'); } /** * Returns the `is_date_only` (Whether the event only has a date specified, but no time) as bool if present. - * - * @return bool|null */ - public function getIsDateOnly() + public function getIsDateOnly(): bool { - return $this->getField('is_date_only'); + return $this->getField('is_date_only') ?? false; } /** * Returns the `name` (Event name) as string if present. - * - * @return string|null */ - public function getName() + public function getName(): ?string { return $this->getField('name'); } /** * Returns the `owner` (The profile that created the event) as GraphNode if present. - * - * @return GraphNode|null */ - public function getOwner() + public function getOwner(): ?GraphNode { return $this->getField('owner'); } /** * Returns the `parent_group` (The group the event belongs to) as GraphGroup if present. - * - * @return GraphGroup|null */ - public function getParentGroup() + public function getParentGroup(): ?GraphGroup { return $this->getField('parent_group'); } /** * Returns the `place` (Event Place information) as GraphPage if present. - * - * @return GraphPage|null */ - public function getPlace() + public function getPlace(): ?GraphPage { return $this->getField('place'); } /** * Returns the `privacy` (Who can see the event) as string if present. - * - * @return string|null */ - public function getPrivacy() + public function getPrivacy(): ?string { return $this->getField('privacy'); } /** * Returns the `start_time` (Start time) as DateTime if present. - * - * @return \DateTime|null */ - public function getStartTime() + public function getStartTime(): ?DateTime { return $this->getField('start_time'); } /** * Returns the `ticket_uri` (The link users can visit to buy a ticket to this event) as string if present. - * - * @return string|null */ - public function getTicketUri() + public function getTicketUri(): ?string { return $this->getField('ticket_uri'); } /** * Returns the `timezone` (Timezone) as string if present. - * - * @return string|null */ - public function getTimezone() + public function getTimezone(): ?string { return $this->getField('timezone'); } /** * Returns the `updated_time` (Last update time) as DateTime if present. - * - * @return \DateTime|null */ - public function getUpdatedTime() + public function getUpdatedTime(): ?DateTime { return $this->getField('updated_time'); } - /** - * Returns the `picture` (Event picture) as GraphPicture if present. - * - * @return GraphPicture|null - */ - public function getPicture() - { - return $this->getField('picture'); - } - /** * Returns the `attending_count` (Number of people attending the event) as int if present. - * - * @return int|null */ - public function getAttendingCount() + public function getAttendingCount(): ?int { return $this->getField('attending_count'); } /** * Returns the `declined_count` (Number of people who declined the event) as int if present. - * - * @return int|null */ - public function getDeclinedCount() + public function getDeclinedCount(): ?int { return $this->getField('declined_count'); } /** * Returns the `maybe_count` (Number of people who maybe going to the event) as int if present. - * - * @return int|null */ - public function getMaybeCount() + public function getMaybeCount(): ?int { return $this->getField('maybe_count'); } /** * Returns the `noreply_count` (Number of people who did not reply to the event) as int if present. - * - * @return int|null */ - public function getNoreplyCount() + public function getNoreplyCount(): ?int { return $this->getField('noreply_count'); } @@ -235,8 +192,13 @@ public function getNoreplyCount() * * @return int|null */ - public function getInvitedCount() + public function getInvitedCount(): ?int { return $this->getField('invited_count'); } + + public function getType(): ?string + { + return $this->getField('type'); + } } diff --git a/src/Facebook/GraphNodes/GraphExperience.php b/src/Facebook/GraphNodes/GraphExperience.php new file mode 100644 index 0000000..2b10ca7 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphExperience.php @@ -0,0 +1,34 @@ + GraphUser::class + ]; + + public function getId(): ?string + { + return $this->getField('id'); + } + + public function getDescription(): ?string + { + return $this->getField('description'); + } + + public function getName(): ?string + { + return $this->getField('name'); + } + + public function getWith(): ?GraphUser + { + return $this->getField('with'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphGroup.php b/src/Facebook/GraphNodes/GraphGroup.php index 6217bd4..b3a656a 100644 --- a/src/Facebook/GraphNodes/GraphGroup.php +++ b/src/Facebook/GraphNodes/GraphGroup.php @@ -21,150 +21,92 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; +use DateTime; + /** * Class GraphGroup * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/group */ class GraphGroup extends GraphNode { /** * @var array Maps object key names to GraphNode types. */ - protected static $graphObjectMap = [ - 'cover' => '\Facebook\GraphNodes\GraphCoverPhoto', - 'venue' => '\Facebook\GraphNodes\GraphLocation', + protected static array $graphObjectMap = [ + 'cover' => GraphCoverPhoto::class ]; - /** - * Returns the `id` (The Group ID) as string if present. - * - * @return string|null - */ - public function getId() + public function getId(): ?string { return $this->getField('id'); } - /** - * Returns the `cover` (The cover photo of the Group) as GraphCoverPhoto if present. - * - * @return GraphCoverPhoto|null - */ - public function getCover() + public function getCover(): ?GraphCoverPhoto { return $this->getField('cover'); } - /** - * Returns the `description` (A brief description of the Group) as string if present. - * - * @return string|null - */ - public function getDescription() + public function getDescription(): ?string { return $this->getField('description'); } - /** - * Returns the `email` (The email address to upload content to the Group. Only current members of the Group can use this) as string if present. - * - * @return string|null - */ - public function getEmail() + public function getEmail(): ?string { return $this->getField('email'); } - /** - * Returns the `icon` (The URL for the Group's icon) as string if present. - * - * @return string|null - */ - public function getIcon() + public function getIcon(): ?string { return $this->getField('icon'); } - /** - * Returns the `link` (The Group's website) as string if present. - * - * @return string|null - */ - public function getLink() + public function getMemberCount(): ?int { - return $this->getField('link'); + return $this->getField('member_count'); } - /** - * Returns the `name` (The name of the Group) as string if present. - * - * @return string|null - */ - public function getName() + public function getMemberRequestCount(): ?int { - return $this->getField('name'); + return $this->getField('member_request_count'); } - /** - * Returns the `member_request_count` (Number of people asking to join the group.) as int if present. - * - * @return int|null - */ - public function getMemberRequestCount() + public function getName(): ?string { - return $this->getField('member_request_count'); + return $this->getField('name'); } /** - * Returns the `owner` (The profile that created this Group) as GraphNode if present. - * - * @return GraphNode|null + * @deprecated Deprecated in v9.0. Probably does not work anymore. */ - public function getOwner() + public function getOwner(): ?GraphNode { return $this->getField('owner'); } - /** - * Returns the `parent` (The parent Group of this Group, if it exists) as GraphNode if present. - * - * @return GraphNode|null - */ - public function getParent() + public function getParent(): ?GraphNode { return $this->getField('parent'); } - /** - * Returns the `privacy` (The privacy setting of the Group) as string if present. - * - * @return string|null - */ - public function getPrivacy() + public function getPermissions(): ?string { - return $this->getField('privacy'); + return $this->getField('permissions'); } - /** - * Returns the `updated_time` (The last time the Group was updated (this includes changes in the Group's properties and changes in posts and comments if user can see them)) as \DateTime if present. - * - * @return \DateTime|null - */ - public function getUpdatedTime() + public function getPrivacy(): ?string { - return $this->getField('updated_time'); + return $this->getField('privacy'); } - /** - * Returns the `venue` (The location for the Group) as GraphLocation if present. - * - * @return GraphLocation|null - */ - public function getVenue() + public function getUpdatedTime(): ?DateTime { - return $this->getField('venue'); + return $this->getField('updated_time'); } + } diff --git a/src/Facebook/GraphNodes/GraphInsightsRangeValue.php b/src/Facebook/GraphNodes/GraphInsightsRangeValue.php new file mode 100644 index 0000000..e8259d5 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphInsightsRangeValue.php @@ -0,0 +1,20 @@ +getField('lower_bound'); + } + + public function getUpperBound(): ?string + { + return $this->getField('upper_bound'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php deleted file mode 100644 index 3dfbd49..0000000 --- a/src/Facebook/GraphNodes/GraphList.php +++ /dev/null @@ -1,36 +0,0 @@ -getField('street'); } - /** - * Returns the city component of the location - * - * @return string|null - */ - public function getCity() + public function getCity(): ?string { return $this->getField('city'); } - /** - * Returns the state component of the location - * - * @return string|null - */ - public function getState() + public function getState(): ?string { return $this->getField('state'); } - /** - * Returns the country component of the location - * - * @return string|null - */ - public function getCountry() + public function getCountry(): ?string { return $this->getField('country'); } - /** - * Returns the zipcode component of the location - * - * @return string|null - */ - public function getZip() + public function getZip(): ?string { return $this->getField('zip'); } - /** - * Returns the latitude component of the location - * - * @return float|null - */ - public function getLatitude() + public function getLatitude(): ?float { return $this->getField('latitude'); } - /** - * Returns the street component of the location - * - * @return float|null - */ - public function getLongitude() + public function getLongitude(): ?float { return $this->getField('longitude'); } diff --git a/src/Facebook/GraphNodes/GraphMailingAddress.php b/src/Facebook/GraphNodes/GraphMailingAddress.php new file mode 100644 index 0000000..430c25e --- /dev/null +++ b/src/Facebook/GraphNodes/GraphMailingAddress.php @@ -0,0 +1,55 @@ + GraphPage::class + ]; + + public function getId(): ?string + { + return $this->getField('id'); + } + + public function getCity(): ?string + { + return $this->getField('city'); + } + + public function getCountry(): ?string + { + return $this->getField('country'); + } + + public function getPostalCode(): ?string + { + return $this->getField('postal_code'); + } + + public function getRegion(): ?string + { + return $this->getField('region'); + } + + public function getStreet1(): ?string + { + return $this->getField('street1'); + } + + public function getStreet2(): ?string + { + return $this->getField('street2'); + } + + public function getCityPage(): ?GraphPage + { + return $this->getField('city_page'); + } + +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphNode.php b/src/Facebook/GraphNodes/GraphNode.php index a81c47b..80bc43b 100644 --- a/src/Facebook/GraphNodes/GraphNode.php +++ b/src/Facebook/GraphNodes/GraphNode.php @@ -23,6 +23,9 @@ */ namespace Facebook\GraphNodes; +use DateTime; +use Exception; + /** * Class GraphNode * @@ -33,7 +36,7 @@ class GraphNode extends Collection /** * @var array Maps object key names to Graph object types. */ - protected static $graphObjectMap = []; + protected static array $graphObjectMap = []; /** * Init this Graph object. @@ -55,16 +58,18 @@ public function __construct(array $data = []) * * @return array */ - public function castItems(array $data) + public function castItems(array $data): array { $items = []; foreach ($data as $k => $v) { if ($this->shouldCastAsDateTime($k) - && (is_numeric($v) - || $this->isIso8601DateString($v)) ) { - $items[$k] = $this->castToDateTime($v); + try { + $items[$k] = $this->castToDateTime($v); + } catch (Exception) { + // If it cannot be parsed as a date but should be one, we cannot add it because of type checking. + } } elseif ($k === 'birthday') { $items[$k] = $this->castToBirthday($v); } else { @@ -81,13 +86,13 @@ public function castItems(array $data) * * @return array */ - public function uncastItems() + public function uncastItems(): array { $items = $this->asArray(); return array_map(function ($v) { - if ($v instanceof \DateTime) { - return $v->format(\DateTime::ISO8601); + if ($v instanceof DateTime) { + return $v->format(DateTime::ISO8601); } return $v; @@ -96,43 +101,12 @@ public function uncastItems() /** * Get the collection of items as JSON. - * - * @param int $options - * - * @return string */ - public function asJson($options = 0) + public function asJson(int $options = 0): string { return json_encode($this->uncastItems(), $options); } - /** - * Detects an ISO 8601 formatted string. - * - * @param string $string - * - * @return boolean - * - * @see https://developers.facebook.com/docs/graph-api/using-graph-api/#readmodifiers - * @see http://www.cl.cam.ac.uk/~mgk25/iso-time.html - * @see http://en.wikipedia.org/wiki/ISO_8601 - */ - public function isIso8601DateString($string) - { - // This insane regex was yoinked from here: - // http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ - // ...and I'm all like: - // http://thecodinglove.com/post/95378251969/when-code-works-and-i-dont-know-why - $crazyInsaneRegexThatSomehowDetectsIso8601 = '/^([\+-]?\d{4}(?!\d{2}\b))' - . '((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?' - . '|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d' - . '|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])' - . '((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d' - . '([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/'; - - return preg_match($crazyInsaneRegexThatSomehowDetectsIso8601, $string) === 1; - } - /** * Determines if a value from Graph should be cast to DateTime. * @@ -140,7 +114,7 @@ public function isIso8601DateString($string) * * @return boolean */ - public function shouldCastAsDateTime($key) + public function shouldCastAsDateTime(string $key): bool { return in_array($key, [ 'created_time', @@ -157,18 +131,16 @@ public function shouldCastAsDateTime($key) /** * Casts a date value from Graph to DateTime. - * - * @param int|string $value - * - * @return \DateTime + * On PHP 8.3+, this is DateMalformedStringException, so we catch everything. + * @throws Exception */ - public function castToDateTime($value) + private function castToDateTime(int|string $value): DateTime { if (is_int($value)) { - $dt = new \DateTime(); + $dt = new DateTime(); $dt->setTimestamp($value); } else { - $dt = new \DateTime($value); + $dt = new DateTime($value); } return $dt; @@ -176,12 +148,8 @@ public function castToDateTime($value) /** * Casts a birthday value from Graph to Birthday - * - * @param string $value - * - * @return Birthday */ - public function castToBirthday($value) + private function castToBirthday(string $value): Birthday { return new Birthday($value); } @@ -191,7 +159,7 @@ public function castToBirthday($value) * * @return array */ - public static function getObjectMap() + public static function getObjectMap(): array { return static::$graphObjectMap; } diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index 937128b..990d344 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -42,30 +42,16 @@ */ class GraphNodeFactory { - /** - * @const string The base graph object class. - */ - const BASE_GRAPH_NODE_CLASS = '\Facebook\GraphNodes\GraphNode'; - - /** - * @const string The base graph edge class. - */ - const BASE_GRAPH_EDGE_CLASS = '\Facebook\GraphNodes\GraphEdge'; - - /** - * @const string The graph object prefix. - */ - const BASE_GRAPH_OBJECT_PREFIX = '\Facebook\GraphNodes\\'; /** * @var FacebookResponse The response entity from Graph. */ - protected $response; + protected FacebookResponse $response; /** - * @var array The decoded body of the FacebookResponse entity from Graph. + * @var array|null The decoded body of the FacebookResponse entity from Graph. */ - protected $decodedBody; + protected ?array $decodedBody; /** * Init this Graph object. @@ -83,11 +69,9 @@ public function __construct(FacebookResponse $response) * * @param string|null $subclassName The GraphNode sub class to cast to. * - * @return GraphNode - * * @throws FacebookSDKException */ - public function makeGraphNode($subclassName = null) + public function makeGraphNode(?string $subclassName = null): GraphEdge|GraphNode { $this->validateResponseAsArray(); $this->validateResponseCastableAsGraphNode(); @@ -95,109 +79,20 @@ public function makeGraphNode($subclassName = null) return $this->castAsGraphNodeOrGraphEdge($this->decodedBody, $subclassName); } - /** - * Convenience method for creating a GraphAchievement collection. - * - * @return GraphAchievement - * - * @throws FacebookSDKException - */ - public function makeGraphAchievement() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); - } - - /** - * Convenience method for creating a GraphAlbum collection. - * - * @return GraphAlbum - * - * @throws FacebookSDKException - */ - public function makeGraphAlbum() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); - } - - /** - * Convenience method for creating a GraphPage collection. - * - * @return GraphPage - * - * @throws FacebookSDKException - */ - public function makeGraphPage() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); - } - - /** - * Convenience method for creating a GraphSessionInfo collection. - * - * @return GraphSessionInfo - * - * @throws FacebookSDKException - */ - public function makeGraphSessionInfo() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); - } - - /** - * Convenience method for creating a GraphUser collection. - * - * @return GraphUser - * - * @throws FacebookSDKException - */ - public function makeGraphUser() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); - } - - /** - * Convenience method for creating a GraphEvent collection. - * - * @return GraphEvent - * - * @throws FacebookSDKException - */ - public function makeGraphEvent() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); - } - - /** - * Convenience method for creating a GraphGroup collection. - * - * @return GraphGroup - * - * @throws FacebookSDKException - */ - public function makeGraphGroup() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphGroup'); - } - /** * Tries to convert a FacebookResponse entity into a GraphEdge. * * @param string|null $subclassName The GraphNode sub class to cast the list items to. - * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. * - * @return GraphEdge + * @return GraphEdge|GraphNode * * @throws FacebookSDKException */ - public function makeGraphEdge($subclassName = null, $auto_prefix = true) + public function makeGraphEdge(?string $subclassName = null): GraphEdge|GraphNode { $this->validateResponseAsArray(); $this->validateResponseCastableAsGraphEdge(); - if ($subclassName && $auto_prefix) { - $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; - } - return $this->castAsGraphNodeOrGraphEdge($this->decodedBody, $subclassName); } @@ -206,7 +101,7 @@ public function makeGraphEdge($subclassName = null, $auto_prefix = true) * * @throws FacebookSDKException */ - public function validateResponseAsArray() + private function validateResponseAsArray(): void { if (!is_array($this->decodedBody)) { throw new FacebookSDKException('Unable to get response from Graph as array.', 620); @@ -218,7 +113,7 @@ public function validateResponseAsArray() * * @throws FacebookSDKException */ - public function validateResponseCastableAsGraphNode() + public function validateResponseCastableAsGraphNode(): void { if (isset($this->decodedBody['data']) && static::isCastableAsGraphEdge($this->decodedBody['data'])) { throw new FacebookSDKException( @@ -233,7 +128,7 @@ public function validateResponseCastableAsGraphNode() * * @throws FacebookSDKException */ - public function validateResponseCastableAsGraphEdge() + public function validateResponseCastableAsGraphEdge(): void { if (!(isset($this->decodedBody['data']) && static::isCastableAsGraphEdge($this->decodedBody['data']))) { throw new FacebookSDKException( @@ -249,34 +144,40 @@ public function validateResponseCastableAsGraphEdge() * @param array $data The array of data to iterate over. * @param string|null $subclassName The subclass to cast this collection to. * - * @return GraphNode - * * @throws FacebookSDKException */ - public function safelyMakeGraphNode(array $data, $subclassName = null) + private function safelyMakeGraphNode(array $data, ?string $subclassName = null): GraphNode { - $subclassName = $subclassName ?: static::BASE_GRAPH_NODE_CLASS; + $subclassName = $subclassName ?: GraphNode::class; static::validateSubclass($subclassName); // Remember the parent node ID - $parentNodeId = isset($data['id']) ? $data['id'] : null; + $parentNodeId = $data['id'] ?? null; $items = []; foreach ($data as $k => $v) { - // Array means could be recurable if (is_array($v)) { - // Detect any smart-casting from the $graphObjectMap array. - // This is always empty on the GraphNode collection, but subclasses can define - // their own array of smart-casting types. - $graphObjectMap = $subclassName::getObjectMap(); - $objectSubClass = isset($graphObjectMap[$k]) - ? $graphObjectMap[$k] - : null; - - // Could be a GraphEdge or GraphNode - $items[$k] = $this->castAsGraphNodeOrGraphEdge($v, $objectSubClass, $k, $parentNodeId); + if (array_is_list($v)) { + // If the array is a list of objects, we want to cast each of those objects to the appropriate GraphNode + // subclass, but retain the array structure. Since everything is an array when we use associative arrays + // when reading the JSON, we need array_is_list to distinguish a JSON array from an object. + $children = []; + foreach ($v as $cv) { + if (is_array($cv)) { + $children[] = $this->castAsGraphNodeOrGraphEdge($cv, $subclassName::getObjectMap()[$k] ?? null, $k, $parentNodeId); + } else { + // Element in array is not an object, i.e. if a property is an array of plain strings. + $children[] = $cv; + } + } + $items[$k] = $children; + } else { + // This means it's an object, not an array. + $items[$k] = $this->castAsGraphNodeOrGraphEdge($v, $subclassName::getObjectMap()[$k] ?? null, $k, $parentNodeId); + } } else { + // If it's not an "array" (or JSON object), use the value directly and don't attempt to cast it. $items[$k] = $v; } } @@ -292,11 +193,9 @@ public function safelyMakeGraphNode(array $data, $subclassName = null) * @param string|null $parentKey The key of this data (Graph edge). * @param string|null $parentNodeId The parent Graph node ID. * - * @return GraphNode|GraphEdge - * * @throws FacebookSDKException */ - public function castAsGraphNodeOrGraphEdge(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + private function castAsGraphNodeOrGraphEdge(array $data, ?string $subclassName = null, ?string $parentKey = null, ?string $parentNodeId = null): GraphNode|GraphEdge { if (isset($data['data'])) { // Create GraphEdge @@ -321,11 +220,9 @@ public function castAsGraphNodeOrGraphEdge(array $data, $subclassName = null, $p * @param string|null $parentKey The key of this data (Graph edge). * @param string|null $parentNodeId The parent Graph node ID. * - * @return GraphEdge - * * @throws FacebookSDKException */ - public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + private function safelyMakeGraphEdge(array $data, ?string $subclassName = null, ?string $parentKey = null, ?string $parentNodeId = null): GraphEdge { if (!isset($data['data'])) { throw new FacebookSDKException('Cannot cast data to GraphEdge. Expected a "data" key.', 620); @@ -340,9 +237,8 @@ public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKe // We'll need to make an edge endpoint for this in case it's a GraphEdge (for cursor pagination) $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; - $className = static::BASE_GRAPH_EDGE_CLASS; - return new $className($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + return new GraphEdge($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); } /** @@ -352,7 +248,7 @@ public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKe * * @return array */ - public function getMetaData(array $data) + public function getMetaData(array $data): array { unset($data['data']); @@ -361,19 +257,15 @@ public function getMetaData(array $data) /** * Determines whether or not the data should be cast as a GraphEdge. - * - * @param array $data - * - * @return boolean */ - public static function isCastableAsGraphEdge(array $data) + public static function isCastableAsGraphEdge(array $data): bool { if ($data === []) { return true; } // Checks for a sequential numeric array which would be a GraphEdge - return array_keys($data) === range(0, count($data) - 1); + return array_is_list($data); } /** @@ -383,9 +275,10 @@ public static function isCastableAsGraphEdge(array $data) * * @throws FacebookSDKException */ - public static function validateSubclass($subclassName) + public static function validateSubclass(string $subclassName): void { - if ($subclassName == static::BASE_GRAPH_NODE_CLASS || is_subclass_of($subclassName, static::BASE_GRAPH_NODE_CLASS)) { + + if (is_a($subclassName, GraphNode::class, true) || is_subclass_of($subclassName, GraphNode::class)) { return; } diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php deleted file mode 100644 index 0633c40..0000000 --- a/src/Facebook/GraphNodes/GraphObject.php +++ /dev/null @@ -1,36 +0,0 @@ -makeGraphNode($subclassName); - } - - /** - * Convenience method for creating a GraphEvent collection. - * - * @return GraphEvent - * - * @throws FacebookSDKException - */ - public function makeGraphEvent() - { - return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); - } - - /** - * Tries to convert a FacebookResponse entity into a GraphEdge. - * - * @param string|null $subclassName The GraphNode sub class to cast the list items to. - * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. - * - * @return GraphEdge - * - * @deprecated 5.0.0 GraphObjectFactory has been renamed to GraphNodeFactory - */ - public function makeGraphList($subclassName = null, $auto_prefix = true) - { - return $this->makeGraphEdge($subclassName, $auto_prefix); - } -} diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index 503b96b..b4654a4 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -21,137 +21,113 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; +use Facebook\FileUpload\FacebookVideo; + /** * Class GraphPage * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/page/ */ class GraphPage extends GraphNode { - /** - * @var array Maps object key names to Graph object types. - */ - protected static $graphObjectMap = [ - 'best_page' => '\Facebook\GraphNodes\GraphPage', - 'global_brand_parent_page' => '\Facebook\GraphNodes\GraphPage', - 'location' => '\Facebook\GraphNodes\GraphLocation', - 'cover' => '\Facebook\GraphNodes\GraphCoverPhoto', - 'picture' => '\Facebook\GraphNodes\GraphPicture', + protected static array $graphObjectMap = [ + 'featured_video' => GraphVideo::class, + 'engagement' => GraphEngagement::class, + 'contact_address' => GraphMailingAddress::class, + 'best_page' => GraphPage::class, + 'location' => GraphLocation::class, + 'cover' => GraphCoverPhoto::class ]; - /** - * Returns the ID for the user's page as a string if present. - * - * @return string|null - */ - public function getId() + public function getId(): ?string { return $this->getField('id'); } - /** - * Returns the Category for the user's page as a string if present. - * - * @return string|null - */ - public function getCategory() + public function getAbout(): ?string + { + return $this->getField('about'); + } + + public function getCategory(): ?string { return $this->getField('category'); } + public function getDescription(): ?string + { + return $this->getField('description'); + } + + public function getDescriptionHtml(): ?string + { + return $this->getField('description_html'); + } + /** - * Returns the Name of the user's page as a string if present. - * - * @return string|null + * @return ?string[] */ - public function getName() + public function getEmails(): ?array + { + return $this->getField('emails'); + } + + public function getEngagement(): ?GraphEngagement + { + return $this->getField('engagement'); + } + + public function getName(): ?string { return $this->getField('name'); } - /** - * Returns the best available Page on Facebook. - * - * @return GraphPage|null - */ - public function getBestPage() + public function getAppId(): ?string { - return $this->getField('best_page'); + return $this->getField('app_id'); } - /** - * Returns the brand's global (parent) Page. - * - * @return GraphPage|null - */ - public function getGlobalBrandParentPage() + public function getBestPage(): ?GraphPage { - return $this->getField('global_brand_parent_page'); + return $this->getField('best_page'); } - /** - * Returns the location of this place. - * - * @return GraphLocation|null - */ - public function getLocation() + public function getLocation(): ?GraphLocation { return $this->getField('location'); } - /** - * Returns CoverPhoto of the Page. - * - * @return GraphCoverPhoto|null - */ - public function getCover() + public function getCover(): ?GraphCoverPhoto { return $this->getField('cover'); } - /** - * Returns Picture of the Page. - * - * @return GraphPicture|null - */ - public function getPicture() + public function getAccessToken(): ?string + { + return $this->getField('access_token'); + } + + public function getAffiliation(): ?string { - return $this->getField('picture'); + return $this->getField('affiliation'); } - /** - * Returns the page access token for the admin user. - * - * Only available in the `/me/accounts` context. - * - * @return string|null - */ - public function getAccessToken() + public function getFanCount(): ?int { - return $this->getField('access_token'); + return $this->getField('fan_count'); } - /** - * Returns the roles of the page admin user. - * - * Only available in the `/me/accounts` context. - * - * @return array|null - */ - public function getPerms() + public function getFeaturedVideo(): ?GraphVideo { - return $this->getField('perms'); + return $this->getField('featured_video'); } - /** - * Returns the `fan_count` (Number of people who likes to page) as int if present. - * - * @return int|null - */ - public function getFanCount() + public function getContactAddress(): ?GraphMailingAddress { - return $this->getField('fan_count'); + return $this->getField('contact_address'); } } diff --git a/src/Facebook/GraphNodes/GraphPaymentPricePoint.php b/src/Facebook/GraphNodes/GraphPaymentPricePoint.php new file mode 100644 index 0000000..2fb0366 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPaymentPricePoint.php @@ -0,0 +1,24 @@ +getField('credits'); + } + + public function getCurrency(): ?string + { + return $this->getField('currency'); + } + + public function getUserPrice(): ?string + { + return $this->getField('user_price'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphPaymentPricePoints.php b/src/Facebook/GraphNodes/GraphPaymentPricePoints.php new file mode 100644 index 0000000..208b36d --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPaymentPricePoints.php @@ -0,0 +1,22 @@ + GraphPaymentPricePoint::class + ]; + + /** + * @return ?GraphPaymentPricePoint[] + */ + public function getMobile(): ?array + { + return $this->getField('mobile'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphPermission.php b/src/Facebook/GraphNodes/GraphPermission.php new file mode 100644 index 0000000..8395152 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPermission.php @@ -0,0 +1,20 @@ +getField('permission'); + } + + public function getStatus(): string + { + return $this->getField('status'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphPhoto.php b/src/Facebook/GraphNodes/GraphPhoto.php new file mode 100644 index 0000000..00c0bc5 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPhoto.php @@ -0,0 +1,127 @@ + GraphEvent::class, + 'album' => GraphAlbum::class, + 'images' => GraphPlatformImageSource::class, + 'webp_images' => GraphPlatformImageSource::class, + 'place' => GraphPlace::class, + ]; + + public function getId(): ?string + { + return $this->getField('id'); + } + + public function getAlbum(): ?GraphAlbum + { + return $this->getField('album'); + } + + public function getAltText(): ?string + { + return $this->getField('alt_text'); + } + + public function getAltTextCustom(): ?string + { + return $this->getField('alt_text_custom'); + } + + public function getBackDatedTime(): ?DateTime + { + return $this->getField('backdated_time'); + } + + public function canBackDate(): bool + { + return (bool)$this->getField('can_backdate'); + } + + public function canDelete(): bool + { + return (bool)$this->getField('can_delete'); + } + + public function canTag(): bool + { + return (bool)$this->getField('can_tag'); + } + + public function getCreatedTime(): ?DateTime + { + return $this->getField('created_time'); + } + + public function getEvent(): ?GraphEvent + { + return $this->getField('event'); + } + + public function getHeight(): ?int + { + return $this->getField('height'); + } + + public function getWidth(): ?int + { + return $this->getField('width'); + } + + public function getIcon(): ?string + { + return $this->getField('icon'); + } + + public function getLink(): ?string + { + return $this->getField('link'); + } + + public function getName(): ?string + { + return $this->getField('name'); + } + + public function getPageStoryId(): ?string + { + return $this->getField('page_story_id'); + } + + public function getPlace(): ?GraphPlace + { + return $this->getField('place'); + } + + public function getUpdatedTime(): ?DateTime + { + return $this->getField('updated_time'); + } + + /** + * @return ?GraphPlatformImageSource[] + */ + public function getWebPImages(): ?array + { + return $this->getField('webp_images'); + } + + /** + * @return ?GraphPlatformImageSource[] + */ + public function getImages(): ?array + { + return $this->getField('images'); + } + +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphPicture.php b/src/Facebook/GraphNodes/GraphPicture.php index 10274ec..eba00f0 100644 --- a/src/Facebook/GraphNodes/GraphPicture.php +++ b/src/Facebook/GraphNodes/GraphPicture.php @@ -32,40 +32,32 @@ class GraphPicture extends GraphNode { /** * Returns true if user picture is silhouette. - * - * @return bool|null */ - public function isSilhouette() + public function isSilhouette(): bool { - return $this->getField('is_silhouette'); + return $this->getField('is_silhouette') ?? false; } /** * Returns the url of user picture if it exists - * - * @return string|null */ - public function getUrl() + public function getUrl(): ?string { return $this->getField('url'); } /** * Returns the width of user picture if it exists - * - * @return int|null */ - public function getWidth() + public function getWidth(): ?int { return $this->getField('width'); } /** * Returns the height of user picture if it exists - * - * @return int|null */ - public function getHeight() + public function getHeight(): ?int { return $this->getField('height'); } diff --git a/src/Facebook/GraphNodes/GraphPlace.php b/src/Facebook/GraphNodes/GraphPlace.php new file mode 100644 index 0000000..7e2a801 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPlace.php @@ -0,0 +1,34 @@ + GraphLocation::class + ]; + + public function getId(): ?string + { + return $this->getField('id'); + } + + public function getLocation(): ?GraphLocation + { + return $this->getField('location'); + } + + public function getName(): ?string + { + return $this->getField('name'); + } + + public function getOverallRating(): ?float + { + return $this->getField('overall_rating'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphPlatformImageSource.php b/src/Facebook/GraphNodes/GraphPlatformImageSource.php new file mode 100644 index 0000000..7542f54 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPlatformImageSource.php @@ -0,0 +1,26 @@ +getField('height'); + } + + public function getWidth(): ?int + { + return $this->getField('width'); + } + + public function getSource(): ?string + { + return $this->getField('source'); + } + +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index df8dd35..1383ff5 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -23,6 +23,8 @@ */ namespace Facebook\GraphNodes; +use DateTime; + /** * Class GraphSessionInfo * @@ -32,70 +34,56 @@ class GraphSessionInfo extends GraphNode { /** * Returns the application id the token was issued for. - * - * @return string|null */ - public function getAppId() + public function getAppId(): ?string { return $this->getField('app_id'); } /** * Returns the application name the token was issued for. - * - * @return string|null */ - public function getApplication() + public function getApplication(): ?string { return $this->getField('application'); } /** * Returns the date & time that the token expires. - * - * @return \DateTime|null */ - public function getExpiresAt() + public function getExpiresAt(): ?DateTime { return $this->getField('expires_at'); } /** * Returns whether the token is valid. - * - * @return boolean */ - public function getIsValid() + public function getIsValid(): bool { - return $this->getField('is_valid'); + return $this->getField('is_valid') ?? false; } /** * Returns the date & time the token was issued at. - * - * @return \DateTime|null */ - public function getIssuedAt() + public function getIssuedAt(): ?DateTime { return $this->getField('issued_at'); } /** * Returns the scope permissions associated with the token. - * - * @return array */ - public function getScopes() + public function getScopes(): ?array { return $this->getField('scopes'); } /** * Returns the login id of the user associated with the token. - * - * @return string|null */ - public function getUserId() + public function getUserId(): ?string { return $this->getField('user_id'); } diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 6e1ed8f..c91b01c 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -21,152 +21,224 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\GraphNodes; /** * Class GraphUser * * @package Facebook + * @link https://developers.facebook.com/docs/graph-api/reference/user/ */ class GraphUser extends GraphNode { - /** - * @var array Maps object key names to Graph object types. - */ - protected static $graphObjectMap = [ - 'hometown' => '\Facebook\GraphNodes\GraphPage', - 'location' => '\Facebook\GraphNodes\GraphPage', - 'significant_other' => '\Facebook\GraphNodes\GraphUser', - 'picture' => '\Facebook\GraphNodes\GraphPicture', + + protected static array $graphObjectMap = [ + 'age_range' => GraphAgeRange::class, + 'hometown' => GraphPage::class, + 'location' => GraphPage::class, + 'picture' => GraphPicture::class, + 'significant_other' => GraphUser::class, + 'sports' => GraphExperience::class, + 'favorite_teams' => GraphExperience::class, + 'favorite_athletes' => GraphExperience::class, + 'languages' => GraphExperience::class, + 'inspirational_people' => GraphExperience::class, + 'video_upload_limits' => GraphVideoUploadLimits::class, + 'permissions' => GraphPermission::class, + 'payment_pricepoints' => GraphPaymentPricePoints::class, + 'albums' => GraphAlbum::class ]; - /** - * Returns the ID for the user as a string if present. - * - * @return string|null - */ - public function getId() + public function getId(): ?string { return $this->getField('id'); } - /** - * Returns the name for the user as a string if present. - * - * @return string|null - */ - public function getName() + public function getName(): ?string { return $this->getField('name'); } + public function getProfilePicture(): ?string + { + return $this->getField('profile_pic'); + } + + public function getClientBusinessId(): ?string + { + return $this->getField('client_business_id'); + } + + public function getTokenForBusiness(): ?string + { + return $this->getField('token_for_business'); + } + + public function getIdForAvatars(): ?string + { + return $this->getField('id_for_avatars'); + } + /** - * Returns the first name for the user as a string if present. - * - * @return string|null + * @return ?GraphExperience[] */ - public function getFirstName() + public function getFavoriteAthletes(): ?array { - return $this->getField('first_name'); + return $this->getField('favorite_athletes'); } /** - * Returns the middle name for the user as a string if present. - * - * @return string|null + * @return ?GraphExperience[] */ - public function getMiddleName() + public function getFavoriteTeams(): ?array { - return $this->getField('middle_name'); + return $this->getField('favorite_teams'); } /** - * Returns the last name for the user as a string if present. - * - * @return string|null + * @return ?GraphExperience[] */ - public function getLastName() + public function getLanguages(): ?array { - return $this->getField('last_name'); + return $this->getField('languages'); } /** - * Returns the email for the user as a string if present. - * - * @return string|null + * @return ?GraphExperience[] */ - public function getEmail() + public function getInspirationalPeople(): ?array + { + return $this->getField('inspirational_people'); + } + + public function getAbout(): ?string + { + return $this->getField('about'); + } + + public function getNameFormat(): ?string + { + return $this->getField('name_format'); + } + + public function getShortName(): ?string + { + return $this->getField('short_name'); + } + + public function getFirstName(): ?string + { + return $this->getField('first_name'); + } + + public function getMiddleName(): ?string + { + return $this->getField('middle_name'); + } + + public function getLastName(): ?string + { + return $this->getField('last_name'); + } + + public function getEmail(): ?string { return $this->getField('email'); } - /** - * Returns the gender for the user as a string if present. - * - * @return string|null - */ - public function getGender() + public function getGender(): ?string { return $this->getField('gender'); } - /** - * Returns the Facebook URL for the user as a string if available. - * - * @return string|null - */ - public function getLink() + public function getLink(): ?string { return $this->getField('link'); } - /** - * Returns the users birthday, if available. - * - * @return Birthday|null - */ - public function getBirthday() + public function getBirthday(): ?Birthday { return $this->getField('birthday'); } - /** - * Returns the current location of the user as a GraphPage. - * - * @return GraphPage|null - */ - public function getLocation() + public function getLocation(): ?GraphPage { return $this->getField('location'); } /** * Returns the current location of the user as a GraphPage. - * - * @return GraphPage|null */ - public function getHometown() + public function getHometown(): ?GraphPage { return $this->getField('hometown'); } /** * Returns the current location of the user as a GraphUser. - * - * @return GraphUser|null */ - public function getSignificantOther() + public function getSignificantOther(): ?GraphUser { return $this->getField('significant_other'); } /** * Returns the picture of the user as a GraphPicture - * - * @return GraphPicture|null */ - public function getPicture() + public function getPicture(): ?GraphPicture { return $this->getField('picture'); } + + public function supportsDonateButtonInLiveVideos(): bool + { + return (bool)$this->getField('supports_donate_button_in_live_video'); + } + + public function getAgeRange(): ?GraphAgeRange + { + return $this->getField('age_range'); + } + + public function isInstalled(): bool + { + return (bool)$this->getField('installed'); + } + + /** + * @return ?string[] + */ + public function getMeetingFor(): ?array + { + return $this->getField('meeting_for'); + } + + /** + * @return ?GraphExperience[] + */ + public function getSports(): ?array + { + return $this->getField('sports'); + } + + public function getVideoUploadLimits(): ?GraphVideoUploadLimits + { + return $this->getField('video_upload_limits'); + } + + public function getPermissions(): ?GraphEdge + { + return $this->getField('permissions'); + } + + public function getAlbums(): ?GraphEdge + { + return $this->getField('albums'); + } + + public function getPaymentPricePoints(): ?GraphPaymentPricePoints + { + return $this->getField('payment_pricepoints'); + } } diff --git a/src/Facebook/GraphNodes/GraphVideo.php b/src/Facebook/GraphNodes/GraphVideo.php new file mode 100644 index 0000000..afccf64 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphVideo.php @@ -0,0 +1,132 @@ + GraphEvent::class, + 'format' => GraphVideoFormat::class, + 'place' => GraphPlace::class, + ]; + + public function getId(): ?string + { + return $this->getField('id'); + } + + /** + * @return ?int[] + */ + public function adBreaks(): ?array + { + return $this->getField('ad_breaks'); + } + + public function getCreatedTime(): ?DateTime + { + return $this->getField('created_time'); + } + + /** + * @return ?string[] + */ + public function getCustomLabels(): ?array + { + return $this->getField('custom_labels'); + } + + public function getDescription(): ?string + { + return $this->getField('description'); + } + + public function getEmbedHtml(): ?string + { + return $this->getField('embed_html'); + } + + public function isEmbeddable(): bool + { + return (bool)$this->getField('embeddable'); + } + + public function getBackdatedTime(): ?DateTime + { + return $this->getField('backdated_time'); + } + + public function getEvent(): ?GraphEvent + { + return $this->getField('event'); + } + + /** + * @return ?GraphVideoFormat[] + */ + public function getFormat(): ?array + { + return $this->getField('format'); + } + + public function getLength(): ?float + { + return $this->getField('length'); + } + + public function getIcon(): ?string + { + return $this->getField('icon'); + } + + public function isCrossPostVideo(): bool + { + return (bool)$this->getField('is_crosspost_video'); + } + + public function isCrossPostEligible(): bool + { + return (bool)$this->getField('is_crossposting_eligible'); + } + + public function isEpisode(): bool + { + return (bool)$this->getField('is_episode'); + } + + public function isInstagramEligible(): bool + { + return (bool)$this->getField('is_instagram_eligible'); + } + + public function isReferenceOnly(): bool + { + return (bool)$this->getField('is_reference_only'); + } + + public function permaLinkUrl(): ?string + { + return $this->getField('permalink_url'); + } + + public function getPlace(): ?GraphPlace + { + return $this->getField('place'); + } + + public function getPostId(): ?string + { + return $this->getField('post_id'); + } + + public function getPostViews(): ?int + { + return $this->getField('post_views'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphVideoFormat.php b/src/Facebook/GraphNodes/GraphVideoFormat.php new file mode 100644 index 0000000..f37cb46 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphVideoFormat.php @@ -0,0 +1,34 @@ +getField('embed_html'); + } + + public function getFilter(): ?string + { + return $this->getField('filter'); + } + + public function getHeight(): ?int + { + return $this->getField('height'); + } + + public function getWidth(): ?int + { + return $this->getField('width'); + } + + public function getPicture(): ?string + { + return $this->getField('picture'); + } +} \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphVideoUploadLimits.php b/src/Facebook/GraphNodes/GraphVideoUploadLimits.php new file mode 100644 index 0000000..3cb9c26 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphVideoUploadLimits.php @@ -0,0 +1,20 @@ +getField('length'); + } + + public function getSize(): ?int + { + return $this->getField('size'); + } +} \ No newline at end of file diff --git a/src/Facebook/Helpers/FacebookCanvasHelper.php b/src/Facebook/Helpers/FacebookCanvasHelper.php index 7f3466f..78b42d5 100644 --- a/src/Facebook/Helpers/FacebookCanvasHelper.php +++ b/src/Facebook/Helpers/FacebookCanvasHelper.php @@ -32,20 +32,16 @@ class FacebookCanvasHelper extends FacebookSignedRequestFromInputHelper { /** * Returns the app data value. - * - * @return mixed|null */ - public function getAppData() + public function getAppData(): mixed { - return $this->signedRequest ? $this->signedRequest->get('app_data') : null; + return $this->signedRequest?->get('app_data'); } /** * Get raw signed request from POST. - * - * @return string|null */ - public function getRawSignedRequest() + public function getRawSignedRequest(): ?string { return $this->getRawSignedRequestFromPost() ?: null; } diff --git a/src/Facebook/Helpers/FacebookJavaScriptHelper.php b/src/Facebook/Helpers/FacebookJavaScriptHelper.php index 01a76b8..ed2ef36 100644 --- a/src/Facebook/Helpers/FacebookJavaScriptHelper.php +++ b/src/Facebook/Helpers/FacebookJavaScriptHelper.php @@ -32,10 +32,8 @@ class FacebookJavaScriptHelper extends FacebookSignedRequestFromInputHelper { /** * Get raw signed request from the cookie. - * - * @return string|null */ - public function getRawSignedRequest() + public function getRawSignedRequest(): ?string { return $this->getRawSignedRequestFromCookie(); } diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index da2c356..79fae3b 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -36,7 +36,7 @@ class FacebookPageTabHelper extends FacebookCanvasHelper /** * @var array|null */ - protected $pageData; + protected ?array $pageData = null; /** * Initialize the helper and process available signed request data. @@ -45,7 +45,7 @@ class FacebookPageTabHelper extends FacebookCanvasHelper * @param FacebookClient $client The client to make HTTP requests. * @param string|null $graphVersion The version of Graph to use. */ - public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) + public function __construct(FacebookApp $app, FacebookClient $client, ?string $graphVersion = null) { parent::__construct($app, $client, $graphVersion); @@ -58,13 +58,8 @@ public function __construct(FacebookApp $app, FacebookClient $client, $graphVers /** * Returns a value from the page data. - * - * @param string $key - * @param mixed|null $default - * - * @return mixed|null */ - public function getPageData($key, $default = null) + public function getPageData(string $key, mixed $default = null): mixed { if (isset($this->pageData[$key])) { return $this->pageData[$key]; @@ -73,22 +68,12 @@ public function getPageData($key, $default = null) return $default; } - /** - * Returns true if the user is an admin. - * - * @return boolean - */ - public function isAdmin() + public function isAdmin(): bool { return $this->getPageData('admin') === true; } - /** - * Returns the page id if available. - * - * @return string|null - */ - public function getPageId() + public function getPageId(): ?string { return $this->getPageData('id'); } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index a6e7d21..4b09346 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\Helpers; use Facebook\Authentication\AccessToken; @@ -33,6 +34,7 @@ use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\Url\FacebookUrlManipulator; use Facebook\Url\UrlDetectionInterface; +use function hash_equals; /** * Class FacebookRedirectLoginHelper @@ -49,30 +51,30 @@ class FacebookRedirectLoginHelper /** * @var OAuth2Client The OAuth 2.0 client service. */ - protected $oAuth2Client; + protected OAuth2Client $oAuth2Client; /** * @var UrlDetectionInterface The URL detection handler. */ - protected $urlDetectionHandler; + protected UrlDetectionInterface $urlDetectionHandler; /** * @var PersistentDataInterface The persistent data handler. */ - protected $persistentDataHandler; + protected PersistentDataInterface $persistentDataHandler; /** * @var PseudoRandomStringGeneratorInterface The cryptographically secure pseudo-random string generator. */ - protected $pseudoRandomStringGenerator; + protected PseudoRandomStringGeneratorInterface $pseudoRandomStringGenerator; /** - * @param OAuth2Client $oAuth2Client The OAuth 2.0 client service. - * @param PersistentDataInterface|null $persistentDataHandler The persistent data handler. - * @param UrlDetectionInterface|null $urlHandler The URL detection handler. - * @param PseudoRandomStringGeneratorInterface|null $prsg The cryptographically secure pseudo-random string generator. + * @param OAuth2Client $oAuth2Client The OAuth 2.0 client service. + * @param PersistentDataInterface|null $persistentDataHandler The persistent data handler. + * @param UrlDetectionInterface|null $urlHandler The URL detection handler. + * @param PseudoRandomStringGeneratorInterface|null $prsg The cryptographically secure pseudo-random string generator. */ - public function __construct(OAuth2Client $oAuth2Client, PersistentDataInterface $persistentDataHandler = null, UrlDetectionInterface $urlHandler = null, PseudoRandomStringGeneratorInterface $prsg = null) + public function __construct(OAuth2Client $oAuth2Client, ?PersistentDataInterface $persistentDataHandler = null, ?UrlDetectionInterface $urlHandler = null, ?PseudoRandomStringGeneratorInterface $prsg = null) { $this->oAuth2Client = $oAuth2Client; $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); @@ -82,30 +84,24 @@ public function __construct(OAuth2Client $oAuth2Client, PersistentDataInterface /** * Returns the persistent data handler. - * - * @return PersistentDataInterface */ - public function getPersistentDataHandler() + public function getPersistentDataHandler(): PersistentDataInterface { return $this->persistentDataHandler; } /** * Returns the URL detection handler. - * - * @return UrlDetectionInterface */ - public function getUrlDetectionHandler() + public function getUrlDetectionHandler(): UrlDetectionInterface { return $this->urlDetectionHandler; } /** * Returns the cryptographically secure pseudo-random string generator. - * - * @return PseudoRandomStringGeneratorInterface */ - public function getPseudoRandomStringGenerator() + public function getPseudoRandomStringGenerator(): PseudoRandomStringGeneratorInterface { return $this->pseudoRandomStringGenerator; } @@ -114,13 +110,12 @@ public function getPseudoRandomStringGenerator() * Stores CSRF state and returns a URL to which the user should be sent to in order to continue the login process with Facebook. * * @param string $redirectUrl The URL Facebook should redirect users to after login. - * @param array $scope List of permissions to request during login. - * @param array $params An array of parameters to generate URL. - * @param string $separator The separator to use in http_build_query(). - * + * @param array $scope List of permissions to request during login. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). * @return string */ - private function makeUrl($redirectUrl, array $scope, array $params = [], $separator = '&') + private function makeUrl(string $redirectUrl, array $scope, array $params = [], string $separator = '&'): string { $state = $this->persistentDataHandler->get('state') ?: $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state); @@ -132,12 +127,10 @@ private function makeUrl($redirectUrl, array $scope, array $params = [], $separa * Returns the URL to send the user in order to login to Facebook. * * @param string $redirectUrl The URL Facebook should redirect users to after login. - * @param array $scope List of permissions to request during login. - * @param string $separator The separator to use in http_build_query(). - * - * @return string + * @param array $scope List of permissions to request during login. + * @param string $separator The separator to use in http_build_query(). */ - public function getLoginUrl($redirectUrl, array $scope = [], $separator = '&') + public function getLoginUrl(string $redirectUrl, array $scope = [], string $separator = '&'): string { return $this->makeUrl($redirectUrl, $scope, [], $separator); } @@ -146,14 +139,12 @@ public function getLoginUrl($redirectUrl, array $scope = [], $separator = '&') * Returns the URL to send the user in order to log out of Facebook. * * @param AccessToken|string $accessToken The access token that will be logged out. - * @param string $next The url Facebook should redirect the user to after a successful logout. - * @param string $separator The separator to use in http_build_query(). - * - * @return string + * @param string $next The url Facebook should redirect the user to after a successful logout. + * @param string $separator The separator to use in http_build_query(). * * @throws FacebookSDKException */ - public function getLogoutUrl($accessToken, $next, $separator = '&') + public function getLogoutUrl(AccessToken|string $accessToken, string $next, string $separator = '&'): string { if (!$accessToken instanceof AccessToken) { $accessToken = new AccessToken($accessToken); @@ -164,7 +155,7 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') } $params = [ - 'next' => $next, + 'next' => $next, 'access_token' => $accessToken->getValue(), ]; @@ -175,12 +166,10 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') * Returns the URL to send the user in order to login to Facebook with permission(s) to be re-asked. * * @param string $redirectUrl The URL Facebook should redirect users to after login. - * @param array $scope List of permissions to request during login. - * @param string $separator The separator to use in http_build_query(). - * - * @return string + * @param array $scope List of permissions to request during login. + * @param string $separator The separator to use in http_build_query(). */ - public function getReRequestUrl($redirectUrl, array $scope = [], $separator = '&') + public function getReRequestUrl(string $redirectUrl, array $scope = [], string $separator = '&'): string { $params = ['auth_type' => 'rerequest']; @@ -191,12 +180,10 @@ public function getReRequestUrl($redirectUrl, array $scope = [], $separator = '& * Returns the URL to send the user in order to login to Facebook with user to be re-authenticated. * * @param string $redirectUrl The URL Facebook should redirect users to after login. - * @param array $scope List of permissions to request during login. - * @param string $separator The separator to use in http_build_query(). - * - * @return string + * @param array $scope List of permissions to request during login. + * @param string $separator The separator to use in http_build_query(). */ - public function getReAuthenticationUrl($redirectUrl, array $scope = [], $separator = '&') + public function getReAuthenticationUrl(string $redirectUrl, array $scope = [], string $separator = '&'): string { $params = ['auth_type' => 'reauthenticate']; @@ -212,7 +199,7 @@ public function getReAuthenticationUrl($redirectUrl, array $scope = [], $separat * * @throws FacebookSDKException */ - public function getAccessToken($redirectUrl = null) + public function getAccessToken(?string $redirectUrl = null): ?AccessToken { if (!$code = $this->getCode()) { return null; @@ -233,7 +220,7 @@ public function getAccessToken($redirectUrl = null) * * @throws FacebookSDKException */ - protected function validateCsrf() + protected function validateCsrf(): void { $state = $this->getState(); if (!$state) { @@ -244,7 +231,7 @@ protected function validateCsrf() throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing from persistent data.'); } - if (\hash_equals($savedState, $state)) { + if (hash_equals($savedState, $state)) { return; } @@ -254,67 +241,55 @@ protected function validateCsrf() /** * Resets the CSRF so that it doesn't get reused. */ - private function resetCsrf() + private function resetCsrf(): void { $this->persistentDataHandler->set('state', null); } /** * Return the code. - * - * @return string|null */ - protected function getCode() + protected function getCode(): ?string { return $this->getInput('code'); } /** * Return the state. - * - * @return string|null */ - protected function getState() + protected function getState(): ?string { return $this->getInput('state'); } /** * Return the error code. - * - * @return string|null */ - public function getErrorCode() + public function getErrorCode(): ?string { return $this->getInput('error_code'); } /** * Returns the error. - * - * @return string|null */ - public function getError() + public function getError(): ?string { return $this->getInput('error'); } /** * Returns the error reason. - * - * @return string|null */ - public function getErrorReason() + public function getErrorReason(): ?string { return $this->getInput('error_reason'); } /** * Returns the error description. - * - * @return string|null */ - public function getErrorDescription() + public function getErrorDescription(): ?string { return $this->getInput('error_description'); } @@ -323,11 +298,14 @@ public function getErrorDescription() * Returns a value from a GET param. * * @param string $key - * * @return string|null */ - private function getInput($key) + private function getInput(string $key): ?string { - return isset($_GET[$key]) ? $_GET[$key] : null; + $v = $_GET[$key] ?? null; + if (!is_string($v)) { + return null; + } + return $v; } } diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index 4044da1..bc443d2 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -23,6 +23,7 @@ */ namespace Facebook\Helpers; +use Facebook\Exceptions\FacebookSDKException; use Facebook\Facebook; use Facebook\FacebookApp; use Facebook\FacebookClient; @@ -40,17 +41,17 @@ abstract class FacebookSignedRequestFromInputHelper /** * @var SignedRequest|null The SignedRequest entity. */ - protected $signedRequest; + protected ?SignedRequest $signedRequest = null; /** * @var FacebookApp The FacebookApp entity. */ - protected $app; + protected FacebookApp $app; /** * @var OAuth2Client The OAuth 2.0 client service. */ - protected $oAuth2Client; + protected OAuth2Client $oAuth2Client; /** * Initialize the helper and process available signed request data. @@ -59,7 +60,7 @@ abstract class FacebookSignedRequestFromInputHelper * @param FacebookClient $client The client to make HTTP requests. * @param string|null $graphVersion The version of Graph to use. */ - public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) + public function __construct(FacebookApp $app, FacebookClient $client, ?string $graphVersion = null) { $this->app = $app; $graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; @@ -70,10 +71,8 @@ public function __construct(FacebookApp $app, FacebookClient $client, $graphVers /** * Instantiates a new SignedRequest entity. - * - * @param string|null */ - public function instantiateSignedRequest($rawSignedRequest = null) + public function instantiateSignedRequest(?string $rawSignedRequest = null): void { $rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); @@ -87,11 +86,9 @@ public function instantiateSignedRequest($rawSignedRequest = null) /** * Returns an AccessToken entity from the signed request. * - * @return AccessToken|null - * - * @throws \Facebook\Exceptions\FacebookSDKException + * @throws FacebookSDKException */ - public function getAccessToken() + public function getAccessToken(): ?AccessToken { if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { $code = $this->signedRequest->get('code'); @@ -111,37 +108,29 @@ public function getAccessToken() /** * Returns the SignedRequest entity. - * - * @return SignedRequest|null */ - public function getSignedRequest() + public function getSignedRequest(): ?SignedRequest { return $this->signedRequest; } /** * Returns the user_id if available. - * - * @return string|null */ - public function getUserId() + public function getUserId(): ?string { - return $this->signedRequest ? $this->signedRequest->getUserId() : null; + return $this->signedRequest?->getUserId(); } /** * Get raw signed request from input. - * - * @return string|null */ - abstract public function getRawSignedRequest(); + abstract public function getRawSignedRequest(): ?string; /** * Get raw signed request from POST input. - * - * @return string|null */ - public function getRawSignedRequestFromPost() + public function getRawSignedRequestFromPost(): ?string { if (isset($_POST['signed_request'])) { return $_POST['signed_request']; @@ -152,10 +141,8 @@ public function getRawSignedRequestFromPost() /** * Get raw signed request from cookie set from the Javascript SDK. - * - * @return string|null */ - public function getRawSignedRequestFromCookie() + public function getRawSignedRequestFromCookie(): ?string { if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { return $_COOKIE['fbsr_' . $this->app->getId()]; diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php index 44105c4..4fe08cd 100644 --- a/src/Facebook/Http/GraphRawResponse.php +++ b/src/Facebook/Http/GraphRawResponse.php @@ -33,30 +33,29 @@ class GraphRawResponse /** * @var array The response headers in the form of an associative array. */ - protected $headers; + protected array $headers; /** - * @var string The raw response body. + * @var string|null The raw response body. */ - protected $body; + protected ?string $body; /** - * @var int The HTTP status response code. + * @var int|null The HTTP status response code. */ - protected $httpResponseCode; + protected ?int $httpResponseCode; /** * Creates a new GraphRawResponse entity. * - * @param string|array $headers The headers as a raw string or array. - * @param string $body The raw response body. - * @param int $httpStatusCode The HTTP response code (if sending headers as parsed array). + * @param string|array $headers The headers as a raw string or array. + * @param string|null $body The raw response body. + * @param int|null $httpStatusCode The HTTP response code (if sending headers as parsed array). */ - public function __construct($headers, $body, $httpStatusCode = null) + public function __construct(array|string $headers, ?string $body, ?int $httpStatusCode = null) { - if (is_numeric($httpStatusCode)) { - $this->httpResponseCode = (int)$httpStatusCode; - } + + $this->httpResponseCode = $httpStatusCode; if (is_array($headers)) { $this->headers = $headers; @@ -72,41 +71,35 @@ public function __construct($headers, $body, $httpStatusCode = null) * * @return array */ - public function getHeaders() + public function getHeaders(): array { return $this->headers; } /** * Return the body of the response. - * - * @return string */ - public function getBody() + public function getBody(): ?string { return $this->body; } /** * Return the HTTP response code. - * - * @return int */ - public function getHttpResponseCode() + public function getHttpResponseCode(): ?int { return $this->httpResponseCode; } /** * Sets the HTTP response code from a raw header. - * - * @param string $rawResponseHeader */ - public function setHttpResponseCodeFromHeader($rawResponseHeader) + public function setHttpResponseCodeFromHeader(string $rawResponseHeader): void { // https://tools.ietf.org/html/rfc7230#section-3.1.2 list($version, $status, $reason) = array_pad(explode(' ', $rawResponseHeader, 3), 3, null); - $this->httpResponseCode = (int) $status; + $this->httpResponseCode = (int)$status; } /** @@ -114,7 +107,7 @@ public function setHttpResponseCodeFromHeader($rawResponseHeader) * * @param string $rawHeaders The raw headers from the response. */ - protected function setHeadersFromString($rawHeaders) + protected function setHeadersFromString(string $rawHeaders): void { // Normalize line breaks $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); @@ -127,7 +120,7 @@ protected function setHeadersFromString($rawHeaders) $headerComponents = explode("\n", $rawHeader); foreach ($headerComponents as $line) { - if (strpos($line, ': ') === false) { + if (!str_contains($line, ': ')) { $this->setHttpResponseCodeFromHeader($line); } else { list($key, $value) = explode(': ', $line, 2); diff --git a/src/Facebook/Http/RequestBodyInterface.php b/src/Facebook/Http/RequestBodyInterface.php index 1c03f4f..2b4d69d 100644 --- a/src/Facebook/Http/RequestBodyInterface.php +++ b/src/Facebook/Http/RequestBodyInterface.php @@ -32,8 +32,6 @@ interface RequestBodyInterface { /** * Get the body of the request to send to Graph. - * - * @return string */ - public function getBody(); + public function getBody(): string; } diff --git a/src/Facebook/Http/RequestBodyMultipart.php b/src/Facebook/Http/RequestBodyMultipart.php index ae9de41..b4c169e 100644 --- a/src/Facebook/Http/RequestBodyMultipart.php +++ b/src/Facebook/Http/RequestBodyMultipart.php @@ -39,24 +39,24 @@ class RequestBodyMultipart implements RequestBodyInterface /** * @var string The boundary. */ - private $boundary; + private string $boundary; /** * @var array The parameters to send with this request. */ - private $params; + private array $params; /** * @var array The files to send with this request. */ - private $files = []; + private array $files; /** - * @param array $params The parameters to send with this request. - * @param array $files The files to send with this request. - * @param string $boundary Provide a specific boundary. + * @param array $params The parameters to send with this request. + * @param array $files The files to send with this request. + * @param string|null $boundary Provide a specific boundary. */ - public function __construct(array $params = [], array $files = [], $boundary = null) + public function __construct(array $params = [], array $files = [], ?string $boundary = null) { $this->params = $params; $this->files = $files; @@ -66,7 +66,7 @@ public function __construct(array $params = [], array $files = [], $boundary = n /** * @inheritdoc */ - public function getBody() + public function getBody(): string { $body = ''; @@ -82,30 +82,23 @@ public function getBody() } // Peace out - $body .= "--{$this->boundary}--\r\n"; + $body .= "--$this->boundary--\r\n"; return $body; } /** * Get the boundary - * - * @return string */ - public function getBoundary() + public function getBoundary(): string { return $this->boundary; } /** * Get the string needed to transfer a file. - * - * @param string $name - * @param FacebookFile $file - * - * @return string */ - private function getFileString($name, FacebookFile $file) + private function getFileString(string $name, FacebookFile $file): string { return sprintf( "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n", @@ -119,13 +112,8 @@ private function getFileString($name, FacebookFile $file) /** * Get the string needed to transfer a POST field. - * - * @param string $name - * @param string $value - * - * @return string */ - private function getParamString($name, $value) + private function getParamString(string $name, string $value): string { return sprintf( "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", @@ -137,12 +125,8 @@ private function getParamString($name, $value) /** * Returns the params as an array of nested params. - * - * @param array $params - * - * @return array */ - private function getNestedParams(array $params) + private function getNestedParams(array $params): array { $query = http_build_query($params); $params = explode('&', $query); @@ -158,12 +142,8 @@ private function getNestedParams(array $params) /** * Get the headers needed before transferring the content of a POST file. - * - * @param FacebookFile $file - * - * @return string */ - protected function getFileHeaders(FacebookFile $file) + protected function getFileHeaders(FacebookFile $file): string { return "\r\nContent-Type: {$file->getMimetype()}"; } diff --git a/src/Facebook/Http/RequestBodyUrlEncoded.php b/src/Facebook/Http/RequestBodyUrlEncoded.php index 5fbe390..6004d5f 100644 --- a/src/Facebook/Http/RequestBodyUrlEncoded.php +++ b/src/Facebook/Http/RequestBodyUrlEncoded.php @@ -33,7 +33,7 @@ class RequestBodyUrlEncoded implements RequestBodyInterface /** * @var array The parameters to send with this request. */ - protected $params = []; + protected array $params = []; /** * Creates a new GraphUrlEncodedBody entity. @@ -48,7 +48,7 @@ public function __construct(array $params) /** * @inheritdoc */ - public function getBody() + public function getBody(): string { return http_build_query($this->params); } diff --git a/src/Facebook/HttpClients/FacebookCurl.php b/src/Facebook/HttpClients/FacebookCurl.php index 28e4ba5..6a1cdb5 100644 --- a/src/Facebook/HttpClients/FacebookCurl.php +++ b/src/Facebook/HttpClients/FacebookCurl.php @@ -48,63 +48,49 @@ public function init() /** * Set a curl option - * - * @param $key - * @param $value */ - public function setopt($key, $value) + public function setopt(int $key, mixed $value): void { curl_setopt($this->curl, $key, $value); } /** * Set an array of options to a curl resource - * - * @param array $options */ - public function setoptArray(array $options) + public function setoptArray(array $options): void { curl_setopt_array($this->curl, $options); } /** * Send a curl request - * - * @return mixed */ - public function exec() + public function exec(): bool|string { return curl_exec($this->curl); } /** * Return the curl error number - * - * @return int */ - public function errno() + public function errno(): ?int { + // For some reason, adding int type to return here causes the mock testing framework to not work and return null. return curl_errno($this->curl); } /** * Return the curl error message - * - * @return string */ - public function error() + public function error(): string { return curl_error($this->curl); } /** * Get info from a curl reference - * - * @param $type - * - * @return mixed */ - public function getinfo($type) + public function getinfo(?int $type): mixed { return curl_getinfo($this->curl, $type); } @@ -112,9 +98,9 @@ public function getinfo($type) /** * Get the currently installed curl version * - * @return array + * @return array|false */ - public function version() + public function version(): array|false { return curl_version(); } @@ -122,7 +108,7 @@ public function version() /** * Close the resource connection to curl */ - public function close() + public function close(): void { curl_close($this->curl); } diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 9516cc8..54bdc8e 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -33,30 +33,21 @@ */ class FacebookCurlHttpClient implements FacebookHttpClientInterface { - /** - * @var string The client error message - */ - protected $curlErrorMessage = ''; - - /** - * @var int The curl client error code - */ - protected $curlErrorCode = 0; /** * @var string|boolean The raw response from the server */ - protected $rawResponse; + protected string|bool $rawResponse; /** * @var FacebookCurl Procedural curl as object */ - protected $facebookCurl; + protected FacebookCurl $facebookCurl; /** - * @param FacebookCurl|null Procedural curl as object + * @param FacebookCurl|null $facebookCurl Procedural curl as object */ - public function __construct(FacebookCurl $facebookCurl = null) + public function __construct(?FacebookCurl $facebookCurl = null) { $this->facebookCurl = $facebookCurl ?: new FacebookCurl(); } @@ -64,7 +55,7 @@ public function __construct(FacebookCurl $facebookCurl = null) /** * @inheritdoc */ - public function send($url, $method, $body, array $headers, $timeOut) + public function send(string $url, string $method, ?string $body, array $headers, int $timeOut): GraphRawResponse { $this->openConnection($url, $method, $body, $headers, $timeOut); $this->sendRequest(); @@ -84,13 +75,13 @@ public function send($url, $method, $body, array $headers, $timeOut) /** * Opens a new curl connection. * - * @param string $url The endpoint to send the request to. - * @param string $method The request method. - * @param string $body The body of the request. - * @param array $headers The request headers. - * @param int $timeOut The timeout in seconds for the request. + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param string|null $body The body of the request. + * @param array $headers The request headers. + * @param int $timeOut The timeout in seconds for the request. */ - public function openConnection($url, $method, $body, array $headers, $timeOut) + public function openConnection(string $url, string $method, ?string $body, array $headers, int $timeOut) { $options = [ CURLOPT_CUSTOMREQUEST => $method, @@ -105,7 +96,7 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ]; - if ($method !== "GET") { + if ($method !== "GET" && $body) { $options[CURLOPT_POSTFIELDS] = $body; } @@ -116,7 +107,7 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) /** * Closes an existing curl connection */ - public function closeConnection() + public function closeConnection(): void { $this->facebookCurl->close(); } @@ -124,7 +115,7 @@ public function closeConnection() /** * Send the request and get the raw response from curl */ - public function sendRequest() + public function sendRequest(): void { $this->rawResponse = $this->facebookCurl->exec(); } @@ -136,7 +127,7 @@ public function sendRequest() * * @return array */ - public function compileRequestHeaders(array $headers) + public function compileRequestHeaders(array $headers): array { $return = []; @@ -152,7 +143,7 @@ public function compileRequestHeaders(array $headers) * * @return array */ - public function extractResponseHeadersAndBody() + public function extractResponseHeadersAndBody(): array { $parts = explode("\r\n\r\n", $this->rawResponse); $rawBody = array_pop($parts); diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index f96a9bb..527876b 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -36,12 +36,12 @@ class FacebookGuzzleHttpClient implements FacebookHttpClientInterface /** * @var Client The Guzzle client. */ - protected $guzzleClient; + protected Client $guzzleClient; /** * @param Client|null $guzzleClient The Guzzle client. */ - public function __construct(Client $guzzleClient = null) + public function __construct(?Client $guzzleClient = null) { $this->guzzleClient = $guzzleClient ?: new Client(); } @@ -49,17 +49,20 @@ public function __construct(Client $guzzleClient = null) /** * @inheritdoc */ - public function send($url, $method, $body, array $headers, $timeOut) + public function send(string $url, string $method, ?string $body, array $headers, int $timeOut): GraphRawResponse { $options = [ 'headers' => $headers, - 'body' => $body, 'timeout' => $timeOut, 'http_errors' => false, 'connect_timeout' => 10, 'verify' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ]; + if ($body) { + $options['body'] = $body; + } + try { $rawResponse = $this->guzzleClient->request($method, $url, $options); @@ -80,10 +83,8 @@ public function send($url, $method, $body, array $headers, $timeOut) * Returns the Guzzle array of headers as a string. * * @param ResponseInterface $response The Guzzle response. - * - * @return string */ - public function getHeadersAsString(ResponseInterface $response) + public function getHeadersAsString(ResponseInterface $response): string { $headers = $response->getHeaders(); $rawHeaders = []; diff --git a/src/Facebook/HttpClients/FacebookHttpClientInterface.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php index 1fbf953..9bdb6cf 100644 --- a/src/Facebook/HttpClients/FacebookHttpClientInterface.php +++ b/src/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -21,8 +21,12 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\HttpClients; +use Facebook\Exceptions\FacebookSDKException; +use Facebook\Http\GraphRawResponse; + /** * Interface FacebookHttpClientInterface * @@ -33,15 +37,15 @@ interface FacebookHttpClientInterface /** * Sends a request to the server and returns the raw response. * - * @param string $url The endpoint to send the request to. - * @param string $method The request method. - * @param string $body The body of the request. - * @param array $headers The request headers. - * @param int $timeOut The timeout in seconds for the request. + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param string|null $body The body of the request. + * @param array $headers The request headers. + * @param int $timeOut The timeout in seconds for the request. * - * @return \Facebook\Http\GraphRawResponse Raw response from the server. + * @return GraphRawResponse Raw response from the server. * - * @throws \Facebook\Exceptions\FacebookSDKException + * @throws FacebookSDKException */ - public function send($url, $method, $body, array $headers, $timeOut); + public function send(string $url, string $method, ?string $body, array $headers, int $timeOut): GraphRawResponse; } diff --git a/src/Facebook/HttpClients/FacebookStream.php b/src/Facebook/HttpClients/FacebookStream.php index 3f39988..37f04eb 100644 --- a/src/Facebook/HttpClients/FacebookStream.php +++ b/src/Facebook/HttpClients/FacebookStream.php @@ -41,24 +41,22 @@ class FacebookStream /** * @var array Response headers from the stream wrapper */ - protected $responseHeaders = []; + protected array $responseHeaders = []; /** * Make a new context stream reference instance - * - * @param array $options */ - public function streamContextCreate(array $options) + public function streamContextCreate(array $options): void { $this->stream = stream_context_create($options); } /** * The response headers from the stream wrapper - * - * @return array + * For some reason, this must be nullable or it fails when mocked in test. + * This array is never null. */ - public function getResponseHeaders() + public function getResponseHeaders(): ?array { return $this->responseHeaders; } @@ -68,9 +66,9 @@ public function getResponseHeaders() * * @param string $url * - * @return mixed + * @return string|false */ - public function fileGetContents($url) + public function fileGetContents(string $url): string|false { $rawResponse = file_get_contents($url, false, $this->stream); $this->responseHeaders = $http_response_header ?: []; diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index 1cdfd53..be38599 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -31,12 +31,12 @@ class FacebookStreamHttpClient implements FacebookHttpClientInterface /** * @var FacebookStream Procedural stream wrapper as object. */ - protected $facebookStream; + protected FacebookStream $facebookStream; /** - * @param FacebookStream|null Procedural stream wrapper as object. + * @param FacebookStream|null $facebookStream Procedural stream wrapper as object. */ - public function __construct(FacebookStream $facebookStream = null) + public function __construct(?FacebookStream $facebookStream = null) { $this->facebookStream = $facebookStream ?: new FacebookStream(); } @@ -44,7 +44,7 @@ public function __construct(FacebookStream $facebookStream = null) /** * @inheritdoc */ - public function send($url, $method, $body, array $headers, $timeOut) + public function send(string $url, string $method, ?string $body, array $headers, int $timeOut): GraphRawResponse { $options = [ 'http' => [ @@ -77,12 +77,8 @@ public function send($url, $method, $body, array $headers, $timeOut) /** * Formats the headers for use in the stream wrapper. - * - * @param array $headers The request headers. - * - * @return string */ - public function compileHeader(array $headers) + public function compileHeader(array $headers): string { $header = []; foreach ($headers as $k => $v) { diff --git a/src/Facebook/HttpClients/HttpClientsFactory.php b/src/Facebook/HttpClients/HttpClientsFactory.php index 84b55b8..08ed3e3 100644 --- a/src/Facebook/HttpClients/HttpClientsFactory.php +++ b/src/Facebook/HttpClients/HttpClientsFactory.php @@ -37,16 +37,16 @@ private function __construct() /** * HTTP client generation. * - * @param FacebookHttpClientInterface|Client|string|null $handler + * @param FacebookHttpClientInterface|Client|string|null $handler - mixed type since we don't know if Guzzle is installed. * * @throws Exception If the cURL extension or the Guzzle client aren't available (if required). * @throws InvalidArgumentException If the http client handler isn't "curl", "stream", "guzzle", or an instance of Facebook\HttpClients\FacebookHttpClientInterface. * * @return FacebookHttpClientInterface */ - public static function createHttpClient($handler) + public static function createHttpClient(mixed $handler): FacebookHttpClientInterface { - if (!$handler) { + if ($handler === null) { return self::detectDefaultClient(); } @@ -81,10 +81,8 @@ public static function createHttpClient($handler) /** * Detect default HTTP client. - * - * @return FacebookHttpClientInterface */ - private static function detectDefaultClient() + private static function detectDefaultClient(): FacebookHttpClientInterface { if (class_exists('GuzzleHttp\Client')) { diff --git a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php index 4b7c87e..ab341e7 100644 --- a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php @@ -33,20 +33,20 @@ class FacebookMemoryPersistentDataHandler implements PersistentDataInterface /** * @var array The session data to keep in memory. */ - protected $sessionData = []; + protected array $sessionData = []; /** * @inheritdoc */ - public function get($key) + public function get(mixed $key): mixed { - return isset($this->sessionData[$key]) ? $this->sessionData[$key] : null; + return $this->sessionData[$key] ?? null; } /** * @inheritdoc */ - public function set($key, $value) + public function set(mixed $key, mixed $value): void { $this->sessionData[$key] = $value; } diff --git a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php index 9123e3d..d0ade5c 100644 --- a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\PersistentData; use Facebook\Exceptions\FacebookSDKException; @@ -35,16 +36,14 @@ class FacebookSessionPersistentDataHandler implements PersistentDataInterface /** * @var string Prefix to use for session variables. */ - protected $sessionPrefix = 'FBRLH_'; + protected string $sessionPrefix = 'FBRLH_'; /** * Init the session handler. * - * @param boolean $enableSessionCheck - * * @throws FacebookSDKException */ - public function __construct($enableSessionCheck = true) + public function __construct(bool $enableSessionCheck = true) { if ($enableSessionCheck && session_status() !== PHP_SESSION_ACTIVE) { throw new FacebookSDKException( @@ -57,7 +56,7 @@ public function __construct($enableSessionCheck = true) /** * @inheritdoc */ - public function get($key) + public function get(mixed $key): mixed { if (isset($_SESSION[$this->sessionPrefix . $key])) { return $_SESSION[$this->sessionPrefix . $key]; @@ -69,7 +68,7 @@ public function get($key) /** * @inheritdoc */ - public function set($key, $value) + public function set(mixed $key, mixed $value): void { $_SESSION[$this->sessionPrefix . $key] = $value; } diff --git a/src/Facebook/PersistentData/PersistentDataFactory.php b/src/Facebook/PersistentData/PersistentDataFactory.php index 18fb8fd..72678af 100644 --- a/src/Facebook/PersistentData/PersistentDataFactory.php +++ b/src/Facebook/PersistentData/PersistentDataFactory.php @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\PersistentData; use InvalidArgumentException; @@ -37,11 +38,11 @@ private function __construct() * * @param PersistentDataInterface|string|null $handler * + * @return PersistentDataInterface * @throws InvalidArgumentException If the persistent data handler isn't "session", "memory", or an instance of Facebook\PersistentData\PersistentDataInterface. * - * @return PersistentDataInterface */ - public static function createPersistentDataHandler($handler) + public static function createPersistentDataHandler(PersistentDataInterface|string|null $handler): PersistentDataInterface { if (!$handler) { return session_status() === PHP_SESSION_ACTIVE diff --git a/src/Facebook/PersistentData/PersistentDataInterface.php b/src/Facebook/PersistentData/PersistentDataInterface.php index 3517ee1..6e5c2ea 100644 --- a/src/Facebook/PersistentData/PersistentDataInterface.php +++ b/src/Facebook/PersistentData/PersistentDataInterface.php @@ -37,7 +37,7 @@ interface PersistentDataInterface * * @return mixed */ - public function get($key); + public function get(mixed $key): mixed; /** * Set a value in the persistent data store. @@ -45,5 +45,5 @@ public function get($key); * @param string $key * @param mixed $value */ - public function set($key, $value); + public function set(mixed $key, mixed $value): void; } diff --git a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php deleted file mode 100644 index bf57374..0000000 --- a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php +++ /dev/null @@ -1,68 +0,0 @@ -validateLength($length); - - $binaryString = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); - - if ($binaryString === false) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'mcrypt_create_iv() returned an error.' - ); - } - - return $this->binToHex($binaryString, $length); - } -} diff --git a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php index 4b4276d..4b76b75 100644 --- a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php @@ -32,7 +32,7 @@ class OpenSslPseudoRandomStringGenerator implements PseudoRandomStringGeneratorI /** * @const string The error message when generating the string fails. */ - const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from openssl_random_pseudo_bytes().'; + private const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from openssl_random_pseudo_bytes(): '; /** * @throws FacebookSDKException @@ -46,19 +46,19 @@ public function __construct() /** * @inheritdoc + * @throws FacebookSDKException */ - public function getPseudoRandomString($length) + public function getPseudoRandomString(int $length): string { - $this->validateLength($length); $wasCryptographicallyStrong = false; $binaryString = openssl_random_pseudo_bytes($length, $wasCryptographicallyStrong); - if ($binaryString === false) { + if (!$binaryString) { throw new FacebookSDKException(static::ERROR_MESSAGE . 'openssl_random_pseudo_bytes() returned an unknown error.'); } - if ($wasCryptographicallyStrong !== true) { + if (!$wasCryptographicallyStrong) { throw new FacebookSDKException(static::ERROR_MESSAGE . 'openssl_random_pseudo_bytes() returned a pseudo-random string but it was not cryptographically secure and cannot be used.'); } diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php index 412f481..7b1598a 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php @@ -21,9 +21,9 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\PseudoRandomString; -use Facebook\Exceptions\FacebookSDKException; use InvalidArgumentException; class PseudoRandomStringGeneratorFactory @@ -36,13 +36,10 @@ private function __construct() /** * Pseudo random string generator creation. * - * @param PseudoRandomStringGeneratorInterface|string|null $generator - * - * @throws InvalidArgumentException If the pseudo random string generator must be set to "random_bytes", "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface. - * - * @return PseudoRandomStringGeneratorInterface + * @param string|PseudoRandomStringGeneratorInterface|null $generator The pseudo random string generator must be set to "random_bytes", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface. + * @throws InvalidArgumentException */ - public static function createPseudoRandomStringGenerator($generator) + public static function createPseudoRandomStringGenerator(string|null|PseudoRandomStringGeneratorInterface $generator): PseudoRandomStringGeneratorInterface { if (!$generator) { return self::detectDefaultPseudoRandomStringGenerator(); @@ -55,9 +52,6 @@ public static function createPseudoRandomStringGenerator($generator) if ('random_bytes' === $generator) { return new RandomBytesPseudoRandomStringGenerator(); } - if ('mcrypt' === $generator) { - return new McryptPseudoRandomStringGenerator(); - } if ('openssl' === $generator) { return new OpenSslPseudoRandomStringGenerator(); } @@ -65,29 +59,23 @@ public static function createPseudoRandomStringGenerator($generator) return new UrandomPseudoRandomStringGenerator(); } - throw new InvalidArgumentException('The pseudo random string generator must be set to "random_bytes", "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface'); + throw new InvalidArgumentException('The pseudo random string generator must be set to "random_bytes", "openssl", "urandom" or be an instance of ' . PseudoRandomStringGeneratorInterface::class); } /** * Detects which pseudo-random string generator to use. * - * @throws FacebookSDKException If unable to detect a cryptographically secure pseudo-random string generator. - * * @return PseudoRandomStringGeneratorInterface + * @throws InvalidArgumentException If unable to detect a cryptographically secure pseudo-random string generator. + * */ - private static function detectDefaultPseudoRandomStringGenerator() + private static function detectDefaultPseudoRandomStringGenerator(): PseudoRandomStringGeneratorInterface { // Check for PHP 7's CSPRNG first to keep mcrypt deprecation messages from appearing in PHP 7.1. if (function_exists('random_bytes')) { return new RandomBytesPseudoRandomStringGenerator(); } - // Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically - // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() next. - if (function_exists('mcrypt_create_iv')) { - return new McryptPseudoRandomStringGenerator(); - } - if (function_exists('openssl_random_pseudo_bytes')) { return new OpenSslPseudoRandomStringGenerator(); } @@ -96,6 +84,6 @@ private static function detectDefaultPseudoRandomStringGenerator() return new UrandomPseudoRandomStringGenerator(); } - throw new FacebookSDKException('Unable to detect a cryptographically secure pseudo-random string generator.'); + throw new InvalidArgumentException('Unable to detect a cryptographically secure pseudo-random string generator.'); } } diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php index 914ee3c..7ab7cb8 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php @@ -23,6 +23,8 @@ */ namespace Facebook\PseudoRandomString; +use InvalidArgumentException; + /** * Interface * @@ -39,7 +41,7 @@ interface PseudoRandomStringGeneratorInterface * * @return string * - * @throws \Facebook\Exceptions\FacebookSDKException|\InvalidArgumentException + * @throws InvalidArgumentException */ - public function getPseudoRandomString($length); + public function getPseudoRandomString(int $length): string; } diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index 0f587ea..dc81b7a 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -21,38 +21,24 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\PseudoRandomString; +use function bin2hex; +use function substr; + trait PseudoRandomStringGeneratorTrait { - /** - * Validates the length argument of a random string. - * - * @param int $length The length to validate. - * - * @throws \InvalidArgumentException - */ - public function validateLength($length) - { - if (!is_int($length)) { - throw new \InvalidArgumentException('getPseudoRandomString() expects an integer for the string length'); - } - - if ($length < 1) { - throw new \InvalidArgumentException('getPseudoRandomString() expects a length greater than 1'); - } - } - /** * Converts binary data to hexadecimal of arbitrary length. * * @param string $binaryData The binary data to convert to hex. - * @param int $length The length of the string to return. + * @param int $length The length of the string to return. * * @return string */ - public function binToHex($binaryData, $length) + public function binToHex(string $binaryData, int $length): string { - return \substr(\bin2hex($binaryData), 0, $length); + return substr(bin2hex($binaryData), 0, $length); } } diff --git a/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php index b5943f6..0fdfe89 100644 --- a/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php @@ -32,7 +32,7 @@ class RandomBytesPseudoRandomStringGenerator implements PseudoRandomStringGenera /** * @const string The error message when generating the string fails. */ - const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from random_bytes(). '; + const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from random_bytes(): '; /** * @throws FacebookSDKException @@ -50,9 +50,8 @@ public function __construct() /** * @inheritdoc */ - public function getPseudoRandomString($length) + public function getPseudoRandomString(int $length): string { - $this->validateLength($length); return $this->binToHex(random_bytes($length), $length); } diff --git a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php index 5ab434e..381690f 100644 --- a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php @@ -33,7 +33,7 @@ class UrandomPseudoRandomStringGenerator implements PseudoRandomStringGeneratorI /** * @const string The error message when generating the string fails. */ - const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from /dev/urandom. '; + const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from /dev/urandom: '; /** * @throws FacebookSDKException @@ -57,10 +57,10 @@ public function __construct() /** * @inheritdoc + * @throws FacebookSDKException */ - public function getPseudoRandomString($length) + public function getPseudoRandomString(int $length): string { - $this->validateLength($length); $stream = fopen('/dev/urandom', 'rb'); if (!is_resource($stream)) { diff --git a/src/Facebook/SignedRequest.php b/src/Facebook/SignedRequest.php index 6a175a0..ea61334 100644 --- a/src/Facebook/SignedRequest.php +++ b/src/Facebook/SignedRequest.php @@ -21,9 +21,11 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook; use Facebook\Exceptions\FacebookSDKException; +use function hash_equals; /** * Class SignedRequest @@ -35,27 +37,28 @@ class SignedRequest /** * @var FacebookApp The FacebookApp entity. */ - protected $app; + protected FacebookApp $app; /** - * @var string The raw encrypted signed request. + * @var string|null The raw encrypted signed request. */ - protected $rawSignedRequest; + protected ?string $rawSignedRequest; /** - * @var array The payload from the decrypted signed request. + * @var array|null The payload from the decrypted signed request. */ - protected $payload; + protected ?array $payload; /** * Instantiate a new SignedRequest entity. * - * @param FacebookApp $facebookApp The FacebookApp entity. + * @param FacebookApp $facebookApp The FacebookApp entity. * @param string|null $rawSignedRequest The raw signed request. */ - public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null) + public function __construct(FacebookApp $facebookApp, ?string $rawSignedRequest = null) { $this->app = $facebookApp; + $this->payload = null; if (!$rawSignedRequest) { return; @@ -68,33 +71,24 @@ public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null) /** * Returns the raw signed request data. - * - * @return string|null */ - public function getRawSignedRequest() + public function getRawSignedRequest(): ?string { return $this->rawSignedRequest; } /** * Returns the parsed signed request data. - * - * @return array|null */ - public function getPayload() + public function getPayload(): ?array { return $this->payload; } /** * Returns a property from the signed request data if available. - * - * @param string $key - * @param mixed|null $default - * - * @return mixed|null */ - public function get($key, $default = null) + public function get(string $key, mixed $default = null): mixed { if (isset($this->payload[$key])) { return $this->payload[$key]; @@ -105,35 +99,27 @@ public function get($key, $default = null) /** * Returns user_id from signed request data if available. - * - * @return string|null */ - public function getUserId() + public function getUserId(): ?string { return $this->get('user_id'); } /** * Checks for OAuth data in the payload. - * - * @return boolean */ - public function hasOAuthData() + public function hasOAuthData(): bool { return $this->get('oauth_token') || $this->get('code'); } /** * Creates a signed request from an array of data. - * - * @param array $payload - * - * @return string */ - public function make(array $payload) + public function make(array $payload): string { - $payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-SHA256'; - $payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time(); + $payload['algorithm'] = $payload['algorithm'] ?? 'HMAC-SHA256'; + $payload['issued_at'] = $payload['issued_at'] ?? time(); $encodedPayload = $this->base64UrlEncode(json_encode($payload)); $hashedSig = $this->hashSignature($encodedPayload); @@ -146,7 +132,7 @@ public function make(array $payload) * Validates and decodes a signed request and saves * the payload to an array. */ - protected function parse() + protected function parse(): void { list($encodedSig, $encodedPayload) = $this->split(); @@ -164,13 +150,11 @@ protected function parse() /** * Splits a raw signed request into signature and payload. * - * @return array - * * @throws FacebookSDKException */ - protected function split() + protected function split(): array { - if (strpos($this->rawSignedRequest, '.') === false) { + if (!str_contains($this->rawSignedRequest, '.')) { throw new FacebookSDKException('Malformed signed request.', 606); } @@ -180,13 +164,9 @@ protected function split() /** * Decodes the raw signature from a signed request. * - * @param string $encodedSig - * - * @return string - * * @throws FacebookSDKException */ - protected function decodeSignature($encodedSig) + protected function decodeSignature(string $encodedSig): string { $sig = $this->base64UrlDecode($encodedSig); @@ -200,13 +180,9 @@ protected function decodeSignature($encodedSig) /** * Decodes the raw payload from a signed request. * - * @param string $encodedPayload - * - * @return array - * * @throws FacebookSDKException */ - protected function decodePayload($encodedPayload) + protected function decodePayload(string $encodedPayload): array { $payload = $this->base64UrlDecode($encodedPayload); @@ -226,7 +202,7 @@ protected function decodePayload($encodedPayload) * * @throws FacebookSDKException */ - protected function validateAlgorithm() + protected function validateAlgorithm(): void { if ($this->get('algorithm') !== 'HMAC-SHA256') { throw new FacebookSDKException('Signed request is using the wrong algorithm.', 605); @@ -236,19 +212,15 @@ protected function validateAlgorithm() /** * Hashes the signature used in a signed request. * - * @param string $encodedData - * - * @return string - * * @throws FacebookSDKException */ - protected function hashSignature($encodedData) + protected function hashSignature(string $encodedData): string { $hashedSig = hash_hmac( 'sha256', $encodedData, $this->app->getSecret(), - $raw_output = true + true ); if (!$hashedSig) { @@ -261,14 +233,11 @@ protected function hashSignature($encodedData) /** * Validates the signature used in a signed request. * - * @param string $hashedSig - * @param string $sig - * * @throws FacebookSDKException */ - protected function validateSignature($hashedSig, $sig) + protected function validateSignature(string $hashedSig, string $sig): void { - if (\hash_equals($hashedSig, $sig)) { + if (hash_equals($hashedSig, $sig)) { return; } @@ -281,12 +250,9 @@ protected function validateSignature($hashedSig, $sig) * / instead of _ * * @link http://en.wikipedia.org/wiki/Base64#URL_applications - * - * @param string $input base64 url encoded input - * - * @return string decoded string + * @throws FacebookSDKException */ - public function base64UrlDecode($input) + public function base64UrlDecode(string $input): string { $urlDecodedBase64 = strtr($input, '-_', '+/'); $this->validateBase64($urlDecodedBase64); @@ -300,12 +266,8 @@ public function base64UrlDecode($input) * / instead of _ * * @link http://en.wikipedia.org/wiki/Base64#URL_applications - * - * @param string $input string to encode - * - * @return string base64 url encoded input */ - public function base64UrlEncode($input) + public function base64UrlEncode(string $input): string { return strtr(base64_encode($input), '+/', '-_'); } @@ -313,11 +275,9 @@ public function base64UrlEncode($input) /** * Validates a base64 string. * - * @param string $input base64 value to validate - * * @throws FacebookSDKException */ - protected function validateBase64($input) + protected function validateBase64(string $input): void { if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $input)) { throw new FacebookSDKException('Signed request contains malformed base64 encoding.', 608); diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index 1d134dd..acb4b43 100644 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -33,27 +33,23 @@ class FacebookUrlDetectionHandler implements UrlDetectionInterface /** * @inheritdoc */ - public function getCurrentUrl() + public function getCurrentUrl(): string { return $this->getHttpScheme() . '://' . $this->getHostName() . $this->getServerVar('REQUEST_URI'); } /** * Get the currently active URL scheme. - * - * @return string */ - protected function getHttpScheme() + protected function getHttpScheme(): string { return $this->isBehindSsl() ? 'https' : 'http'; } /** * Tries to detect if the server is running behind an SSL. - * - * @return boolean */ - protected function isBehindSsl() + protected function isBehindSsl(): bool { // Check for proxy first $protocol = $this->getHeader('X_FORWARDED_PROTO'); @@ -66,7 +62,7 @@ protected function isBehindSsl() return $this->protocolWithActiveSsl($protocol); } - return (string)$this->getServerVar('SERVER_PORT') === '443'; + return $this->getCurrentPort() === '443'; } /** @@ -76,11 +72,10 @@ protected function isBehindSsl() * * @return boolean */ - protected function protocolWithActiveSsl($protocol) + protected function protocolWithActiveSsl(string $protocol): bool { - $protocol = strtolower((string)$protocol); - return in_array($protocol, ['on', '1', 'https', 'ssl'], true); + return in_array(strtolower($protocol), ['on', '1', 'https', 'ssl'], true); } /** @@ -89,10 +84,8 @@ protected function protocolWithActiveSsl($protocol) * Some elements adapted from * * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php - * - * @return string */ - protected function getHostName() + protected function getHostName(): string { // Check for proxy first $header = $this->getHeader('X_FORWARDED_HOST'); @@ -122,16 +115,14 @@ protected function getHostName() return $host . $appendPort; } - protected function getCurrentPort() + protected function getCurrentPort(): string { // Check for proxy first - $port = $this->getHeader('X_FORWARDED_PORT'); - if ($port) { - return (string)$port; + if ($port = $this->getHeader('X_FORWARDED_PORT')) { + return $port; } - $protocol = (string)$this->getHeader('X_FORWARDED_PROTO'); - if ($protocol === 'https') { + if ($this->getHeader('X_FORWARDED_PROTO') === 'https') { return '443'; } @@ -140,24 +131,16 @@ protected function getCurrentPort() /** * Returns the a value from the $_SERVER super global. - * - * @param string $key - * - * @return string */ - protected function getServerVar($key) + protected function getServerVar(string $key): mixed { - return isset($_SERVER[$key]) ? $_SERVER[$key] : ''; + return $_SERVER[$key] ?? ''; } /** * Gets a value from the HTTP request headers. - * - * @param string $key - * - * @return string */ - protected function getHeader($key) + protected function getHeader(string $key): string { return $this->getServerVar('HTTP_' . $key); } @@ -165,18 +148,14 @@ protected function getHeader($key) /** * Checks if the value in X_FORWARDED_HOST is a valid hostname * Could prevent unintended redirections - * - * @param string $header - * - * @return boolean */ - protected function isValidForwardedHost($header) + protected function isValidForwardedHost(string $header): bool { $elements = explode(',', $header); $host = $elements[count($elements) - 1]; return preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $host) //valid chars check && 0 < strlen($host) && strlen($host) < 254 //overall length check - && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $host); //length of each label + && preg_match("/^[^.]{1,63}(\.[^.]{1,63})*$/", $host); //length of each label } } diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index 0c8cca9..3929d37 100644 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -33,12 +33,12 @@ class FacebookUrlManipulator /** * Remove params from a URL. * - * @param string $url The URL to filter. - * @param array $paramsToFilter The params to filter from the URL. + * @param string|null $url The URL to filter. + * @param array $paramsToFilter The params to filter from the URL. * * @return string The URL with the params removed. */ - public static function removeParamsFromUrl($url, array $paramsToFilter) + public static function removeParamsFromUrl(?string $url, array $paramsToFilter): string { if (!is_string($url)) { return ''; @@ -62,9 +62,9 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) } $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; - $host = isset($parts['host']) ? $parts['host'] : ''; + $host = $parts['host'] ?? ''; $port = isset($parts['port']) ? ':' . $parts['port'] : ''; - $path = isset($parts['path']) ? $parts['path'] : ''; + $path = $parts['path'] ?? ''; $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; return $scheme . $host . $port . $path . $query . $fragment; @@ -75,16 +75,14 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) * * @param string $url The URL that will receive the params. * @param array $newParams The params to append to the URL. - * - * @return string */ - public static function appendParamsToUrl($url, array $newParams = []) + public static function appendParamsToUrl(string $url, array $newParams = []): string { if (empty($newParams)) { return $url; } - if (strpos($url, '?') === false) { + if (!str_contains($url, '?')) { return $url . '?' . http_build_query($newParams); } @@ -104,11 +102,11 @@ public static function appendParamsToUrl($url, array $newParams = []) /** * Returns the params from a URL in the form of an array. * - * @param string $url The URL to parse the params from. + * @param string|null $url The URL to parse the params from. * * @return array */ - public static function getParamsAsArray($url) + public static function getParamsAsArray(?string $url): array { if (!is_string($url)) { return []; @@ -133,7 +131,7 @@ public static function getParamsAsArray($url) * * @return string The $urlToAddTo with any new params from $urlToStealFrom. */ - public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) + public static function mergeUrlParams(string $urlToStealFrom, string $urlToAddTo): string { $newParams = static::getParamsAsArray($urlToStealFrom); // Nothing new to add, return as-is @@ -146,18 +144,14 @@ public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) /** * Check for a "/" prefix and prepend it if not exists. - * - * @param string|null $string - * - * @return string|null */ - public static function forceSlashPrefix($string) + public static function forceSlashPrefix(?string $string): ?string { if (!$string) { return $string; } - return strpos($string, '/') === 0 ? $string : '/' . $string; + return str_starts_with($string, '/') ? $string : '/' . $string; } /** @@ -167,7 +161,7 @@ public static function forceSlashPrefix($string) * * @return string The $urlToTrim with the hostname and Graph version removed. */ - public static function baseGraphUrlEndpoint($urlToTrim) + public static function baseGraphUrlEndpoint(string $urlToTrim): string { return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); } diff --git a/src/Facebook/Url/UrlDetectionInterface.php b/src/Facebook/Url/UrlDetectionInterface.php index dca38a0..e2081bb 100644 --- a/src/Facebook/Url/UrlDetectionInterface.php +++ b/src/Facebook/Url/UrlDetectionInterface.php @@ -35,5 +35,5 @@ interface UrlDetectionInterface * * @return string */ - public function getCurrentUrl(); + public function getCurrentUrl(): string; } diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php deleted file mode 100644 index e0dd21c..0000000 --- a/src/Facebook/autoload.php +++ /dev/null @@ -1,81 +0,0 @@ - [ 'app_id' => '123', 'application' => 'Foo App', @@ -60,8 +61,8 @@ public function testDatesGetCastToDateTime(): void $expires = $metadata->getExpiresAt(); $issuedAt = $metadata->getIssuedAt(); - $this->assertInstanceOf('DateTime', $expires); - $this->assertInstanceOf('DateTime', $issuedAt); + $this->assertInstanceOf(DateTime::class, $expires); + $this->assertInstanceOf(DateTime::class, $issuedAt); } public function testAllTheGettersReturnTheProperValue(): void @@ -129,7 +130,7 @@ public function testAnActiveAccessTokenWillNotThrow(): void public function testAnExpiredAccessTokenWillThrow(): void { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); + $this->expectException(FacebookSDKException::class); $this->graphResponseData['data']['expires_at'] = time() - 1000; $metadata = new AccessTokenMetadata($this->graphResponseData); diff --git a/tests/Authentication/FooFacebookClientForOAuth2Test.php b/tests/Authentication/FooFacebookClientForOAuth2Test.php index 8c59ae1..09174fd 100644 --- a/tests/Authentication/FooFacebookClientForOAuth2Test.php +++ b/tests/Authentication/FooFacebookClientForOAuth2Test.php @@ -29,24 +29,24 @@ class FooFacebookClientForOAuth2Test extends FacebookClient { - protected $response = ''; + protected string $response = ''; - public function setMetadataResponse() + public function setMetadataResponse(): void { $this->response = '{"data":{"user_id":"444"}}'; } - public function setAccessTokenResponse() + public function setAccessTokenResponse(): void { $this->response = '{"access_token":"my_access_token","expires":"1422115200"}'; } - public function setCodeResponse() + public function setCodeResponse(): void { $this->response = '{"code":"my_neat_code"}'; } - public function sendRequest(FacebookRequest $request) + public function sendRequest(FacebookRequest $request): FacebookResponse { return new FacebookResponse( $request, diff --git a/tests/Authentication/OAuth2ClientTest.php b/tests/Authentication/OAuth2ClientTest.php index cb7ef38..b592fa6 100644 --- a/tests/Authentication/OAuth2ClientTest.php +++ b/tests/Authentication/OAuth2ClientTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\Authentication; +use Facebook\Authentication\AccessToken; use Facebook\Facebook; use Facebook\FacebookApp; use Facebook\Authentication\OAuth2Client; @@ -39,12 +40,12 @@ class OAuth2ClientTest extends BaseTestCase /** * @var FooFacebookClientForOAuth2Test */ - protected $client; + protected FooFacebookClientForOAuth2Test $client; /** * @var OAuth2Client */ - protected $oauth; + protected OAuth2Client $oauth; protected function setUp(): void { @@ -59,7 +60,6 @@ public function testCanGetMetadataFromAnAccessToken(): void $metadata = $this->oauth->debugToken('baz_token'); - $this->assertInstanceOf('Facebook\Authentication\AccessTokenMetadata', $metadata); $this->assertEquals('444', $metadata->getUserId()); $expectedParams = [ @@ -108,7 +108,7 @@ public function testCanGetAccessTokenFromCode(): void $accessToken = $this->oauth->getAccessTokenFromCode('bar_code', 'foo_uri'); - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertInstanceOf(AccessToken::class, $accessToken); $this->assertEquals('my_access_token', $accessToken->getValue()); $expectedParams = [ diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index e9e56c4..544027a 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -23,6 +23,12 @@ */ namespace Facebook\Tests\Exceptions; +use Facebook\Exceptions\FacebookAuthenticationException; +use Facebook\Exceptions\FacebookAuthorizationException; +use Facebook\Exceptions\FacebookClientException; +use Facebook\Exceptions\FacebookOtherException; +use Facebook\Exceptions\FacebookServerException; +use Facebook\Exceptions\FacebookThrottleException; use Facebook\FacebookApp; use Facebook\FacebookRequest; use Facebook\FacebookResponse; @@ -35,14 +41,14 @@ class FacebookResponseExceptionTest extends BaseTestCase /** * @var FacebookRequest */ - protected $request; + protected FacebookRequest $request; protected function setUp(): void { $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); } - public function testAuthenticationExceptions() + public function testFacebookAuthenticationExceptions() { $params = [ 'error' => [ @@ -55,7 +61,7 @@ public function testAuthenticationExceptions() $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(100, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -66,13 +72,13 @@ public function testAuthenticationExceptions() $params['error']['code'] = 102; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(102, $exception->getCode()); $params['error']['code'] = 190; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(190, $exception->getCode()); $params['error']['type'] = 'OAuthException'; @@ -80,31 +86,31 @@ public function testAuthenticationExceptions() $params['error']['error_subcode'] = 458; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(458, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 460; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(460, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 463; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(463, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 467; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(467, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 0; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(0, $exception->getSubErrorCode()); } @@ -121,7 +127,7 @@ public function testServerExceptions() $response = new FacebookResponse($this->request, json_encode($params), 500); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookServerException::class, $exception->getPrevious()); $this->assertEquals(1, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -132,7 +138,7 @@ public function testServerExceptions() $params['error']['code'] = 2; $response = new FacebookResponse($this->request, json_encode($params), 500); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookServerException::class, $exception->getPrevious()); $this->assertEquals(2, $exception->getCode()); } @@ -148,7 +154,7 @@ public function testThrottleExceptions() ]; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookThrottleException::class, $exception->getPrevious()); $this->assertEquals(4, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -159,13 +165,13 @@ public function testThrottleExceptions() $params['error']['code'] = 17; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookThrottleException::class, $exception->getPrevious()); $this->assertEquals(17, $exception->getCode()); $params['error']['code'] = 341; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookThrottleException::class, $exception->getPrevious()); $this->assertEquals(341, $exception->getCode()); } @@ -181,7 +187,7 @@ public function testUserIssueExceptions() ]; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(230, $exception->getCode()); $this->assertEquals(459, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -192,7 +198,7 @@ public function testUserIssueExceptions() $params['error']['error_subcode'] = 464; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthenticationException::class, $exception->getPrevious()); $this->assertEquals(464, $exception->getSubErrorCode()); } @@ -208,7 +214,7 @@ public function testAuthorizationExceptions() ]; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthorizationException::class, $exception->getPrevious()); $this->assertEquals(10, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -219,19 +225,19 @@ public function testAuthorizationExceptions() $params['error']['code'] = 200; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthorizationException::class, $exception->getPrevious()); $this->assertEquals(200, $exception->getCode()); $params['error']['code'] = 250; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthorizationException::class, $exception->getPrevious()); $this->assertEquals(250, $exception->getCode()); $params['error']['code'] = 299; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookAuthorizationException::class, $exception->getPrevious()); $this->assertEquals(299, $exception->getCode()); } @@ -247,7 +253,7 @@ public function testClientExceptions() ]; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookClientException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookClientException::class, $exception->getPrevious()); $this->assertEquals(506, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -268,7 +274,7 @@ public function testOtherException() ]; $response = new FacebookResponse($this->request, json_encode($params), 200); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookOtherException', $exception->getPrevious()); + $this->assertInstanceOf(FacebookOtherException::class, $exception->getPrevious()); $this->assertEquals(42, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('feature', $exception->getErrorType()); diff --git a/tests/FacebookAppTest.php b/tests/FacebookAppTest.php index 4c862a7..2961bf3 100644 --- a/tests/FacebookAppTest.php +++ b/tests/FacebookAppTest.php @@ -27,10 +27,8 @@ class FacebookAppTest extends BaseTestCase { - /** - * @var FacebookApp - */ - private $app; + + private FacebookApp $app; protected function setUp(): void { @@ -51,7 +49,6 @@ public function testAnAppAccessTokenCanBeGenerated() { $accessToken = $this->app->getAccessToken(); - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); $this->assertEquals('id|secret', (string)$accessToken); } @@ -59,17 +56,11 @@ public function testSerialization() { $newApp = unserialize(serialize($this->app)); - $this->assertInstanceOf('Facebook\FacebookApp', $newApp); + $this->assertInstanceOf(FacebookApp::class, $newApp); $this->assertEquals('id', $newApp->getId()); $this->assertEquals('secret', $newApp->getSecret()); } - public function testOverflowIntegersWillThrow() - { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); - new FacebookApp(PHP_INT_MAX + 1, "foo"); - } - public function testUnserializedIdsWillBeString() { $newApp = unserialize(serialize(new FacebookApp(1, "foo"))); diff --git a/tests/FacebookBatchRequestTest.php b/tests/FacebookBatchRequestTest.php index 45ccbdb..7990b5b 100755 --- a/tests/FacebookBatchRequestTest.php +++ b/tests/FacebookBatchRequestTest.php @@ -97,14 +97,6 @@ public function testWillThrowWhenNoThereIsNoAccessTokenFallback() $request->addFallbackDefaults(new FacebookRequest($this->app)); } - public function testAnInvalidTypeGivenToAddWillThrow() - { - $this->expectException(\InvalidArgumentException::class); - $request = new FacebookBatchRequest(); - - $request->add('foo'); - } - public function testAddingRequestsWillBeFormattedInAnArrayProperly() { $requests = [ @@ -194,7 +186,7 @@ public function testLessOrEqualThanFiftyRequestsWillNotThrow() /** * @dataProvider requestsAndExpectedResponsesProvider */ - public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $expectedArray) + public function testBatchRequestEntitiesProperlyGetConvertedToAnArray(FacebookRequest $request, array $expectedArray) { $batchRequest = $this->createBatchRequest(); $batchRequest->add($request, 'foo_name'); @@ -205,7 +197,7 @@ public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $this->assertEquals($expectedArray, $batchRequestArray); } - public function requestsAndExpectedResponsesProvider() + public function requestsAndExpectedResponsesProvider(): array { $headers = $this->defaultHeaders(); $apiVersion = Facebook::DEFAULT_GRAPH_VERSION; @@ -369,7 +361,7 @@ public function testPreppingABatchRequestWithOptionsProperlySetsThePostParams() $this->assertEquals($expectedBatchParams, $params); } - private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) + private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, string $expectedToken): void { $app = $request->getApp(); $token = $request->getAccessToken(); @@ -378,7 +370,7 @@ private function assertRequestContainsAppAndToken(FacebookRequest $request, Face $this->assertEquals($expectedToken, $token); } - private function defaultHeaders() + private function defaultHeaders(): array { $headers = []; foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { @@ -388,19 +380,19 @@ private function defaultHeaders() return $headers; } - private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $number) + private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, int $number): void { for ($i = 0; $i < $number; $i++) { $batchRequest->add(new FacebookRequest()); } } - private function createBatchRequest() + private function createBatchRequest(): FacebookBatchRequest { return new FacebookBatchRequest($this->app, [], 'foo_token'); } - private function createBatchRequestWithRequests(array $requests) + private function createBatchRequestWithRequests(array $requests): FacebookBatchRequest { $batchRequest = $this->createBatchRequest(); $batchRequest->add($requests); @@ -408,7 +400,7 @@ private function createBatchRequestWithRequests(array $requests) return $batchRequest; } - private function assertRequestsMatch($requests, $formattedRequests) + private function assertRequestsMatch(array $requests, array $formattedRequests): void { $expectedRequests = []; foreach ($requests as $name => $request) { diff --git a/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index 6625c06..8295827 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -28,6 +28,7 @@ use Facebook\FacebookResponse; use Facebook\FacebookBatchRequest; use Facebook\FacebookBatchResponse; +use Facebook\GraphNodes\GraphNode; class FacebookBatchResponseTest extends BaseTestCase { @@ -80,12 +81,12 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() // Single Graph object. $this->assertFalse($decodedResponses[0]->isError(), 'Did not expect Response to return an error for single Graph object.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $decodedResponses[0]->getGraphNode()); + $this->assertInstanceOf(GraphNode::class, $decodedResponses[0]->getGraphNode()); // Paginated list of Graph objects. $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); $graphEdge = $decodedResponses[1]->getGraphEdge(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[1]); + $this->assertInstanceOf(GraphNode::class, $graphEdge[0]); + $this->assertInstanceOf(GraphNode::class, $graphEdge[1]); } public function testABatchResponseCanBeIteratedOver() @@ -103,11 +104,11 @@ public function testABatchResponseCanBeIteratedOver() ]); $batchResponse = new FacebookBatchResponse($batchRequest, $response); - $this->assertInstanceOf('IteratorAggregate', $batchResponse); + $this->assertInstanceOf(\IteratorAggregate::class, $batchResponse); foreach ($batchResponse as $key => $responseEntity) { $this->assertTrue(in_array($key, ['req_one', 'req_two', 'req_three'])); - $this->assertInstanceOf('Facebook\FacebookResponse', $responseEntity); + $this->assertInstanceOf(FacebookResponse::class, $responseEntity); } } @@ -129,8 +130,8 @@ public function testTheOriginalRequestCanBeObtainedForEachRequest() $batchRequest = new FacebookBatchRequest($this->app, $requests); $batchResponse = new FacebookBatchResponse($batchRequest, $response); - $this->assertInstanceOf('Facebook\FacebookResponse', $batchResponse[0]); - $this->assertInstanceOf('Facebook\FacebookRequest', $batchResponse[0]->getRequest()); + $this->assertInstanceOf(FacebookResponse::class, $batchResponse[0]); + $this->assertInstanceOf(FacebookRequest::class, $batchResponse[0]->getRequest()); $this->assertEquals('foo_token_one', $batchResponse[0]->getAccessToken()); $this->assertEquals('foo_token_two', $batchResponse[1]->getAccessToken()); $this->assertEquals('foo_token_three', $batchResponse[2]->getAccessToken()); diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index af76c97..8c148dd 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\Tests; use Facebook\Exceptions\FacebookSDKException; @@ -34,7 +35,6 @@ use Facebook\HttpClients\FacebookGuzzleHttpClient; use Facebook\Tests\Fixtures\MyFooBatchClientHandler; use Facebook\Tests\Fixtures\MyFooClientHandler; -use Facebook\GraphNodes\GraphNode; use Facebook\FacebookBatchResponse; use Facebook\FacebookResponse; use Facebook\HttpClients\FacebookStreamHttpClient; @@ -42,25 +42,10 @@ class FacebookClientTest extends BaseTestCase { - /** - * @var FacebookApp - */ - public $fbApp; - - /** - * @var FacebookClient - */ - public $fbClient; - - /** - * @var FacebookApp - */ - public static $testFacebookApp; - - /** - * @var FacebookClient - */ - public static $testFacebookClient; + public FacebookApp $fbApp; + public FacebookClient $fbClient; + public static ?FacebookApp $testFacebookApp = null; + public static ?FacebookClient $testFacebookClient = null; protected function setUp(): void { @@ -157,11 +142,11 @@ public function testAFacebookBatchRequestWillProperlyBatchFiles(): void $fbRequests = [ new FacebookRequest($this->fbApp, 'token', 'POST', '/photo', [ 'message' => 'foobar', - 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), ]), new FacebookRequest($this->fbApp, 'token', 'POST', '/video', [ 'message' => 'foobar', - 'source' => new FacebookVideo(__DIR__ . '/foo.txt'), + 'source' => new FacebookVideo(__DIR__ . '/foo2.txt'), ]), ]; $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); @@ -208,91 +193,4 @@ public function testAFacebookRequestValidatesTheAccessTokenWhenOneIsNotProvided( $this->fbClient->sendRequest($fbRequest); } - /** - * @group integration - */ - public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser(): void - { - $this->initializeTestApp(); - - // Create a test user - $testUserPath = '/' . FacebookTestCredentials::$appId . '/accounts/test-users'; - $params = [ - 'installed' => true, - 'name' => 'Foo Phpunit User', - 'locale' => 'en_US', - 'permissions' => implode(',', ['read_stream', 'user_photos']), - ]; - - $request = new FacebookRequest( - static::$testFacebookApp, - static::$testFacebookApp->getAccessToken(), - 'POST', - $testUserPath, - $params - ); - $response = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - - $testUserId = $response->getField('id'); - $testUserAccessToken = $response->getField('access_token'); - - // Get the test user's profile - $request = new FacebookRequest( - static::$testFacebookApp, - $testUserAccessToken, - 'GET', - '/me' - ); - $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - - $this->assertInstanceOf(GraphNode::class, $graphNode); - $this->assertNotNull($graphNode->getField('id')); - $this->assertEquals('Foo Phpunit User', $graphNode->getField('name')); - - // Delete test user - $request = new FacebookRequest( - static::$testFacebookApp, - static::$testFacebookApp->getAccessToken(), - 'DELETE', - '/' . $testUserId - ); - $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - - $this->assertTrue($graphNode->getField('success')); - } - - public function initializeTestApp(): void - { - if (!file_exists(__DIR__ . '/FacebookTestCredentials.php')) { - throw new FacebookSDKException( - 'You must create a FacebookTestCredentials.php file from FacebookTestCredentials.php.dist' - ); - } - - if (!strlen(FacebookTestCredentials::$appId) || - !strlen(FacebookTestCredentials::$appSecret) - ) { - throw new FacebookSDKException( - 'You must fill out FacebookTestCredentials.php' - ); - } - static::$testFacebookApp = new FacebookApp( - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); - - // Use default client - $client = null; - - // Uncomment to enable curl implementation. - //$client = new FacebookCurlHttpClient(); - - // Uncomment to enable stream wrapper implementation. - //$client = new FacebookStreamHttpClient(); - - // Uncomment to enable Guzzle implementation. - //$client = new FacebookGuzzleHttpClient(); - - static::$testFacebookClient = new FacebookClient($client); - } } diff --git a/tests/FacebookRequestTest.php b/tests/FacebookRequestTest.php index 0d2e40f..d04b00e 100755 --- a/tests/FacebookRequestTest.php +++ b/tests/FacebookRequestTest.php @@ -36,7 +36,7 @@ public function testAnEmptyRequestEntityCanInstantiate() $app = new FacebookApp('123', 'foo_secret'); $request = new FacebookRequest($app); - $this->assertInstanceOf('Facebook\FacebookRequest', $request); + $this->assertInstanceOf(FacebookRequest::class, $request); } public function testAMissingAccessTokenWillThrow() diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index 4181550..0890e9a 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -23,16 +23,16 @@ */ namespace Facebook\Tests; +use Facebook\Exceptions\FacebookResponseException; use Facebook\FacebookApp; use Facebook\FacebookRequest; use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphNode; class FacebookResponseTest extends BaseTestCase { - /** - * @var \Facebook\FacebookRequest - */ - protected $request; + + protected FacebookRequest $request; protected function setUp(): void { @@ -79,7 +79,7 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphNode() 'id' => '123', 'name' => 'Foo', ], $decodedResponse); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertInstanceOf(GraphNode::class, $graphNode); } public function testASuccessfulJsonResponseWillBeDecodedToAGraphEdge() @@ -90,8 +90,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphEdge() $graphEdge = $response->getGraphEdge(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[1]); + $this->assertInstanceOf(GraphNode::class, $graphEdge[0]); + $this->assertInstanceOf(GraphNode::class, $graphEdge[1]); } public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() @@ -116,6 +116,6 @@ public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() $exception = $response->getThrownException(); $this->assertTrue($response->isError(), 'Expected Response to return an error.'); - $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $exception); + $this->assertInstanceOf(FacebookResponseException::class, $exception); } } diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 2d38f57..0803925 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -26,20 +26,31 @@ use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; use Facebook\Facebook; +use Facebook\FacebookBatchRequest; use Facebook\FacebookClient; use Facebook\FacebookRequest; use Facebook\Authentication\AccessToken; +use Facebook\FacebookResponse; use Facebook\GraphNodes\GraphEdge; +use Facebook\GraphNodes\GraphUser; +use Facebook\HttpClients\FacebookCurlHttpClient; +use Facebook\HttpClients\FacebookGuzzleHttpClient; +use Facebook\HttpClients\FacebookStreamHttpClient; +use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\RandomBytesPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; use Facebook\Tests\Fixtures\FakeGraphApiForResumableUpload; use Facebook\Tests\Fixtures\FooBarPseudoRandomStringGenerator; use Facebook\Tests\Fixtures\FooClientInterface; use Facebook\Tests\Fixtures\FooPersistentDataInterface; use Facebook\Tests\Fixtures\FooUrlDetectionInterface; +use Facebook\Url\FacebookUrlDetectionHandler; use InvalidArgumentException; class FacebookTest extends BaseTestCase { - protected $config = [ + protected array $config = [ 'app_id' => '1337', 'app_secret' => 'foo_secret', ]; @@ -88,7 +99,7 @@ public function testCurlHttpClientHandlerCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\HttpClients\FacebookCurlHttpClient', + FacebookCurlHttpClient::class, $fb->getClient()->getHttpClientHandler() ); } @@ -100,7 +111,7 @@ public function testStreamHttpClientHandlerCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\HttpClients\FacebookStreamHttpClient', + FacebookStreamHttpClient::class, $fb->getClient()->getHttpClientHandler() ); } @@ -112,7 +123,7 @@ public function testGuzzleHttpClientHandlerCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\HttpClients\FacebookGuzzleHttpClient', + FacebookGuzzleHttpClient::class, $fb->getClient()->getHttpClientHandler() ); } @@ -133,7 +144,7 @@ public function testPersistentDataHandlerCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\PersistentData\FacebookMemoryPersistentDataHandler', + FacebookMemoryPersistentDataHandler::class, $fb->getRedirectLoginHelper()->getPersistentDataHandler() ); } @@ -155,7 +166,7 @@ public function testSettingAnInvalidUrlHandlerThrows() public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() { $fb = new Facebook($this->config); - $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); + $this->assertInstanceOf(FacebookUrlDetectionHandler::class, $fb->getUrlDetectionHandler()); } public function testAnAccessTokenCanBeSetAsAString() @@ -164,7 +175,7 @@ public function testAnAccessTokenCanBeSetAsAString() $fb->setDefaultAccessToken('foo_token'); $accessToken = $fb->getDefaultAccessToken(); - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertInstanceOf(AccessToken::class, $accessToken); $this->assertEquals('foo_token', (string)$accessToken); } @@ -174,7 +185,7 @@ public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() $fb->setDefaultAccessToken(new AccessToken('bar_token')); $accessToken = $fb->getDefaultAccessToken(); - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertInstanceOf(AccessToken::class, $accessToken); $this->assertEquals('bar_token', (string)$accessToken); } @@ -196,7 +207,7 @@ public function testRandomBytesCsprgCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\PseudoRandomString\RandomBytesPseudoRandomStringGenerator', + RandomBytesPseudoRandomStringGenerator::class, $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() ); } @@ -215,7 +226,7 @@ public function testOpenSslCsprgCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator', + OpenSslPseudoRandomStringGenerator::class, $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() ); } @@ -240,7 +251,7 @@ public function testUrandomCsprgCanBeForced() ]); $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator', + UrandomPseudoRandomStringGenerator::class, $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() ); } @@ -292,8 +303,8 @@ public function testCreatingANewBatchRequestWillDefaultToTheProperConfig() FacebookClient::BASE_GRAPH_URL_BETA, $fb->getClient()->getBaseGraphUrl() ); - $this->assertInstanceOf('Facebook\FacebookBatchRequest', $batchRequest); - $this->assertEquals(0, count($batchRequest->getRequests())); + $this->assertInstanceOf(FacebookBatchRequest::class, $batchRequest); + $this->assertCount(0, $batchRequest->getRequests()); } public function testCanInjectCustomHandlers() @@ -307,19 +318,19 @@ public function testCanInjectCustomHandlers() $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\Tests\Fixtures\FooClientInterface', + FooClientInterface::class, $fb->getClient()->getHttpClientHandler() ); $this->assertInstanceOf( - 'Facebook\Tests\Fixtures\FooPersistentDataInterface', + FooPersistentDataInterface::class, $fb->getRedirectLoginHelper()->getPersistentDataHandler() ); $this->assertInstanceOf( - 'Facebook\Tests\Fixtures\FooUrlDetectionInterface', + FooUrlDetectionInterface::class, $fb->getRedirectLoginHelper()->getUrlDetectionHandler() ); $this->assertInstanceOf( - 'Facebook\Tests\Fixtures\FooBarPseudoRandomStringGenerator', + FooBarPseudoRandomStringGenerator::class, $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() ); } @@ -346,16 +357,16 @@ public function testPaginationReturnsProperResponse() ] ], '/1337/photos', - '\Facebook\GraphNodes\GraphUser' + GraphUser::class ); $nextPage = $fb->next($graphEdge); - $this->assertInstanceOf('Facebook\GraphNodes\GraphEdge', $nextPage); - $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); + $this->assertInstanceOf(GraphEdge::class, $nextPage); + $this->assertInstanceOf(GraphUser::class, $nextPage[0]); $this->assertEquals('Foo', $nextPage[0]['name']); $lastResponse = $fb->getLastResponse(); - $this->assertInstanceOf('Facebook\FacebookResponse', $lastResponse); + $this->assertInstanceOf(FacebookResponse::class, $lastResponse); $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); } diff --git a/tests/FileUpload/FacebookFileTest.php b/tests/FileUpload/FacebookFileTest.php index b9d2e8d..7f30051 100644 --- a/tests/FileUpload/FacebookFileTest.php +++ b/tests/FileUpload/FacebookFileTest.php @@ -23,12 +23,13 @@ */ namespace Facebook\Tests\FileUpload; +use Facebook\Exceptions\FacebookSDKException; use Facebook\FileUpload\FacebookFile; use Facebook\Tests\BaseTestCase; class FacebookFileTest extends BaseTestCase { - protected $testFile = ''; + protected string $testFile = ''; protected function setUp(): void { @@ -40,7 +41,7 @@ public function testCanOpenAndReadAndCloseAFile() $file = new FacebookFile($this->testFile); $fileContents = $file->getContents(); - $this->assertEquals('This is a text file used for testing. Let\'s dance.', $fileContents); + $this->assertEquals('This is a text file used for testing.', $fileContents); } public function testPartialFilesCanBeCreated() @@ -53,7 +54,7 @@ public function testPartialFilesCanBeCreated() public function testTryingToOpenAFileThatDoesntExistsThrows() { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); + $this->expectException(FacebookSDKException::class); new FacebookFile('does_not_exist.file'); } } diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index d3d04f4..2dbc51e 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -24,6 +24,7 @@ namespace Facebook\Tests\FileUpload; +use Facebook\Exceptions\FacebookResponseException; use Facebook\FileUpload\FacebookFile; use Facebook\FacebookApp; use Facebook\FacebookClient; @@ -34,25 +35,11 @@ class FacebookResumableUploaderTest extends BaseTestCase { - /** - * @var FacebookApp - */ - private $fbApp; - /** - * @var FacebookClient - */ - private $client; - - /** - * @var FakeGraphApiForResumableUpload - */ - private $graphApi; - - /** - * @var FacebookFile - */ - private $file; + private FacebookApp $fbApp; + private FacebookClient $client; + private FakeGraphApiForResumableUpload $graphApi; + private FacebookFile $file; protected function setUp(): void { @@ -67,7 +54,7 @@ public function testResumableUploadCanStartTransferAndFinish() $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); $endpoint = '/me/videos'; $chunk = $uploader->start($endpoint, $this->file); - $this->assertInstanceOf('Facebook\FileUpload\FacebookTransferChunk', $chunk); + $this->assertInstanceOf(FacebookTransferChunk::class, $chunk); $this->assertEquals('42', $chunk->getUploadSessionId()); $this->assertEquals('1337', $chunk->getVideoId()); @@ -81,7 +68,7 @@ public function testResumableUploadCanStartTransferAndFinish() public function testStartWillLetErrorResponsesThrow() { - $this->expectException(\Facebook\Exceptions\FacebookResponseException::class); + $this->expectException(FacebookResponseException::class); $this->graphApi->failOnStart(); $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); diff --git a/tests/Fixtures/FakeGraphApiForResumableUpload.php b/tests/Fixtures/FakeGraphApiForResumableUpload.php index 29f5644..0cab43d 100644 --- a/tests/Fixtures/FakeGraphApiForResumableUpload.php +++ b/tests/Fixtures/FakeGraphApiForResumableUpload.php @@ -29,37 +29,37 @@ class FakeGraphApiForResumableUpload implements FacebookHttpClientInterface { - public $transferCount = 0; - private $respondWith = 'SUCCESS'; + public int $transferCount = 0; + private string $respondWith = 'SUCCESS'; - public function failOnStart() + public function failOnStart(): void { $this->respondWith = 'FAIL_ON_START'; } - public function failOnTransfer() + public function failOnTransfer(): void { $this->respondWith = 'FAIL_ON_TRANSFER'; } - public function failOnTransferAndUploadNewChunk() + public function failOnTransferAndUploadNewChunk(): void { $this->respondWith = 'FAIL_ON_TRANSFER_AND_UPLOAD_NEW_CHUNK'; } - public function send($url, $method, $body, array $headers, $timeOut) + public function send(string $url, string $method, ?string $body, array $headers, int $timeOut): GraphRawResponse { // Could be start, transfer or finish - if (strpos($body, 'transfer') !== false) { + if (str_contains($body, 'transfer')) { return $this->respondTransfer(); - } elseif (strpos($body, 'finish') !== false) { + } elseif (str_contains($body, 'finish')) { return $this->respondFinish(); } return $this->respondStart(); } - private function respondStart() + private function respondStart(): GraphRawResponse { if ($this->respondWith == 'FAIL_ON_START') { return new GraphRawResponse( @@ -76,7 +76,7 @@ private function respondStart() ); } - private function respondTransfer() + private function respondTransfer(): GraphRawResponse { if ($this->respondWith == 'FAIL_ON_TRANSFER') { return new GraphRawResponse( @@ -115,7 +115,7 @@ private function respondTransfer() ); } - private function respondFinish() + private function respondFinish(): GraphRawResponse { return new GraphRawResponse( "HTTP/1.1 200 OK\r\nFoo: Bar", diff --git a/tests/Fixtures/FooBarPseudoRandomStringGenerator.php b/tests/Fixtures/FooBarPseudoRandomStringGenerator.php index 17448b6..a4ff895 100644 --- a/tests/Fixtures/FooBarPseudoRandomStringGenerator.php +++ b/tests/Fixtures/FooBarPseudoRandomStringGenerator.php @@ -27,7 +27,7 @@ class FooBarPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { - public function getPseudoRandomString($length) + public function getPseudoRandomString(int $length): string { return 'csprs123'; } diff --git a/tests/Fixtures/FooClientInterface.php b/tests/Fixtures/FooClientInterface.php index f4548d8..deaf5e5 100644 --- a/tests/Fixtures/FooClientInterface.php +++ b/tests/Fixtures/FooClientInterface.php @@ -28,7 +28,7 @@ class FooClientInterface implements FacebookHttpClientInterface { - public function send($url, $method, $body, array $headers, $timeOut) + public function send(string $url, string $method, ?string $body, array $headers, int $timeOut): GraphRawResponse { return new GraphRawResponse( "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", diff --git a/tests/Fixtures/FooPersistentDataInterface.php b/tests/Fixtures/FooPersistentDataInterface.php index 5ff5793..3dc4d49 100644 --- a/tests/Fixtures/FooPersistentDataInterface.php +++ b/tests/Fixtures/FooPersistentDataInterface.php @@ -27,12 +27,12 @@ class FooPersistentDataInterface implements PersistentDataInterface { - public function get($key) + public function get(mixed $key): string { return 'foo'; } - public function set($key, $value) + public function set(mixed $key, mixed $value): void { } } diff --git a/tests/Fixtures/FooPseudoRandomStringGenerator.php b/tests/Fixtures/FooPseudoRandomStringGenerator.php index d5a94d6..59df117 100644 --- a/tests/Fixtures/FooPseudoRandomStringGenerator.php +++ b/tests/Fixtures/FooPseudoRandomStringGenerator.php @@ -27,7 +27,7 @@ class FooPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { - public function getPseudoRandomString($length) + public function getPseudoRandomString($length): string { return 'csprs123'; } diff --git a/tests/Fixtures/FooRedirectLoginOAuth2Client.php b/tests/Fixtures/FooRedirectLoginOAuth2Client.php index 2a2aeed..f08f9e1 100644 --- a/tests/Fixtures/FooRedirectLoginOAuth2Client.php +++ b/tests/Fixtures/FooRedirectLoginOAuth2Client.php @@ -28,7 +28,7 @@ class FooRedirectLoginOAuth2Client extends OAuth2Client { - public function getAccessTokenFromCode($code, $redirectUri = '', $machineId = null) + public function getAccessTokenFromCode(string $code, string $redirectUri = ''): AccessToken { return new AccessToken('foo_token_from_code|' . $code . '|' . $redirectUri); } diff --git a/tests/Fixtures/FooSignedRequestHelper.php b/tests/Fixtures/FooSignedRequestHelper.php index 9131631..8774777 100644 --- a/tests/Fixtures/FooSignedRequestHelper.php +++ b/tests/Fixtures/FooSignedRequestHelper.php @@ -27,7 +27,7 @@ class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper { - public function getRawSignedRequest() + public function getRawSignedRequest(): ?string { return null; } diff --git a/tests/Fixtures/FooSignedRequestHelperFacebookClient.php b/tests/Fixtures/FooSignedRequestHelperFacebookClient.php index 0b08b8c..244976f 100644 --- a/tests/Fixtures/FooSignedRequestHelperFacebookClient.php +++ b/tests/Fixtures/FooSignedRequestHelperFacebookClient.php @@ -29,7 +29,7 @@ class FooSignedRequestHelperFacebookClient extends FacebookClient { - public function sendRequest(FacebookRequest $request) + public function sendRequest(FacebookRequest $request): FacebookResponse { $params = $request->getParams(); $rawResponse = json_encode([ diff --git a/tests/Fixtures/FooUrlDetectionInterface.php b/tests/Fixtures/FooUrlDetectionInterface.php index 8ee70c3..24f5372 100644 --- a/tests/Fixtures/FooUrlDetectionInterface.php +++ b/tests/Fixtures/FooUrlDetectionInterface.php @@ -27,7 +27,7 @@ class FooUrlDetectionInterface implements UrlDetectionInterface { - public function getCurrentUrl() + public function getCurrentUrl(): string { return 'https://foo.bar'; } diff --git a/tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php b/tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php deleted file mode 100644 index 8c39c8a..0000000 --- a/tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php +++ /dev/null @@ -1,31 +0,0 @@ - '\Facebook\Tests\Fixtures\MyFooSubClassGraphNode', ]; } diff --git a/tests/GraphNodes/AbstractGraphNode.php b/tests/GraphNodes/AbstractGraphNode.php index 6708e1a..f0d3400 100644 --- a/tests/GraphNodes/AbstractGraphNode.php +++ b/tests/GraphNodes/AbstractGraphNode.php @@ -23,30 +23,20 @@ */ namespace Facebook\Tests\GraphNodes; +use Facebook\FacebookResponse; use Facebook\Tests\BaseTestCase; use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; abstract class AbstractGraphNode extends BaseTestCase { - /** - * @var \Facebook\FacebookResponse|\Mockery\MockInterface - */ - protected $responseMock; + + protected FacebookResponse $responseMock; protected function setUp(): void { parent::setUp(); - $this->responseMock = m::mock('\Facebook\FacebookResponse'); + $this->responseMock = m::mock(FacebookResponse::class); } - protected function makeFactoryWithData($data) - { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($data); - - return new GraphNodeFactory($this->responseMock); - } } diff --git a/tests/GraphNodes/CollectionTest.php b/tests/GraphNodes/CollectionTest.php index 05ffb94..8d3c305 100755 --- a/tests/GraphNodes/CollectionTest.php +++ b/tests/GraphNodes/CollectionTest.php @@ -25,6 +25,7 @@ use Facebook\GraphNodes\Collection; use Facebook\Tests\BaseTestCase; +use IteratorAggregate; class CollectionTest extends BaseTestCase { @@ -35,10 +36,6 @@ public function testAnExistingPropertyCanBeAccessed() $field = $graphNode->getField('foo'); $this->assertEquals('bar', $field); - - // @todo v6: Remove this assertion - $property = $graphNode->getProperty('foo'); - $this->assertEquals('bar', $property); } public function testAMissingPropertyWillReturnNull() @@ -55,10 +52,6 @@ public function testAMissingPropertyWillReturnTheDefault() $field = $graphNode->getField('baz', 'faz'); $this->assertEquals('faz', $field); - - // @todo v6: Remove this assertion - $property = $graphNode->getProperty('baz', 'faz'); - $this->assertEquals('faz', $property); } public function testFalseDefaultsWillReturnSameType() @@ -85,10 +78,6 @@ public function testTheKeysFromTheCollectionCanBeReturned() $fieldNames = $graphNode->getFieldNames(); $this->assertEquals(['key1', 'key2', 'key3'], $fieldNames); - - // @todo v6: Remove this assertion - $propertyNames = $graphNode->getPropertyNames(); - $this->assertEquals(['key1', 'key2', 'key3'], $propertyNames); } public function testAnArrayCanBeInjectedViaTheConstructor() @@ -127,7 +116,7 @@ public function testACollectionCanBeIteratedOver() { $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); - $this->assertInstanceOf('IteratorAggregate', $collection); + $this->assertInstanceOf(IteratorAggregate::class, $collection); $newArray = []; diff --git a/tests/GraphNodes/GraphAchievementTest.php b/tests/GraphNodes/GraphAchievementTest.php deleted file mode 100644 index 5be1140..0000000 --- a/tests/GraphNodes/GraphAchievementTest.php +++ /dev/null @@ -1,117 +0,0 @@ - '1337' - ]; - - $factory = $this->makeFactoryWithData($dataFromGraph); - $graphNode = $factory->makeGraphAchievement(); - - $id = $graphNode->getId(); - - $this->assertEquals($dataFromGraph['id'], $id); - } - - public function testTypeIsAlwaysString() - { - $dataFromGraph = [ - 'id' => '1337' - ]; - - $factory = $this->makeFactoryWithData($dataFromGraph); - $graphNode = $factory->makeGraphAchievement(); - - $type = $graphNode->getType(); - - $this->assertEquals('game.achievement', $type); - } - - public function testNoFeedStoryIsBoolean() - { - $dataFromGraph = [ - 'no_feed_story' => (rand(0, 1) == 1) - ]; - - $factory = $this->makeFactoryWithData($dataFromGraph); - $graphNode = $factory->makeGraphAchievement(); - - $isNoFeedStory = $graphNode->isNoFeedStory(); - - $this->assertTrue(is_bool($isNoFeedStory)); - } - - public function testDatesGetCastToDateTime() - { - $dataFromGraph = [ - 'publish_time' => '2014-07-15T03:54:34+0000' - ]; - - $factory = $this->makeFactoryWithData($dataFromGraph); - $graphNode = $factory->makeGraphAchievement(); - - $publishTime = $graphNode->getPublishTime(); - - $this->assertInstanceOf('DateTime', $publishTime); - } - - public function testFromGetsCastAsGraphUser() - { - $dataFromGraph = [ - 'from' => [ - 'id' => '1337', - 'name' => 'Foo McBar' - ] - ]; - - $factory = $this->makeFactoryWithData($dataFromGraph); - $graphNode = $factory->makeGraphAchievement(); - - $from = $graphNode->getFrom(); - - $this->assertInstanceOf('\Facebook\GraphNodes\GraphUser', $from); - } - - public function testApplicationGetsCastAsGraphApplication() - { - $dataFromGraph = [ - 'application' => [ - 'id' => '1337' - ] - ]; - - $factory = $this->makeFactoryWithData($dataFromGraph); - $graphNode = $factory->makeGraphAchievement(); - - $app = $graphNode->getApplication(); - - $this->assertInstanceOf('\Facebook\GraphNodes\GraphApplication', $app); - } -} diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 6b6b5b4..f07721d 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -23,6 +23,12 @@ */ namespace Facebook\Tests\GraphNodes; +use DateTime; +use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphAlbum; +use Facebook\GraphNodes\GraphLocation; +use Facebook\GraphNodes\GraphPlace; +use Facebook\GraphNodes\GraphUser; use Facebook\Tests\BaseTestCase; use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; @@ -30,14 +36,11 @@ class GraphAlbumTest extends BaseTestCase { - /** - * @var \Facebook\FacebookResponse - */ - protected $responseMock; + protected FacebookResponse $responseMock; protected function setUp(): void { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + $this->responseMock = m::mock(FacebookResponse::class); } public function testDatesGetCastToDateTime() @@ -54,13 +57,14 @@ public function testDatesGetCastToDateTime() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphAlbum(); + /** @var GraphAlbum $graphNode */ + $graphNode = $factory->makeGraphNode(GraphAlbum::class); $createdTime = $graphNode->getCreatedTime(); $updatedTime = $graphNode->getUpdatedTime(); - $this->assertInstanceOf('DateTime', $createdTime); - $this->assertInstanceOf('DateTime', $updatedTime); + $this->assertInstanceOf(DateTime::class, $createdTime); + $this->assertInstanceOf(DateTime::class, $updatedTime); } public function testFromGetsCastAsGraphUser() @@ -78,14 +82,15 @@ public function testFromGetsCastAsGraphUser() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphAlbum(); + /** @var GraphAlbum $graphNode */ + $graphNode = $factory->makeGraphNode(GraphAlbum::class); $from = $graphNode->getFrom(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $from); + $this->assertInstanceOf(GraphUser::class, $from); } - public function testPlacePropertyWillGetCastAsGraphPageObject() + public function testPlacePropertyWillGetCastAsGraphPlaceObject() { $dataFromGraph = [ 'id' => '123', @@ -93,6 +98,16 @@ public function testPlacePropertyWillGetCastAsGraphPageObject() 'place' => [ 'id' => '1', 'name' => 'For Bar Place', + 'overall_rating' => 4.5, + 'location' => [ + 'street' => 'Foo Street', + 'city' => 'Bar City', + 'state' => 'CA', + 'country' => 'US', + 'zip' => '90210', + 'latitude' => 49.55, + 'longitude' => -34.444 + ] ] ]; @@ -101,10 +116,25 @@ public function testPlacePropertyWillGetCastAsGraphPageObject() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphAlbum(); + /** @var GraphAlbum $graphNode */ + $graphNode = $factory->makeGraphNode(GraphAlbum::class); $place = $graphNode->getPlace(); + $location = $place->getLocation(); + + $this->assertInstanceOf(GraphPlace::class, $place); + $this->assertInstanceOf(GraphLocation::class, $place->getLocation()); + + $this->assertEquals('For Bar Place', $place->getName()); + $this->assertEquals(4.5, $place->getOverallRating()); + + $this->assertEquals('Foo Street', $location->getStreet()); + $this->assertEquals('Bar City', $location->getCity()); + $this->assertEquals('CA', $location->getState()); + $this->assertEquals('90210', $location->getZip()); + $this->assertEquals(49.55, $location->getLatitude()); + $this->assertEquals(-34.444, $location->getLongitude()); + $this->assertEquals('US', $location->getCountry()); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $place); } } diff --git a/tests/GraphNodes/GraphEdgeTest.php b/tests/GraphNodes/GraphEdgeTest.php index 533f31b..0c2183b 100644 --- a/tests/GraphNodes/GraphEdgeTest.php +++ b/tests/GraphNodes/GraphEdgeTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\GraphNodes; +use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookApp; use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphEdge; @@ -32,12 +33,9 @@ class GraphEdgeTest extends BaseTestCase { - /** - * @var \Facebook\FacebookRequest - */ - protected $request; + protected FacebookRequest $request; - protected $pagination = [ + protected array $pagination = [ 'next' => 'https://graph.facebook.com/v7.12/998899/photos?pretty=0&limit=25&after=foo_after_cursor', 'previous' => 'https://graph.facebook.com/v7.12/998899/photos?pretty=0&limit=25&before=foo_before_cursor', ]; @@ -58,7 +56,7 @@ protected function setUp(): void public function testNonGetRequestsWillThrow() { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); + $this->expectException(FacebookSDKException::class); $this->request->setMethod('POST'); $graphEdge = new GraphEdge($this->request); $graphEdge->validateForPagination(); @@ -89,8 +87,8 @@ public function testCanInstantiateNewPaginationRequest() $nextPage = $graphEdge->getNextPageRequest(); $prevPage = $graphEdge->getPreviousPageRequest(); - $this->assertInstanceOf('Facebook\FacebookRequest', $nextPage); - $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); + $this->assertInstanceOf(FacebookRequest::class, $nextPage); + $this->assertInstanceOf(FacebookRequest::class, $prevPage); $this->assertNotSame($this->request, $nextPage); $this->assertNotSame($this->request, $prevPage); $this->assertEquals('/v1337/998899/photos?access_token=foo_token&after=foo_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&limit=25&pretty=0', $nextPage->getUrl()); diff --git a/tests/GraphNodes/GraphEventTest.php b/tests/GraphNodes/GraphEventTest.php index 5d27f3b..b3b9ba4 100644 --- a/tests/GraphNodes/GraphEventTest.php +++ b/tests/GraphNodes/GraphEventTest.php @@ -24,20 +24,21 @@ namespace Facebook\Tests\GraphNodes; use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphCoverPhoto; +use Facebook\GraphNodes\GraphEvent; +use Facebook\GraphNodes\GraphGroup; +use Facebook\GraphNodes\GraphPage; use Facebook\Tests\BaseTestCase; -use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; +use Mockery; class GraphEventTest extends BaseTestCase { - /** - * @var FacebookResponse - */ - protected $responseMock; + protected FacebookResponse $responseMock; protected function setUp(): void { - $this->responseMock = m::mock('\Facebook\FacebookResponse'); + $this->responseMock = Mockery::mock(FacebookResponse::class); } public function testCoverGetsCastAsGraphCoverPhoto() @@ -51,10 +52,11 @@ public function testCoverGetsCastAsGraphCoverPhoto() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphEvent(); + /** @var GraphEvent $graphObject */ + $graphObject = $factory->makeGraphNode(GraphEvent::class); $cover = $graphObject->getCover(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); + $this->assertInstanceOf(GraphCoverPhoto::class, $cover); } public function testPlaceGetsCastAsGraphPage() @@ -68,16 +70,17 @@ public function testPlaceGetsCastAsGraphPage() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphEvent(); + /** @var GraphEvent $graphObject */ + $graphObject = $factory->makeGraphNode(GraphEvent::class); $place = $graphObject->getPlace(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphPage', $place); + $this->assertInstanceOf(GraphPage::class, $place); } - public function testPictureGetsCastAsGraphPicture() + public function testPictureGetsCastAsGraphCover() { $dataFromGraph = [ - 'picture' => ['id' => '1337'] + 'cover' => ['id' => '1337'] ]; $this->responseMock @@ -85,10 +88,11 @@ public function testPictureGetsCastAsGraphPicture() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphEvent(); + /** @var GraphEvent $graphObject */ + $graphObject = $factory->makeGraphNode(GraphEvent::class); - $picture = $graphObject->getPicture(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphPicture', $picture); + $picture = $graphObject->getCover(); + $this->assertInstanceOf(GraphCoverPhoto::class, $picture); } public function testParentGroupGetsCastAsGraphGroup() @@ -102,9 +106,10 @@ public function testParentGroupGetsCastAsGraphGroup() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphEvent(); + /** @var GraphEvent $graphObject */ + $graphObject = $factory->makeGraphNode(GraphEvent::class); $parentGroup = $graphObject->getParentGroup(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphGroup', $parentGroup); + $this->assertInstanceOf(GraphGroup::class, $parentGroup); } } diff --git a/tests/GraphNodes/GraphGroupTest.php b/tests/GraphNodes/GraphGroupTest.php index aacd30a..d249277 100644 --- a/tests/GraphNodes/GraphGroupTest.php +++ b/tests/GraphNodes/GraphGroupTest.php @@ -21,29 +21,41 @@ * DEALINGS IN THE SOFTWARE. * */ + namespace Facebook\Tests\GraphNodes; use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphCoverPhoto; +use Facebook\GraphNodes\GraphGroup; use Facebook\Tests\BaseTestCase; use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; class GraphGroupTest extends BaseTestCase { - /** - * @var FacebookResponse - */ - protected $responseMock; + + protected FacebookResponse $responseMock; protected function setUp(): void { - $this->responseMock = m::mock('\Facebook\FacebookResponse'); + $this->responseMock = m::mock(FacebookResponse::class); } public function testCoverGetsCastAsGraphCoverPhoto() { $dataFromGraph = [ - 'cover' => ['id' => '1337'] + 'id' => '12848493', + 'icon' => 'https://foo.bar.icon', + 'email' => 'foo@bar.com', + 'description' => 'foo description', + 'cover' => [ + 'id' => '1337', + 'source' => 'https://foo.bar', + 'offset_x' => 24, + 'offset_y' => 35 + ], + 'member_request_count' => 403, + 'member_count' => 2844, ]; $this->responseMock @@ -51,26 +63,22 @@ public function testCoverGetsCastAsGraphCoverPhoto() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphGroup(); + /** @var GraphGroup $graphNode */ + $graphNode = $factory->makeGraphNode(GraphGroup::class); $cover = $graphNode->getCover(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); - } - - public function testVenueGetsCastAsGraphLocation() - { - $dataFromGraph = [ - 'venue' => ['id' => '1337'] - ]; + $this->assertInstanceOf(GraphCoverPhoto::class, $cover); + $this->assertEquals('12848493', $graphNode->getId()); + $this->assertEquals(403, $graphNode->getMemberRequestCount()); + $this->assertEquals(2844, $graphNode->getMemberCount()); + $this->assertEquals('foo@bar.com', $graphNode->getEmail()); + $this->assertEquals('https://foo.bar.icon', $graphNode->getIcon()); + $this->assertEquals('foo description', $graphNode->getDescription()); - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphGroup(); - - $venue = $graphNode->getVenue(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphLocation', $venue); + $this->assertEquals('1337', $cover->getId()); + $this->assertEquals(24, $cover->getOffsetX()); + $this->assertEquals(35, $cover->getOffsetY()); + $this->assertEquals('https://foo.bar', $cover->getSource()); } + } diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 04ee8d5..e75cde5 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -27,15 +27,19 @@ use Facebook\FacebookApp; use Facebook\FacebookRequest; use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphAlbum; +use Facebook\GraphNodes\GraphEdge; +use Facebook\GraphNodes\GraphNode; use Facebook\GraphNodes\GraphNodeFactory; +use Facebook\GraphNodes\GraphUser; use Facebook\Tests\BaseTestCase; +use Facebook\Tests\Fixtures\MyFooGraphNode; +use Facebook\Tests\Fixtures\MyFooSubClassGraphNode; class GraphNodeFactoryTest extends BaseTestCase { - /** - * @var \Facebook\FacebookRequest - */ - protected $request; + + protected FacebookRequest $request; protected function setUp(): void { @@ -110,9 +114,9 @@ public function testInvalidSubClassesWillThrow() public function testValidSubClassesWillNotThrow() { - GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphNode'); - GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); - GraphNodeFactory::validateSubclass('\Facebook\Tests\Fixtures\MyFooGraphNode'); + GraphNodeFactory::validateSubclass(GraphNode::class); + GraphNodeFactory::validateSubclass(GraphAlbum::class); + GraphNodeFactory::validateSubclass(MyFooGraphNode::class); $this->assertEquals(1, 1); } @@ -122,9 +126,9 @@ public function testCastingAsASubClassObjectWillInstantiateTheSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\Fixtures\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode(MyFooGraphNode::class); - $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf(MyFooGraphNode::class, $mySubClassObject); } public function testASubClassMappingWillAutomaticallyInstantiateSubClass() @@ -133,11 +137,11 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\Fixtures\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode(MyFooGraphNode::class); $fooObject = $mySubClassObject->getField('foo_object'); - $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $mySubClassObject); - $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooSubClassGraphNode', $fooObject); + $this->assertInstanceOf(MyFooGraphNode::class, $mySubClassObject); + $this->assertInstanceOf(MyFooSubClassGraphNode::class, $fooObject); } public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() @@ -148,18 +152,20 @@ public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() 'unknown_object' => [ 'id' => '1337', 'name' => 'Should be generic!', + 'my_foo_field' => 'foo', ], ]); $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\Fixtures\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode(MyFooGraphNode::class); $unknownObject = $mySubClassObject->getField('unknown_object'); - $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $mySubClassObject); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $unknownObject); - $this->assertNotInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $unknownObject); + $this->assertInstanceOf(MyFooGraphNode::class, $mySubClassObject); + $this->assertInstanceOf(GraphNode::class, $unknownObject); + $this->assertNotInstanceOf(MyFooGraphNode::class, $unknownObject); + $this->assertEquals('foo', $unknownObject->getField('my_foo_field')); } public function testAListFromGraphWillBeCastAsAGraphEdge() @@ -188,7 +194,7 @@ public function testAListFromGraphWillBeCastAsAGraphEdge() $graphEdge = $factory->makeGraphEdge(); $graphData = $graphEdge->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphEdge); + $this->assertInstanceOf(GraphEdge::class, $graphEdge); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -214,7 +220,7 @@ public function testAGraphNodeWillBeCastAsAGraphNode() $graphNode = $factory->makeGraphNode(); $graphData = $graphNode->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertInstanceOf(GraphNode::class, $graphNode); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -238,7 +244,7 @@ public function testAGraphNodeWithARootDataKeyWillBeCastAsAGraphNode() $graphNode = $factory->makeGraphNode(); $graphData = $graphNode->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertInstanceOf(GraphNode::class, $graphNode); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -261,7 +267,7 @@ public function testAGraphNodeWithARootDataKeyWillConserveRootKeys() $factory = new GraphNodeFactory($res); $graphNode = $factory->makeGraphNode(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertInstanceOf(GraphNode::class, $graphNode); $graphData = $graphNode->asArray(); @@ -359,24 +365,24 @@ public function testAGraphEdgeWillBeCastRecursively() $factory = new GraphNodeFactory($res); $graphNode = $factory->makeGraphEdge(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphNode); + $this->assertInstanceOf(GraphEdge::class, $graphNode); // Story $storyObject = $graphNode[0]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $storyObject['from']); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['likes']); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['comments']); + $this->assertInstanceOf(GraphNode::class, $storyObject['from']); + $this->assertInstanceOf(GraphEdge::class, $storyObject['likes']); + $this->assertInstanceOf(GraphEdge::class, $storyObject['comments']); // Story Comments $storyComments = $storyObject['comments']; $firstStoryComment = $storyComments[0]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $firstStoryComment['from']); + $this->assertInstanceOf(GraphNode::class, $firstStoryComment['from']); // Message $messageObject = $graphNode[1]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $messageObject['to']); + $this->assertInstanceOf(GraphEdge::class, $messageObject['to']); $toUsers = $messageObject['to']; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $toUsers[0]); + $this->assertInstanceOf(GraphNode::class, $toUsers[0]); } public function testAGraphEdgeWillGenerateTheProperParentGraphEdges() @@ -448,4 +454,45 @@ public function testAGraphEdgeWillGenerateTheProperParentGraphEdges() $this->assertEquals('/222/photos', $childGraphEdgeThree); $this->assertEquals('/777/likes', $childGraphEdgeFour); } + + public function testGraphEdgeWillHandleSubclasses() + { + + $example = <<request, $example); + + $factory = new GraphNodeFactory($res); + $graphNode = $factory->makeGraphNode(GraphUser::class); + + $this->assertInstanceOf(GraphUser::class, $graphNode); + + } } diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php index 933c948..1f96850 100644 --- a/tests/GraphNodes/GraphNodeTest.php +++ b/tests/GraphNodes/GraphNodeTest.php @@ -23,7 +23,12 @@ */ namespace Facebook\Tests\GraphNodes; +use DateTime; +use DateTimeInterface; +use Facebook\GraphNodes\GraphAlbum; +use Facebook\GraphNodes\GraphEvent; use Facebook\GraphNodes\GraphNode; +use Facebook\GraphNodes\GraphPhoto; use Facebook\Tests\BaseTestCase; class GraphNodeTest extends BaseTestCase @@ -46,38 +51,55 @@ public function testAGraphNodeCanInstantiateWithData() public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() { - $graphNode = new GraphNode(); - - // Should pass - $shouldPass = $graphNode->isIso8601DateString('1985-10-26T01:21:00+0000'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date from Back To The Future to pass.'); - - $shouldPass = $graphNode->isIso8601DateString('1999-12-31'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); - - $shouldPass = $graphNode->isIso8601DateString('2009-05-19T14:39Z'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - - $shouldPass = $graphNode->isIso8601DateString('2014-W36'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - // Should fail - $shouldFail = $graphNode->isIso8601DateString('2009-05-19T14a39r'); - $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); - - $shouldFail = $graphNode->isIso8601DateString('foo_time'); - $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + $graphNode = new GraphAlbum([ + 'created_time' => '1985-10-26T01:21:00+0000' + ] + ); + $this->assertInstanceOf(DateTime::class, $graphNode->getCreatedTime(), 'Expected the valid ISO 8601 formatted date from Back To The Future to pass.'); + + $graphNode = new GraphAlbum([ + 'created_time' => '1999-12-31' + ] + ); + $this->assertInstanceOf(DateTime::class, $graphNode->getCreatedTime(),'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); + + $graphNode = new GraphAlbum([ + 'created_time' => '2009-05-19T14:39Z' + ] + ); + $this->assertInstanceOf(DateTime::class, $graphNode->getCreatedTime(),'Expected the valid ISO 8601 formatted date to pass.'); + + $graphNode = new GraphAlbum([ + 'created_time' => '2014-W36' + ] + ); + $this->assertInstanceOf(DateTime::class, $graphNode->getCreatedTime(),'Expected the valid ISO 8601 formatted date to pass.'); + + $graphNode = new GraphAlbum([ + 'created_time' => '2009-05-19T14a39r' + ] + ); + $this->assertNotInstanceOf(DateTime::class, $graphNode->getCreatedTime(),'Expected the invalid ISO 8601 format to fail.'); + + $graphNode = new GraphAlbum([ + 'created_time' => 'foo_time' + ] + ); + $this->assertNotInstanceOf(DateTime::class, $graphNode->getCreatedTime(),'Expected the invalid ISO 8601 format to fail.'); } public function testATimeStampCanBeConvertedToADateTimeObject() { $someTimeStampFromGraph = 1405547020; - $graphNode = new GraphNode(); - $dateTime = $graphNode->castToDateTime($someTimeStampFromGraph); - $prettyDate = $dateTime->format(\DateTime::RFC1036); - $timeStamp = $dateTime->getTimestamp(); + $graphNode = new GraphPhoto([ + 'created_time' => $someTimeStampFromGraph + ]); + $createdTime = $graphNode->getCreatedTime(); + $prettyDate = $createdTime->format(DateTimeInterface::RFC1036); + $timeStamp = $createdTime->getTimestamp(); - $this->assertInstanceOf('DateTime', $dateTime); + $this->assertInstanceOf(DateTime::class, $createdTime); $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); $this->assertEquals(1405547020, $timeStamp); } @@ -85,12 +107,14 @@ public function testATimeStampCanBeConvertedToADateTimeObject() public function testAGraphDateStringCanBeConvertedToADateTimeObject() { $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; - $graphNode = new GraphNode(); - $dateTime = $graphNode->castToDateTime($someDateStringFromGraph); - $prettyDate = $dateTime->format(\DateTime::RFC1036); - $timeStamp = $dateTime->getTimestamp(); + $graphNode = new GraphPhoto([ + 'created_time' => $someDateStringFromGraph + ]); + $createdTime = $graphNode->getCreatedTime(); + $prettyDate = $createdTime->format(DateTimeInterface::RFC1036); + $timeStamp = $createdTime->getTimestamp(); - $this->assertInstanceOf('DateTime', $dateTime); + $this->assertInstanceOf(DateTime::class, $createdTime); $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); $this->assertEquals(1405395893, $timeStamp); } @@ -100,7 +124,7 @@ public function testUncastingAGraphNodeWillUncastTheDateTimeObject() $collectionOne = new GraphNode(['foo', 'bar']); $collectionTwo = new GraphNode([ 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'date' => new DateTime('2014-07-15T03:44:53+0000'), 'some_collection' => $collectionOne, ]); @@ -117,19 +141,19 @@ public function testGettingGraphNodeAsAnArrayWillNotUncastTheDateTimeObject() { $collection = new GraphNode([ 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'date' => new DateTime('2014-07-15T03:44:53+0000'), ]); $collectionAsArray = $collection->asArray(); - $this->assertInstanceOf('DateTime', $collectionAsArray['date']); + $this->assertInstanceOf(DateTime::class, $collectionAsArray['date']); } public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() { $collection = new GraphNode([ 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'date' => new DateTime('2014-07-15T03:44:53+0000'), ]); $collectionAsString = $collection->asJson(); diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php deleted file mode 100644 index 71ae5c4..0000000 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ /dev/null @@ -1,115 +0,0 @@ -request = new FacebookRequest( - $app, - 'foo_token', - 'GET', - '/me/photos?keep=me', - ['foo' => 'bar'], - 'foo_eTag', - 'v1337' - ); - } - - public function testAGraphNodeWillBeCastAsAGraphNode() - { - $data = json_encode([ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ]); - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $graphObject = $factory->makeGraphObject(); - $graphData = $graphObject->asArray(); - - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); - $this->assertEquals([ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], $graphData); - } - - public function testAListFromGraphWillBeCastAsAGraphEdge() - { - $data = json_encode([ - 'data' => [ - [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], - [ - 'id' => '1337', - 'name' => 'Bar McBaz', - 'link' => 'http://facebook/bar', - ], - ], - 'paging' => [ - 'next' => 'http://facebook/next', - 'previous' => 'http://facebook/prev', - ], - ]); - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $graphList = $factory->makeGraphList(); - $graphData = $graphList->asArray(); - - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); - $this->assertEquals([ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], $graphData[0]); - $this->assertEquals([ - 'id' => '1337', - 'name' => 'Bar McBaz', - 'link' => 'http://facebook/bar', - ], $graphData[1]); - } -} diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php index 6600c23..6cada77 100644 --- a/tests/GraphNodes/GraphPageTest.php +++ b/tests/GraphNodes/GraphPageTest.php @@ -23,20 +23,21 @@ */ namespace Facebook\Tests\GraphNodes; +use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphLocation; +use Facebook\GraphNodes\GraphPage; +use Facebook\GraphNodes\GraphVideo; use Facebook\Tests\BaseTestCase; use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; class GraphPageTest extends BaseTestCase { - /** - * @var \Facebook\FacebookResponse - */ - protected $responseMock; + protected FacebookResponse $responseMock; protected function setUp(): void { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + $this->responseMock = m::mock(FacebookResponse::class); } public function testPagePropertiesReturnGraphPageObjects() @@ -48,10 +49,13 @@ public function testPagePropertiesReturnGraphPageObjects() 'id' => '1', 'name' => 'Bar Page', ], - 'global_brand_parent_page' => [ + 'featured_video' => [ 'id' => '2', - 'name' => 'Faz Page', + 'is_reference_only' => true, ], + 'contact_address' => [ + 'street1' => '123 Fake St', + ] ]; $this->responseMock @@ -59,26 +63,31 @@ public function testPagePropertiesReturnGraphPageObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphPage(); + /** @var GraphPage $graphNode */ + $graphNode = $factory->makeGraphNode(GraphPage::class); $bestPage = $graphNode->getBestPage(); - $globalBrandParentPage = $graphNode->getGlobalBrandParentPage(); + $video = $graphNode->getFeaturedVideo(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $bestPage); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $globalBrandParentPage); + $this->assertInstanceOf(GraphPage::class, $bestPage); + $this->assertInstanceOf(GraphVideo::class, $video); + $this->assertEquals('2', $video->getId()); + $this->assertTrue($video->isReferenceOnly()); } public function testLocationPropertyWillGetCastAsGraphLocationObject() { $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo Page', + 'id' => '123', + 'name' => 'Foo Page', 'location' => [ - 'city' => 'Washington', - 'country' => 'United States', - 'latitude' => 38.881634205431, + 'city' => 'Washington', + 'country' => 'United States', + 'latitude' => 38.881634205431, 'longitude' => -77.029121075722, - 'state' => 'DC', + 'state' => 'DC', + 'zip' => '19933', + 'street' => 'Pennsylvania Avenue 2', ], ]; @@ -87,10 +96,18 @@ public function testLocationPropertyWillGetCastAsGraphLocationObject() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphPage(); + /** @var GraphPage $graphNode */ + $graphNode = $factory->makeGraphNode(GraphPage::class); $location = $graphNode->getLocation(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphLocation', $location); + $this->assertInstanceOf(GraphLocation::class, $location); + $this->assertEquals('Washington', $location->getCity()); + $this->assertEquals(38.881634205431, $location->getLatitude()); + $this->assertEquals(-77.029121075722, $location->getLongitude()); + $this->assertEquals('DC', $location->getState()); + $this->assertEquals('United States', $location->getCountry()); + $this->assertEquals('19933', $location->getZip()); + $this->assertEquals('Pennsylvania Avenue 2', $location->getStreet()); } } diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index df8bc85..4edf543 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -23,20 +23,21 @@ */ namespace Facebook\Tests\GraphNodes; +use DateTime; +use Facebook\FacebookResponse; +use Facebook\GraphNodes\GraphSessionInfo; use Facebook\Tests\BaseTestCase; use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; class GraphSessionInfoTest extends BaseTestCase { - /** - * @var \Facebook\FacebookResponse - */ - protected $responseMock; + + protected FacebookResponse $responseMock; protected function setUp(): void { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + $this->responseMock = m::mock(FacebookResponse::class); } public function testDatesGetCastToDateTime() @@ -52,12 +53,13 @@ public function testDatesGetCastToDateTime() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphSessionInfo(); + /** @var GraphSessionInfo $graphNode */ + $graphNode = $factory->makeGraphNode(GraphSessionInfo::class); $expires = $graphNode->getExpiresAt(); $issuedAt = $graphNode->getIssuedAt(); - $this->assertInstanceOf('DateTime', $expires); - $this->assertInstanceOf('DateTime', $issuedAt); + $this->assertInstanceOf(DateTime::class, $expires); + $this->assertInstanceOf(DateTime::class, $issuedAt); } } diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index 037b354..c59101d 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -23,21 +23,36 @@ */ namespace Facebook\Tests\GraphNodes; +use DateTime; +use Facebook\FacebookRequest; use Facebook\FacebookResponse; +use Facebook\GraphNodes\Birthday; +use Facebook\GraphNodes\GraphAgeRange; +use Facebook\GraphNodes\GraphAlbum; +use Facebook\GraphNodes\GraphEdge; +use Facebook\GraphNodes\GraphEvent; +use Facebook\GraphNodes\GraphExperience; +use Facebook\GraphNodes\GraphPage; +use Facebook\GraphNodes\GraphPaymentPricePoints; +use Facebook\GraphNodes\GraphPermission; +use Facebook\GraphNodes\GraphPhoto; +use Facebook\GraphNodes\GraphPicture; +use Facebook\GraphNodes\GraphPlace; +use Facebook\GraphNodes\GraphPlatformImageSource; +use Facebook\GraphNodes\GraphUser; +use Facebook\GraphNodes\GraphVideoUploadLimits; use Facebook\Tests\BaseTestCase; use Mockery as m; use Facebook\GraphNodes\GraphNodeFactory; class GraphUserTest extends BaseTestCase { - /** - * @var FacebookResponse - */ - protected $responseMock; + + protected FacebookResponse $responseMock; protected function setUp(): void { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + $this->responseMock = m::mock(FacebookResponse::class); } public function testDatesGetCastToDateTime() @@ -51,11 +66,12 @@ public function testDatesGetCastToDateTime() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); $updatedTime = $graphNode->getField('updated_time'); - $this->assertInstanceOf('DateTime', $updatedTime); + $this->assertInstanceOf(DateTime::class, $updatedTime); } public function testBirthdaysGetCastToBirthday() @@ -69,14 +85,15 @@ public function testBirthdaysGetCastToBirthday() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); $birthday = $graphNode->getBirthday(); // Test to ensure BC - $this->assertInstanceOf('DateTime', $birthday); + $this->assertInstanceOf(DateTime::class, $birthday); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\Birthday', $birthday); + $this->assertInstanceOf(Birthday::class, $birthday); $this->assertTrue($birthday->hasDate()); $this->assertTrue($birthday->hasYear()); $this->assertEquals('1984/01/01', $birthday->format('Y/m/d')); @@ -93,7 +110,8 @@ public function testBirthdayCastHandlesDateWithoutYear() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); $birthday = $graphNode->getBirthday(); @@ -113,7 +131,8 @@ public function testBirthdayCastHandlesYearWithoutDate() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); $birthday = $graphNode->getBirthday(); @@ -142,24 +161,75 @@ public function testPagePropertiesWillGetCastAsGraphPageObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); $hometown = $graphNode->getHometown(); $location = $graphNode->getLocation(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $hometown); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $location); + $this->assertInstanceOf(GraphPage::class, $hometown); + $this->assertInstanceOf(GraphPage::class, $location); } public function testUserPropertiesWillGetCastAsGraphUserObjects() { $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo User', - 'significant_other' => [ - 'id' => '1337', + 'id' => '123', + 'name' => 'Foo User', + 'short_name' => 'Foo B.', + 'age_range' => [ + 'min' => 20, + 'max' => 30 + ], + 'significant_other' => [ + 'id' => '1337', 'name' => 'Bar User', ], + 'video_upload_limits' => [ + 'size' => 4, + 'length' => 5 + ], + 'token_for_business' => 'token test', + 'favorite_teams' => [ + [ + 'id' => 'team id', + 'description' => 'team description', + 'name' => 'team name', + 'with' => [ + 'id' => 'with_user_id', + 'name' => 'With Name' + ] + ] + ], + 'favorite_athletes' => [ + [ + 'id' => 'athlete id' + ] + ], + 'languages' => [ + [ + 'id' => 'en', + 'name' => 'English' + ] + ], + 'inspirational_people' => [ + [ + 'id' => '28424' + ] + ], + 'hometown' => [ + 'id' => '454', + 'name' => 'New York' + ], + 'payment_pricepoints' => [ + 'mobile' => [ + [ + 'credits' => 4545.34, + 'currency' => 'USD', + 'user_price' => '4,545.34 USD' + ] + ] + ] ]; $this->responseMock @@ -167,11 +237,45 @@ public function testUserPropertiesWillGetCastAsGraphUserObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); + + $this->assertInstanceOf(GraphUser::class, $graphNode->getSignificantOther()); + + $this->assertInstanceOf(GraphAgeRange::class, $graphNode->getAgeRange()); + $this->assertEquals(20, $graphNode->getAgeRange()->getMin()); + $this->assertEquals(30, $graphNode->getAgeRange()->getMax()); + + $this->assertInstanceOf(GraphVideoUploadLimits::class, $graphNode->getVideoUploadLimits()); + $this->assertEquals(4, $graphNode->getVideoUploadLimits()->getSize()); + $this->assertEquals(5, $graphNode->getVideoUploadLimits()->getLength()); + + $this->assertIsArray($graphNode->getFavoriteTeams()); + $this->assertIsArray($graphNode->getFavoriteAthletes()); + $this->assertIsArray($graphNode->getLanguages()); + $this->assertIsArray($graphNode->getInspirationalPeople()); + + $this->assertInstanceOf(GraphExperience::class, $graphNode->getFavoriteTeams()[0]); + $this->assertEquals('team description', $graphNode->getFavoriteTeams()[0]->getDescription()); + + $this->assertInstanceOf(GraphPage::class, $graphNode->getHometown()); + $this->assertEquals('New York', $graphNode->getHometown()->getName()); + $this->assertEquals('454', $graphNode->getHometown()->getId()); - $significantOther = $graphNode->getSignificantOther(); + $this->assertInstanceOf(GraphPaymentPricePoints::class, $graphNode->getPaymentPricePoints()); + $this->assertIsArray($graphNode->getPaymentPricePoints()->getMobile()); + $this->assertEquals('4,545.34 USD', $graphNode->getPaymentPricePoints()->getMobile()[0]->getUserPrice()); + $this->assertEquals('USD', $graphNode->getPaymentPricePoints()->getMobile()[0]->getCurrency()); + $this->assertEquals(4545.34, $graphNode->getPaymentPricePoints()->getMobile()[0]->getCredits()); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); + $this->assertInstanceOf(GraphExperience::class, $graphNode->getFavoriteAthletes()[0]); + $this->assertInstanceOf(GraphExperience::class, $graphNode->getLanguages()[0]); + $this->assertInstanceOf(GraphExperience::class, $graphNode->getInspirationalPeople()[0]); + + $this->assertInstanceOf(GraphUser::class, $graphNode->getFavoriteTeams()[0]->getWith()); + + $this->assertEquals('Foo B.', $graphNode->getShortName()); + $this->assertEquals('token test', $graphNode->getTokenForBusiness()); } public function testPicturePropertiesWillGetCastAsGraphPictureObjects() @@ -192,14 +296,197 @@ public function testPicturePropertiesWillGetCastAsGraphPictureObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphNode = $factory->makeGraphUser(); + /** @var GraphUser $graphNode */ + $graphNode = $factory->makeGraphNode(GraphUser::class); $Picture = $graphNode->getPicture(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPicture', $Picture); + $this->assertInstanceOf(GraphPicture::class, $Picture); $this->assertTrue($Picture->isSilhouette()); $this->assertEquals(200, $Picture->getWidth()); $this->assertEquals(200, $Picture->getHeight()); $this->assertEquals('http://foo.bar', $Picture->getUrl()); } + + public function testPhotoPropertiesWillGetCastAsGraphPhotoObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'album' => [ + 'id' => '844', + 'name' => 'album name' + ], + 'alt_text' => 'alt text', + 'alt_text_custom' => 'alt text custom', + 'backdated_time' => 1742481204, + 'can_backdate' => true, + 'can_delete' => true, + 'can_tag' => true, + 'created_time' =>1742481234, + 'event' => [ + 'id' => '3843', + 'name' => 'event name' + ], + 'height' => 884, + 'width' => 483, + 'icon' => 'icon string', + 'link' => 'link string', + 'name' => 'photo name', + 'page_story_id' => '3848232', + 'place' => [ + 'id' => '28523', + 'name' => 'some place name' + ], + 'updated_time' => 1742481303, + 'webp_images' => [ + [ + 'height' => 422, + 'width' => 433, + 'source' => 'webp source' + ] + ], + 'images' => [ + [ + 'height' => 555, + 'width' => 666, + 'source' => 'image source' + ] + ] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + /** @var GraphPhoto $graphNode */ + $graphNode = $factory->makeGraphNode(GraphPhoto::class); + + $event = $graphNode->getEvent(); + $place = $graphNode->getPlace(); + $album = $graphNode->getAlbum(); + + $this->assertInstanceOf(GraphEvent::class, $event); + $this->assertEquals('3843', $event->getId()); + + $this->assertInstanceOf(GraphPlace::class, $place); + $this->assertEquals('some place name', $place->getName()); + + $this->assertInstanceOf(GraphAlbum::class, $album); + $this->assertEquals('album name', $album->getName()); + + $this->assertEquals('alt text', $graphNode->getAltText()); + $this->assertEquals('alt text custom', $graphNode->getAltTextCustom()); + $this->assertEquals('3848232', $graphNode->getPageStoryId()); + $this->assertEquals('link string', $graphNode->getLink()); + $this->assertEquals('icon string', $graphNode->getIcon()); + + $this->assertInstanceOf(DateTime::class, $graphNode->getUpdatedTime()); + $this->assertInstanceOf(DateTime::class, $graphNode->getCreatedTime()); + $this->assertInstanceOf(DateTime::class, $graphNode->getBackDatedTime()); + + $this->assertIsArray($graphNode->getWebPImages()); + $this->assertIsArray($graphNode->getImages()); + + $this->assertInstanceOf(GraphPlatformImageSource::class, $graphNode->getWebPImages()[0]); + $this->assertInstanceOf(GraphPlatformImageSource::class, $graphNode->getImages()[0]); + + $this->assertEquals(422, $graphNode->getWebPImages()[0]->getHeight()); + $this->assertEquals(433, $graphNode->getWebPImages()[0]->getWidth()); + $this->assertEquals('webp source', $graphNode->getWebPImages()[0]->getSource()); + + } + + public function testGraphNodeUserArraysAndListsRecursively() + { + + $json = <<makeGraphNode(GraphUser::class); + + $this->assertInstanceOf(GraphUser::class, $graphNode); + $this->assertIsArray($graphNode->getSports()); + + $this->assertCount(2, $graphNode->getSports()); + $this->assertInstanceOf(GraphExperience::class, $graphNode->getSports()[0]); + $this->assertEquals('some description', $graphNode->getSports()[0]->getDescription()); + $this->assertEquals('some description 2', $graphNode->getSports()[1]->getDescription()); + + $this->assertIsArray($graphNode->getField('string_array')); + $this->assertCount(3, $graphNode->getField('string_array')); + $this->assertEquals('foo', $graphNode->getField('string_array')[0]); + $this->assertEquals('bar', $graphNode->getField('string_array')[1]); + + $this->assertInstanceOf(GraphEdge::class, $graphNode->getPermissions()); + $this->assertInstanceOf(GraphPermission::class, $graphNode->getPermissions()->all()[0]); + + $this->assertInstanceOf(GraphEdge::class, $graphNode->getAlbums()); + + $album = $graphNode->getAlbums()->all()[0]; + $this->assertInstanceOf(GraphAlbum::class, $album); + $this->assertInstanceOf(GraphPhoto::class, $album->getCoverPhoto()); + $this->assertInstanceOf(GraphAlbum::class, $album->getCoverPhoto()->getAlbum()); + + $this->assertEquals($album->getCoverPhoto()->getAlbum()->getId(), $album->getId()); + + } } diff --git a/tests/Helpers/FacebookCanvasHelperTest.php b/tests/Helpers/FacebookCanvasHelperTest.php index c366c32..f8dcd8f 100644 --- a/tests/Helpers/FacebookCanvasHelperTest.php +++ b/tests/Helpers/FacebookCanvasHelperTest.php @@ -30,12 +30,9 @@ class FacebookCanvasHelperTest extends BaseTestCase { - public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public string $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; - /** - * @var FacebookCanvasHelper - */ - protected $helper; + protected FacebookCanvasHelper $helper; protected function setUp(): void { diff --git a/tests/Helpers/FacebookJavaScriptHelperTest.php b/tests/Helpers/FacebookJavaScriptHelperTest.php index 2956833..d3d5014 100644 --- a/tests/Helpers/FacebookJavaScriptHelperTest.php +++ b/tests/Helpers/FacebookJavaScriptHelperTest.php @@ -30,7 +30,7 @@ class FacebookJavaScriptHelperTest extends BaseTestCase { - public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public string $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; public function testARawSignedRequestCanBeRetrievedFromCookieData() { diff --git a/tests/Helpers/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php index d13606e..634211b 100644 --- a/tests/Helpers/FacebookPageTabHelperTest.php +++ b/tests/Helpers/FacebookPageTabHelperTest.php @@ -30,7 +30,7 @@ class FacebookPageTabHelperTest extends BaseTestCase { - protected $rawSignedRequestAuthorized = '6Hi26ECjkj347belC0O8b8H5lwiIz5eA6V9VVjTg-HU=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MzIxLCJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsInVzZXJfaWQiOiIxMjMiLCJwYWdlIjp7ImlkIjoiNDIiLCJsaWtlZCI6dHJ1ZSwiYWRtaW4iOmZhbHNlfX0='; + protected string $rawSignedRequestAuthorized = '6Hi26ECjkj347belC0O8b8H5lwiIz5eA6V9VVjTg-HU=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MzIxLCJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsInVzZXJfaWQiOiIxMjMiLCJwYWdlIjp7ImlkIjoiNDIiLCJsaWtlZCI6dHJ1ZSwiYWRtaW4iOmZhbHNlfX0='; public function testPageDataCanBeAccessed() { diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 45a7572..2e2b052 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -35,15 +35,8 @@ class FacebookRedirectLoginHelperTest extends BaseTestCase { - /** - * @var FacebookMemoryPersistentDataHandler - */ - protected $persistentDataHandler; - - /** - * @var FacebookRedirectLoginHelper - */ - protected $redirectLoginHelper; + protected FacebookMemoryPersistentDataHandler $persistentDataHandler; + protected FacebookRedirectLoginHelper $redirectLoginHelper; const REDIRECT_URL = 'http://invalid.zzz'; const FOO_CODE = "foo_code"; diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 78f4965..ea8a7e5 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\Helpers; +use Facebook\Authentication\AccessToken; use Facebook\FacebookApp; use Facebook\Tests\BaseTestCase; use Facebook\Tests\Fixtures\FooSignedRequestHelper; @@ -30,14 +31,12 @@ class FacebookSignedRequestFromInputHelperTest extends BaseTestCase { - /** - * @var FooSignedRequestHelper - */ - protected $helper; - public $rawSignedRequestAuthorizedWithAccessToken = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; - public $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; - public $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; + protected FooSignedRequestHelper $helper; + + public string $rawSignedRequestAuthorizedWithAccessToken = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public string $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; + public string $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; protected function setUp(): void { @@ -76,7 +75,7 @@ public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessTok $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); $accessToken = $this->helper->getAccessToken(); - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertInstanceOf(AccessToken::class, $accessToken); $this->assertEquals('foo_token', $accessToken->getValue()); } @@ -85,7 +84,7 @@ public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); $accessToken = $this->helper->getAccessToken(); - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertInstanceOf(AccessToken::class, $accessToken); $this->assertEquals('foo_access_token_from:foo_code', $accessToken->getValue()); } } diff --git a/tests/Http/GraphRawResponseTest.php b/tests/Http/GraphRawResponseTest.php index 70e19d0..4c7e5e9 100644 --- a/tests/Http/GraphRawResponseTest.php +++ b/tests/Http/GraphRawResponseTest.php @@ -29,9 +29,9 @@ class GraphRawResponseTest extends BaseTestCase { - protected $fakeRawProxyHeader = "HTTP/1.0 200 Connection established + protected string $fakeRawProxyHeader = "HTTP/1.0 200 Connection established Proxy-agent: Kerio Control/7.1.1 build 1971\r\n\r\n"; - protected $fakeRawHeader = <<
'"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', 'Content-Type' => 'text/javascript; charset=UTF-8', 'X-FB-Rev' => '9244768', @@ -49,8 +49,8 @@ class GraphRawResponseTest extends BaseTestCase 'Access-Control-Allow-Origin' => '*', ]; - protected $jsonFakeHeader = 'x-fb-ads-insights-throttle: {"app_id_util_pct": 0.00,"acc_id_util_pct": 0.00}'; - protected $jsonFakeHeaderAsArray = ['x-fb-ads-insights-throttle' => '{"app_id_util_pct": 0.00,"acc_id_util_pct": 0.00}']; + protected string $jsonFakeHeader = 'x-fb-ads-insights-throttle: {"app_id_util_pct": 0.00,"acc_id_util_pct": 0.00}'; + protected array $jsonFakeHeaderAsArray = ['x-fb-ads-insights-throttle' => '{"app_id_util_pct": 0.00,"acc_id_util_pct": 0.00}']; public function testCanSetTheHeadersFromAnArray(): void { diff --git a/tests/Http/RequestBodyMultipartTest.php b/tests/Http/RequestBodyMultipartTest.php index 5da4f0d..9fdf639 100644 --- a/tests/Http/RequestBodyMultipartTest.php +++ b/tests/Http/RequestBodyMultipartTest.php @@ -60,7 +60,7 @@ public function testCanProperlyEncodeFilesAndParams() $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; $expectedBody .= "--foo_boundary\r\n"; $expectedBody .= "Content-Disposition: form-data; name=\"foo_file\"; filename=\"foo.txt\"\r\n"; - $expectedBody .= "Content-Type: text/plain\r\n\r\nThis is a text file used for testing. Let's dance.\r\n"; + $expectedBody .= "Content-Type: text/plain\r\n\r\nThis is a text file used for testing.\r\n"; $expectedBody .= "--foo_boundary--\r\n"; $this->assertEquals($expectedBody, $body); diff --git a/tests/HttpClients/AbstractTestHttpClient.php b/tests/HttpClients/AbstractTestHttpClient.php index ccafed3..737d0c4 100644 --- a/tests/HttpClients/AbstractTestHttpClient.php +++ b/tests/HttpClients/AbstractTestHttpClient.php @@ -27,13 +27,13 @@ abstract class AbstractTestHttpClient extends BaseTestCase { - protected $fakeRawRedirectHeader = "HTTP/1.1 302 Found + protected string $fakeRawRedirectHeader = "HTTP/1.1 302 Found Content-Type: text/html; charset=utf-8 Location: https://foobar.com/\r\n\r\n"; - protected $fakeRawProxyHeader = "HTTP/1.0 200 Connection established\r\n\r\n"; - protected $fakeRawProxyHeader2 = "HTTP/1.0 200 Connection established + protected string $fakeRawProxyHeader = "HTTP/1.0 200 Connection established\r\n\r\n"; + protected string $fakeRawProxyHeader2 = "HTTP/1.0 200 Connection established Proxy-agent: Kerio Control/7.1.1 build 1971\r\n\r\n"; - protected $fakeRawHeader = "HTTP/1.1 200 OK + protected string $fakeRawHeader = "HTTP/1.1 200 OK Etag: \"9d86b21aa74d74e574bbb35ba13524a52deb96e3\" Content-Type: text/javascript; charset=UTF-8 X-FB-Rev: 9244768 @@ -45,8 +45,8 @@ abstract class AbstractTestHttpClient extends BaseTestCase Content-Length: 29 Cache-Control: private, no-cache, no-store, must-revalidate Access-Control-Allow-Origin: *\r\n\r\n"; - protected $fakeRawBody = "{\"id\":\"123\",\"name\":\"Foo Bar\"}"; - protected $fakeHeadersAsArray = [ + protected string $fakeRawBody = "{\"id\":\"123\",\"name\":\"Foo Bar\"}"; + protected array $fakeHeadersAsArray = [ 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', 'Content-Type' => 'text/javascript; charset=UTF-8', 'X-FB-Rev' => '9244768', diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 30049de..6f72ffd 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -23,20 +23,22 @@ */ namespace Facebook\Tests\HttpClients; +use Facebook\Exceptions\FacebookSDKException; +use Facebook\HttpClients\FacebookCurl; use Mockery as m; use Facebook\HttpClients\FacebookCurlHttpClient; class FacebookCurlHttpClientTest extends AbstractTestHttpClient { /** - * @var \Facebook\HttpClients\FacebookCurl + * @var FacebookCurl */ - protected $curlMock; + protected FacebookCurl $curlMock; /** * @var FacebookCurlHttpClient */ - protected $curlClient; + protected FacebookCurlHttpClient $curlClient; const CURL_VERSION_STABLE = 0x072400; const CURL_VERSION_BUGGY = 0x071400; @@ -244,9 +246,8 @@ public function testCanSendNormalRequest(): void ->once() ->andReturn(null); - $response = $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); + $response = $this->curlClient->send('http://foo.com/', 'GET', null, [], 60); - $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); $this->assertEquals($this->fakeRawBody, $response->getBody()); $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); $this->assertEquals(200, $response->getHttpResponseCode()); @@ -254,7 +255,7 @@ public function testCanSendNormalRequest(): void public function testThrowsExceptionOnClientError(): void { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); + $this->expectException(FacebookSDKException::class); $this->curlMock ->shouldReceive('init') ->once() @@ -276,6 +277,6 @@ public function testThrowsExceptionOnClientError(): void ->once() ->andReturn('Foo error'); - $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); + $this->curlClient->send('http://foo.com/', 'GET', null, [], 60); } } diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index c4cf48f..becfce5 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -26,6 +26,8 @@ use Facebook\Exceptions\FacebookSDKException; +use Facebook\Http\GraphRawResponse; +use GuzzleHttp\Client; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Utils; @@ -35,19 +37,14 @@ class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient { - /** - * @var \GuzzleHttp\Client - */ - protected $guzzleMock; - /** - * @var FacebookGuzzleHttpClient - */ - protected $guzzleClient; + protected Client $guzzleMock; + + protected FacebookGuzzleHttpClient $guzzleClient; protected function setUp(): void { - $this->guzzleMock = m::mock('GuzzleHttp\Client'); + $this->guzzleMock = m::mock(Client::class); $this->guzzleClient = new FacebookGuzzleHttpClient($this->guzzleMock); } @@ -89,7 +86,7 @@ public function testCanSendNormalRequest() $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); - $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertInstanceOf(GraphRawResponse::class, $response); $this->assertEquals($this->fakeRawBody, $response->getBody()); $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); $this->assertEquals(200, $response->getHttpResponseCode()); diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index d5a2d7c..af6fee4 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -23,20 +23,17 @@ */ namespace Facebook\Tests\HttpClients; +use Facebook\Exceptions\FacebookSDKException; +use Facebook\Http\GraphRawResponse; +use Facebook\HttpClients\FacebookStream; use Mockery as m; use Facebook\HttpClients\FacebookStreamHttpClient; class FacebookStreamHttpClientTest extends AbstractTestHttpClient { - /** - * @var \Facebook\HttpClients\FacebookStream - */ - protected $streamMock; - /** - * @var FacebookStreamHttpClient - */ - protected $streamClient; + protected FacebookStream $streamMock; + protected FacebookStreamHttpClient $streamClient; protected function setUp(): void { @@ -104,7 +101,7 @@ public function testCanSendNormalRequest() $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); - $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertInstanceOf(GraphRawResponse::class, $response); $this->assertEquals($this->fakeRawBody, $response->getBody()); $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); $this->assertEquals(200, $response->getHttpResponseCode()); @@ -112,7 +109,7 @@ public function testCanSendNormalRequest() public function testThrowsExceptionOnClientError() { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); + $this->expectException(FacebookSDKException::class); $this->streamMock ->shouldReceive('streamContextCreate') ->once() diff --git a/tests/HttpClients/HttpClientsFactoryTest.php b/tests/HttpClients/HttpClientsFactoryTest.php index d78dee2..b6eaef0 100644 --- a/tests/HttpClients/HttpClientsFactoryTest.php +++ b/tests/HttpClients/HttpClientsFactoryTest.php @@ -25,47 +25,41 @@ use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookGuzzleHttpClient; +use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookStreamHttpClient; use Facebook\HttpClients\HttpClientsFactory; use Facebook\Tests\BaseTestCase; use GuzzleHttp\Client; -use PHPUnit_Framework_TestCase; class HttpClientsFactoryTest extends BaseTestCase { - const COMMON_NAMESPACE = 'Facebook\HttpClients\\'; - const COMMON_INTERFACE = 'Facebook\HttpClients\FacebookHttpClientInterface'; - /** - * @param mixed $handler - * @param string $expected - * * @dataProvider httpClientsProvider */ - public function testCreateHttpClient($handler, $expected) + public function testCreateHttpClient(mixed $handler, string $expected) { $httpClient = HttpClientsFactory::createHttpClient($handler); - $this->assertInstanceOf(self::COMMON_INTERFACE, $httpClient); + $this->assertInstanceOf(FacebookHttpClientInterface::class, $httpClient); $this->assertInstanceOf($expected, $httpClient); } /** * @return array */ - public function httpClientsProvider() + public function httpClientsProvider(): array { $clients = [ - ['guzzle', self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], - ['stream', self::COMMON_NAMESPACE . 'FacebookStreamHttpClient'], - [new Client(), self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], - [new FacebookGuzzleHttpClient(), self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], - [new FacebookStreamHttpClient(), self::COMMON_NAMESPACE . 'FacebookStreamHttpClient'], - [null, self::COMMON_INTERFACE], + ['guzzle', FacebookGuzzleHttpClient::class], + ['stream', FacebookStreamHttpClient::class], + [new Client(), FacebookGuzzleHttpClient::class], + [new FacebookGuzzleHttpClient(), FacebookGuzzleHttpClient::class], + [new FacebookStreamHttpClient(), FacebookStreamHttpClient::class], + [null, FacebookHttpClientInterface::class], ]; if (extension_loaded('curl')) { - $clients[] = ['curl', self::COMMON_NAMESPACE . 'FacebookCurlHttpClient']; - $clients[] = [new FacebookCurlHttpClient(), self::COMMON_NAMESPACE . 'FacebookCurlHttpClient']; + $clients[] = ['curl', FacebookCurlHttpClient::class]; + $clients[] = [new FacebookCurlHttpClient(), FacebookCurlHttpClient::class]; } return $clients; diff --git a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php index 6b59ce6..24da710 100644 --- a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php +++ b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\PersistentData; +use Facebook\Exceptions\FacebookSDKException; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; use Facebook\Tests\BaseTestCase; @@ -30,13 +31,13 @@ class FacebookSessionPersistentDataHandlerTest extends BaseTestCase { public function testInactiveSessionsWillThrow() { - $this->expectException(\Facebook\Exceptions\FacebookSDKException::class); + $this->expectException(FacebookSDKException::class); new FacebookSessionPersistentDataHandler(); } public function testCanSetAValue() { - $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $handler = new FacebookSessionPersistentDataHandler(false); $handler->set('foo', 'bar'); $this->assertEquals('bar', $_SESSION['FBRLH_foo']); @@ -45,7 +46,7 @@ public function testCanSetAValue() public function testCanGetAValue() { $_SESSION['FBRLH_faz'] = 'baz'; - $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $handler = new FacebookSessionPersistentDataHandler(false); $value = $handler->get('faz'); $this->assertEquals('baz', $value); @@ -53,7 +54,7 @@ public function testCanGetAValue() public function testGettingAValueThatDoesntExistWillReturnNull() { - $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $handler = new FacebookSessionPersistentDataHandler(false); $value = $handler->get('does_not_exist'); $this->assertNull($value); diff --git a/tests/PersistentData/PersistentDataFactoryTest.php b/tests/PersistentData/PersistentDataFactoryTest.php index fd7f17f..783fafe 100644 --- a/tests/PersistentData/PersistentDataFactoryTest.php +++ b/tests/PersistentData/PersistentDataFactoryTest.php @@ -26,42 +26,34 @@ use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; use Facebook\PersistentData\PersistentDataFactory; +use Facebook\PersistentData\PersistentDataInterface; use Facebook\Tests\BaseTestCase; -use PHPUnit_Framework_TestCase; class PersistentDataFactoryTest extends BaseTestCase { - const COMMON_NAMESPACE = 'Facebook\PersistentData\\'; - const COMMON_INTERFACE = 'Facebook\PersistentData\PersistentDataInterface'; /** - * @param mixed $handler - * @param string $expected - * * @dataProvider persistentDataHandlerProviders */ - public function testCreatePersistentDataHandler($handler, $expected) + public function testCreatePersistentDataHandler(mixed $handler, string $expected) { $persistentDataHandler = PersistentDataFactory::createPersistentDataHandler($handler); - $this->assertInstanceOf(self::COMMON_INTERFACE, $persistentDataHandler); + $this->assertInstanceOf(PersistentDataInterface::class, $persistentDataHandler); $this->assertInstanceOf($expected, $persistentDataHandler); } - /** - * @return array - */ - public function persistentDataHandlerProviders() + public function persistentDataHandlerProviders(): array { $handlers = [ - ['memory', self::COMMON_NAMESPACE . 'FacebookMemoryPersistentDataHandler'], - [new FacebookMemoryPersistentDataHandler(), self::COMMON_NAMESPACE . 'FacebookMemoryPersistentDataHandler'], - [new FacebookSessionPersistentDataHandler(false), self::COMMON_NAMESPACE . 'FacebookSessionPersistentDataHandler'], - [null, self::COMMON_INTERFACE], + ['memory', FacebookMemoryPersistentDataHandler::class], + [new FacebookMemoryPersistentDataHandler(), FacebookMemoryPersistentDataHandler::class], + [new FacebookSessionPersistentDataHandler(false), FacebookSessionPersistentDataHandler::class], + [null, PersistentDataInterface::class], ]; if (session_status() === PHP_SESSION_ACTIVE) { - $handlers[] = ['session', self::COMMON_NAMESPACE . 'FacebookSessionPersistentDataHandler']; + $handlers[] = ['session', FacebookSessionPersistentDataHandler::class]; } return $handlers; diff --git a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php index aa5eae4..13d8d59 100644 --- a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php +++ b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php @@ -23,14 +23,15 @@ */ namespace Facebook\Tests\PseudoRandomString; +use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; +use Facebook\PseudoRandomString\RandomBytesPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; use Facebook\Tests\BaseTestCase; -use PHPUnit_Framework_TestCase; class PseudoRandomStringFactoryTest extends BaseTestCase { - const COMMON_NAMESPACE = 'Facebook\PseudoRandomString\\'; - const COMMON_INTERFACE = 'Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface'; /** * @param mixed $handler @@ -38,33 +39,30 @@ class PseudoRandomStringFactoryTest extends BaseTestCase * * @dataProvider csprngProvider */ - public function testCsprng($handler, $expected) + public function testCsprng(mixed $handler, string $expected) { $pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator($handler); - $this->assertInstanceOf(self::COMMON_INTERFACE, $pseudoRandomStringGenerator); + $this->assertInstanceOf(PseudoRandomStringGeneratorInterface::class, $pseudoRandomStringGenerator); $this->assertInstanceOf($expected, $pseudoRandomStringGenerator); } /** * @return array */ - public function csprngProvider() + public function csprngProvider(): array { $providers = [ - [null, self::COMMON_INTERFACE], + [null, PseudoRandomStringGeneratorInterface::class], ]; if (function_exists('random_bytes')) { - $providers[] = ['random_bytes', self::COMMON_NAMESPACE . 'RandomBytesPseudoRandomStringGenerator']; - } - if (function_exists('mcrypt_create_iv')) { - $providers[] = ['mcrypt', self::COMMON_NAMESPACE . 'McryptPseudoRandomStringGenerator']; + $providers[] = ['random_bytes', RandomBytesPseudoRandomStringGenerator::class]; } if (function_exists('openssl_random_pseudo_bytes')) { - $providers[] = ['openssl', self::COMMON_NAMESPACE . 'OpenSslPseudoRandomStringGenerator']; + $providers[] = ['openssl', OpenSslPseudoRandomStringGenerator::class]; } if (!ini_get('open_basedir') && is_readable('/dev/urandom')) { - $providers[] = ['urandom', self::COMMON_NAMESPACE . 'UrandomPseudoRandomStringGenerator']; + $providers[] = ['urandom', UrandomPseudoRandomStringGenerator::class]; } return $providers; diff --git a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php deleted file mode 100644 index a2850c3..0000000 --- a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php +++ /dev/null @@ -1,47 +0,0 @@ -expectException(InvalidArgumentException::class); - - $prsg = new MyFooBarPseudoRandomStringGenerator(); - $prsg->validateLength('foo_len'); - } - - public function testALengthThatIsNotAtLeastOneCharacterWillThrow() - { - $this->expectException(InvalidArgumentException::class); - - $prsg = new MyFooBarPseudoRandomStringGenerator(); - $prsg->validateLength(0); - } -} diff --git a/tests/Url/FacebookUrlManipulatorTest.php b/tests/Url/FacebookUrlManipulatorTest.php index 2d7011d..30827d0 100644 --- a/tests/Url/FacebookUrlManipulatorTest.php +++ b/tests/Url/FacebookUrlManipulatorTest.php @@ -31,7 +31,7 @@ class FacebookUrlManipulatorTest extends BaseTestCase /** * @dataProvider provideUris */ - public function testParamsGetRemovedFromAUrl($dirtyUrl, $expectedCleanUrl) + public function testParamsGetRemovedFromAUrl(string $dirtyUrl, string $expectedCleanUrl) { $removeParams = [ 'state', @@ -45,7 +45,7 @@ public function testParamsGetRemovedFromAUrl($dirtyUrl, $expectedCleanUrl) $this->assertEquals($expectedCleanUrl, $currentUri); } - public function provideUris() + public function provideUris(): array { return [ [ @@ -156,14 +156,14 @@ public function testParamsCanBeReturnedAsArray() /** * @dataProvider provideMergableEndpoints */ - public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) + public function testParamsCanBeMergedOntoUrlProperly(string $urlOne, string $urlTwo, string $expected) { $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); $this->assertEquals($result, $expected); } - public function provideMergableEndpoints() + public function provideMergableEndpoints(): array { return [ [ diff --git a/tests/foo.txt b/tests/foo.txt index fa6541b..3e35a2c 100644 --- a/tests/foo.txt +++ b/tests/foo.txt @@ -1 +1 @@ -This is a text file used for testing. Let's dance. \ No newline at end of file +This is a text file used for testing. \ No newline at end of file diff --git a/tests/foo2.txt b/tests/foo2.txt new file mode 100644 index 0000000..ccf2b23 --- /dev/null +++ b/tests/foo2.txt @@ -0,0 +1 @@ +This is a second text file used for testing. \ No newline at end of file