From 9a856cb77a018bcc775a86eb5478eae2e72082c3 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 3 Jul 2014 15:17:00 +0200 Subject: [PATCH 001/407] Fix permissions --- src/Facebook/HttpClients/FacebookCurl.php | 0 src/Facebook/HttpClients/FacebookCurlHttpClient.php | 0 src/Facebook/HttpClients/FacebookGuzzleHttpClient.php | 0 src/Facebook/HttpClients/FacebookHttpable.php | 0 src/Facebook/HttpClients/FacebookStream.php | 0 src/Facebook/HttpClients/FacebookStreamHttpClient.php | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/Facebook/HttpClients/FacebookCurl.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookCurlHttpClient.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookGuzzleHttpClient.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookHttpable.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookStream.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookStreamHttpClient.php diff --git a/src/Facebook/HttpClients/FacebookCurl.php b/src/Facebook/HttpClients/FacebookCurl.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookHttpable.php b/src/Facebook/HttpClients/FacebookHttpable.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookStream.php b/src/Facebook/HttpClients/FacebookStream.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php old mode 100755 new mode 100644 From 2e9035784f50ad36ae761ae5d1320c6b9d0cf787 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 3 Jul 2014 20:07:56 +0200 Subject: [PATCH 002/407] Fix permissions --- src/Facebook/HttpClients/FacebookCurl.php | 0 src/Facebook/HttpClients/FacebookCurlHttpClient.php | 0 src/Facebook/HttpClients/FacebookGuzzleHttpClient.php | 0 src/Facebook/HttpClients/FacebookHttpable.php | 0 src/Facebook/HttpClients/FacebookStream.php | 0 src/Facebook/HttpClients/FacebookStreamHttpClient.php | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/Facebook/HttpClients/FacebookCurl.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookCurlHttpClient.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookGuzzleHttpClient.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookHttpable.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookStream.php mode change 100755 => 100644 src/Facebook/HttpClients/FacebookStreamHttpClient.php diff --git a/src/Facebook/HttpClients/FacebookCurl.php b/src/Facebook/HttpClients/FacebookCurl.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookHttpable.php b/src/Facebook/HttpClients/FacebookHttpable.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookStream.php b/src/Facebook/HttpClients/FacebookStream.php old mode 100755 new mode 100644 diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php old mode 100755 new mode 100644 From a417ea0ae61fad14abab6b81728b79e8a912a082 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 3 Jul 2014 21:19:20 +0200 Subject: [PATCH 003/407] Move files --- src/Facebook/{ => Exceptions}/FacebookAuthorizationException.php | 0 src/Facebook/{ => Exceptions}/FacebookClientException.php | 0 src/Facebook/{ => Exceptions}/FacebookOtherException.php | 0 src/Facebook/{ => Exceptions}/FacebookPermissionException.php | 0 src/Facebook/{ => Exceptions}/FacebookRequestException.php | 0 src/Facebook/{ => Exceptions}/FacebookSDKException.php | 0 src/Facebook/{ => Exceptions}/FacebookServerException.php | 0 src/Facebook/{ => Exceptions}/FacebookThrottleException.php | 0 src/Facebook/{ => GraphNodes}/GraphAlbum.php | 0 src/Facebook/{ => GraphNodes}/GraphLocation.php | 0 src/Facebook/{ => GraphNodes}/GraphObject.php | 0 src/Facebook/{ => GraphNodes}/GraphPage.php | 0 src/Facebook/{ => GraphNodes}/GraphSessionInfo.php | 0 src/Facebook/{ => GraphNodes}/GraphUser.php | 0 src/Facebook/{ => GraphNodes}/GraphUserPage.php | 0 src/Facebook/{ => Helpers}/FacebookCanvasLoginHelper.php | 0 src/Facebook/{ => Helpers}/FacebookJavaScriptLoginHelper.php | 0 src/Facebook/{ => Helpers}/FacebookPageTabHelper.php | 0 src/Facebook/{ => Helpers}/FacebookRedirectLoginHelper.php | 0 .../{ => Helpers}/FacebookSignedRequestFromInputHelper.php | 0 .../{FacebookHttpable.php => FacebookHttpClientInterface.php} | 0 tests/{ => Exceptions}/FacebookRequestExceptionTest.php | 0 tests/{ => GraphNodes}/GraphAlbumTest.php | 0 tests/{ => GraphNodes}/GraphLocationTest.php | 0 tests/{ => GraphNodes}/GraphObjectTest.php | 0 tests/{ => GraphNodes}/GraphSessionInfoTest.php | 0 tests/{ => GraphNodes}/GraphUserTest.php | 0 tests/{ => Helpers}/FacebookCanvasLoginHelperTest.php | 0 tests/{ => Helpers}/FacebookJavaScriptLoginHelperTest.php | 0 tests/{ => Helpers}/FacebookPageTabHelperTest.php | 0 tests/{ => Helpers}/FacebookRedirectLoginHelperTest.php | 0 tests/{ => Helpers}/FacebookSignedRequestFromInputHelperTest.php | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename src/Facebook/{ => Exceptions}/FacebookAuthorizationException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookClientException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookOtherException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookPermissionException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookRequestException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookSDKException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookServerException.php (100%) rename src/Facebook/{ => Exceptions}/FacebookThrottleException.php (100%) rename src/Facebook/{ => GraphNodes}/GraphAlbum.php (100%) rename src/Facebook/{ => GraphNodes}/GraphLocation.php (100%) rename src/Facebook/{ => GraphNodes}/GraphObject.php (100%) rename src/Facebook/{ => GraphNodes}/GraphPage.php (100%) rename src/Facebook/{ => GraphNodes}/GraphSessionInfo.php (100%) rename src/Facebook/{ => GraphNodes}/GraphUser.php (100%) rename src/Facebook/{ => GraphNodes}/GraphUserPage.php (100%) rename src/Facebook/{ => Helpers}/FacebookCanvasLoginHelper.php (100%) rename src/Facebook/{ => Helpers}/FacebookJavaScriptLoginHelper.php (100%) rename src/Facebook/{ => Helpers}/FacebookPageTabHelper.php (100%) rename src/Facebook/{ => Helpers}/FacebookRedirectLoginHelper.php (100%) rename src/Facebook/{ => Helpers}/FacebookSignedRequestFromInputHelper.php (100%) rename src/Facebook/HttpClients/{FacebookHttpable.php => FacebookHttpClientInterface.php} (100%) rename tests/{ => Exceptions}/FacebookRequestExceptionTest.php (100%) rename tests/{ => GraphNodes}/GraphAlbumTest.php (100%) rename tests/{ => GraphNodes}/GraphLocationTest.php (100%) rename tests/{ => GraphNodes}/GraphObjectTest.php (100%) rename tests/{ => GraphNodes}/GraphSessionInfoTest.php (100%) rename tests/{ => GraphNodes}/GraphUserTest.php (100%) rename tests/{ => Helpers}/FacebookCanvasLoginHelperTest.php (100%) rename tests/{ => Helpers}/FacebookJavaScriptLoginHelperTest.php (100%) rename tests/{ => Helpers}/FacebookPageTabHelperTest.php (100%) rename tests/{ => Helpers}/FacebookRedirectLoginHelperTest.php (100%) rename tests/{ => Helpers}/FacebookSignedRequestFromInputHelperTest.php (100%) diff --git a/src/Facebook/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php similarity index 100% rename from src/Facebook/FacebookAuthorizationException.php rename to src/Facebook/Exceptions/FacebookAuthorizationException.php diff --git a/src/Facebook/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php similarity index 100% rename from src/Facebook/FacebookClientException.php rename to src/Facebook/Exceptions/FacebookClientException.php diff --git a/src/Facebook/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php similarity index 100% rename from src/Facebook/FacebookOtherException.php rename to src/Facebook/Exceptions/FacebookOtherException.php diff --git a/src/Facebook/FacebookPermissionException.php b/src/Facebook/Exceptions/FacebookPermissionException.php similarity index 100% rename from src/Facebook/FacebookPermissionException.php rename to src/Facebook/Exceptions/FacebookPermissionException.php diff --git a/src/Facebook/FacebookRequestException.php b/src/Facebook/Exceptions/FacebookRequestException.php similarity index 100% rename from src/Facebook/FacebookRequestException.php rename to src/Facebook/Exceptions/FacebookRequestException.php diff --git a/src/Facebook/FacebookSDKException.php b/src/Facebook/Exceptions/FacebookSDKException.php similarity index 100% rename from src/Facebook/FacebookSDKException.php rename to src/Facebook/Exceptions/FacebookSDKException.php diff --git a/src/Facebook/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php similarity index 100% rename from src/Facebook/FacebookServerException.php rename to src/Facebook/Exceptions/FacebookServerException.php diff --git a/src/Facebook/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php similarity index 100% rename from src/Facebook/FacebookThrottleException.php rename to src/Facebook/Exceptions/FacebookThrottleException.php diff --git a/src/Facebook/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php similarity index 100% rename from src/Facebook/GraphAlbum.php rename to src/Facebook/GraphNodes/GraphAlbum.php diff --git a/src/Facebook/GraphLocation.php b/src/Facebook/GraphNodes/GraphLocation.php similarity index 100% rename from src/Facebook/GraphLocation.php rename to src/Facebook/GraphNodes/GraphLocation.php diff --git a/src/Facebook/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php similarity index 100% rename from src/Facebook/GraphObject.php rename to src/Facebook/GraphNodes/GraphObject.php diff --git a/src/Facebook/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php similarity index 100% rename from src/Facebook/GraphPage.php rename to src/Facebook/GraphNodes/GraphPage.php diff --git a/src/Facebook/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php similarity index 100% rename from src/Facebook/GraphSessionInfo.php rename to src/Facebook/GraphNodes/GraphSessionInfo.php diff --git a/src/Facebook/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php similarity index 100% rename from src/Facebook/GraphUser.php rename to src/Facebook/GraphNodes/GraphUser.php diff --git a/src/Facebook/GraphUserPage.php b/src/Facebook/GraphNodes/GraphUserPage.php similarity index 100% rename from src/Facebook/GraphUserPage.php rename to src/Facebook/GraphNodes/GraphUserPage.php diff --git a/src/Facebook/FacebookCanvasLoginHelper.php b/src/Facebook/Helpers/FacebookCanvasLoginHelper.php similarity index 100% rename from src/Facebook/FacebookCanvasLoginHelper.php rename to src/Facebook/Helpers/FacebookCanvasLoginHelper.php diff --git a/src/Facebook/FacebookJavaScriptLoginHelper.php b/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php similarity index 100% rename from src/Facebook/FacebookJavaScriptLoginHelper.php rename to src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php diff --git a/src/Facebook/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php similarity index 100% rename from src/Facebook/FacebookPageTabHelper.php rename to src/Facebook/Helpers/FacebookPageTabHelper.php diff --git a/src/Facebook/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php similarity index 100% rename from src/Facebook/FacebookRedirectLoginHelper.php rename to src/Facebook/Helpers/FacebookRedirectLoginHelper.php diff --git a/src/Facebook/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php similarity index 100% rename from src/Facebook/FacebookSignedRequestFromInputHelper.php rename to src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php diff --git a/src/Facebook/HttpClients/FacebookHttpable.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php similarity index 100% rename from src/Facebook/HttpClients/FacebookHttpable.php rename to src/Facebook/HttpClients/FacebookHttpClientInterface.php diff --git a/tests/FacebookRequestExceptionTest.php b/tests/Exceptions/FacebookRequestExceptionTest.php similarity index 100% rename from tests/FacebookRequestExceptionTest.php rename to tests/Exceptions/FacebookRequestExceptionTest.php diff --git a/tests/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php similarity index 100% rename from tests/GraphAlbumTest.php rename to tests/GraphNodes/GraphAlbumTest.php diff --git a/tests/GraphLocationTest.php b/tests/GraphNodes/GraphLocationTest.php similarity index 100% rename from tests/GraphLocationTest.php rename to tests/GraphNodes/GraphLocationTest.php diff --git a/tests/GraphObjectTest.php b/tests/GraphNodes/GraphObjectTest.php similarity index 100% rename from tests/GraphObjectTest.php rename to tests/GraphNodes/GraphObjectTest.php diff --git a/tests/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php similarity index 100% rename from tests/GraphSessionInfoTest.php rename to tests/GraphNodes/GraphSessionInfoTest.php diff --git a/tests/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php similarity index 100% rename from tests/GraphUserTest.php rename to tests/GraphNodes/GraphUserTest.php diff --git a/tests/FacebookCanvasLoginHelperTest.php b/tests/Helpers/FacebookCanvasLoginHelperTest.php similarity index 100% rename from tests/FacebookCanvasLoginHelperTest.php rename to tests/Helpers/FacebookCanvasLoginHelperTest.php diff --git a/tests/FacebookJavaScriptLoginHelperTest.php b/tests/Helpers/FacebookJavaScriptLoginHelperTest.php similarity index 100% rename from tests/FacebookJavaScriptLoginHelperTest.php rename to tests/Helpers/FacebookJavaScriptLoginHelperTest.php diff --git a/tests/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php similarity index 100% rename from tests/FacebookPageTabHelperTest.php rename to tests/Helpers/FacebookPageTabHelperTest.php diff --git a/tests/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php similarity index 100% rename from tests/FacebookRedirectLoginHelperTest.php rename to tests/Helpers/FacebookRedirectLoginHelperTest.php diff --git a/tests/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php similarity index 100% rename from tests/FacebookSignedRequestFromInputHelperTest.php rename to tests/Helpers/FacebookSignedRequestFromInputHelperTest.php From 7c1b4b847ecbc1879a5977092490ded8cc129450 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 3 Jul 2014 21:46:25 +0200 Subject: [PATCH 004/407] Fix naming --- src/Facebook/Entities/AccessToken.php | 4 +- src/Facebook/Entities/SignedRequest.php | 2 +- .../FacebookAuthorizationException.php | 2 +- .../Exceptions/FacebookClientException.php | 2 +- .../Exceptions/FacebookOtherException.php | 2 +- .../FacebookPermissionException.php | 2 +- .../Exceptions/FacebookRequestException.php | 2 +- .../Exceptions/FacebookSDKException.php | 2 +- .../Exceptions/FacebookServerException.php | 2 +- .../Exceptions/FacebookThrottleException.php | 2 +- src/Facebook/FacebookRequest.php | 11 +- src/Facebook/FacebookResponse.php | 6 +- src/Facebook/FacebookSession.php | 2 + src/Facebook/GraphNodes/GraphAlbum.php | 2 +- src/Facebook/GraphNodes/GraphLocation.php | 2 +- src/Facebook/GraphNodes/GraphObject.php | 6 +- src/Facebook/GraphNodes/GraphPage.php | 2 +- src/Facebook/GraphNodes/GraphSessionInfo.php | 2 +- src/Facebook/GraphNodes/GraphUser.php | 2 +- src/Facebook/GraphNodes/GraphUserPage.php | 2 +- .../Helpers/FacebookCanvasLoginHelper.php | 2 +- .../Helpers/FacebookJavaScriptLoginHelper.php | 2 +- .../Helpers/FacebookPageTabHelper.php | 2 +- .../Helpers/FacebookRedirectLoginHelper.php | 6 +- .../FacebookSignedRequestFromInputHelper.php | 3 +- .../HttpClients/FacebookCurlHttpClient.php | 6 +- .../HttpClients/FacebookGuzzleHttpClient.php | 6 +- .../FacebookHttpClientInterface.php | 6 +- .../HttpClients/FacebookStreamHttpClient.php | 6 +- tests/Entities/AccessTokenTest.php | 10 +- tests/Entities/SignedRequestTest.php | 12 +- .../FacebookRequestExceptionTest.php | 18 +-- tests/FacebookSessionTest.php | 2 +- tests/GraphNodes/GraphAlbumTest.php | 4 +- tests/GraphNodes/GraphLocationTest.php | 4 +- tests/GraphNodes/GraphObjectTest.php | 4 +- tests/GraphNodes/GraphSessionInfoTest.php | 2 +- tests/GraphNodes/GraphUserTest.php | 2 +- .../Helpers/FacebookCanvasLoginHelperTest.php | 2 +- .../FacebookJavaScriptLoginHelperTest.php | 2 +- tests/Helpers/FacebookPageTabHelperTest.php | 2 +- .../FacebookRedirectLoginHelperTest.php | 142 +++++++++--------- ...cebookSignedRequestFromInputHelperTest.php | 2 +- .../FacebookCurlHttpClientTest.php | 2 +- .../FacebookGuzzleHttpClientTest.php | 2 +- .../FacebookStreamHttpClientTest.php | 2 +- 46 files changed, 161 insertions(+), 151 deletions(-) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 111e5a681..4a038cac1 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -24,9 +24,9 @@ namespace Facebook\Entities; use Facebook\FacebookRequest; -use Facebook\FacebookRequestException; +use Facebook\Exceptions\FacebookRequestException; use Facebook\FacebookSession; -use Facebook\GraphSessionInfo; +use Facebook\GraphNodes\GraphSessionInfo; /** * Class AccessToken diff --git a/src/Facebook/Entities/SignedRequest.php b/src/Facebook/Entities/SignedRequest.php index 09134c5bf..75701eb17 100644 --- a/src/Facebook/Entities/SignedRequest.php +++ b/src/Facebook/Entities/SignedRequest.php @@ -23,7 +23,7 @@ */ namespace Facebook\Entities; -use Facebook\FacebookSDKException; +use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookSession; /** diff --git a/src/Facebook/Exceptions/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php index 8a3a15c20..41220d4ca 100644 --- a/src/Facebook/Exceptions/FacebookAuthorizationException.php +++ b/src/Facebook/Exceptions/FacebookAuthorizationException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookAuthorizationException diff --git a/src/Facebook/Exceptions/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php index 0eaadae88..fee4434e0 100644 --- a/src/Facebook/Exceptions/FacebookClientException.php +++ b/src/Facebook/Exceptions/FacebookClientException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookClientException diff --git a/src/Facebook/Exceptions/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php index 7d6fdf4d5..9a9dfd2a0 100644 --- a/src/Facebook/Exceptions/FacebookOtherException.php +++ b/src/Facebook/Exceptions/FacebookOtherException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookOtherException diff --git a/src/Facebook/Exceptions/FacebookPermissionException.php b/src/Facebook/Exceptions/FacebookPermissionException.php index 7fe970c03..b4ec10cf9 100644 --- a/src/Facebook/Exceptions/FacebookPermissionException.php +++ b/src/Facebook/Exceptions/FacebookPermissionException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookPermissionException diff --git a/src/Facebook/Exceptions/FacebookRequestException.php b/src/Facebook/Exceptions/FacebookRequestException.php index 8d3fe7167..4493677c5 100644 --- a/src/Facebook/Exceptions/FacebookRequestException.php +++ b/src/Facebook/Exceptions/FacebookRequestException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookRequestException diff --git a/src/Facebook/Exceptions/FacebookSDKException.php b/src/Facebook/Exceptions/FacebookSDKException.php index 92d1412db..e45cdc957 100644 --- a/src/Facebook/Exceptions/FacebookSDKException.php +++ b/src/Facebook/Exceptions/FacebookSDKException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookSDKException diff --git a/src/Facebook/Exceptions/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php index d46223d8e..078afa40a 100644 --- a/src/Facebook/Exceptions/FacebookServerException.php +++ b/src/Facebook/Exceptions/FacebookServerException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookServerException diff --git a/src/Facebook/Exceptions/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php index a1b2f0996..ed5ebb060 100644 --- a/src/Facebook/Exceptions/FacebookThrottleException.php +++ b/src/Facebook/Exceptions/FacebookThrottleException.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Exceptions; /** * Class FacebookThrottleException diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index bab9466f4..1376b373b 100644 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -23,9 +23,10 @@ */ namespace Facebook; -use Facebook\HttpClients\FacebookHttpable; +use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; +use Facebook\Exceptions\FacebookRequestException; /** * Class FacebookRequest @@ -82,7 +83,7 @@ class FacebookRequest private $etag; /** - * @var FacebookHttpable HTTP client handler + * @var FacebookHttpClientInterface HTTP client handler */ private static $httpClientHandler; @@ -145,9 +146,9 @@ public function getETag() * setHttpClientHandler - Returns an instance of the HTTP client * handler * - * @param \Facebook\HttpClients\FacebookHttpable + * @param FacebookHttpClientInterface */ - public static function setHttpClientHandler(FacebookHttpable $handler) + public static function setHttpClientHandler(FacebookHttpClientInterface $handler) { static::$httpClientHandler = $handler; } @@ -156,7 +157,7 @@ public static function setHttpClientHandler(FacebookHttpable $handler) * getHttpClientHandler - Returns an instance of the HTTP client * data handler * - * @return FacebookHttpable + * @return FacebookHttpClientInterface */ public static function getHttpClientHandler() { diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index e174a9459..2a8e38c35 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -23,6 +23,8 @@ */ namespace Facebook; +use Facebook\GraphNodes\GraphObject; + /** * Class FacebookResponse * @package Facebook @@ -133,7 +135,7 @@ public function getETag() * * @return mixed */ - public function getGraphObject($type = 'Facebook\GraphObject') { + public function getGraphObject($type = 'Facebook\GraphNodes\GraphObject') { return (new GraphObject($this->responseData))->cast($type); } @@ -145,7 +147,7 @@ public function getGraphObject($type = 'Facebook\GraphObject') { * * @return mixed */ - public function getGraphObjectList($type = 'Facebook\GraphObject') { + public function getGraphObjectList($type = 'Facebook\GraphNodes\GraphObject') { $out = array(); $data = $this->responseData->data; for ($i = 0; $i < count($data); $i++) { diff --git a/src/Facebook/FacebookSession.php b/src/Facebook/FacebookSession.php index 580966ff7..171c3ad8b 100644 --- a/src/Facebook/FacebookSession.php +++ b/src/Facebook/FacebookSession.php @@ -25,6 +25,8 @@ use Facebook\Entities\AccessToken; use Facebook\Entities\SignedRequest; +use Facebook\GraphNodes\GraphSessionInfo; +use Facebook\Exceptions\FacebookSDKException; /** * Class FacebookSession diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index 5f9dc8ce8..28793b5e9 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphAlbum diff --git a/src/Facebook/GraphNodes/GraphLocation.php b/src/Facebook/GraphNodes/GraphLocation.php index 5326ea53a..aa72be325 100644 --- a/src/Facebook/GraphNodes/GraphLocation.php +++ b/src/Facebook/GraphNodes/GraphLocation.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphLocation diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index 4f22d2b22..d73904859 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphObject @@ -97,7 +97,7 @@ public function asArray() * * @return mixed */ - public function getProperty($name, $type = 'Facebook\GraphObject') + public function getProperty($name, $type = 'Facebook\GraphNodes\GraphObject') { if (isset($this->backingData[$name])) { $value = $this->backingData[$name]; @@ -124,7 +124,7 @@ public function getProperty($name, $type = 'Facebook\GraphObject') * * @return array */ - public function getPropertyAsArray($name, $type = 'Facebook\GraphObject') + public function getPropertyAsArray($name, $type = 'Facebook\GraphNodes\GraphObject') { $target = array(); if (isset($this->backingData[$name]['data'])) { diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index a66068e99..a3da2d463 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphPage diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index 4b97580ae..b96de8e92 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphSessionInfo diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 8da369f9c..3884e385a 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphUser diff --git a/src/Facebook/GraphNodes/GraphUserPage.php b/src/Facebook/GraphNodes/GraphUserPage.php index 9115da113..b2e16c872 100644 --- a/src/Facebook/GraphNodes/GraphUserPage.php +++ b/src/Facebook/GraphNodes/GraphUserPage.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\GraphNodes; /** * Class GraphUserPage diff --git a/src/Facebook/Helpers/FacebookCanvasLoginHelper.php b/src/Facebook/Helpers/FacebookCanvasLoginHelper.php index f673d9e6d..6e1c6496d 100644 --- a/src/Facebook/Helpers/FacebookCanvasLoginHelper.php +++ b/src/Facebook/Helpers/FacebookCanvasLoginHelper.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Helpers; /** * Class FacebookCanvasLoginHelper diff --git a/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php b/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php index b0a3e7e21..f72cb1729 100644 --- a/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php +++ b/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Helpers; /** * Class FacebookJavaScriptLoginHelper diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 60c96e308..c4ae53be9 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Helpers; /** * Class FacebookPageTabHelper diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index c29d509f7..76aa8ce62 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -21,7 +21,11 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Helpers; + +use Facebook\FacebookSession; +use Facebook\FacebookRequest; +use Facebook\Exceptions\FacebookSDKException; /** * Class FacebookRedirectLoginHelper diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index c497246a2..94c967cf8 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -21,8 +21,9 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook; +namespace Facebook\Helpers; +use Facebook\FacebookSession; use Facebook\Entities\SignedRequest; /** diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index bfe3fce4b..85ecd53a6 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -23,13 +23,13 @@ */ namespace Facebook\HttpClients; -use Facebook\FacebookSDKException; +use Facebook\Exceptions\FacebookSDKException; /** * Class FacebookCurlHttpClient * @package Facebook */ -class FacebookCurlHttpClient implements FacebookHttpable +class FacebookCurlHttpClient implements FacebookHttpClientInterface { /** @@ -125,7 +125,7 @@ public function getResponseHttpStatusCode() * * @return string Raw response from the server * - * @throws \Facebook\FacebookSDKException + * @throws FacebookSDKException */ public function send($url, $method = 'GET', $parameters = array()) { diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index de6977302..03a91c85a 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -23,13 +23,13 @@ */ namespace Facebook\HttpClients; -use Facebook\FacebookSDKException; +use Facebook\Exceptions\FacebookSDKException; use GuzzleHttp\Client; use GuzzleHttp\Exception\AdapterException; use GuzzleHttp\Exception\RequestException; -class FacebookGuzzleHttpClient implements FacebookHttpable { +class FacebookGuzzleHttpClient implements FacebookHttpClientInterface { /** * @var array The headers to be sent with the request @@ -99,7 +99,7 @@ public function getResponseHttpStatusCode() * * @return string Raw response from the server * - * @throws \Facebook\FacebookSDKException + * @throws FacebookSDKException */ public function send($url, $method = 'GET', $parameters = array()) { diff --git a/src/Facebook/HttpClients/FacebookHttpClientInterface.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php index e3afaf392..a0b475a34 100644 --- a/src/Facebook/HttpClients/FacebookHttpClientInterface.php +++ b/src/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -24,10 +24,10 @@ namespace Facebook\HttpClients; /** - * Interface FacebookHttpable + * Interface FacebookHttpClientInterface * @package Facebook */ -interface FacebookHttpable +interface FacebookHttpClientInterface { /** @@ -61,7 +61,7 @@ public function getResponseHttpStatusCode(); * * @return string Raw response from the server * - * @throws \Facebook\FacebookSDKException + * @throws \Facebook\Exceptions\FacebookSDKException */ public function send($url, $method = 'GET', $parameters = array()); diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index 006d1030a..ada2da2c8 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -23,9 +23,9 @@ */ namespace Facebook\HttpClients; -use Facebook\FacebookSDKException; +use Facebook\Exceptions\FacebookSDKException; -class FacebookStreamHttpClient implements FacebookHttpable { +class FacebookStreamHttpClient implements FacebookHttpClientInterface { /** * @var array The headers to be sent with the request @@ -95,7 +95,7 @@ public function getResponseHttpStatusCode() * * @return string Raw response from the server * - * @throws \Facebook\FacebookSDKException + * @throws FacebookSDKException */ public function send($url, $method = 'GET', $parameters = array()) { diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index 405c51ae0..a6c9a2247 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -44,7 +44,7 @@ public function testATokenIsValidatedOnTheAppIdAndMachineIdAndTokenValidityAndTo $dt = new \DateTime(); $dt->setTimestamp($aWeek); - $graphSessionInfoMock = m::mock('Facebook\GraphSessionInfo'); + $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock ->shouldReceive('getAppId') ->once() @@ -74,7 +74,7 @@ public function testATokenWillNotBeValidIfTheAppIdDoesNotMatch() $dt = new \DateTime(); $dt->setTimestamp($aWeek); - $graphSessionInfoMock = m::mock('Facebook\GraphSessionInfo'); + $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock ->shouldReceive('getAppId') ->once() @@ -104,7 +104,7 @@ public function testATokenWillNotBeValidIfTheMachineIdDoesNotMatch() $dt = new \DateTime(); $dt->setTimestamp($aWeek); - $graphSessionInfoMock = m::mock('Facebook\GraphSessionInfo'); + $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock ->shouldReceive('getAppId') ->once() @@ -134,7 +134,7 @@ public function testATokenWillNotBeValidIfTheCollectionTellsUsItsNotValid() $dt = new \DateTime(); $dt->setTimestamp($aWeek); - $graphSessionInfoMock = m::mock('Facebook\GraphSessionInfo'); + $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock ->shouldReceive('getAppId') ->once() @@ -164,7 +164,7 @@ public function testATokenWillNotBeValidIfTheTokenHasExpired() $dt = new \DateTime(); $dt->setTimestamp($lastWeek); - $graphSessionInfoMock = m::mock('Facebook\GraphSessionInfo'); + $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock ->shouldReceive('getAppId') ->once() diff --git a/tests/Entities/SignedRequestTest.php b/tests/Entities/SignedRequestTest.php index 3b42d7f8e..e40b42d48 100644 --- a/tests/Entities/SignedRequestTest.php +++ b/tests/Entities/SignedRequestTest.php @@ -26,7 +26,7 @@ public function testValidSignedRequestsWillPassFormattingValidation() } /** - * @expectedException \Facebook\FacebookSDKException + * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testInvalidSignedRequestsWillFailFormattingValidation() { @@ -63,7 +63,7 @@ public function testAValidEncodedSignatureCanBeDecoded() } /** - * @expectedException \Facebook\FacebookSDKException + * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testAnImproperlyEncodedSignatureWillThrowAnException() { @@ -78,7 +78,7 @@ public function testAValidEncodedPayloadCanBeDecoded() } /** - * @expectedException \Facebook\FacebookSDKException + * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testAnImproperlyEncodedPayloadWillThrowAnException() { @@ -91,7 +91,7 @@ public function testSignedRequestDataMustContainTheHmacSha256Algorithm() } /** - * @expectedException \Facebook\FacebookSDKException + * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testNonApprovedAlgorithmsWillThrowAnException() { @@ -115,7 +115,7 @@ public function testTwoBinaryStringsCanBeComparedForSignatureValidation() } /** - * @expectedException \Facebook\FacebookSDKException + * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testNonSameBinaryStringsWillThrowAnExceptionForSignatureValidation() { @@ -130,7 +130,7 @@ public function testASignedRequestWillPassCsrfValidation() } /** - * @expectedException \Facebook\FacebookSDKException + * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testASignedRequestWithIncorrectCsrfDataWillThrowAnException() { diff --git a/tests/Exceptions/FacebookRequestExceptionTest.php b/tests/Exceptions/FacebookRequestExceptionTest.php index a0ceeb169..dce931def 100644 --- a/tests/Exceptions/FacebookRequestExceptionTest.php +++ b/tests/Exceptions/FacebookRequestExceptionTest.php @@ -1,12 +1,12 @@ setExpectedException( - 'Facebook\\FacebookSDKException', 'Session has expired' + 'Facebook\\Exceptions\\FacebookSDKException', 'Session has expired' ); $bogusSession->validate(); } @@ -258,7 +258,7 @@ public function testInvalidCredentialsException() { $bogusSession = new FacebookSession('invalid-token'); $this->setExpectedException( - 'Facebook\\FacebookAuthorizationException', 'Invalid OAuth access token' + 'Facebook\\Exceptions\\FacebookAuthorizationException', 'Invalid OAuth access token' ); $bogusSession->validate('invalid-app-id', 'invalid-app-secret'); } diff --git a/tests/FacebookSessionTest.php b/tests/FacebookSessionTest.php index 8f53866f1..e80d5f212 100644 --- a/tests/FacebookSessionTest.php +++ b/tests/FacebookSessionTest.php @@ -2,7 +2,7 @@ use Mockery as m; use Facebook\FacebookSession; -use Facebook\GraphSessionInfo; +use Facebook\GraphNodes\GraphSessionInfo; class FacebookSessionTest extends PHPUnit_Framework_TestCase { diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index f72ce95fc..dc2045ac9 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -1,7 +1,7 @@ assertTrue($response instanceof GraphAlbum); $this->assertEquals($albumId, $response->getId()); - $this->assertTrue($response->getFrom() instanceof \Facebook\GraphUser); + $this->assertTrue($response->getFrom() instanceof \Facebook\GraphNodes\GraphUser); $this->assertTrue($response->canUpload()); $this->assertEquals(0, $response->getCount()); $this->assertEquals(self::ALBUM_NAME, $response->getName()); diff --git a/tests/GraphNodes/GraphLocationTest.php b/tests/GraphNodes/GraphLocationTest.php index 483b755b4..aba62bca0 100644 --- a/tests/GraphNodes/GraphLocationTest.php +++ b/tests/GraphNodes/GraphLocationTest.php @@ -1,8 +1,8 @@ disableSessionStatusCheck(); - $loginUrl = $helper->getLoginUrl(); - $state = $_SESSION['FBRLH_state']; - $params = array( - 'client_id' => FacebookTestCredentials::$appId, - 'redirect_uri' => self::REDIRECT_URL, - 'state' => $state, - 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, - 'scope' => implode(',', array()) - ); - $expectedUrl = 'https://www.facebook.com/v2.0/dialog/oauth?'; - $this->assertTrue(strpos($loginUrl, $expectedUrl) !== false); - foreach ($params as $key => $value) { - $this->assertTrue( - strpos($loginUrl, $key . '=' . urlencode($value)) !== false - ); - } - } - - public function testLogoutURL() - { - $helper = new FacebookRedirectLoginHelper( - self::REDIRECT_URL, - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); - $helper->disableSessionStatusCheck(); - $logoutUrl = $helper->getLogoutUrl( - FacebookTestHelper::$testSession, self::REDIRECT_URL - ); - $params = array( - 'next' => self::REDIRECT_URL, - 'access_token' => FacebookTestHelper::$testSession->getToken() - ); - $expectedUrl = 'https://www.facebook.com/logout.php?'; - $this->assertTrue(strpos($logoutUrl, $expectedUrl) !== false); - foreach ($params as $key => $value) { - $this->assertTrue( - strpos($logoutUrl, $key . '=' . urlencode($value)) !== false - ); - } - } - - public function testCSPRNG() - { - $helper = new FacebookRedirectLoginHelper( - self::REDIRECT_URL, - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); - $this->assertTrue(preg_match('/^([0-9a-f]+)$/', $helper->random(32))); - } - -} +disableSessionStatusCheck(); + $loginUrl = $helper->getLoginUrl(); + $state = $_SESSION['FBRLH_state']; + $params = array( + 'client_id' => FacebookTestCredentials::$appId, + 'redirect_uri' => self::REDIRECT_URL, + 'state' => $state, + 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, + 'scope' => implode(',', array()) + ); + $expectedUrl = 'https://www.facebook.com/v2.0/dialog/oauth?'; + $this->assertTrue(strpos($loginUrl, $expectedUrl) !== false); + foreach ($params as $key => $value) { + $this->assertTrue( + strpos($loginUrl, $key . '=' . urlencode($value)) !== false + ); + } + } + + public function testLogoutURL() + { + $helper = new FacebookRedirectLoginHelper( + self::REDIRECT_URL, + FacebookTestCredentials::$appId, + FacebookTestCredentials::$appSecret + ); + $helper->disableSessionStatusCheck(); + $logoutUrl = $helper->getLogoutUrl( + FacebookTestHelper::$testSession, self::REDIRECT_URL + ); + $params = array( + 'next' => self::REDIRECT_URL, + 'access_token' => FacebookTestHelper::$testSession->getToken() + ); + $expectedUrl = 'https://www.facebook.com/logout.php?'; + $this->assertTrue(strpos($logoutUrl, $expectedUrl) !== false); + foreach ($params as $key => $value) { + $this->assertTrue( + strpos($logoutUrl, $key . '=' . urlencode($value)) !== false + ); + } + } + + public function testCSPRNG() + { + $helper = new FacebookRedirectLoginHelper( + self::REDIRECT_URL, + FacebookTestCredentials::$appId, + FacebookTestCredentials::$appSecret + ); + $this->assertTrue(preg_match('/^([0-9a-f]+)$/', $helper->random(32))); + } + +} diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 436888429..9cd3c1e27 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -1,6 +1,6 @@ Date: Thu, 3 Jul 2014 21:48:21 +0200 Subject: [PATCH 005/407] Fix CSPRNG test --- tests/Helpers/FacebookRedirectLoginHelperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 9de51e933..7c8a3e101 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -65,7 +65,7 @@ public function testCSPRNG() FacebookTestCredentials::$appId, FacebookTestCredentials::$appSecret ); - $this->assertTrue(preg_match('/^([0-9a-f]+)$/', $helper->random(32))); + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $helper->random(32))); } } From 77059e08ed83386bdfcb33b0c29845735c3c6418 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Thu, 3 Jul 2014 17:26:10 -0700 Subject: [PATCH 006/407] Updating version to 4.1.0-wip --- src/Facebook/FacebookRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index 1376b373b..3c3a560e5 100644 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -40,7 +40,7 @@ class FacebookRequest /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '4.0.9'; + const VERSION = '4.1.0-wip'; /** * @const string Default Graph API version for requests From f945fe49f36e53d7a1579bf5e54b5b1dd0aa2797 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Sun, 6 Jul 2014 00:50:02 +0200 Subject: [PATCH 007/407] Refactored FacebookRedirectLoginHelper --- .../Helpers/FacebookRedirectLoginHelper.php | 80 +++++++++++++------ .../FacebookRedirectLoginHelperTest.php | 24 +++++- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 76aa8ce62..73dd1ff4a 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -46,39 +46,26 @@ class FacebookRedirectLoginHelper */ private $appSecret; - /** - * @var string The redirect URL for the application - */ - private $redirectUrl; - /** * @var string Prefix to use for session variables */ private $sessionPrefix = 'FBRLH_'; - /** - * @var string State token for CSRF validation - */ - protected $state; - /** * @var boolean Toggle for PHP session status check */ protected $checkForSessionStatus = true; /** - * Constructs a RedirectLoginHelper for a given appId and redirectUrl. + * Constructs a RedirectLoginHelper for a given appId. * - * @param string $redirectUrl The URL Facebook should redirect users to - * after login * @param string $appId The application id * @param string $appSecret The application secret */ - public function __construct($redirectUrl, $appId = null, $appSecret = null) + public function __construct($appId = null, $appSecret = null) { $this->appId = FacebookSession::_getTargetAppId($appId); $this->appSecret = FacebookSession::_getTargetAppSecret($appSecret); - $this->redirectUrl = $redirectUrl; } /** @@ -86,20 +73,22 @@ public function __construct($redirectUrl, $appId = null, $appSecret = null) * in order to continue the login process with Facebook. The * provided redirectUrl should invoke the handleRedirect method. * + * @param string $redirectUrl The URL Facebook should redirect users to + * after login * @param array $scope List of permissions to request during login * @param string $version Optional Graph API version if not default (v2.0) * * @return string */ - public function getLoginUrl($scope = array(), $version = null) + public function getLoginUrl($redirectUrl, $scope = array(), $version = null) { $version = ($version ?: FacebookRequest::GRAPH_API_VERSION); - $this->state = $this->random(16); - $this->storeState($this->state); + $state = $this->random(16); + $this->storeState($state); $params = array( 'client_id' => $this->appId, - 'redirect_uri' => $this->redirectUrl, - 'state' => $this->state, + 'redirect_uri' => $redirectUrl, + 'state' => $state, 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, 'scope' => implode(',', $scope) ); @@ -133,11 +122,10 @@ public function getLogoutUrl(FacebookSession $session, $next) */ public function getSessionFromRedirect() { - $this->loadState(); if ($this->isValidRedirect()) { $params = array( 'client_id' => FacebookSession::_getTargetAppId($this->appId), - 'redirect_uri' => $this->redirectUrl, + 'redirect_uri' => $this->getCurrentUri(), 'client_secret' => FacebookSession::_getTargetAppSecret($this->appSecret), 'code' => $this->getCode() @@ -163,7 +151,7 @@ public function getSessionFromRedirect() protected function isValidRedirect() { return $this->getCode() && isset($_GET['state']) - && $_GET['state'] == $this->state; + && $_GET['state'] == $this->loadState(); } /** @@ -214,12 +202,52 @@ protected function loadState() ); } if (isset($_SESSION[$this->sessionPrefix . 'state'])) { - $this->state = $_SESSION[$this->sessionPrefix . 'state']; - return $this->state; + return $_SESSION[$this->sessionPrefix . 'state']; } return null; } - + + protected function getCurrentUri() + { + $protocol = 'http'; + if (isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1) + || isset($_SERVER['SERVER_PORT']) && + ($_SERVER['SERVER_PORT'] === '443')) { + $protocol = 'https'; + } + $currentUri = $protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $parts = parse_url($currentUri); + + $full_query = array(); + parse_str($parts['query'], $full_query); + + // remove Facebook appended query params + $real_query = array_diff_key($full_query, array_flip(array('code', 'state'))); + $query = ''; + if (!empty($real_query)) { + $query = '?'.http_build_query($real_query, null, '&'); + } + + // use port if non default + $port = + isset($parts['port']) && + (($protocol === 'http' && $parts['port'] !== 80) || + ($protocol === 'https' && $parts['port'] !== 443)) + ? ':' . $parts['port'] : ''; + + // rebuild + return $protocol . '://' . $parts['host'] . $port . $parts['path'] . $query; + } + + /** + * Returns the HTTP Protocol + * + * @return string The HTTP Protocol + */ + protected function getHttpProtocol() { + } + /** * Generate a cryptographically secure pseudrandom number * diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 7c8a3e101..c39bea7e3 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -11,12 +11,11 @@ class FacebookRedirectLoginHelperTest extends PHPUnit_Framework_TestCase public function testLoginURL() { $helper = new FacebookRedirectLoginHelper( - self::REDIRECT_URL, FacebookTestCredentials::$appId, FacebookTestCredentials::$appSecret ); $helper->disableSessionStatusCheck(); - $loginUrl = $helper->getLoginUrl(); + $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); $state = $_SESSION['FBRLH_state']; $params = array( 'client_id' => FacebookTestCredentials::$appId, @@ -37,7 +36,6 @@ public function testLoginURL() public function testLogoutURL() { $helper = new FacebookRedirectLoginHelper( - self::REDIRECT_URL, FacebookTestCredentials::$appId, FacebookTestCredentials::$appSecret ); @@ -58,10 +56,28 @@ public function testLogoutURL() } } + public function testGetCurrentUriRemoveFacebookQueryParams() + { + $helper = new FacebookRedirectLoginHelper( + FacebookTestCredentials::$appId, + FacebookTestCredentials::$appSecret + ); + $helper->disableSessionStatusCheck(); + + $class = new ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); + $method = $class->getMethod('getCurrentUri'); + $method->setAccessible(true); + + $_SERVER['HTTP_HOST'] = 'localhost'; + $_SERVER['REQUEST_URI'] = '/something?state=0000&foo=bar&code=abcd'; + + $currentUri = $method->invoke($helper); + $this->assertEquals('http://localhost/something?foo=bar', $currentUri); + } + public function testCSPRNG() { $helper = new FacebookRedirectLoginHelper( - self::REDIRECT_URL, FacebookTestCredentials::$appId, FacebookTestCredentials::$appSecret ); From 69dcc620e7401c3746d0574c53d4d1fd345279e4 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Fri, 4 Jul 2014 19:03:30 +0200 Subject: [PATCH 008/407] Add composer master branch alias --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index 70ba459a6..d2edba898 100644 --- a/composer.json +++ b/composer.json @@ -26,5 +26,10 @@ "psr-4": { "Facebook\\": "src/Facebook/" } + }, + "extra": { + "branch-alias": { + "dev-master": "4.1.x-dev" + } } } From a0508f4fb01aa8d72c35ededd5d536f3ce12233c Mon Sep 17 00:00:00 2001 From: Dilip Raj Baral Date: Mon, 14 Jul 2014 16:54:47 +0545 Subject: [PATCH 009/407] Add an option to allow re-asking declined permissions Add an option to allow re-asking declined permissions as mentioned in https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.0#re-asking-declined-permissions --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 73dd1ff4a..8bd1eb2e5 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -80,7 +80,7 @@ public function __construct($appId = null, $appSecret = null) * * @return string */ - public function getLoginUrl($redirectUrl, $scope = array(), $version = null) + public function getLoginUrl($redirectUrl, $scope = array(), $rerequest = false, $version = null) { $version = ($version ?: FacebookRequest::GRAPH_API_VERSION); $state = $this->random(16); @@ -92,6 +92,10 @@ public function getLoginUrl($redirectUrl, $scope = array(), $version = null) 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, 'scope' => implode(',', $scope) ); + + if ($rerequest) + $params['auth_type'] = 'rerequest'; + return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . http_build_query($params, null, '&'); } From a896f9c3add15a12746fe772ae375b51f04a6c86 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 14 Jul 2014 11:18:11 +0200 Subject: [PATCH 010/407] [RedirectLoginHelper] Extract URI filtering feature --- .../Helpers/FacebookRedirectLoginHelper.php | 63 +++++++++++-------- .../FacebookRedirectLoginHelperTest.php | 9 +-- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 8bd1eb2e5..2276ef784 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -129,7 +129,7 @@ public function getSessionFromRedirect() if ($this->isValidRedirect()) { $params = array( 'client_id' => FacebookSession::_getTargetAppId($this->appId), - 'redirect_uri' => $this->getCurrentUri(), + 'redirect_uri' => $this->getFilteredUri($this->getCurrentUri()), 'client_secret' => FacebookSession::_getTargetAppSecret($this->appSecret), 'code' => $this->getCode() @@ -211,37 +211,42 @@ protected function loadState() return null; } - protected function getCurrentUri() + protected function getFilteredUri($uri) { - $protocol = 'http'; - if (isset($_SERVER['HTTPS']) && - ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1) - || isset($_SERVER['SERVER_PORT']) && - ($_SERVER['SERVER_PORT'] === '443')) { - $protocol = 'https'; - } - $currentUri = $protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - $parts = parse_url($currentUri); + $parts = parse_url($uri); + $scheme = isset($parts['scheme']) ? $parts['scheme'] : $this->getHttpScheme(); - $full_query = array(); - parse_str($parts['query'], $full_query); + $path = isset($parts['path']) ? $parts['path'] : ''; - // remove Facebook appended query params - $real_query = array_diff_key($full_query, array_flip(array('code', 'state'))); $query = ''; - if (!empty($real_query)) { - $query = '?'.http_build_query($real_query, null, '&'); + if (isset($parts['query'])) { + $full_query = array(); + parse_str($parts['query'], $full_query); + + // remove Facebook appended query params + $real_query = array_diff_key($full_query, array_flip(array('state', 'code'))); + + $query = ''; + if (!empty($real_query)) { + $query = '?' . http_build_query($real_query, null, '&'); + } } - + // use port if non default - $port = - isset($parts['port']) && - (($protocol === 'http' && $parts['port'] !== 80) || - ($protocol === 'https' && $parts['port'] !== 443)) - ? ':' . $parts['port'] : ''; + $port = isset($parts['port']) ? ':' . $parts['port'] : ''; // rebuild - return $protocol . '://' . $parts['host'] . $port . $parts['path'] . $query; + return $scheme . '://' . $parts['host'] . $port . $path . $query; + } + + /** + * Returns the current URI + * + * @return string + */ + protected function getCurrentUri() + { + return $this->getHttpScheme() . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } /** @@ -249,7 +254,15 @@ protected function getCurrentUri() * * @return string The HTTP Protocol */ - protected function getHttpProtocol() { + protected function getHttpScheme() { + $scheme = 'http'; + if (isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1) + || isset($_SERVER['SERVER_PORT']) && + ($_SERVER['SERVER_PORT'] === '443')) { + $scheme = 'https'; + } + return $scheme; } /** diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index c39bea7e3..d0022106c 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -56,7 +56,7 @@ public function testLogoutURL() } } - public function testGetCurrentUriRemoveFacebookQueryParams() + public function testGetFilterdUriRemoveFacebookQueryParams() { $helper = new FacebookRedirectLoginHelper( FacebookTestCredentials::$appId, @@ -65,13 +65,10 @@ public function testGetCurrentUriRemoveFacebookQueryParams() $helper->disableSessionStatusCheck(); $class = new ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); - $method = $class->getMethod('getCurrentUri'); + $method = $class->getMethod('getFilteredUri'); $method->setAccessible(true); - $_SERVER['HTTP_HOST'] = 'localhost'; - $_SERVER['REQUEST_URI'] = '/something?state=0000&foo=bar&code=abcd'; - - $currentUri = $method->invoke($helper); + $currentUri = $method->invoke($helper, 'http://localhost/something?state=0000&foo=bar&code=abcd'); $this->assertEquals('http://localhost/something?foo=bar', $currentUri); } From e2e365aea3989afeec921176ab949369418a0ceb Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 14 Jul 2014 11:40:29 +0200 Subject: [PATCH 011/407] [RedirectLoginHelper] Filter URI even if the user decline login --- .../Helpers/FacebookRedirectLoginHelper.php | 12 +++++- .../FacebookRedirectLoginHelperTest.php | 39 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 2276ef784..036a957b7 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -224,7 +224,17 @@ protected function getFilteredUri($uri) parse_str($parts['query'], $full_query); // remove Facebook appended query params - $real_query = array_diff_key($full_query, array_flip(array('state', 'code'))); + $toDrop = array(); + if (isset($full_query['state']) && isset($full_query['code'])) { + $toDrop = array('state', 'code'); + } elseif (isset($full_query['state']) + && isset($full_query['error']) + && isset($full_query['error_reason']) + && isset($full_query['error_description']) + && isset($full_query['error_code'])) { + $toDrop = array('state', 'error', 'error_reason', 'error_description', 'error_code'); + } + $real_query = array_diff_key($full_query, array_flip($toDrop)); $query = ''; if (!empty($real_query)) { diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index d0022106c..018e6b1af 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -56,7 +56,10 @@ public function testLogoutURL() } } - public function testGetFilterdUriRemoveFacebookQueryParams() + /** + * @dataProvider provideUris + */ + public function testGetFilterdUriRemoveFacebookQueryParams($uri, $expected) { $helper = new FacebookRedirectLoginHelper( FacebookTestCredentials::$appId, @@ -68,8 +71,38 @@ public function testGetFilterdUriRemoveFacebookQueryParams() $method = $class->getMethod('getFilteredUri'); $method->setAccessible(true); - $currentUri = $method->invoke($helper, 'http://localhost/something?state=0000&foo=bar&code=abcd'); - $this->assertEquals('http://localhost/something?foo=bar', $currentUri); + $currentUri = $method->invoke($helper, $uri); + $this->assertEquals($expected, $currentUri); + } + + public function provideUris() + { + return array( + array( + 'http://localhost/something?state=0000&foo=bar&code=abcd', + 'http://localhost/something?foo=bar', + ), + array( + 'https://localhost/something?state=0000&foo=bar&code=abcd', + 'https://localhost/something?foo=bar', + ), + array( + 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'http://localhost/something?foo=bar', + ), + array( + 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'https://localhost/something?foo=bar', + ), + array( + 'http://localhost/something?state=0000&foo=bar&error=abcd', + 'http://localhost/something?state=0000&foo=bar&error=abcd', + ), + array( + 'https://localhost/something?state=0000&foo=bar&error=abcd', + 'https://localhost/something?state=0000&foo=bar&error=abcd', + ), + ); } public function testCSPRNG() From fb5851188dd40a3f5d91687f1d926442f7e3ce7a Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 14 Jul 2014 16:12:25 +0200 Subject: [PATCH 012/407] [RedirectLoginHelper] Make redirect login help extendable --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 036a957b7..e9ca12ac5 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -39,17 +39,17 @@ class FacebookRedirectLoginHelper /** * @var string The application id */ - private $appId; + protected $appId; /** * @var string The application secret */ - private $appSecret; + protected $appSecret; /** * @var string Prefix to use for session variables */ - private $sessionPrefix = 'FBRLH_'; + protected $sessionPrefix = 'FBRLH_'; /** * @var boolean Toggle for PHP session status check From 42c88e63fb24b823bd26f8ce12787f9dc141987b Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 14 Jul 2014 16:00:53 +0200 Subject: [PATCH 013/407] [RedirectLoginHelper] Make the state generation extendable --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index e9ca12ac5..e843f32ab 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -83,7 +83,7 @@ public function __construct($appId = null, $appSecret = null) public function getLoginUrl($redirectUrl, $scope = array(), $rerequest = false, $version = null) { $version = ($version ?: FacebookRequest::GRAPH_API_VERSION); - $state = $this->random(16); + $state = $this->generateState(); $this->storeState($state); $params = array( 'client_id' => $this->appId, @@ -168,6 +168,16 @@ protected function getCode() return isset($_GET['code']) ? $_GET['code'] : null; } + /** + * Generate a state string for CSRF protection. + * + * @return string + */ + protected function generateState() + { + return $this->random(16); + } + /** * Stores a state string in session storage for CSRF protection. * Developers should subclass and override this method if they want to store From 36fe36061936481ba9c0ad4657f88a7c2b03a669 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 14 Jul 2014 17:38:12 +0200 Subject: [PATCH 014/407] [RedirectLoginHelper] make random function private --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 +- tests/Helpers/FacebookRedirectLoginHelperTest.php | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index e843f32ab..14db815bd 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -296,7 +296,7 @@ protected function getHttpScheme() { * * @todo Support Windows platforms */ - public function random($bytes) + private function random($bytes) { if (!is_numeric($bytes)) { throw new FacebookSDKException( diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 018e6b1af..a05028418 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -111,7 +111,12 @@ public function testCSPRNG() FacebookTestCredentials::$appId, FacebookTestCredentials::$appSecret ); - $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $helper->random(32))); + + $class = new ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); + $method = $class->getMethod('random'); + $method->setAccessible(true); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $method->invoke($helper, 32))); } } From 02c206e7820e153c341f577052fad63e17190e1a Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Tue, 15 Jul 2014 02:37:15 +0200 Subject: [PATCH 015/407] [RedirectLoginHelper] Remove code duplication and fix access token expires --- .../Helpers/FacebookRedirectLoginHelper.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 14db815bd..446bf6fb9 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -25,6 +25,7 @@ use Facebook\FacebookSession; use Facebook\FacebookRequest; +use Facebook\Entities\AccessToken; use Facebook\Exceptions\FacebookSDKException; /** @@ -128,21 +129,10 @@ public function getSessionFromRedirect() { if ($this->isValidRedirect()) { $params = array( - 'client_id' => FacebookSession::_getTargetAppId($this->appId), 'redirect_uri' => $this->getFilteredUri($this->getCurrentUri()), - 'client_secret' => - FacebookSession::_getTargetAppSecret($this->appSecret), 'code' => $this->getCode() ); - $response = (new FacebookRequest( - FacebookSession::newAppSession($this->appId, $this->appSecret), - 'GET', - '/oauth/access_token', - $params - ))->execute()->getResponse(); - if (isset($response['access_token'])) { - return new FacebookSession($response['access_token']); - } + return new FacebookSession(AccessToken::requestAccessToken($params, $this->appId, $this->appSecret)); } return null; } From fcf19afd04f12d774a4da00b10f4f3871abcbb63 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Tue, 15 Jul 2014 11:48:14 +0200 Subject: [PATCH 016/407] Make AccessToken serializable --- src/Facebook/Entities/AccessToken.php | 19 ++++++++++++++++++- tests/Entities/AccessTokenTest.php | 9 +++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 4a038cac1..f9bb0b0df 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -32,7 +32,7 @@ * Class AccessToken * @package Facebook */ -class AccessToken +class AccessToken implements \Serializable { /** @@ -367,4 +367,21 @@ public function __toString() return $this->accessToken; } + public function serialize() + { + $expiresAt = null; + if ($this->expiresAt instanceof \DateTime) { + $expiresAt = $this->expiresAt->getTimestamp(); + } + + return serialize(array($this->accessToken, $expiresAt, $this->machineId)); + } + + public function unserialize($serialized) + { + list($accessToken, $expiresAt, $machineId) = unserialize($serialized); + + $this->__construct($accessToken, $expiresAt, $machineId); + } + } diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index a6c9a2247..e4189cc23 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -244,4 +244,13 @@ public function testACodeCanBeUsedToObtainAnAccessToken() $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessTokenFromCode); } + public function testSerialization() + { + $accessToken = new AccessToken('foo', time(), 'bar'); + $newAccessToken = unserialize(serialize($accessToken)); + + $this->assertEquals((string)$accessToken, (string)$newAccessToken); + $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); + $this->assertEquals($accessToken->getMachineId(), $newAccessToken->getMachineId()); + } } From be5e5f0b3ddeced577b7739b55ab252a26bef6ca Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Wed, 16 Jul 2014 09:34:03 +0200 Subject: [PATCH 017/407] [AccessToken] Add isExpired function --- src/Facebook/Entities/AccessToken.php | 15 +++++++++++++++ tests/Entities/AccessTokenTest.php | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index f9bb0b0df..253ed3729 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -117,6 +117,21 @@ public function isLongLived() return false; } + /** + * Checks the expiration of the access token. + * + * @return boolean|null + */ + public function isExpired() + { + if ($this->getExpiresAt() instanceof \DateTime) { + return $this->getExpiresAt()->getTimestamp() < time(); + } + + // Not all access tokens return an expiration. E.g. an app access token. + return false; + } + /** * Checks the validity of the access token. * diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index e4189cc23..be1fd759d 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -253,4 +253,23 @@ public function testSerialization() $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); $this->assertEquals($accessToken->getMachineId(), $newAccessToken->getMachineId()); } + + /** + * @dataProvider provideAccessTokenExpiration + */ + public function testIsExpired($expiresAt, $expected) + { + $accessToken = new AccessToken('foo', $expiresAt); + + $this->assertEquals($expected, $accessToken->isExpired()); + } + + public function provideAccessTokenExpiration() + { + return array( + array(time()+60, false), + array(time()-60, true), + array(0, false), + ); + } } From cef48ae9c00c84478544f35b50ede84fa0a3887e Mon Sep 17 00:00:00 2001 From: Marco Balmer Date: Wed, 16 Jul 2014 13:36:22 +0200 Subject: [PATCH 018/407] W3C Fix for FacebookRedirectLoginHelper.php Change & to & to be compilant with W3C checks. --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 446bf6fb9..51c360a93 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -98,7 +98,7 @@ public function getLoginUrl($redirectUrl, $scope = array(), $rerequest = false, $params['auth_type'] = 'rerequest'; return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . - http_build_query($params, null, '&'); + http_build_query($params, null, '&'); } /** @@ -116,7 +116,7 @@ public function getLogoutUrl(FacebookSession $session, $next) 'next' => $next, 'access_token' => $session->getToken() ); - return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, '&'); + return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, '&'); } /** From 4538983d7240f28a75650e5e4b8c6e4876e83504 Mon Sep 17 00:00:00 2001 From: SammyK Date: Mon, 21 Jul 2014 09:57:40 -0500 Subject: [PATCH 019/407] Added ext-mbstring to composer require. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d2edba898..72851d24b 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ } ], "require": { - "php": ">=5.4.0" + "php": ">=5.4.0", + "ext-mbstring": "*" }, "require-dev": { "phpunit/phpunit": "3.7.*", From 080d1964d1c4c45c745a60bbea545766aff47397 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Mon, 21 Jul 2014 16:35:47 -0700 Subject: [PATCH 020/407] Adding developer site doc content, needs lots of updates. --- docs/FacebookCanvasLoginHelper.fbmd | 37 ++++++ docs/FacebookJavaScriptLoginHelper.fbmd | 39 ++++++ docs/FacebookRedirectLoginHelper.fbmd | 54 +++++++++ docs/FacebookRequest.fbmd | 59 +++++++++ docs/FacebookRequestException.fbmd | 43 +++++++ docs/FacebookResponse.fbmd | 57 +++++++++ docs/FacebookSession.fbmd | 71 +++++++++++ docs/GraphObject.fbmd | 155 ++++++++++++++++++++++++ docs/post_links.fbmd | 44 +++++++ docs/retrieve_user_profile.fbmd | 38 ++++++ docs/sdk_getting_started.fbmd | 135 +++++++++++++++++++++ docs/sdk_landing_page.fbmd | 45 +++++++ docs/upload_photo.fbmd | 49 ++++++++ 13 files changed, 826 insertions(+) create mode 100644 docs/FacebookCanvasLoginHelper.fbmd create mode 100644 docs/FacebookJavaScriptLoginHelper.fbmd create mode 100644 docs/FacebookRedirectLoginHelper.fbmd create mode 100644 docs/FacebookRequest.fbmd create mode 100644 docs/FacebookRequestException.fbmd create mode 100644 docs/FacebookResponse.fbmd create mode 100644 docs/FacebookSession.fbmd create mode 100644 docs/GraphObject.fbmd create mode 100644 docs/post_links.fbmd create mode 100644 docs/retrieve_user_profile.fbmd create mode 100644 docs/sdk_getting_started.fbmd create mode 100644 docs/sdk_landing_page.fbmd create mode 100644 docs/upload_photo.fbmd diff --git a/docs/FacebookCanvasLoginHelper.fbmd b/docs/FacebookCanvasLoginHelper.fbmd new file mode 100644 index 000000000..c3e64c76d --- /dev/null +++ b/docs/FacebookCanvasLoginHelper.fbmd @@ -0,0 +1,37 @@ + +# FacebookCanvasLoginHelper for the Facebook SDK for PHP + +A helper class for getting a FacebookSession in a Canvas app + + + +## Facebook\FacebookCanvasLoginHelper {#overview} + +If your app is loaded through Canvas, Facebook sends a POST request with a signed request. This helper class will handle processing and validating that information with Facebook, and returns a `FacebookSession`. + +Usage: + +~~~~ + +$helper = new FacebookCanvasLoginHelper(); +try { + $session = $helper->getSession(); +} catch (FacebookRequestException $ex) { + // When Facebook returns an error +} catch (\Exception $ex) { + // When validation fails or other local issues +} +if ($session) { + // Logged in. +} + +~~~~ + + + +## Instance Methods {#instance-methods} + +### getSession {#getsession} +`getSession()` +Processes the POST request from Facebook, if present. Returns a `FacebookSession` or `null`. + \ No newline at end of file diff --git a/docs/FacebookJavaScriptLoginHelper.fbmd b/docs/FacebookJavaScriptLoginHelper.fbmd new file mode 100644 index 000000000..e63499802 --- /dev/null +++ b/docs/FacebookJavaScriptLoginHelper.fbmd @@ -0,0 +1,39 @@ + +# FacebookJavaScriptLoginHelper for the Facebook SDK for PHP + +A helper class for getting a FacebookSession using the session from the Facebook SDK for JavaScript. + + + +## Facebook\FacebookJavaScriptLoginHelper {#overview} + +If your web app uses the Facebook SDK for JavaScript, you can access that in your PHP code as well. This helper class will process and validate the cookie data used by the Facebook SDK for JavaScript, returning a `FacebookSession` on success. + +Usage: + +~~~~ + +$helper = new FacebookJavaScriptLoginHelper(); +try { + $session = $helper->getSession(); +} catch(FacebookRequestException $ex) { + // When Facebook returns an error +} catch(\Exception $ex) { + // When validation fails or other local issues +} +if ($session) { + // Logged in. +} + +~~~~ + +It's important to note that on first access, or if a session has since expired, these methods will operate on data that is one request-cycle stale. 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 {#instance-methods} + +### getSession {#getsession} +`getSession()` +Processes the data available from the Facebook SDK for JavaScript, if present. Returns a `FacebookSession` or `null`. + \ No newline at end of file diff --git a/docs/FacebookRedirectLoginHelper.fbmd b/docs/FacebookRedirectLoginHelper.fbmd new file mode 100644 index 000000000..35124be14 --- /dev/null +++ b/docs/FacebookRedirectLoginHelper.fbmd @@ -0,0 +1,54 @@ + +# FacebookRedirectLoginHelper for the Facebook SDK for PHP + +A helper class for getting a FacebookSession using the OAuth protocol. + + + +## Facebook\FacebookRedirectLoginHelper {#overview} + +If your web app uses Facebook Login on the back-end, you'll need to redirect your visitors to a URL at Facebook to initiate a login request. Facebook then redirects the user to your apps callback URL, providing session data. This helper class will generate the login URL for you, and can process and validate the data from Facebook, returning a `FacebookSession` on success. + +This class can be extended, and the `storeState($state)` and `loadState()` methods overridden, to store the state check using another method besides the default `$_SESSION`. + +Usage: + +~~~~ + +$helper = new FacebookRedirectLoginHelper($redirect_url, $appId = NULL, $appSecret = NULL); +echo 'Login with Facebook'; + +~~~~ + +Then, in your callback page (at the redirect url) when Facebook sends the user back: + +~~~~ + +$helper = new FacebookRedirectLoginHelper($redirect_url); +try { + $session = $helper->getSessionFromRedirect(); +} catch(FacebookRequestException $ex) { + // When Facebook returns an error +} catch(\Exception $ex) { + // When validation fails or other local issues +} +if ($session) { + // Logged in. +} + +~~~~ + + + +## Instance Methods {#instance-methods} + +### getLoginUrl {#getloginurl} +`getLoginUrl()` +Generates the URL to redirect a web visitor to Facebook to login to your app. +### getLogoutUrl {#getlogouturl} +`getLogoutUrl($next_url)` +Generates the URL to redirect a web visitor to Facebook to logout, with a url to redirect to after. +### getSessionFromRedirect {#getsessionfromredirect} +`getSessionFromRedirect()` +Processes the redirect data from Facebook, if present. Returns a `FacebookSession` or `null`. + \ No newline at end of file diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd new file mode 100644 index 000000000..30ef9c995 --- /dev/null +++ b/docs/FacebookRequest.fbmd @@ -0,0 +1,59 @@ + +# FacebookRequest for the Facebook SDK for PHP + +Represents a request that will be made against the Graph API. + + + +## Facebook\FacebookRequest {#overview} + +Constructor: + +~~~~ +$request = new FacebookRequest( + FacebookSession $session, + string $httpMethod, + string $path, + array $params = NULL, + string $version = NULL +); +~~~~ + +Usage: + +~~~~ +// Make a new request and execute it. +try { + $response = (new FacebookRequest($session, 'GET', '/me'))->execute(); + $object = $response->getGraphObject(); + echo $object->getProperty('name'); +} catch (FacebookRequestException $ex) { + echo $ex->getMessage(); +} catch (\Exception $ex) { + echo $ex->getMessage(); +} + +// You can chain methods together and get a strongly typed GraphUser +$me = (new FacebookRequest( + $session, 'GET', '/me' +))->execute()->getGraphObject(GraphUser::className); +echo $me->getName(); +~~~~ + + + +## Instance Methods {#instance-methods} + +### execute {#execute} +`execute()` +Returns a `Facebook\FacebookResponse` from this request, from which a strongly-typed result can be retrieved. Throws an exception if the request fails. If the error is returned from Facebook, as opposed to a networking issue, a `Facebook\FacebookRequestException` is thrown. +### getPath {#getpath} +`getPath()` +Returns a copy of the path for the request, not including the version. +### getParameters {#getparams} +`getParameters()` +Returns a copy of the parameters array for the request. +### getSession {#getsession} +`getSession()` +Returns the `Facebook\FacebookSession` object associated with this request. + \ No newline at end of file diff --git a/docs/FacebookRequestException.fbmd b/docs/FacebookRequestException.fbmd new file mode 100644 index 000000000..e9257c345 --- /dev/null +++ b/docs/FacebookRequestException.fbmd @@ -0,0 +1,43 @@ + +# FacebookRequestException for the Facebook SDK for PHP + +Represents an exception thrown by executing a Facebook request. + + + +## Facebook\FacebookRequestException {#overview} + +This base class has several subclasses: + +`FacebookAuthorizationException` +`FacebookClientException` +`FacebookPermissionException` +`FacebookServerException` +`FacebookThrottleException` +`FacebookOtherException` + +Whenever a FacebookRequestException is thrown, it will be one of these types. +They are derived from the error information here: https://developers.facebook.com/docs/graph-api/using-graph-api/#errors + + + +## Instance Methods {#instance-methods} + +`FacebookRequestException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. + +### getHttpStatusCode {#gethttpstatus} +`getHttpStatusCode()` +Returns the HTTP status code returned with this exception. +### getSubErrorCode {#getsuberrorcode} +`getSubErrorCode()` +Returns the numeric sub-error code returned from Facebook. +### getErrorType {#geterrortype} +`getErrorType()` +Returns the type of error as a string. +### getResponse {#getresponse} +`getResponse()` +Returns the decoded response used to create the exception. +### getRawResponse {#getrawresponse} +`getRawResponse()` +Returns the raw response used to create the exception. + \ No newline at end of file diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd new file mode 100644 index 000000000..c3f9d61cf --- /dev/null +++ b/docs/FacebookResponse.fbmd @@ -0,0 +1,57 @@ + +# FacebookResponse for the Facebook SDK for PHP + +Represents a response from the Graph API. + + + +## Facebook\FacebookResponse {#overview} + +Usage: + +~~~~ +// A FacebookResponse is returned from an executed FacebookRequest +try { + $response = (new FacebookRequest($session, 'GET', '/me'))->execute(); + // You can get the request back: + $request = $response->getRequest(); + // You can get the response as a GraphObject: + $object = $response->getGraphObject(); + // You can get the response as a subclass of GraphObject: + $me = $response->getGraphObject(GraphUser::className()); + // If this response has multiple pages, you can get a request for the next or previous pages: + $nextPageRequest = $response->getRequestForNextPage(); + $previousPageRequest = $response->getRequestForPreviousPage(); +} catch (FacebookRequestException $ex) { + echo $ex->getMessage(); +} catch (\Exception $ex) { + echo $ex->getMessage(); +} + +// You can also chain the methods together: +$me = (new FacebookRequest( + $session, 'GET', '/me' +))->execute()->getGraphObject(GraphUser::className); +echo $me->getName(); +~~~~ + + + +## Instance Methods {#instance-methods} + +### getGraphObject {#getgraphobject} +`getGraphObject(string $type = 'Facebook\GraphObject')` +Returns the result as a `GraphObject`. If specified, a strongly-typed subclass of `GraphObject` is returned. +### getGraphObjectList {#getgraphobjectlist} +`getGraphObjectList(string $type = 'Facebook\GraphObject')` +Returns an array of `GraphObject` returned by this request. If specified, a strongly-typed subclass of `GraphObject` is returned. +### getRequest {#getrequest} +`getRequest()` +Returns the `FacebookRequest` that produced this response. +### getRequestForNextPage {#getnextpage} +`getRequestForNextPage()` +If the response has paginated data, produces a `FacebookRequest` for the next pge of data. +### getRequestForPreviousPage {#getpreviouspage} +`getRequestForPreviousPage()` +If the response has paginated data, produces a `FacebookRequest` for the previous page of data. + \ No newline at end of file diff --git a/docs/FacebookSession.fbmd b/docs/FacebookSession.fbmd new file mode 100644 index 000000000..9378c66c1 --- /dev/null +++ b/docs/FacebookSession.fbmd @@ -0,0 +1,71 @@ + +# FacebookSession for the Facebook SDK for PHP + +Represents a Facebook Session, which is used when making requests to the Graph API. + + + +## Facebook\FacebookSession {#overview} + +Usage: + +~~~~ +use Facebook\FacebookSession; + +FacebookSession::setDefaultApplication('app-id', 'app-secret'); + +// If you already have a valid access token: +$session = new FacebookSession('access-token'); + +// If you're making app-level requests: +$session = FacebookSession::newAppSession(); + +// To validate the session: +try { + $session->validate(); +} catch (FacebookRequestException $ex) { + // Session not valid, Graph API returned an exception with the reason. + echo $ex->getMessage(); +} catch (\Exception $ex) { + // Graph API returned info, but it may mismatch the current app or have expired. + echo $ex->getMessage(); +} +~~~~ + + + +## Static Methods {#static-methods} + +### setDefaultApplication {#setdefaultapp} +`setDefaultApplication(string $appId, string $appSecret)` +Configures and app ID and secret that will be used by default throughout the SDK (but can be overridden whenever necessary using parameters to other methods. +### validate {#validate} +`validate(Facebook\GraphSessionInfo $sessionInfo, string $appId = NULL, string $appSecret = NULL)` +Ensures that the provided GraphSessionInfo is valid, throwing an exception if not. It does this by ensuring the app ID in the token info matches the given (or default) app ID, ensuring the token itself is valid, and ensuring that the expiration time has not passed. +### newAppSession {#newappsession} +`newAppSession(string $appId = NULL, string $appSecret = NULL)` +Returns a `Facebook\FacebookSession` configured with a token for the app which can be used for publishing and for requesting app-level information. +### newSessionFromSignedRequest {#newsessionfromsr} +`newSessionFromSignedRequest(string $signedRequest)` +Returns a `Facebook\FacebookSession` for the given signed request. + + + +## Instance Methods {#instance-methods} + +### getToken {#gettoken} +`getToken()` +Returns the token string for the session. +### getSessionInfo {#getsessioninfo} +`getSessionInfo(string $appId = NULL, string $appSecret = NULL)` +Equivalent to calling the /debug_token endpoint of the Graph API to get the details for the access token for this session. Returns a `Facebook\GraphSessionInfo` object. +### getLongLivedSession {#getlonglivedsession} +`getLongLivedSession(string $appId = NULL, string $appSecret = NULL)` +Returns a new `Facebook\FacebookSession` resulting from extending a short-lived access token. This method will make a network request. If you know you already have a long-lived session, you do not need to call this. The only time you get a short-lived session as of March 2014 is from the Facebook SDK for JavaScript. If this session is not short-lived, this method will return `$this`. A long-lived session is on the order of months. A short-lived session is on the order of hours. You can figure out whether a session is short-lived or long-lived by checking the expiration date in the session info, but it's not a precise thing. +### getExchangeToken {#getexchangetoken} +`getExchangeToken(string $appId = NULL, string $appSecret = NULL)` +Returns an exchange token string which can be sent back to clients and exchanged for a device-linked access token. You need this when your user did not log in on a particular device, but you want to be able to make Graph API calls from that device as this user. +### validate {#validatei} +`validate(string $appId = NULL, string $appSecret = NULL)` +Ensures that a session is valid, throwing an exception if not. It does this by fetching the token info, ensuring the app ID in the token info matches the given (or default) app ID, ensuring the token itself is valid, and ensuring that the expiration time has not passed. + \ No newline at end of file diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd new file mode 100644 index 000000000..99517b895 --- /dev/null +++ b/docs/GraphObject.fbmd @@ -0,0 +1,155 @@ + +# GraphObject for the Facebook SDK for PHP + +Represents an object returned by the Graph API. + + + + +## Facebook\GraphObject {#overview} + +This base class has several subclasses, some are provided by default: + +[__GraphUser__](#user-instance-methods) +[__GraphLocation__](#location-instance-methods) +[__GraphSessionInfo__](#sessioninfo-instance-methods) + +Usage: + +~~~~ +// Get the base class GraphObject from the response +$object = $response->getGraphObject(); + +// Get the response typed as a GraphUser +$user = $response->getGraphObject(GraphUser::className()); +// or convert the base object previously accessed +// $user = $object->cast(GraphUser::className()); + +// Get the response typed as a GraphLocation +$loc = $response->getGraphObject(GraphLocation::className()); +// or convert the base object previously accessed +// $loc = $object->cast(GraphLocation::className()); + +// User example +echo $object->getProperty('name'); +echo $user->getName(); + +// Location example +echo $object->getProperty('country'); +echo $loc->getCountry(); + +// SessionInfo example +$info = $session->getSessionInfo()); +echo $info->getxpiresAt(); +~~~~ + + + + +## GraphObject Instance Methods {#instance-methods} + +### cast {#cast} +`cast(string $type)` +Returns a new instance of a GraphObject subclass with this objects underlying data. + +### asArray {#asarray} +`asArray()` +Returns the raw representation (associative arrays, nested) of this objects underlying data. + +### getProperty {#getproperty} +`getProperty(string $name, string $type = 'Facebook\GraphObject')` +Gets the value of a named key for this graph object. 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 GraphObject cast to the appropriate subclass type if provided. + +### getPropertyAsArray {#getproparray} +`getPropertyAsArray()` +Gets the contents of a named array property on this graph object. If the values are scalar (strings, numbers, etc.) they will be returned as-is. If the values are associative arrays, they will be returned as GraphObjects cast to the appropriate subclass type if provided. + +### getPropertyNames +`getPropertyNames()` +Returns an array with the names of all properties present on this graph object. + + + +## GraphUser Instance Methods {#user-instance-methods} + +### getId {#getid} +`getId()` +Returns the `id` property for the user as a string if present. +### getName {#getname} +`getName()` +Returns the `name` property for the user as a string if present. +### getFirstName {#getfirstname} +`getFirstName()` +Returns the `first_name` property for the user as a string if present. +### getMiddleName {#getmiddlename} +`getMiddleName()` +Returns the `middle_name` property for the user as a string if present. +### getLastName {#getlastname} +`getLastName()` +Returns the `last_name` property for the user as a string if present. +### getLink {#getlink} +`getLink()` +Returns the `link` property for the user as a string if present. +### getUsername {#getusername} +`getUsername()` +Returns the `username` property for the user as a string if present. +### getBirthday {#getbirthday} +`getBirthday()` +Returns the `birthday` property for the user as a `\DateTime` if present. +### getLocation {#getlocation} +`getLocation()` +Returns the `location` property for the user as a `Facebook\GraphLocation` if present.' + + + +## GraphLocation Instance Methods {#location-instance-methods} + +### getStreet {#getstreet} +`getStreet()` +Returns the `street` property for the location as a string if present. +### getCity {#getcity} +`getCity()` +Returns the `city` property for the location as a string if present. +### getState {#getstate} +`getState()` +Returns the `state` property for the location as a string if present. +### getCountry {#getcountry} +`getCountry()` +Returns the `country` property for the location as a string if present. +### getZip {#getzip} +`getZip()` +Returns the `zip` property for the user as a location if present. +### getLatitude {#getlat} +`getLatitude()` +Returns the `latitude` property for the location as a float if present. +### getLongitude {#getlon} +`getLongitude()` +Returns the `latitude` property for the location as a float if present. + + + +## GraphSessionInfo Instance Methods {#sessioninfo-instance-methods} + +### getAppId {#getappid} +`getAppId()` +Returns the `app_id` property for the session as a string if present. +### getApplication {#getapp} +`getApplication()` +Returns the `application` property for the session as a string if present. +### getExpiresAt {#getexpires} +`getExpiresAt()` +Returns the `expires_at` property for the session as a \DateTime if present. +### getIsValid {#getvalid} +`getIsValid()` +Returns the `is_valid` property for the session as a boolean if present. +### getIssuedAt {#getissued} +`getIssuedAt()` +Returns the `issued_at` property for the session as a \DateTime if present. +### getScopes {#getscopes} +`getScopes()` +Returns the `scopes` property for the session as an array if present. +### getId {#getuid} +`getId()` +Returns the `user_id` property for the session as a string if present. + + diff --git a/docs/post_links.fbmd b/docs/post_links.fbmd new file mode 100644 index 000000000..a4866f560 --- /dev/null +++ b/docs/post_links.fbmd @@ -0,0 +1,44 @@ + +# 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 set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). You must have requested the `publish_actions` scope when logging in the user for this to work. + +For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookRequestException`](/docs/php/FacebookRequestException). + + + + + +~~~~ +use Facebook\FacebookRequest; +use Facebook\GraphObject; +use Facebook\FacebookRequestException; + +if($session) { + + try { + + $response = (new FacebookRequest( + $session, 'POST', '/me/feed', array( + 'link' => 'www.example.com', + 'message' => 'User provided message' + ) + ))->execute()->getGraphObject(); + + echo "Posted with id: " . $response->getProperty('id'); + + } catch(FacebookRequestException $e) { + + echo "Exception occured, code: " . $e->getCode(); + echo " with message: " . $e->getMessage(); + + } + +} +~~~~ + +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). + + \ No newline at end of file diff --git a/docs/retrieve_user_profile.fbmd b/docs/retrieve_user_profile.fbmd new file mode 100644 index 000000000..83393d260 --- /dev/null +++ b/docs/retrieve_user_profile.fbmd @@ -0,0 +1,38 @@ + +# 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 set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). + +For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`GraphUser`](/docs/php/GraphObject/#user-instance-methods), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookRequestException`](/docs/php/FacebookRequestException). + + + + + +~~~~ +use Facebook\FacebookRequest; +use Facebook\GraphUser; +use Facebook\FacebookRequestException; + +if($session) { + + try { + + $user_profile = (new FacebookRequest( + $session, 'GET', '/me' + ))->execute()->getGraphObject(GraphUser::className()); + + echo "Name: " . $user_profile->getName(); + + } catch(FacebookRequestException $e) { + + echo "Exception occured, code: " . $e->getCode(); + echo " with message: " . $e->getMessage(); + + } + +} +~~~~ + \ No newline at end of file diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd new file mode 100644 index 000000000..e31c55970 --- /dev/null +++ b/docs/sdk_getting_started.fbmd @@ -0,0 +1,135 @@ + +# Getting started with the Facebook SDK for PHP + +The Facebook SDK for PHP provides developers with a modern, native library for accessing the Graph API and taking advantage of Facebook Login. Usually this means you're developing with PHP for a Facebook Canvas app, building your own website, or adding server-side functionality to an app that already uses the [Facebook SDK for JavaScript](/docs/reference/javascript/). + + + +## Download the SDK {#download} + +%FB(devsite:markdown-wiki:info-card { + content: "The Facebook SDK for PHP v4 requires PHP 5.4 or greater.", + type: 'warning', +}) + +If you're using [Composer](https://getcomposer.org/) as a package manager for PHP, which we recommend, installing the SDK is as easy as adding a require entry for the Facebook SDK for PHP to the composer.json file in the root of your project: + +~~~~ +{ + "require" : { + "facebook/php-sdk-v4" : "4.0.*" + } +} +~~~~ + +Then run composer with the install parameter, and it will download the newest version. If you're using the autoloader as part of Composer, the Facebook namespace will be available for use without adding require statements for all of the files. + +If you're not using Composer, you can download the SDK from our GitHub: + +%FB(devsite:markdown-wiki:button { + text: 'Download the PHP SDK', + href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/4.0-dev.zip', + size: 'large', + use: 'special', +}) + + + +## Initializing {#init} + +You will need to have configured a Facebook App, which you can obtain from the [App Dashboard](http://developers.facebook.com/apps). + +Then, initialize the SDK with your app ID and secret: + +~~~ +FacebookSession::setDefaultApplication('YOUR_APP_ID', 'YOUR_APP_SECRET'); +~~~ + + + +## Authentication and authorization {#authentication} + +The SDK can be used to support login your site using a Facebook account. On the server-side, the SDK provides helper classes for the most common scenarios. + +For most websites, you'll use the [FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper). Generate the login URL to redirect visitors to with the `getLoginUrl()` method, redirect them, and then process the response from Facebook with the `getSessionFromRedirect()` method, which returns a `FacebookSession`. + +~~~~ +$helper = new FacebookRedirectLoginHelper('your redirect URL here'); +$loginUrl = $helper->getLoginUrl(); +// Use the login url on a link or button to redirect to Facebook for authentication +~~~~ + +~~~~ +$helper = new FacebookRedirectLoginHelper(); +try { + $session = $helper->getSessionFromRedirect(); +} catch(FacebookRequestException $ex) { + // When Facebook returns an error +} catch(\Exception $ex) { + // When validation fails or other local issues +} +if ($session) { + // Logged in +} +~~~~ + +If your app is on Facebook Canvas, use the `getSession()` method on [FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) to get a `FacebookSession` for the user. + +~~~~ +$helper = new FacebookCanvasLoginHelper(); +try { + $session = $helper->getSession(); +} catch(FacebookRequestException $ex) { + // When Facebook returns an error +} catch(\Exception $ex) { + // When validation fails or other local issues +} +if ($session) { + // Logged in +} +~~~~ + +If you're already using the Facebook SDK for JavaScript to authenticate users, you can also log them in on the server side with the [FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper). The `getSession()` method will return a `FacebookSession`. + +~~~~ +$helper = new FacebookJavaScriptLoginHelper(); +try { + $session = $helper->getSession(); +} catch(FacebookRequestException $ex) { + // When Facebook returns an error +} catch(\Exception $ex) { + // When validation fails or other local issues +} +if ($session) { + // Logged in +} +~~~~ + +You can also create a `FacebookSession` with an access token you've acquired through some other means, by passing it to the constructor. + +~~~~ +$session = new FacebookSession('access token here'); +~~~~ + + + +## Making Requests to the Graph API {#making-requests} + +Once you have a `FacebookSession` you can begin making calls to the Graph API with [FacebookRequest](/docs/php/FacebookRequest). + +~~~~ +$request = new FacebookRequest($session, 'GET', '/me'); +$response = $request->execute(); +$graphObject = $response->getGraphObject(); +~~~~ + +You can also chain these methods: + +~~~~ +$me = (new FacebookRequest( + $session, 'GET', '/me' +))->execute()->getGraphObject(GraphUser::className()); +~~~~ + +For more details, see the examples and API reference for all of these classes listed on the [landing page for the Facebook SDK for PHP](/docs/reference/php). + \ No newline at end of file diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd new file mode 100644 index 000000000..f38aea86e --- /dev/null +++ b/docs/sdk_landing_page.fbmd @@ -0,0 +1,45 @@ + +# Facebook SDK for PHP + +The Facebook SDK for PHP provides developers with a modern, native library for accessing the Graph API and taking advantage of Facebook Login. Usually this means you're developing with PHP for a Facebook Canvas app, building your own website, or adding server-side functionality to an app that already uses the [Facebook SDK for JavaScript](/docs/reference/javascript/). + +Take a look through our guide, [Getting Started with the Facebook SDK for PHP](/docs/php/gettingstarted), and then check out some of the examples below. + + + +## Examples {#examples} + +* [Retrieve a users profile](/docs/php/howto/profilewithgraphapi) +* [Post a link to a users feed](/docs/php/howto/postwithgraphapi) +* [Upload a photo to a users profile](/docs/php/howto/uploadphoto) + + + + +## API Reference - Facebook namespace {#reference} + +[Facebook\FacebookSession](/docs/php/FacebookSession) +An access token backed session used when making requests against the Graph API. + +[Facebook\FacebookRequest](/docs/php/FacebookRequest) +Makes requests against the Graph API. + +[Facebook\FacebookResponse](/docs/php/FacebookResponse) +A successful response from the Graph API resulting from a FacebookRequest. + +[Facebook\FacebookRequestException](/docs/php/FacebookRequestException) +An error returned by the Graph API during a FacebookRequest. Subclasses: FacebookClientException, FacebookServerException, FacebookAuthorizationException, FacebookPermissionException, FacebookThrottleException, FacebookOtherException. + +[Facebook\GraphObject](/docs/php/GraphObject) +Represents an object returned by the Graph API. Subclasses: GraphUser, GraphLocation, GraphSessionInfo + +[Facebook\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper) +A helper class for getting a FacebookSession using the OAuth protocol. + +[Facebook\FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) +A helper class for getting a FacebookSession from Facebook Canvas. + +[Facebook\FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper) +A helper class for getting a FacebookSession from the Facebook SDK for JavaScript. + + \ No newline at end of file diff --git a/docs/upload_photo.fbmd b/docs/upload_photo.fbmd new file mode 100644 index 000000000..d2555c0ff --- /dev/null +++ b/docs/upload_photo.fbmd @@ -0,0 +1,49 @@ + +# 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 set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). You must have requested the `publish_actions` scope when logging in the user for this to work. + +For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookRequestException`](/docs/php/FacebookRequestException). + + + + + +~~~~ +use Facebook\FacebookRequest; +use Facebook\GraphObject; +use Facebook\FacebookRequestException; + +if($session) { + + try { + + // Upload to a user's profile. The photo will be in the + // first album in the profile. You can also upload to + // a specific album by using /ALBUM_ID as the path + $response = (new FacebookRequest( + $session, 'POST', '/me/photos', array( + 'source' => new CURLFile('path/to/file.name', 'image/png'), + 'message' => 'User provided message' + ) + ))->execute()->getGraphObject(); + + // If you're not using PHP 5.5 or later, change the file reference to: + // 'source' => '@/path/to/file.name' + + echo "Posted with id: " . $response->getProperty('id'); + + } catch(FacebookRequestException $e) { + + echo "Exception occured, code: " . $e->getCode(); + echo " with message: " . $e->getMessage(); + + } + +} +~~~~ + +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). + \ No newline at end of file From 36d1e5325e5908479af8f64dc33c9ec566590f29 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 21 Jul 2014 18:40:24 +0200 Subject: [PATCH 021/407] Add FacebookApp entity --- src/Facebook/Entities/FacebookApp.php | 86 +++++++++++++++++++++++++++ tests/Entities/FacebookAppTest.php | 29 +++++++++ 2 files changed, 115 insertions(+) create mode 100644 src/Facebook/Entities/FacebookApp.php create mode 100644 tests/Entities/FacebookAppTest.php diff --git a/src/Facebook/Entities/FacebookApp.php b/src/Facebook/Entities/FacebookApp.php new file mode 100644 index 000000000..e9cc58726 --- /dev/null +++ b/src/Facebook/Entities/FacebookApp.php @@ -0,0 +1,86 @@ +id = $id; + $this->secret = $secret; + } + + /** + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * @return string + */ + public function getSecret() + { + return $this->secret; + } + + /** + * @return AccessToken + */ + public function getAccessToken() + { + return new AccessToken($this->id . '|' . $this->secret); + } + + public function serialize() + { + return serialize(array($this->id, $this->secret)); + } + + public function unserialize($serialized) + { + list($id, $secret) = unserialize($serialized); + + $this->__construct($id, $secret); + } + +} \ No newline at end of file diff --git a/tests/Entities/FacebookAppTest.php b/tests/Entities/FacebookAppTest.php new file mode 100644 index 000000000..258ab1135 --- /dev/null +++ b/tests/Entities/FacebookAppTest.php @@ -0,0 +1,29 @@ +assertEquals('id', $app->getId()); + } + + public function testGetSecret() + { + $app = new FacebookApp('id', 'secret'); + + $this->assertEquals('secret', $app->getSecret()); + } + + public function testGetAccessToken() + { + $app = new FacebookApp('id', 'secret'); + $accessToken = $app->getAccessToken(); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('id|secret', (string)$accessToken); + } +} From 4b506bbfb07e57b9c989f1260748513a49e9097e Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Wed, 23 Jul 2014 14:15:06 +0200 Subject: [PATCH 022/407] Namespace tests and add licence header --- composer.json | 5 +++ tests/Entities/AccessTokenTest.php | 27 +++++++++++++++- tests/Entities/SignedRequestTest.php | 25 ++++++++++++++- .../FacebookRequestExceptionTest.php | 25 ++++++++++++++- tests/FacebookRequestTest.php | 29 +++++++++++++++-- tests/FacebookSessionTest.php | 26 +++++++++++++++- tests/FacebookTestCredentials.php.dist | 23 ++++++++++++++ tests/FacebookTestHelper.php | 24 ++++++++++++++ tests/GraphNodes/GraphAlbumTest.php | 30 ++++++++++++++++-- tests/GraphNodes/GraphLocationTest.php | 26 +++++++++++++++- tests/GraphNodes/GraphObjectTest.php | 26 +++++++++++++++- tests/GraphNodes/GraphSessionInfoTest.php | 26 +++++++++++++++- tests/GraphNodes/GraphUserTest.php | 26 +++++++++++++++- .../Helpers/FacebookCanvasLoginHelperTest.php | 25 ++++++++++++++- .../FacebookJavaScriptLoginHelperTest.php | 25 ++++++++++++++- tests/Helpers/FacebookPageTabHelperTest.php | 25 ++++++++++++++- .../FacebookRedirectLoginHelperTest.php | 31 +++++++++++++++++-- ...cebookSignedRequestFromInputHelperTest.php | 25 ++++++++++++++- tests/HttpClients/AbstractTestHttpClient.php | 25 ++++++++++++++- .../FacebookCurlHttpClientTest.php | 24 ++++++++++++++ .../FacebookGuzzleHttpClientTest.php | 24 ++++++++++++++ .../FacebookStreamHttpClientTest.php | 24 ++++++++++++++ tests/bootstrap.php | 27 +++++++++++++--- 23 files changed, 548 insertions(+), 25 deletions(-) diff --git a/composer.json b/composer.json index 72851d24b..68b3da008 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,11 @@ "Facebook\\": "src/Facebook/" } }, + "autoload-dev": { + "psr-4": { + "Facebook\\Tests\\": "tests/" + } + }, "extra": { "branch-alias": { "dev-master": "4.1.x-dev" diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index be1fd759d..a7b00367c 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -1,9 +1,34 @@ assertTrue(in_array($response->getType(),$type)); date_default_timezone_set('GMT'); - $this->assertTrue($response->getCreatedTime() instanceof DateTime); - $this->assertTrue($response->getUpdatedTime() instanceof DateTime); + $this->assertTrue($response->getCreatedTime() instanceof \DateTime); + $this->assertTrue($response->getUpdatedTime() instanceof \DateTime); } } diff --git a/tests/GraphNodes/GraphLocationTest.php b/tests/GraphNodes/GraphLocationTest.php index aba62bca0..a78bbbbf0 100644 --- a/tests/GraphNodes/GraphLocationTest.php +++ b/tests/GraphNodes/GraphLocationTest.php @@ -1,10 +1,34 @@ disableSessionStatusCheck(); - $class = new ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); + $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); $method = $class->getMethod('getFilteredUri'); $method->setAccessible(true); @@ -112,7 +137,7 @@ public function testCSPRNG() FacebookTestCredentials::$appSecret ); - $class = new ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); + $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); $method = $class->getMethod('random'); $method->setAccessible(true); diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 9cd3c1e27..d850731d0 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -1,4 +1,27 @@ Date: Wed, 23 Jul 2014 21:53:37 +0200 Subject: [PATCH 023/407] Rename FacebookRequestException to FacebookResponseException --- src/Facebook/Entities/AccessToken.php | 12 ++--- .../FacebookAuthorizationException.php | 2 +- .../Exceptions/FacebookClientException.php | 2 +- .../Exceptions/FacebookOtherException.php | 2 +- .../FacebookPermissionException.php | 2 +- ...tion.php => FacebookResponseException.php} | 8 ++-- .../Exceptions/FacebookServerException.php | 2 +- .../Exceptions/FacebookThrottleException.php | 2 +- src/Facebook/FacebookRequest.php | 6 +-- ....php => FacebookResponseExceptionTest.php} | 46 +++++++++---------- 10 files changed, 42 insertions(+), 42 deletions(-) rename src/Facebook/Exceptions/{FacebookRequestException.php => FacebookResponseException.php} (96%) rename tests/Exceptions/{FacebookRequestExceptionTest.php => FacebookResponseExceptionTest.php} (85%) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 253ed3729..40581af61 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -24,7 +24,7 @@ namespace Facebook\Entities; use Facebook\FacebookRequest; -use Facebook\Exceptions\FacebookRequestException; +use Facebook\Exceptions\FacebookResponseException; use Facebook\FacebookSession; use Facebook\GraphNodes\GraphSessionInfo; @@ -251,7 +251,7 @@ public function extend($appId = null, $appSecret = null) * * @return AccessToken * - * @throws FacebookRequestException + * @throws FacebookResponseException */ public static function requestAccessToken(array $params, $appId = null, $appSecret = null) { @@ -275,7 +275,7 @@ public static function requestAccessToken(array $params, $appId = null, $appSecr } } - throw FacebookRequestException::create( + throw FacebookResponseException::create( $response->getRawResponse(), $data, 401 @@ -291,7 +291,7 @@ public static function requestAccessToken(array $params, $appId = null, $appSecr * * @return string * - * @throws FacebookRequestException + * @throws FacebookResponseException */ public static function requestCode(array $params, $appId = null, $appSecret = null) { @@ -302,7 +302,7 @@ public static function requestCode(array $params, $appId = null, $appSecret = nu return (string) $data->code; } - throw FacebookRequestException::create( + throw FacebookResponseException::create( $response->getRawResponse(), $data, 401 @@ -319,7 +319,7 @@ public static function requestCode(array $params, $appId = null, $appSecret = nu * * @return \Facebook\FacebookResponse * - * @throws FacebookRequestException + * @throws FacebookResponseException */ protected static function request($endpoint, array $params, $appId = null, $appSecret = null) { diff --git a/src/Facebook/Exceptions/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php index 41220d4ca..0a373eb3e 100644 --- a/src/Facebook/Exceptions/FacebookAuthorizationException.php +++ b/src/Facebook/Exceptions/FacebookAuthorizationException.php @@ -27,7 +27,7 @@ * Class FacebookAuthorizationException * @package Facebook */ -class FacebookAuthorizationException extends FacebookRequestException +class FacebookAuthorizationException extends FacebookResponseException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php index fee4434e0..e22219efd 100644 --- a/src/Facebook/Exceptions/FacebookClientException.php +++ b/src/Facebook/Exceptions/FacebookClientException.php @@ -27,7 +27,7 @@ * Class FacebookClientException * @package Facebook */ -class FacebookClientException extends FacebookRequestException +class FacebookClientException extends FacebookResponseException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php index 9a9dfd2a0..9a0e77842 100644 --- a/src/Facebook/Exceptions/FacebookOtherException.php +++ b/src/Facebook/Exceptions/FacebookOtherException.php @@ -27,7 +27,7 @@ * Class FacebookOtherException * @package Facebook */ -class FacebookOtherException extends FacebookRequestException +class FacebookOtherException extends FacebookResponseException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookPermissionException.php b/src/Facebook/Exceptions/FacebookPermissionException.php index b4ec10cf9..d37d30920 100644 --- a/src/Facebook/Exceptions/FacebookPermissionException.php +++ b/src/Facebook/Exceptions/FacebookPermissionException.php @@ -27,7 +27,7 @@ * Class FacebookPermissionException * @package Facebook */ -class FacebookPermissionException extends FacebookRequestException +class FacebookPermissionException extends FacebookResponseException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookRequestException.php b/src/Facebook/Exceptions/FacebookResponseException.php similarity index 96% rename from src/Facebook/Exceptions/FacebookRequestException.php rename to src/Facebook/Exceptions/FacebookResponseException.php index 4493677c5..41e5b76d2 100644 --- a/src/Facebook/Exceptions/FacebookRequestException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -24,12 +24,12 @@ namespace Facebook\Exceptions; /** - * Class FacebookRequestException + * Class FacebookResponseException * @package Facebook * @author Fosco Marotto * @author David Poll */ -class FacebookRequestException extends FacebookSDKException +class FacebookResponseException extends FacebookSDKException { /** @@ -48,7 +48,7 @@ class FacebookRequestException extends FacebookSDKException private $responseData; /** - * Creates a FacebookRequestException. + * Creates a FacebookResponseException. * * @param string $rawResponse The raw response from the Graph API * @param array $responseData The decoded response from the Graph API @@ -72,7 +72,7 @@ public function __construct($rawResponse, $responseData, $statusCode) * @param array $data the decoded response from the Graph API * @param int $statusCode the HTTP response code * - * @return FacebookRequestException + * @return FacebookResponseException */ public static function create($raw, $data, $statusCode) { diff --git a/src/Facebook/Exceptions/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php index 078afa40a..06d7f756c 100644 --- a/src/Facebook/Exceptions/FacebookServerException.php +++ b/src/Facebook/Exceptions/FacebookServerException.php @@ -27,7 +27,7 @@ * Class FacebookServerException * @package Facebook */ -class FacebookServerException extends FacebookRequestException +class FacebookServerException extends FacebookResponseException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php index ed5ebb060..be5bee8c3 100644 --- a/src/Facebook/Exceptions/FacebookThrottleException.php +++ b/src/Facebook/Exceptions/FacebookThrottleException.php @@ -27,7 +27,7 @@ * Class FacebookThrottleException * @package Facebook */ -class FacebookThrottleException extends FacebookRequestException +class FacebookThrottleException extends FacebookResponseException { } \ No newline at end of file diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index 3c3a560e5..dad196765 100644 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -26,7 +26,7 @@ use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; -use Facebook\Exceptions\FacebookRequestException; +use Facebook\Exceptions\FacebookResponseException; /** * Class FacebookRequest @@ -223,7 +223,7 @@ protected function getRequestURL() * @return FacebookResponse * * @throws FacebookSDKException - * @throws FacebookRequestException + * @throws FacebookResponseException */ public function execute() { @@ -262,7 +262,7 @@ public function execute() return new FacebookResponse($this, $out, $result, $etagHit, $etagReceived); } if (isset($decodedResult->error)) { - throw FacebookRequestException::create( + throw FacebookResponseException::create( $result, $decodedResult->error, $connection->getResponseHttpStatusCode() diff --git a/tests/Exceptions/FacebookRequestExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php similarity index 85% rename from tests/Exceptions/FacebookRequestExceptionTest.php rename to tests/Exceptions/FacebookResponseExceptionTest.php index bd911d2c3..6d2a37d75 100644 --- a/tests/Exceptions/FacebookRequestExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -23,7 +23,7 @@ */ namespace Facebook\Tests\Exceptions; -use Facebook\Exceptions\FacebookRequestException; +use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookAuthorizationException; use Facebook\Exceptions\FacebookOtherException; use Facebook\Exceptions\FacebookServerException; @@ -32,7 +32,7 @@ use Facebook\Exceptions\FacebookThrottleException; use Facebook\FacebookSession; -class FacebookRequestExceptionTest extends \PHPUnit_Framework_TestCase +class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase { public function testAuthorizationExceptions() @@ -46,7 +46,7 @@ public function testAuthorizationExceptions() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(100, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); @@ -57,13 +57,13 @@ public function testAuthorizationExceptions() $params['error']['code'] = 102; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(102, $exception->getCode()); $params['error']['code'] = 190; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(190, $exception->getCode()); @@ -71,31 +71,31 @@ public function testAuthorizationExceptions() $params['error']['code'] = 0; $params['error']['error_subcode'] = 458; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(458, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 460; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(460, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 463; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(463, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 467; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(467, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 0; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(0, $exception->getSubErrorCode()); } @@ -111,7 +111,7 @@ public function testServerExceptions() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 500); + $exception = FacebookResponseException::create($json, $params, 500); $this->assertTrue($exception instanceof FacebookServerException); $this->assertEquals(1, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); @@ -122,7 +122,7 @@ public function testServerExceptions() $params['error']['code'] = 2; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookServerException); $this->assertEquals(2, $exception->getCode()); } @@ -138,7 +138,7 @@ public function testThrottleExceptions() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookThrottleException); $this->assertEquals(4, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); @@ -149,13 +149,13 @@ public function testThrottleExceptions() $params['error']['code'] = 17; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookThrottleException); $this->assertEquals(17, $exception->getCode()); $params['error']['code'] = 341; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookThrottleException); $this->assertEquals(341, $exception->getCode()); } @@ -171,7 +171,7 @@ public function testUserIssueExceptions() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(230, $exception->getCode()); $this->assertEquals(459, $exception->getSubErrorCode()); @@ -182,7 +182,7 @@ public function testUserIssueExceptions() $params['error']['error_subcode'] = 464; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); $this->assertEquals(464, $exception->getSubErrorCode()); } @@ -198,7 +198,7 @@ public function testPermissionExceptions() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookPermissionException); $this->assertEquals(10, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); @@ -209,19 +209,19 @@ public function testPermissionExceptions() $params['error']['code'] = 200; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookPermissionException); $this->assertEquals(200, $exception->getCode()); $params['error']['code'] = 250; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookPermissionException); $this->assertEquals(250, $exception->getCode()); $params['error']['code'] = 299; $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookPermissionException); $this->assertEquals(299, $exception->getCode()); } @@ -237,7 +237,7 @@ public function testClientExceptions() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 401); + $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookClientException); $this->assertEquals(506, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); @@ -258,7 +258,7 @@ public function testOtherException() ) ); $json = json_encode($params); - $exception = FacebookRequestException::create($json, $params, 200); + $exception = FacebookResponseException::create($json, $params, 200); $this->assertTrue($exception instanceof FacebookOtherException); $this->assertEquals(42, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); From 977e3d3a63c6aaa736f33994ed58fdd57e43a6b3 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 21 Jul 2014 18:40:24 +0200 Subject: [PATCH 024/407] Update FacebookApp tests and add copyright header --- tests/Entities/FacebookAppTest.php | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/Entities/FacebookAppTest.php b/tests/Entities/FacebookAppTest.php index 258ab1135..8b434feff 100644 --- a/tests/Entities/FacebookAppTest.php +++ b/tests/Entities/FacebookAppTest.php @@ -1,4 +1,27 @@ assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); $this->assertEquals('id|secret', (string)$accessToken); } + + public function testSerialization() + { + $app = new FacebookApp('id', 'secret'); + $newApp = unserialize(serialize($app)); + + $this->assertInstanceOf('Facebook\Entities\FacebookApp', $newApp); + $this->assertEquals('id', $newApp->getId()); + $this->assertEquals('secret', $newApp->getSecret()); + } } From 3d3f7434c3eb3de38bcec01ee9a315d839cb6778 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 24 Jul 2014 02:39:41 +0200 Subject: [PATCH 025/407] Fix Mockery --- phpunit.xml.dist | 5 +++++ tests/Entities/AccessTokenTest.php | 5 ----- tests/FacebookSessionTest.php | 5 ----- tests/HttpClients/FacebookCurlHttpClientTest.php | 1 - tests/HttpClients/FacebookGuzzleHttpClientTest.php | 1 - tests/HttpClients/FacebookStreamHttpClientTest.php | 1 - 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index fcca4e79e..1d9a820b7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,4 +16,9 @@ ./src/Facebook + + + + diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index a7b00367c..c84189c29 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -31,11 +31,6 @@ class AccessTokenTest extends \PHPUnit_Framework_TestCase { - public function tearDown() - { - m::close(); - } - public function testAnAccessTokenCanBeReturnedAsAString() { $accessToken = new AccessToken('foo_token'); diff --git a/tests/FacebookSessionTest.php b/tests/FacebookSessionTest.php index fd9fb227b..5ca273c10 100644 --- a/tests/FacebookSessionTest.php +++ b/tests/FacebookSessionTest.php @@ -31,11 +31,6 @@ class FacebookSessionTest extends \PHPUnit_Framework_TestCase { - public function tearDown() - { - m::close(); - } - public function testSessionToken() { $session = new FacebookSession(FacebookTestHelper::getAppToken()); diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index b306b44db..54f85fd6d 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -46,7 +46,6 @@ public function setUp() public function tearDown() { - m::close(); (new FacebookCurlHttpClient()); // Resets the static dependency injection } diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index 474512b3b..7c82f0f94 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -43,7 +43,6 @@ public function setUp() public function tearDown() { - m::close(); (new FacebookGuzzleHttpClient()); // Resets the static dependency injection } diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index 5f980e0c0..a320a4b75 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -43,7 +43,6 @@ public function setUp() public function tearDown() { - m::close(); (new FacebookStreamHttpClient()); // Resets the static dependency injection } From 1cb8eaf4fc8c3f567c7a817c9d0c81612cd6820d Mon Sep 17 00:00:00 2001 From: Adam Elsodaney Date: Sat, 26 Jul 2014 23:29:53 +0100 Subject: [PATCH 026/407] Fix missing whitespace between return keyword and method calls --- src/Facebook/GraphNodes/GraphAlbum.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index 28793b5e9..d4a69dc0f 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -58,7 +58,7 @@ public function canUpload() */ public function getCount() { - return$this->getProperty('count'); + return $this->getProperty('count'); } /** @@ -68,7 +68,7 @@ public function getCount() */ public function getCoverPhoto() { - return$this->getProperty('cover_photo'); + return $this->getProperty('cover_photo'); } /** @@ -106,7 +106,7 @@ public function getUpdatedTime() */ public function getDescription() { - return$this->getProperty('description'); + return $this->getProperty('description'); } /** @@ -126,7 +126,7 @@ public function getFrom() */ public function getLink() { - return$this->getProperty('link'); + return $this->getProperty('link'); } /** @@ -136,7 +136,7 @@ public function getLink() */ public function getLocation() { - return$this->getProperty('location'); + return $this->getProperty('location'); } /** @@ -146,7 +146,7 @@ public function getLocation() */ public function getName() { - return$this->getProperty('name'); + return $this->getProperty('name'); } /** @@ -156,7 +156,7 @@ public function getName() */ public function getPrivacy() { - return$this->getProperty('privacy'); + return $this->getProperty('privacy'); } /** @@ -166,7 +166,7 @@ public function getPrivacy() */ public function getType() { - return$this->getProperty('type'); + return $this->getProperty('type'); } //TODO: public function getPlace() that should return GraphPage From ef3134c04102d0cb23d802c207602180b199f2af Mon Sep 17 00:00:00 2001 From: Dilip Raj Baral Date: Sun, 27 Jul 2014 11:47:28 +0530 Subject: [PATCH 027/407] Update documentation for getLoginUrl() method Added param documentation for $rerequest --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 8bd1eb2e5..355634132 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -72,10 +72,15 @@ public function __construct($appId = null, $appSecret = null) * Stores CSRF state and returns a URL to which the user should be sent to * in order to continue the login process with Facebook. The * provided redirectUrl should invoke the handleRedirect method. + * If a previous request to certain permission(s) was declined + * by the user, rerequest should be set to true or the permission(s) + * will not 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 boolean $rerequest Whether this is the re-request to the previously + * declined permissions * @param string $version Optional Graph API version if not default (v2.0) * * @return string From a068b133667cd44c57eec232f90185767ff3d2ea Mon Sep 17 00:00:00 2001 From: dudu Date: Fri, 1 Aug 2014 23:31:52 +0200 Subject: [PATCH 028/407] Fix "Fatal error: Cannot use object of type stdClass as array" Make sure that the "backingData" property's value will always be converted to an array. --- src/Facebook/GraphNodes/GraphObject.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index d73904859..d3d99f1d7 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -50,7 +50,11 @@ public function __construct($raw) $this->backingData = $raw; if (isset($this->backingData['data']) && count($this->backingData) === 1) { - $this->backingData = $this->backingData['data']; + if ($this->backingData['data'] instanceof \stdClass) { + $this->backingData = get_object_vars($this->backingData['data']); + } else { + $this->backingData = $this->backingData['data']; + } } } From 22cf28c17debcb4913ac66d8d3fe0626208b6c9f Mon Sep 17 00:00:00 2001 From: SammyK Date: Mon, 4 Aug 2014 15:53:47 -0500 Subject: [PATCH 029/407] Fixed warnings when open_basedir directive set --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 5725f1e8b..0e1316b23 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -305,7 +305,8 @@ private function random($bytes) } $buf = ''; // http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ - if (is_readable('/dev/urandom')) { + if (!ini_get('open_basedir') + && is_readable('/dev/urandom')) { $fp = fopen('/dev/urandom', 'rb'); if ($fp !== FALSE) { $buf = fread($fp, $bytes); @@ -315,7 +316,7 @@ private function random($bytes) } } } - + if (function_exists('mcrypt_create_iv')) { $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); if ($buf !== FALSE) { From 6efff6d630c76aac3ef1d59255c30d9be11a35cf Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 12 Aug 2014 13:30:38 -0700 Subject: [PATCH 030/407] Removed GET processing from CanvasLoginHelper. --- src/Facebook/Helpers/FacebookCanvasLoginHelper.php | 14 +------------- tests/Helpers/FacebookCanvasLoginHelperTest.php | 9 --------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/Facebook/Helpers/FacebookCanvasLoginHelper.php b/src/Facebook/Helpers/FacebookCanvasLoginHelper.php index 6e1c6496d..a2eab27e8 100644 --- a/src/Facebook/Helpers/FacebookCanvasLoginHelper.php +++ b/src/Facebook/Helpers/FacebookCanvasLoginHelper.php @@ -43,24 +43,12 @@ public function getAppData() } /** - * Get raw signed request from either GET or POST. + * Get raw signed request from POST. * * @return string|null */ public function getRawSignedRequest() { - /** - * v2.0 apps use GET for Canvas signed requests. - */ - $rawSignedRequest = $this->getRawSignedRequestFromGet(); - if ($rawSignedRequest) { - return $rawSignedRequest; - } - - /** - * v1.0 apps use POST for Canvas signed requests, will eventually be - * deprecated. - */ $rawSignedRequest = $this->getRawSignedRequestFromPost(); if ($rawSignedRequest) { return $rawSignedRequest; diff --git a/tests/Helpers/FacebookCanvasLoginHelperTest.php b/tests/Helpers/FacebookCanvasLoginHelperTest.php index 90b249984..2445f4996 100644 --- a/tests/Helpers/FacebookCanvasLoginHelperTest.php +++ b/tests/Helpers/FacebookCanvasLoginHelperTest.php @@ -36,15 +36,6 @@ public function setUp() $this->helper = new FacebookCanvasLoginHelper('123', 'foo_app_secret'); } - public function testSignedRequestDataCanBeRetrievedFromGetData() - { - $_GET['signed_request'] = $this->rawSignedRequestAuthorized; - - $rawSignedRequest = $this->helper->getRawSignedRequest(); - - $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); - } - public function testSignedRequestDataCanBeRetrievedFromPostData() { $_POST['signed_request'] = $this->rawSignedRequestAuthorized; From 9b0d92fe58bf3fe9096d85a20efdf517b692ead9 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 12 Aug 2014 15:07:09 -0700 Subject: [PATCH 031/407] Updated visibility of FacebookSession:: --- src/Facebook/FacebookSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/FacebookSession.php b/src/Facebook/FacebookSession.php index 171c3ad8b..ba5337401 100644 --- a/src/Facebook/FacebookSession.php +++ b/src/Facebook/FacebookSession.php @@ -60,7 +60,7 @@ class FacebookSession /** * @var bool */ - private static $useAppSecretProof = true; + protected static $useAppSecretProof = true; /** * When creating a Session from an access_token, use: From ee28a90fdd752659cd3a6f629233c431e8ed9e04 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 13 Aug 2014 15:43:26 +0100 Subject: [PATCH 032/407] Updated testing version constraints --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 68b3da008..81e4b338b 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ "ext-mbstring": "*" }, "require-dev": { - "phpunit/phpunit": "3.7.*", - "mockery/mockery": "dev-master", + "phpunit/phpunit": "~4.0", + "mockery/mockery": "~0.8", "guzzlehttp/guzzle": "~4.0" }, "suggest": { From 3d3eaec6b624c64d5afc55f520978d89643a4ae9 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Wed, 13 Aug 2014 20:04:38 +0100 Subject: [PATCH 033/407] Corrected a typo --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index ad5ff3247..c33fe29f2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -23,7 +23,7 @@ */ require_once __DIR__ . '/../vendor/autoload.php'; -use Facebook\FacebookSDKException; +use Facebook\Exceptions\FacebookSDKException; use Facebook\Tests\FacebookTestHelper; if (!file_exists(__DIR__ . '/FacebookTestCredentials.php')) { From c6375ffd8433ca4f78dbc72fa314ce996381beb0 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 13 Aug 2014 17:09:06 -0500 Subject: [PATCH 034/407] [4.1] Disambiguate versions --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2bb28bf1d..d1f071587 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Facebook SDK for PHP ==================== -[![Latest Stable Version](http://img.shields.io/packagist/v/facebook/php-sdk-v4.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Development Version](http://img.shields.io/badge/Development%20Version-4.1.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access Facebook @@ -18,8 +18,8 @@ Minimal example: ```php use Facebook\FacebookSession; use Facebook\FacebookRequest; -use Facebook\GraphUser; -use Facebook\FacebookRequestException; +use Facebook\GraphNodes\GraphUser; +use Facebook\Exceptions\FacebookRequestException; FacebookSession::setDefaultApplication('YOUR_APP_ID','YOUR_APP_SECRET'); From 23e5d9db12be849cb771b2f52badca9a8637d9f6 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Thu, 14 Aug 2014 11:19:31 -0700 Subject: [PATCH 035/407] Reverted URL encoding behavior on FacebookRedirectLoginHelper --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 0e1316b23..63667dae0 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -103,7 +103,7 @@ public function getLoginUrl($redirectUrl, $scope = array(), $rerequest = false, $params['auth_type'] = 'rerequest'; return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . - http_build_query($params, null, '&'); + http_build_query($params, null, '&'); } /** From 0092e1e19bb14a327f23d3cb0c65533acd6410bd Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 23 Jul 2014 20:35:52 -0500 Subject: [PATCH 036/407] Refactored request/response. --- src/Facebook/Entities/AccessToken.php | 196 ++++---- src/Facebook/Entities/AppSecretProof.php | 87 ++++ src/Facebook/Entities/FacebookApp.php | 4 +- .../Entities/FacebookBatchRequest.php | 219 +++++++++ .../Entities/FacebookBatchResponse.php | 100 +++++ src/Facebook/Entities/FacebookRequest.php | 425 ++++++++++++++++++ src/Facebook/Entities/FacebookResponse.php | 291 ++++++++++++ src/Facebook/Entities/SignedRequest.php | 7 +- src/Facebook/FacebookClient.php | 191 ++++++++ src/Facebook/FacebookRequest.php | 314 ------------- src/Facebook/FacebookResponse.php | 204 --------- src/Facebook/FacebookSession.php | 369 --------------- src/Facebook/GraphNodes/GraphAlbum.php | 4 +- src/Facebook/GraphNodes/GraphObject.php | 19 +- src/Facebook/GraphNodes/GraphSessionInfo.php | 4 +- src/Facebook/GraphNodes/GraphUser.php | 2 +- src/Facebook/GraphNodes/GraphUserPage.php | 2 +- .../Helpers/FacebookPageTabHelper.php | 9 +- .../Helpers/FacebookRedirectLoginHelper.php | 117 ++--- .../FacebookSignedRequestFromInputHelper.php | 51 ++- .../HttpClients/FacebookCurlHttpClient.php | 60 +-- .../HttpClients/FacebookGuzzleHttpClient.php | 50 +-- .../FacebookHttpClientInterface.php | 25 +- .../HttpClients/FacebookStreamHttpClient.php | 60 +-- tests/Entities/AccessTokenTest.php | 163 ++++--- .../AppSecretProofTest.php} | 30 +- tests/Entities/FacebookBatchRequestTest.php | 367 +++++++++++++++ tests/Entities/FacebookBatchResponseTest.php | 98 ++++ tests/Entities/FacebookRequestTest.php | 196 ++++++++ tests/Entities/FacebookResponseTest.php | 131 ++++++ .../FacebookResponseExceptionTest.php | 19 - tests/FacebookClientTest.php | 288 ++++++++++++ tests/FacebookRequestTest.php | 165 ------- tests/FacebookSessionTest.php | 103 ----- tests/FacebookTestHelper.php | 98 ---- tests/GraphNodes/GraphAlbumTest.php | 63 ++- tests/GraphNodes/GraphObjectTest.php | 157 ++++--- tests/GraphNodes/GraphSessionInfoTest.php | 40 +- tests/GraphNodes/GraphUserTest.php | 41 +- .../Helpers/FacebookCanvasLoginHelperTest.php | 8 +- .../FacebookJavaScriptLoginHelperTest.php | 6 +- tests/Helpers/FacebookPageTabHelperTest.php | 7 +- .../FacebookRedirectLoginHelperTest.php | 128 +++--- ...cebookSignedRequestFromInputHelperTest.php | 62 ++- .../FacebookCurlHttpClientTest.php | 48 +- .../FacebookGuzzleHttpClientTest.php | 17 +- .../FacebookStreamHttpClientTest.php | 21 +- tests/bootstrap.php | 26 +- 48 files changed, 3139 insertions(+), 1953 deletions(-) create mode 100755 src/Facebook/Entities/AppSecretProof.php create mode 100755 src/Facebook/Entities/FacebookBatchRequest.php create mode 100755 src/Facebook/Entities/FacebookBatchResponse.php create mode 100755 src/Facebook/Entities/FacebookRequest.php create mode 100755 src/Facebook/Entities/FacebookResponse.php create mode 100644 src/Facebook/FacebookClient.php delete mode 100644 src/Facebook/FacebookRequest.php delete mode 100644 src/Facebook/FacebookResponse.php delete mode 100644 src/Facebook/FacebookSession.php rename tests/{GraphNodes/GraphLocationTest.php => Entities/AppSecretProofTest.php} (61%) mode change 100644 => 100755 create mode 100755 tests/Entities/FacebookBatchRequestTest.php create mode 100755 tests/Entities/FacebookBatchResponseTest.php create mode 100755 tests/Entities/FacebookRequestTest.php create mode 100755 tests/Entities/FacebookResponseTest.php create mode 100644 tests/FacebookClientTest.php delete mode 100644 tests/FacebookRequestTest.php delete mode 100644 tests/FacebookSessionTest.php delete mode 100644 tests/FacebookTestHelper.php diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 40581af61..46c6e5f18 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -23,9 +23,9 @@ */ namespace Facebook\Entities; -use Facebook\FacebookRequest; use Facebook\Exceptions\FacebookResponseException; -use Facebook\FacebookSession; +use Facebook\Exceptions\FacebookSDKException; +use Facebook\FacebookClient; use Facebook\GraphNodes\GraphSessionInfo; /** @@ -40,12 +40,12 @@ class AccessToken implements \Serializable * * @var string */ - protected $accessToken; + protected $accessToken = ''; /** * A unique ID to identify a client. * - * @var string + * @var string|null */ protected $machineId; @@ -135,17 +135,17 @@ public function isExpired() /** * Checks the validity of the access token. * - * @param string|null $appId Application ID to use - * @param string|null $appSecret App secret value to use - * @param string|null $machineId + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. + * @param string|null $machineId Unique client identifier. * * @return boolean */ - public function isValid($appId = null, $appSecret = null, $machineId = null) + public function isValid(FacebookApp $app, FacebookClient $client, $machineId = null) { - $accessTokenInfo = $this->getInfo($appId, $appSecret); + $accessTokenInfo = $this->getInfo($app, $client); $machineId = $machineId ?: $this->machineId; - return static::validateAccessToken($accessTokenInfo, $appId, $machineId); + return static::validateAccessToken($accessTokenInfo, $app, $machineId); } /** @@ -155,17 +155,16 @@ public function isValid($appId = null, $appSecret = null, $machineId = null) * that the token is valid and has not expired. * * @param GraphSessionInfo $tokenInfo - * @param string|null $appId Application ID to use + * @param FacebookApp $app The FacebookApp entity. * @param string|null $machineId * * @return boolean */ public static function validateAccessToken(GraphSessionInfo $tokenInfo, - $appId = null, $machineId = null) + FacebookApp $app, + $machineId = null) { - $targetAppId = FacebookSession::_getTargetAppId($appId); - - $appIdIsValid = $tokenInfo->getAppId() == $targetAppId; + $appIdIsValid = $tokenInfo->getProperty('app_id') == $app->getId(); $machineIdIsValid = $tokenInfo->getProperty('machine_id') == $machineId; $accessTokenIsValid = $tokenInfo->isValid(); @@ -183,130 +182,132 @@ public static function validateAccessToken(GraphSessionInfo $tokenInfo, * Get a valid access token from a code. * * @param string $code - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. + * @param string|null $redirectUri * @param string|null $machineId * * @return AccessToken */ - public static function getAccessTokenFromCode($code, $appId = null, $appSecret = null, $machineId = null) + public static function getAccessTokenFromCode($code, + FacebookApp $app, + FacebookClient $client, + $redirectUri = '', + $machineId = null) { - $params = array( + $params = [ 'code' => $code, - 'redirect_uri' => '', - ); + 'redirect_uri' => $redirectUri, + ]; if ($machineId) { $params['machine_id'] = $machineId; } - return static::requestAccessToken($params, $appId, $appSecret); + return static::requestAccessToken($params, $app, $client); } /** * Get a valid code from an access token. * * @param AccessToken|string $accessToken - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. + * @param string|null $redirectUri * * @return AccessToken */ - public static function getCodeFromAccessToken($accessToken, $appId = null, $appSecret = null) + public static function getCodeFromAccessToken($accessToken, + FacebookApp $app, + FacebookClient $client, + $redirectUri = '') { $accessToken = (string) $accessToken; - $params = array( + $params = [ 'access_token' => $accessToken, - 'redirect_uri' => '', - ); + 'redirect_uri' => $redirectUri, + ]; - return static::requestCode($params, $appId, $appSecret); + return static::requestCode($params, $app, $client); } /** * Exchanges a short lived access token with a long lived access token. * - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. * * @return AccessToken */ - public function extend($appId = null, $appSecret = null) + public function extend(FacebookApp $app, FacebookClient $client) { - $params = array( + $params = [ 'grant_type' => 'fb_exchange_token', 'fb_exchange_token' => $this->accessToken, - ); + ]; - return static::requestAccessToken($params, $appId, $appSecret); + return static::requestAccessToken($params, $app, $client); } /** * Request an access token based on a set of params. * * @param array $params - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. * * @return AccessToken * - * @throws FacebookResponseException + * @throws FacebookSDKException */ - public static function requestAccessToken(array $params, $appId = null, $appSecret = null) + public static function requestAccessToken(array $params, FacebookApp $app, FacebookClient $client) { - $response = static::request('/oauth/access_token', $params, $appId, $appSecret); - $data = $response->getResponse(); - - /** - * @TODO fix this malarkey - getResponse() should always return an object - * @see https://github.com/facebook/facebook-php-sdk-v4/issues/36 - */ - if (is_array($data)) { - if (isset($data['access_token'])) { - $expiresAt = isset($data['expires']) ? time() + $data['expires'] : 0; - return new static($data['access_token'], $expiresAt); - } - } elseif($data instanceof \stdClass) { - if (isset($data->access_token)) { - $expiresAt = isset($data->expires_in) ? time() + $data->expires_in : 0; - $machineId = isset($data->machine_id) ? (string) $data->machine_id : null; - return new static((string) $data->access_token, $expiresAt, $machineId); - } + $response = static::request('/oauth/access_token', $params, $app, $client); + $data = $response->getDecodedBody(); + + if (!isset($data['access_token'])) { + throw new FacebookSDKException('Access token was not returned from Graph.', 401); } - throw FacebookResponseException::create( - $response->getRawResponse(), - $data, - 401 - ); + // Graph returns two different key names for expiration time + // on the same endpoint. Doh! :/ + $expiresAt = 0; + if (isset($data['expires'])) { + // For exchanging a short lived token with a long lived token. + // The expiration time in seconds will be returned as "expires". + $expiresAt = time() + $data['expires']; + } elseif (isset($data['expires_in'])) { + // For exchanging a code for a short lived access token. + // The expiration time in seconds will be returned as "expires_in". + // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code + $expiresAt = time() + $data['expires_in']; + } + $machineId = isset($data['machine_id']) ? $data['machine_id'] : null; + return new static($data['access_token'], $expiresAt, $machineId); } /** * Request a code from a long lived access token. * * @param array $params - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. * * @return string * - * @throws FacebookResponseException + * @throws FacebookSDKException */ - public static function requestCode(array $params, $appId = null, $appSecret = null) + public static function requestCode(array $params, FacebookApp $app, FacebookClient $client) { - $response = static::request('/oauth/client_code', $params, $appId, $appSecret); - $data = $response->getResponse(); + $response = static::request('/oauth/client_code', $params, $app, $client); + $data = $response->getDecodedBody(); - if (isset($data->code)) { - return (string) $data->code; + if (isset($data['code'])) { + return $data['code']; } - throw FacebookResponseException::create( - $response->getRawResponse(), - $data, - 401 - ); + throw new FacebookSDKException('Code was not returned from Graph.', 401); } /** @@ -314,55 +315,54 @@ public static function requestCode(array $params, $appId = null, $appSecret = nu * * @param string $endpoint * @param array $params - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. * - * @return \Facebook\FacebookResponse + * @return FacebookResponse * * @throws FacebookResponseException */ - protected static function request($endpoint, array $params, $appId = null, $appSecret = null) + protected static function request($endpoint, array $params, FacebookApp $app, FacebookClient $client) { - $targetAppId = FacebookSession::_getTargetAppId($appId); - $targetAppSecret = FacebookSession::_getTargetAppSecret($appSecret); - if (!isset($params['client_id'])) { - $params['client_id'] = $targetAppId; + $params['client_id'] = $app->getId(); } if (!isset($params['client_secret'])) { - $params['client_secret'] = $targetAppSecret; + $params['client_secret'] = $app->getSecret(); } // The response for this endpoint is not JSON, so it must be handled // differently, not as a GraphObject. $request = new FacebookRequest( - FacebookSession::newAppSession($targetAppId, $targetAppSecret), + $app, + $app->getAccessToken(), 'GET', $endpoint, $params ); - return $request->execute(); + return $client->sendRequest($request); } /** * Get more info about an access token. * - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The Facebook client. * * @return GraphSessionInfo */ - public function getInfo($appId = null, $appSecret = null) + public function getInfo(FacebookApp $app, FacebookClient $client) { - $params = array('input_token' => $this->accessToken); + $params = ['input_token' => $this->accessToken]; $request = new FacebookRequest( - FacebookSession::newAppSession($appId, $appSecret), + $app, + $app->getAccessToken(), 'GET', '/debug_token', $params ); - $response = $request->execute()->getGraphObject(GraphSessionInfo::className()); + $response = $client->sendRequest($request)->getGraphObject(GraphSessionInfo::className()); // Update the data on this token if ($response->getExpiresAt()) { @@ -382,6 +382,11 @@ public function __toString() return $this->accessToken; } + /** + * Serialize the entity. + * + * @return string + */ public function serialize() { $expiresAt = null; @@ -389,9 +394,14 @@ public function serialize() $expiresAt = $this->expiresAt->getTimestamp(); } - return serialize(array($this->accessToken, $expiresAt, $this->machineId)); + return serialize([$this->accessToken, $expiresAt, $this->machineId]); } + /** + * Unserialize the entity. + * + * @param string $serialized + */ public function unserialize($serialized) { list($accessToken, $expiresAt, $machineId) = unserialize($serialized); diff --git a/src/Facebook/Entities/AppSecretProof.php b/src/Facebook/Entities/AppSecretProof.php new file mode 100755 index 000000000..bbf31d352 --- /dev/null +++ b/src/Facebook/Entities/AppSecretProof.php @@ -0,0 +1,87 @@ +accessToken = $accessToken; + $this->appSecret = $appSecret; + } + + /** + * Generate and return the app secret proof value for an access token. + * + * @param string $accessToken The access token as a string. + * @param string $appSecret The app secret. + * + * @return string The app secret proof. + */ + public static function make($accessToken, $appSecret) + { + return hash_hmac('sha256', $accessToken, $appSecret); + } + + /** + * Convert the entity to a string by creating an app secret proof. + * + * @return string The app secret proof. + */ + public function __toString() + { + if ($this->appSecretProof) { + return $this->appSecretProof; + } + + return $this->appSecretProof = static::make($this->accessToken, $this->appSecret); + } + +} diff --git a/src/Facebook/Entities/FacebookApp.php b/src/Facebook/Entities/FacebookApp.php index e9cc58726..d7b9f316c 100644 --- a/src/Facebook/Entities/FacebookApp.php +++ b/src/Facebook/Entities/FacebookApp.php @@ -23,8 +23,6 @@ */ namespace Facebook\Entities; -use Facebook\Entities\AccessToken; - class FacebookApp implements \Serializable { /** @@ -83,4 +81,4 @@ public function unserialize($serialized) $this->__construct($id, $secret); } -} \ No newline at end of file +} diff --git a/src/Facebook/Entities/FacebookBatchRequest.php b/src/Facebook/Entities/FacebookBatchRequest.php new file mode 100755 index 000000000..fc2aee2a5 --- /dev/null +++ b/src/Facebook/Entities/FacebookBatchRequest.php @@ -0,0 +1,219 @@ +add($requests); + } + + /** + * A a new request to the array. + * + * @param FacebookRequest|array $request + * @param string|null $name + * + * @return FacebookBatchRequest + * + * @throws FacebookSDKException + */ + public function add($request, $name = null) + { + if (is_array($request)) { + foreach ($request as $key => $req) { + $this->add($req, $key); + } + return $this; + } elseif ($request instanceof FacebookRequest) { + $this->addFallbackDefaults($request); + $this->requests[] = [ + 'name' => $name, + 'request' => $request, + ]; + return $this; + } + throw new FacebookSDKException( + 'Argument for add() must be of type array or FacebookRequest.' + ); + } + + /** + * Ensures that the FacebookApp and access token fall back when missing. + * + * @param FacebookRequest $request + * + * @throws FacebookSDKException + */ + public function addFallbackDefaults(FacebookRequest $request) + { + if (!$request->getApp()) { + $app = $this->getApp(); + if (!$app) { + throw new FacebookSDKException( + 'Missing FacebookApp on FacebookRequest and no fallback detected on FacebookBatchRequest.' + ); + } + $request->setApp($app); + } + if (!$request->getAccessToken()) { + $accessToken = $this->getAccessToken(); + if (!$accessToken) { + throw new FacebookSDKException( + 'Missing access token on FacebookRequest and no fallback detected on FacebookBatchRequest.' + ); + } + $request->setAccessToken($accessToken); + } + } + + /** + * Return the FacebookRequest entities. + * + * @return array + */ + public function getRequests() + { + return $this->requests; + } + + /** + * Prepares the requests to be sent as a batch request. + * + * @return string + */ + public function prepareRequestsForBatch() + { + $this->validateBatchRequestCount(); + + $params = [ + 'batch' => $this->convertRequestsToJson(), + 'include_headers' => true, + ]; + $this->setParams($params); + } + + /** + * Converts the requests into a JSON(P) string. + * + * @return string + */ + public function convertRequestsToJson() + { + $requests = []; + foreach ($this->requests as $request) { + $requests[] = static::requestEntityToBatchArray($request['request'], $request['name']); + } + + return json_encode($requests); + } + + /** + * Validate the request count before sending them as a batch. + * + * @throws FacebookSDKException + */ + public function validateBatchRequestCount() + { + $batchCount = count($this->requests); + if ($batchCount === 0) { + throw new FacebookSDKException( + 'There are no batch requests to send.' + ); + } elseif ($batchCount > 50) { + // Per: https://developers.facebook.com/docs/graph-api/making-multiple-requests#limits + throw new FacebookSDKException( + 'You cannot send more than 50 batch requests at a time.' + ); + } + } + + /** + * Converts a Request entity into an array that is batch-friendly. + * + * @param FacebookRequest $request The request entity to convert. + * @param string|null $requestName The name of the request. + * + * @return array + */ + public static function requestEntityToBatchArray(FacebookRequest $request, $requestName = null) + { + $compiledHeaders = []; + $headers = $request->getHeaders(); + foreach ($headers as $name => $value) { + $compiledHeaders[] = $name . ': ' . $value; + } + + $batch = [ + 'headers' => $compiledHeaders, + 'method' => $request->getMethod(), + 'relative_url' => $request->getUrl(), + ]; + + $params = $request->getPostParams(); + if ($params) { + $batch['body'] = http_build_query($params, null, '&'); + } + + if (isset($requestName)) { + $batch['name'] = $requestName; + } + + // @TODO Add support for "omit_response_on_success" + // @TODO Add support for "depends_on" + // @TODO Add support for "attached_files" + // @TODO Add support for JSONP with "callback" + + return $batch; + } + +} diff --git a/src/Facebook/Entities/FacebookBatchResponse.php b/src/Facebook/Entities/FacebookBatchResponse.php new file mode 100755 index 000000000..e13d56749 --- /dev/null +++ b/src/Facebook/Entities/FacebookBatchResponse.php @@ -0,0 +1,100 @@ +getApp(); + $httpStatusCode = $response->getHttpStatusCode(); + $headers = $response->getHeaders(); + $body = $response->getBody(); + $accessToken = $response->getAccessToken(); + parent::__construct($app, $httpStatusCode, $headers, $body, $accessToken); + + $responses = $response->getDecodedBody(); + $this->setResponses($responses); + } + + /** + * Returns an array of FacebookResponse entities. + * + * @return array + */ + public function getResponses() + { + return $this->responses; + } + + /** + * 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) + { + $this->responses = []; + foreach ($responses as $graphResponse) { + $httpResponseCode = isset($graphResponse['code']) ? $graphResponse['code'] : null; + $httpResponseHeaders = isset($graphResponse['headers']) ? $graphResponse['headers'] : []; + $httpResponseBody = isset($graphResponse['body']) ? $graphResponse['body'] : null; + // @TODO Figure out an elegant way to get the access token that was used with this response. + $accessToken = null; + $this->responses[] = new FacebookResponse($this->app, $httpResponseCode, $httpResponseHeaders, $httpResponseBody, $accessToken); + } + } + + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->responses); + } + +} diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php new file mode 100755 index 000000000..4006cdc7c --- /dev/null +++ b/src/Facebook/Entities/FacebookRequest.php @@ -0,0 +1,425 @@ +setApp($app); + $this->setAccessToken($accessToken); + $this->setMethod($method); + $this->setEndpoint($endpoint); + $this->setParams($params); + $this->setETag($eTag); + $this->graphVersion = $graphVersion ?: static::getDefaultGraphApiVersion(); + } + + /** + * Set the access token for this request. + * + * @param AccessToken|string + * + * @return FacebookRequest + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken instanceof AccessToken + ? (string) $accessToken + : $accessToken; + return $this; + } + + /** + * Return the access token for this request. + * + * @return string + */ + public function getAccessToken() + { + return (string) $this->accessToken; + } + + /** + * Set the FacebookApp entity used for this request. + * + * @param FacebookApp|null $app + */ + public function setApp(FacebookApp $app = null) + { + $this->app = $app; + } + + /** + * Return the FacebookApp entity used for this request. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Validate that an access token exists for this request. + * + * @throws FacebookSDKException + */ + public function validateAccessToken() + { + $accessToken = $this->getAccessToken(); + if (!$accessToken) { + throw new FacebookSDKException( + 'You must provide an access token.' + ); + } + } + + /** + * Set the HTTP method for this request. + * + * @param string + * + * @return FacebookRequest + */ + public function setMethod($method) + { + $this->method = strtoupper($method); + } + + /** + * Return the HTTP method for this request. + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Validate that the HTTP method is set. + * + * @throws FacebookSDKException + */ + public function validateMethod() + { + if (!$this->method) { + throw new FacebookSDKException( + 'HTTP method not specified.' + ); + } + switch ($this->method) { + case 'GET': + case 'POST': + case 'DELETE': + return; + break; + } + throw new FacebookSDKException( + 'Invalid HTTP method specified.' + ); + } + + /** + * Set the endpoint for this request. + * + * @param string + * + * @return FacebookRequest + */ + public function setEndpoint($endpoint) + { + $this->endpoint = $endpoint; + return $this; + } + + /** + * Return the HTTP method for this request. + * + * @return string + */ + public function getEndpoint() + { + // For batch requests, this will be empty + return $this->endpoint; + } + + /** + * Generate and return the headers for this request. + * + * @return array + */ + public function getHeaders() + { + $headers = static::getDefaultHeaders(); + + if ($this->eTag) { + $headers['If-None-Match'] = $this->eTag; + } + + return $headers; + } + + /** + * Sets the eTag value. + * + * @param string $eTag + */ + public function setETag($eTag) + { + $this->eTag = $eTag; + } + + /** + * Set the params for this request. + * + * @param array $params + * + * @return FacebookRequest + */ + public function setParams(array $params = []) + { + if (is_array($params)) { + $this->params = array_merge($this->params, $params); + } + return $this; + } + + /** + * Generate and return the params for this request. + * + * @return array + */ + public function getParams() + { + $params = $this->params; + + if (!isset($params['access_token']) && $this->getAccessToken()) { + $params['access_token'] = $this->getAccessToken(); + } + if (!isset($params['appsecret_proof']) && isset($params['access_token'])) { + $params['appsecret_proof'] = AppSecretProof::make($params['access_token'], $this->app->getSecret()); + } + + return $params; + } + + /** + * Only return params on POST requests. + * + * @return array + */ + public function getPostParams() + { + if ($this->getMethod() === 'POST') { + return $this->getParams(); + } + + return []; + } + + /** + * The graph version used for this request. + * + * @return string + */ + public function getGraphVersion() + { + return $this->graphVersion; + } + + /** + * Generate and return the URL for this request. + * + * @return string + */ + public function getUrl() + { + $this->validateMethod(); + + $graphVersion = static::forceSlashPrefix($this->graphVersion); + $endpoint = static::forceSlashPrefix($this->getEndpoint()); + + $url = $graphVersion.$endpoint; + + if ($this->getMethod() !== 'POST') { + $params = $this->getParams(); + $url = static::appendParamsToUrl($url, $params); + } + + return $url; + } + + /** + * Gracefully appends params to the URL. + * + * @param string $url + * @param array $params + * + * @return string + */ + public static function appendParamsToUrl($url, $params = []) + { + if (!$params) { + return $url; + } + + if (strpos($url, '?') === false) { + return $url . '?' . http_build_query($params, null, '&'); + } + + list($path, $query_string) = explode('?', $url, 2); + parse_str($query_string, $query_array); + + // Favor params from the original URL over $params + $params = array_merge($params, $query_array); + + return $path . '?' . http_build_query($params, null, '&'); + } + + /** + * Check for a "/" prefix and prepend it if not exists. + * + * @param string|null $string + * + * @return string|null + */ + public static function forceSlashPrefix($string) + { + if (!$string) { + return $string; + } + return strpos($string, '/') === 0 ? $string : '/'.$string; + } + + /** + * Returns the default Graph version. + * + * @param string|null $graphApiVersion The Graph version we want to use. + * + * @return string + */ + public static function getDefaultGraphApiVersion($graphApiVersion = null) + { + return $graphApiVersion ?: static::$defaultGraphApiVersion; + } + + /** + * Sets the default Graph API version. + * + * @param string $graphApiVersion + */ + public static function setDefaultGraphApiVersion($graphApiVersion) + { + static::$defaultGraphApiVersion = $graphApiVersion; + } + + + /** + * Return the default headers that every request should use. + * + * @return array + */ + public static function getDefaultHeaders() + { + return [ + 'User-Agent' => 'fb-php-' . static::VERSION, + 'Accept-Encoding' => '*', + ]; + } + +} diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php new file mode 100755 index 000000000..aef857ebf --- /dev/null +++ b/src/Facebook/Entities/FacebookResponse.php @@ -0,0 +1,291 @@ +app = $app; + $this->httpStatusCode = $httpStatusCode; + $this->headers = $headers; + $this->body = $body; + $this->accessToken = $accessToken; + + $this->decodeBody(); + } + + /** + * Return the FacebookApp entity used for this response. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Return the access token that was used for this response. + * + * @return string + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * Return the HTTP status code for this response. + * + * @return int + */ + public function getHttpStatusCode() + { + return $this->httpStatusCode; + } + + /** + * Return the HTTP headers for this response. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Return the raw body response. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Return the decoded body response. + * + * @return mixed + */ + public function getDecodedBody() + { + return $this->decodedBody; + } + + /** + * @TODO Make this smarter - casting recursively. + * + * Gets the result as a GraphObject. If a type is specified, returns the + * strongly-typed subclass of GraphObject for the data. + * + * @param string $type + * + * @return mixed + */ + public function getGraphObject($type = 'Facebook\GraphNodes\GraphObject') + { + return (new GraphObject($this->decodedBody))->cast($type); + } + + /** + * @TODO This will soon return a GraphList object. + * + * Returns an array of GraphObject returned by the request. If a type is + * specified, returns the strongly-typed subclass of GraphObject for the data. + * + * @param string $type + * + * @return array|null + */ + public function getGraphObjectList($type = 'Facebook\GraphNodes\GraphObject') + { + if (!isset($this->decodedBody['data'])) { + return null; + } + $out = []; + foreach ($this->decodedBody['data'] as $graphObject) { + $out[] = (new GraphObject($graphObject))->cast($type); + } + return $out; + } + + /** + * Get the app secret proof that was used for this response. + * + * @return string + */ + public function getAppSecretProof() + { + return AppSecretProof::make($this->accessToken, $this->app->getSecret()); + } + + /** + * Get the ETag associated with the response. + * + * @return string|null + */ + public function getETag() + { + return isset($this->headers['ETag']) ? $this->headers['ETag'] : null; + } + + /** + * Get the version of Graph that returned this response. + * + * @return string|null + */ + public function getGraphVersion() + { + return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null; + } + + /** + * Returns true if Graph returned an error message. + * + * @return boolean + */ + public function isError() + { + return isset($this->decodedBody['error']); + } + + /** + * Throws the exception. + * + * @throws FacebookSDKException + */ + public function throwException() + { + throw $this->thrownException; + } + + /** + * Instantiates an exception to be thrown later. + */ + public function makeException() + { + $this->thrownException = FacebookResponseException::create( + $this->body, + $this->decodedBody, + $this->httpStatusCode); + } + + /** + * Returns the exception that was thrown for this request. + * + * @return FacebookSDKException|null + */ + public function getThrownException() + { + return $this->thrownException; + } + + /** + * Convert the raw response into an array if possible. + * + * Graph will return 3 types of responses: + * - JSON(P) + * - application/x-www-form-urlencoded key/value pairs + * - The string "true" + * ... And sometimes nothing :/ but that'd be a bug. + */ + public function decodeBody() + { + $this->decodedBody = json_decode($this->body, true); + + if ($this->decodedBody === null) { + $this->decodedBody = []; + parse_str($this->body, $this->decodedBody); + } elseif (is_bool($this->decodedBody)) { + $this->decodedBody = ['was_successful' => $this->decodedBody]; + } + + if ($this->isError()) { + $this->makeException(); + } + } + +} diff --git a/src/Facebook/Entities/SignedRequest.php b/src/Facebook/Entities/SignedRequest.php index 75701eb17..eaa636686 100644 --- a/src/Facebook/Entities/SignedRequest.php +++ b/src/Facebook/Entities/SignedRequest.php @@ -24,7 +24,6 @@ namespace Facebook\Entities; use Facebook\Exceptions\FacebookSDKException; -use Facebook\FacebookSession; /** * Class SignedRequest @@ -267,16 +266,16 @@ public static function validateAlgorithm(array $data) * Hashes the signature used in a signed request. * * @param string $encodedData - * @param string|null $appSecret + * @param string $appSecret * * @return string * * @throws FacebookSDKException */ - public static function hashSignature($encodedData, $appSecret = null) + public static function hashSignature($encodedData, $appSecret) { $hashedSig = hash_hmac( - 'sha256', $encodedData, FacebookSession::_getTargetAppSecret($appSecret), $raw_output = true + 'sha256', $encodedData, $appSecret, $raw_output = true ); if ($hashedSig) { diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php new file mode 100644 index 000000000..f5ccdc793 --- /dev/null +++ b/src/Facebook/FacebookClient.php @@ -0,0 +1,191 @@ +httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler(); + $this->enableBetaMode = $enableBeta; + } + + /** + * Sets the HTTP client handler. + * + * @param FacebookHttpClientInterface $httpClientHandler + */ + public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler) + { + $this->httpClientHandler = $httpClientHandler; + } + + /** + * Returns the HTTP client handler. + * + * @return FacebookHttpClientInterface + */ + public function getHttpClientHandler() + { + return $this->httpClientHandler; + } + + /** + * Detects which HTTP client handler to use. + * + * @return FacebookHttpClientInterface + */ + public function detectHttpClientHandler() + { + return function_exists('curl_init') + ? new FacebookCurlHttpClient() + : new FacebookStreamHttpClient(); + } + + /** + * Toggle beta mode. + * + * @param boolean $betaMode + */ + public function enableBetaMode($betaMode = true) + { + $this->enableBetaMode = $betaMode; + } + + /** + * Returns the base Graph URL. + * + * @return string + */ + public function getBaseGraphUrl() + { + return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL; + } + + /** + * Makes the request to Graph and returns the result. + * + * @param FacebookRequest $request + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function sendRequest(FacebookRequest $request) + { + if (get_class($request) === 'FacebookRequest') { + $request->validateAccessToken(); + } + $url = $this->getBaseGraphUrl() . $request->getUrl(); + $method = $request->getMethod(); + $params = $request->getPostParams(); + $headers = $request->getHeaders(); + + // Should throw `FacebookSDKException` exception on HTTP client error. + // Don't catch to allow it to bubble up. + $response = $this->httpClientHandler->send($url, $method, $params, $headers); + + static::$requestCount++; + + $httpResponseCode = $this->httpClientHandler->getResponseHttpStatusCode(); + $httpResponseHeaders = $this->httpClientHandler->getResponseHeaders(); + + $accessToken = $request->getAccessToken(); + $app = $request->getApp(); + + $returnResponse = new FacebookResponse($app, $httpResponseCode, $httpResponseHeaders, $response, $accessToken); + + if ($returnResponse->isError()) { + throw $returnResponse->getThrownException(); + } + + return $returnResponse; + } + + /** + * Makes a batched request to Graph and returns the result. + * + * @param FacebookBatchRequest $request + * + * @return FacebookBatchResponse + * + * @throws FacebookSDKException + */ + public function sendBatchRequest(FacebookBatchRequest $request) + { + $request->prepareRequestsForBatch(); + $facebookResponse = $this->sendRequest($request); + + return new FacebookBatchResponse($facebookResponse); + } + +} diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php deleted file mode 100644 index dad196765..000000000 --- a/src/Facebook/FacebookRequest.php +++ /dev/null @@ -1,314 +0,0 @@ - - * @author David Poll - */ -class FacebookRequest -{ - - /** - * @const string Version number of the Facebook PHP SDK. - */ - const VERSION = '4.1.0-wip'; - - /** - * @const string Default Graph API version for requests - */ - const GRAPH_API_VERSION = 'v2.0'; - - /** - * @const string Graph API URL - */ - const BASE_GRAPH_URL = 'https://graph.facebook.com'; - - /** - * @var FacebookSession The session used for this request - */ - private $session; - - /** - * @var string The HTTP method for the request - */ - private $method; - - /** - * @var string The path for the request - */ - private $path; - - /** - * @var array The parameters for the request - */ - private $params; - - /** - * @var string The Graph API version for the request - */ - private $version; - - /** - * @var string ETag sent with the request - */ - private $etag; - - /** - * @var FacebookHttpClientInterface HTTP client handler - */ - private static $httpClientHandler; - - /** - * @var int The number of calls that have been made to Graph. - */ - public static $requestCount = 0; - - /** - * getSession - Returns the associated FacebookSession. - * - * @return FacebookSession - */ - public function getSession() - { - return $this->session; - } - - /** - * getPath - Returns the associated path. - * - * @return string - */ - public function getPath() - { - return $this->path; - } - - /** - * getParameters - Returns the associated parameters. - * - * @return array - */ - public function getParameters() - { - return $this->params; - } - - /** - * getMethod - Returns the associated method. - * - * @return string - */ - public function getMethod() - { - return $this->method; - } - - /** - * getETag - Returns the ETag sent with the request. - * - * @return string - */ - public function getETag() - { - return $this->etag; - } - - /** - * setHttpClientHandler - Returns an instance of the HTTP client - * handler - * - * @param FacebookHttpClientInterface - */ - public static function setHttpClientHandler(FacebookHttpClientInterface $handler) - { - static::$httpClientHandler = $handler; - } - - /** - * getHttpClientHandler - Returns an instance of the HTTP client - * data handler - * - * @return FacebookHttpClientInterface - */ - public static function getHttpClientHandler() - { - if (static::$httpClientHandler) { - return static::$httpClientHandler; - } - return function_exists('curl_init') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient(); - } - - /** - * FacebookRequest - Returns a new request using the given session. optional - * parameters hash will be sent with the request. This object is - * immutable. - * - * @param FacebookSession $session - * @param string $method - * @param string $path - * @param array|null $parameters - * @param string|null $version - * @param string|null $etag - */ - public function __construct( - FacebookSession $session, $method, $path, $parameters = null, $version = null, $etag = null - ) - { - $this->session = $session; - $this->method = $method; - $this->path = $path; - if ($version) { - $this->version = $version; - } else { - $this->version = static::GRAPH_API_VERSION; - } - $this->etag = $etag; - - $params = ($parameters ?: array()); - if ($session - && !isset($params["access_token"])) { - $params["access_token"] = $session->getToken(); - } - if (FacebookSession::useAppSecretProof() - && !isset($params["appsecret_proof"])) { - $params["appsecret_proof"] = $this->getAppSecretProof( - $params["access_token"] - ); - } - $this->params = $params; - } - - /** - * Returns the base Graph URL. - * - * @return string - */ - protected function getRequestURL() - { - return static::BASE_GRAPH_URL . '/' . $this->version . $this->path; - } - - /** - * execute - Makes the request to Facebook and returns the result. - * - * @return FacebookResponse - * - * @throws FacebookSDKException - * @throws FacebookResponseException - */ - public function execute() - { - $url = $this->getRequestURL(); - $params = $this->getParameters(); - - if ($this->method === "GET") { - $url = self::appendParamsToUrl($url, $params); - $params = array(); - } - - $connection = self::getHttpClientHandler(); - $connection->addRequestHeader('User-Agent', 'fb-php-' . self::VERSION); - $connection->addRequestHeader('Accept-Encoding', '*'); // Support all available encodings. - - // ETag - if (isset($this->etag)) { - $connection->addRequestHeader('If-None-Match', $this->etag); - } - - // Should throw `FacebookSDKException` exception on HTTP client error. - // Don't catch to allow it to bubble up. - $result = $connection->send($url, $this->method, $params); - - static::$requestCount++; - - $etagHit = 304 == $connection->getResponseHttpStatusCode(); - - $headers = $connection->getResponseHeaders(); - $etagReceived = isset($headers['ETag']) ? $headers['ETag'] : null; - - $decodedResult = json_decode($result); - if ($decodedResult === null) { - $out = array(); - parse_str($result, $out); - return new FacebookResponse($this, $out, $result, $etagHit, $etagReceived); - } - if (isset($decodedResult->error)) { - throw FacebookResponseException::create( - $result, - $decodedResult->error, - $connection->getResponseHttpStatusCode() - ); - } - - return new FacebookResponse($this, $decodedResult, $result, $etagHit, $etagReceived); - } - - /** - * Generate and return the appsecret_proof value for an access_token - * - * @param string $token - * - * @return string - */ - public function getAppSecretProof($token) - { - return hash_hmac('sha256', $token, FacebookSession::_getTargetAppSecret()); - } - - /** - * appendParamsToUrl - Gracefully appends params to the URL. - * - * @param string $url - * @param array $params - * - * @return string - */ - public static function appendParamsToUrl($url, $params = array()) - { - if (!$params) { - return $url; - } - - if (strpos($url, '?') === false) { - return $url . '?' . http_build_query($params, null, '&'); - } - - list($path, $query_string) = explode('?', $url, 2); - parse_str($query_string, $query_array); - - // Favor params from the original URL over $params - $params = array_merge($params, $query_array); - - return $path . '?' . http_build_query($params, null, '&'); - } - -} diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php deleted file mode 100644 index 2a8e38c35..000000000 --- a/src/Facebook/FacebookResponse.php +++ /dev/null @@ -1,204 +0,0 @@ - - * @author David Poll - */ -class FacebookResponse -{ - - /** - * @var FacebookRequest The request which produced this response - */ - private $request; - - /** - * @var array The decoded response from the Graph API - */ - private $responseData; - - /** - * @var string The raw response from the Graph API - */ - private $rawResponse; - - /** - * @var bool Indicates whether sent ETag matched the one on the FB side - */ - private $etagHit; - - /** - * @var string ETag received with the response. `null` in case of ETag hit. - */ - private $etag; - - /** - * Creates a FacebookResponse object for a given request and response. - * - * @param FacebookRequest $request - * @param array $responseData JSON Decoded response data - * @param string $rawResponse Raw string response - * @param bool $etagHit Indicates whether sent ETag matched the one on the FB side - * @param string|null $etag ETag received with the response. `null` in case of ETag hit. - */ - public function __construct($request, $responseData, $rawResponse, $etagHit = false, $etag = null) - { - $this->request = $request; - $this->responseData = $responseData; - $this->rawResponse = $rawResponse; - $this->etagHit = $etagHit; - $this->etag = $etag; - } - - /** - * Returns the request which produced this response. - * - * @return FacebookRequest - */ - public function getRequest() - { - return $this->request; - } - - /** - * Returns the decoded response data. - * - * @return array - */ - public function getResponse() - { - return $this->responseData; - } - - /** - * Returns the raw response - * - * @return string - */ - public function getRawResponse() - { - return $this->rawResponse; - } - - /** - * Returns true if ETag matched the one sent with a request - * - * @return bool - */ - public function isETagHit() - { - return $this->etagHit; - } - - /** - * Returns the ETag - * - * @return string - */ - public function getETag() - { - return $this->etag; - } - - /** - * Gets the result as a GraphObject. If a type is specified, returns the - * strongly-typed subclass of GraphObject for the data. - * - * @param string $type - * - * @return mixed - */ - public function getGraphObject($type = 'Facebook\GraphNodes\GraphObject') { - return (new GraphObject($this->responseData))->cast($type); - } - - /** - * Returns an array of GraphObject returned by the request. If a type is - * specified, returns the strongly-typed subclass of GraphObject for the data. - * - * @param string $type - * - * @return mixed - */ - public function getGraphObjectList($type = 'Facebook\GraphNodes\GraphObject') { - $out = array(); - $data = $this->responseData->data; - for ($i = 0; $i < count($data); $i++) { - $out[] = (new GraphObject($data[$i]))->cast($type); - } - return $out; - } - - /** - * If this response has paginated data, returns the FacebookRequest for the - * next page, or null. - * - * @return FacebookRequest|null - */ - public function getRequestForNextPage() - { - return $this->handlePagination('next'); - } - - /** - * If this response has paginated data, returns the FacebookRequest for the - * previous page, or null. - * - * @return FacebookRequest|null - */ - public function getRequestForPreviousPage() - { - return $this->handlePagination('previous'); - } - - /** - * Returns the FacebookRequest for the previous or next page, or null. - * - * @param string $direction - * - * @return FacebookRequest|null - */ - private function handlePagination($direction) { - if (isset($this->responseData->paging->$direction)) { - $url = parse_url($this->responseData->paging->$direction); - parse_str($url['query'], $params); - - return new FacebookRequest( - $this->request->getSession(), - $this->request->getMethod(), - $this->request->getPath(), - $params - ); - } else { - return null; - } - } - -} diff --git a/src/Facebook/FacebookSession.php b/src/Facebook/FacebookSession.php deleted file mode 100644 index ba5337401..000000000 --- a/src/Facebook/FacebookSession.php +++ /dev/null @@ -1,369 +0,0 @@ - - * @author David Poll - */ -class FacebookSession -{ - - /** - * @var string - */ - private static $defaultAppId; - - /** - * @var string - */ - private static $defaultAppSecret; - - /** - * @var AccessToken The AccessToken entity for this connection. - */ - private $accessToken; - - /** - * @var SignedRequest - */ - private $signedRequest; - - /** - * @var bool - */ - protected static $useAppSecretProof = true; - - /** - * When creating a Session from an access_token, use: - * var $session = new FacebookSession($accessToken); - * This will validate the token and provide a Session object ready for use. - * It will throw a SessionException in case of error. - * - * @param AccessToken|string $accessToken - * @param SignedRequest $signedRequest The SignedRequest entity - */ - public function __construct($accessToken, SignedRequest $signedRequest = null) - { - $this->accessToken = $accessToken instanceof AccessToken ? $accessToken : new AccessToken($accessToken); - $this->signedRequest = $signedRequest; - } - - /** - * Returns the access token. - * - * @return string - */ - public function getToken() - { - return (string) $this->accessToken; - } - - /** - * Returns the access token entity. - * - * @return AccessToken - */ - public function getAccessToken() - { - return $this->accessToken; - } - - /** - * Returns the SignedRequest entity. - * - * @return SignedRequest - */ - public function getSignedRequest() - { - return $this->signedRequest; - } - - /** - * Returns the signed request payload. - * - * @return null|array - */ - public function getSignedRequestData() - { - return $this->signedRequest ? $this->signedRequest->getPayload() : null; - } - - /** - * Returns a property from the signed request data if available. - * - * @param string $key - * - * @return null|mixed - */ - public function getSignedRequestProperty($key) - { - return $this->signedRequest ? $this->signedRequest->get($key) : null; - } - - /** - * Returns user_id from signed request data if available. - * - * @return null|string - */ - public function getUserId() - { - return $this->signedRequest ? $this->signedRequest->getUserId() : null; - } - - // @TODO Remove getSessionInfo() in 4.1: can be accessed from AccessToken directly - /** - * getSessionInfo - Makes a request to /debug_token with the appropriate - * arguments to get debug information about the sessions token. - * - * @param string|null $appId - * @param string|null $appSecret - * - * @return GraphSessionInfo - */ - public function getSessionInfo($appId = null, $appSecret = null) - { - return $this->accessToken->getInfo($appId, $appSecret); - } - - // @TODO Remove getLongLivedSession() in 4.1: can be accessed from AccessToken directly - /** - * getLongLivedSession - Returns a new Facebook session resulting from - * extending a short-lived access token. If this session is not - * short-lived, returns $this. - * - * @param string|null $appId - * @param string|null $appSecret - * - * @return FacebookSession - */ - public function getLongLivedSession($appId = null, $appSecret = null) - { - $longLivedAccessToken = $this->accessToken->extend($appId, $appSecret); - return new static($longLivedAccessToken); - } - - // @TODO Remove getExchangeToken() in 4.1: can be accessed from AccessToken directly - /** - * getExchangeToken - Returns an exchange token string which can be sent - * back to clients and exchanged for a device-linked access token. - * - * @param string|null $appId - * @param string|null $appSecret - * - * @return string - */ - public function getExchangeToken($appId = null, $appSecret = null) - { - return AccessToken::getCodeFromAccessToken($this->accessToken, $appId, $appSecret); - } - - // @TODO Remove validate() in 4.1: can be accessed from AccessToken directly - /** - * validate - Ensures the current session is valid, throwing an exception if - * not. Fetches token info from Facebook. - * - * @param string|null $appId Application ID to use - * @param string|null $appSecret App secret value to use - * @param string|null $machineId - * - * @return boolean - * - * @throws FacebookSDKException - */ - public function validate($appId = null, $appSecret = null, $machineId = null) - { - if ($this->accessToken->isValid($appId, $appSecret, $machineId)) { - return true; - } - - // @TODO For v4.1 this should not throw an exception, but just return false. - throw new FacebookSDKException( - 'Session has expired, or is not valid for this app.', 601 - ); - } - - // @TODO Remove validateSessionInfo() in 4.1: can be accessed from AccessToken directly - /** - * validateTokenInfo - Ensures the provided GraphSessionInfo object is valid, - * throwing an exception if not. Ensures the appId matches, - * that the token is valid and has not expired. - * - * @param GraphSessionInfo $tokenInfo - * @param string|null $appId Application ID to use - * @param string|null $machineId - * - * @return boolean - * - * @throws FacebookSDKException - */ - public static function validateSessionInfo(GraphSessionInfo $tokenInfo, - $appId = null, - $machineId = null) - { - if (AccessToken::validateAccessToken($tokenInfo, $appId, $machineId)) { - return true; - } - - // @TODO For v4.1 this should not throw an exception, but just return false. - throw new FacebookSDKException( - 'Session has expired, or is not valid for this app.', 601 - ); - } - - /** - * newSessionFromSignedRequest - Returns a FacebookSession for a - * given signed request. - * - * @param SignedRequest $signedRequest - * - * @return FacebookSession - */ - public static function newSessionFromSignedRequest(SignedRequest $signedRequest) - { - if ($signedRequest->get('code') - && !$signedRequest->get('oauth_token')) { - return self::newSessionAfterValidation($signedRequest); - } - $accessToken = $signedRequest->get('oauth_token'); - $expiresAt = $signedRequest->get('expires', 0); - $accessToken = new AccessToken($accessToken, $expiresAt); - return new static($accessToken, $signedRequest); - } - - /** - * newSessionAfterValidation - Returns a FacebookSession for a - * validated & parsed signed request. - * - * @param SignedRequest $signedRequest - * - * @return FacebookSession - */ - protected static function newSessionAfterValidation(SignedRequest $signedRequest) - { - $code = $signedRequest->get('code'); - $accessToken = AccessToken::getAccessTokenFromCode($code); - return new static($accessToken, $signedRequest); - } - - /** - * newAppSession - Returns a FacebookSession configured with a token for the - * application which can be used for publishing and requesting app-level - * information. - * - * @param string|null $appId Application ID to use - * @param string|null $appSecret App secret value to use - * - * @return FacebookSession - */ - public static function newAppSession($appId = null, $appSecret = null) - { - $targetAppId = static::_getTargetAppId($appId); - $targetAppSecret = static::_getTargetAppSecret($appSecret); - return new FacebookSession( - $targetAppId . '|' . $targetAppSecret - ); - } - - /** - * setDefaultApplication - Will set the static default appId and appSecret - * to be used for API requests. - * - * @param string $appId Application ID to use by default - * @param string $appSecret App secret value to use by default - */ - public static function setDefaultApplication($appId, $appSecret) - { - self::$defaultAppId = $appId; - self::$defaultAppSecret = $appSecret; - } - - /** - * _getTargetAppId - Will return either the provided app Id or the default, - * throwing if neither are populated. - * - * @param string $appId - * - * @return string - * - * @throws FacebookSDKException - */ - public static function _getTargetAppId($appId = null) { - $target = ($appId ?: self::$defaultAppId); - if (!$target) { - throw new FacebookSDKException( - 'You must provide or set a default application id.', 700 - ); - } - return $target; - } - - /** - * _getTargetAppSecret - Will return either the provided app secret or the - * default, throwing if neither are populated. - * - * @param string $appSecret - * - * @return string - * - * @throws FacebookSDKException - */ - public static function _getTargetAppSecret($appSecret = null) { - $target = ($appSecret ?: self::$defaultAppSecret); - if (!$target) { - throw new FacebookSDKException( - 'You must provide or set a default application secret.', 701 - ); - } - return $target; - } - - /** - * Enable or disable sending the appsecret_proof with requests. - * - * @param bool $on - */ - public static function enableAppSecretProof($on = true) - { - static::$useAppSecretProof = ($on ? true : false); - } - - /** - * Get whether or not appsecret_proof should be sent with requests. - * - * @return bool - */ - public static function useAppSecretProof() - { - return static::$useAppSecretProof; - } - -} diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index d4a69dc0f..e9346df3c 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -46,7 +46,7 @@ public function getId() * * @return boolean|null */ - public function canUpload() + public function getCanUpload() { return $this->getProperty('can_upload'); } @@ -116,7 +116,7 @@ public function getDescription() */ public function getFrom() { - return $this->getProperty('from', GraphUser::className()); + return $this->getProperty('from', null, GraphUser::className()); } /** diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index d3d99f1d7..8264d21f4 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -23,6 +23,8 @@ */ namespace Facebook\GraphNodes; +use Facebook\Exceptions\FacebookSDKException; + /** * Class GraphObject * @package Facebook @@ -35,18 +37,15 @@ class GraphObject /** * @var array - Holds the raw associative data for this object */ - protected $backingData; + protected $backingData = []; /** * Creates a GraphObject using the data provided. * * @param array $raw */ - public function __construct($raw) + public function __construct(array $raw = []) { - if ($raw instanceof \stdClass) { - $raw = get_object_vars($raw); - } $this->backingData = $raw; if (isset($this->backingData['data']) && count($this->backingData) === 1) { @@ -96,12 +95,13 @@ public function asArray() * getProperty - Gets the value of the named property for this graph object, * cast to the appropriate subclass type if provided. * - * @param string $name The property to retrieve - * @param string $type The subclass of GraphObject, optionally + * @param string $name The property to retrieve. + * @param mixed|null $default The default return value. + * @param string $type The subclass of GraphObject, optionally. * * @return mixed */ - public function getProperty($name, $type = 'Facebook\GraphNodes\GraphObject') + public function getProperty($name, $default = null, $type = 'Facebook\GraphNodes\GraphObject') { if (isset($this->backingData[$name])) { $value = $this->backingData[$name]; @@ -110,9 +110,8 @@ public function getProperty($name, $type = 'Facebook\GraphNodes\GraphObject') } else { return (new GraphObject($value))->cast($type); } - } else { - return null; } + return $default; } /** diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index b96de8e92..94c690520 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -72,7 +72,7 @@ public function getExpiresAt() * * @return boolean */ - public function isValid() + public function getIsValid() { return $this->getProperty('is_valid'); } @@ -107,7 +107,7 @@ public function getScopes() * * @return string|null */ - public function getId() + public function getUserId() { return $this->getProperty('user_id'); } diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 3884e385a..59f6f05ba 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -114,7 +114,7 @@ public function getBirthday() */ public function getLocation() { - return $this->getProperty('location', GraphLocation::className()); + return $this->getProperty('location', null, GraphLocation::className()); } } \ No newline at end of file diff --git a/src/Facebook/GraphNodes/GraphUserPage.php b/src/Facebook/GraphNodes/GraphUserPage.php index b2e16c872..08f11a477 100644 --- a/src/Facebook/GraphNodes/GraphUserPage.php +++ b/src/Facebook/GraphNodes/GraphUserPage.php @@ -76,7 +76,7 @@ public function getAccessToken() * * @return array|null */ - public function getPermissions() + public function getPerms() { return $this->getProperty('perms'); } diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index c4ae53be9..5eac7e35d 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -23,6 +23,8 @@ */ namespace Facebook\Helpers; +use Facebook\Entities\FacebookApp; + /** * Class FacebookPageTabHelper * @package Facebook @@ -39,12 +41,11 @@ class FacebookPageTabHelper extends FacebookCanvasLoginHelper /** * Initialize the helper and process available signed request data. * - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. */ - public function __construct($appId = null, $appSecret = null) + public function __construct(FacebookApp $app) { - parent::__construct($appId, $appSecret); + parent::__construct($app); if (!$this->signedRequest) { return; diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 63667dae0..d9d401e85 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -23,10 +23,11 @@ */ namespace Facebook\Helpers; -use Facebook\FacebookSession; -use Facebook\FacebookRequest; use Facebook\Entities\AccessToken; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Exceptions\FacebookSDKException; +use Facebook\FacebookClient; /** * Class FacebookRedirectLoginHelper @@ -38,35 +39,28 @@ class FacebookRedirectLoginHelper { /** - * @var string The application id + * @var FacebookApp The FacebookApp entity. */ - protected $appId; + protected $app; /** - * @var string The application secret - */ - protected $appSecret; - - /** - * @var string Prefix to use for session variables + * @var string Prefix to use for session variables. */ protected $sessionPrefix = 'FBRLH_'; /** - * @var boolean Toggle for PHP session status check + * @var boolean Toggle for PHP session status check. */ protected $checkForSessionStatus = true; /** * Constructs a RedirectLoginHelper for a given appId. * - * @param string $appId The application id - * @param string $appSecret The application secret + * @param FacebookApp $app The FacebookApp entity. */ - public function __construct($appId = null, $appSecret = null) + public function __construct(FacebookApp $app) { - $this->appId = FacebookSession::_getTargetAppId($appId); - $this->appSecret = FacebookSession::_getTargetAppSecret($appSecret); + $this->app = $app; } /** @@ -78,66 +72,78 @@ public function __construct($appId = null, $appSecret = null) * will not 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 boolean $rerequest Whether this is the re-request to the previously - * declined permissions - * @param string $version Optional Graph API version if not default (v2.0) + * after login. + * @param array $scope List of permissions to request during login. + * @param boolean $rerequest Toggle for this authentication to be a rerequest. + * @param string $version Optional Graph API version if not default (v2.0). + * @param string $separator The separator to use in http_build_query(). * * @return string */ - public function getLoginUrl($redirectUrl, $scope = array(), $rerequest = false, $version = null) + public function getLoginUrl($redirectUrl, + array $scope = [], + $rerequest = false, + $version = null, + $separator = '&') { - $version = ($version ?: FacebookRequest::GRAPH_API_VERSION); + $version = FacebookRequest::getDefaultGraphApiVersion($version); $state = $this->generateState(); $this->storeState($state); - $params = array( - 'client_id' => $this->appId, + $params = [ + 'client_id' => $this->app->getId(), 'redirect_uri' => $redirectUrl, 'state' => $state, 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, 'scope' => implode(',', $scope) - ); - - if ($rerequest) + ]; + + if ($rerequest) { $params['auth_type'] = 'rerequest'; + } return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . - http_build_query($params, null, '&'); + http_build_query($params, null, $separator); } /** * Returns the URL to send the user in order to log out of Facebook. * - * @param FacebookSession $session The session that will be logged out + * @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 + * a successful logout. + * @param string $separator The separator to use in http_build_query(). * * @return string */ - public function getLogoutUrl(FacebookSession $session, $next) + public function getLogoutUrl($accessToken, $next, $separator = '&') { - $params = array( + $params = [ 'next' => $next, - 'access_token' => $session->getToken() - ); - return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, '&'); + 'access_token' => (string) $accessToken, + ]; + return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, $separator); } /** - * Handles a response from Facebook, including a CSRF check, and returns a - * FacebookSession. + * Takes a valid code from a login redirect, and returns an AccessToken entity. + * + * @param FacebookClient $client The Facebook client. + * @param string $redirectUrl The redirect URL. * - * @return FacebookSession|null + * @return AccessToken|null */ - public function getSessionFromRedirect() + public function getAccessTokenFromRedirect(FacebookClient $client, $redirectUrl = null) { if ($this->isValidRedirect()) { - $params = array( - 'redirect_uri' => $this->getFilteredUri($this->getCurrentUri()), - 'code' => $this->getCode() - ); - return new FacebookSession(AccessToken::requestAccessToken($params, $this->appId, $this->appSecret)); + $code = $this->getCode(); + $redirectUrl = $redirectUrl ?: $this->getCurrentUri(); + $redirectUrl = $this->getFilteredUri($redirectUrl); + + try { + return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); + } catch (FacebookSDKException $e) { + return null; + } } return null; } @@ -216,6 +222,13 @@ protected function loadState() return null; } + /** + * Return a URL with the Facebook-appended params removed. + * + * @param string $uri The URL to filter. + * + * @return string + */ protected function getFilteredUri($uri) { $parts = parse_url($uri); @@ -255,7 +268,7 @@ protected function getFilteredUri($uri) } /** - * Returns the current URI + * Returns the current URI. * * @return string */ @@ -265,9 +278,9 @@ protected function getCurrentUri() } /** - * Returns the HTTP Protocol + * Returns the HTTP Protocol. * - * @return string The HTTP Protocol + * @return string */ protected function getHttpScheme() { $scheme = 'http'; @@ -281,15 +294,15 @@ protected function getHttpScheme() { } /** - * Generate a cryptographically secure pseudrandom number + * Generate a cryptographically secure pseudrandom number. * - * @param integer $bytes - number of bytes to return + * @param int $bytes Number of bytes to return. * * @return string * * @throws FacebookSDKException * - * @todo Support Windows platforms + * @TODO Add support for Windows platforms. */ private function random($bytes) { @@ -332,7 +345,7 @@ private function random($bytes) } /** - * Disables the session_status() check when using $_SESSION + * Disables the session_status() check when using $_SESSION. */ public function disableSessionStatusCheck() { diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index 94c967cf8..df3b5a6e8 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -23,8 +23,10 @@ */ namespace Facebook\Helpers; -use Facebook\FacebookSession; +use Facebook\Entities\FacebookApp; use Facebook\Entities\SignedRequest; +use Facebook\Entities\AccessToken; +use Facebook\FacebookClient; /** * Class FacebookSignedRequestFromInputHelper @@ -34,35 +36,28 @@ abstract class FacebookSignedRequestFromInputHelper { /** - * @var \Facebook\Entities\SignedRequest|null + * @var SignedRequest|null The SignedRequest entity. */ protected $signedRequest; /** - * @var string the app id + * @var FacebookApp The FacebookApp entity. */ - protected $appId; - - /** - * @var string the app secret - */ - protected $appSecret; + protected $app; /** * @var string|null Random string to prevent CSRF. */ - public $state = null; + public $state; /** * Initialize the helper and process available signed request data. * - * @param string|null $appId - * @param string|null $appSecret + * @param FacebookApp $app The FacebookApp entity. */ - public function __construct($appId = null, $appSecret = null) + public function __construct(FacebookApp $app) { - $this->appId = FacebookSession::_getTargetAppId($appId); - $this->appSecret = FacebookSession::_getTargetAppSecret($appSecret); + $this->app = $app; $this->instantiateSignedRequest(); } @@ -80,18 +75,28 @@ public function instantiateSignedRequest($rawSignedRequest = null) return; } - $this->signedRequest = new SignedRequest($rawSignedRequest, $this->state, $this->appSecret); + $this->signedRequest = new SignedRequest($rawSignedRequest, $this->state, $this->app->getSecret()); } /** - * Instantiates a FacebookSession from the signed request from input. + * Returns an AccessToken entity from the signed request. * - * @return FacebookSession|null + * @param FacebookClient $client The Facebook client. + * + * @return AccessToken|null */ - public function getSession() + public function getAccessToken(FacebookClient $client) { if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { - return FacebookSession::newSessionFromSignedRequest($this->signedRequest); + $code = $this->signedRequest->get('code'); + $accessToken = $this->signedRequest->get('oauth_token'); + + if ($code && !$accessToken) { + return AccessToken::getAccessTokenFromCode($code, $this->app, $client); + } + + $expiresAt = $this->signedRequest->get('expires', 0); + return new AccessToken($accessToken, $expiresAt); } return null; } @@ -99,7 +104,7 @@ public function getSession() /** * Returns the SignedRequest entity. * - * @return \Facebook\Entities\SignedRequest|null + * @return SignedRequest|null */ public function getSignedRequest() { @@ -158,8 +163,8 @@ public function getRawSignedRequestFromPost() */ public function getRawSignedRequestFromCookie() { - if (isset($_COOKIE['fbsr_' . $this->appId])) { - return $_COOKIE['fbsr_' . $this->appId]; + if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { + return $_COOKIE['fbsr_' . $this->app->getId()]; } return null; } diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 85ecd53a6..ffd215985 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -32,15 +32,10 @@ class FacebookCurlHttpClient implements FacebookHttpClientInterface { - /** - * @var array The headers to be sent with the request - */ - protected $requestHeaders = array(); - /** * @var array The headers received from the response */ - protected $responseHeaders = array(); + protected $responseHeaders = []; /** * @var int The HTTP status code returned from the server @@ -85,17 +80,6 @@ public function __construct(FacebookCurl $facebookCurl = null) self::$facebookCurl = $facebookCurl ?: new FacebookCurl(); } - /** - * The headers we want to send with the request - * - * @param string $key - * @param string $value - */ - public function addRequestHeader($key, $value) - { - $this->requestHeaders[$key] = $value; - } - /** * The headers returned in the response * @@ -117,19 +101,20 @@ public function getResponseHttpStatusCode() } /** - * Sends a request to the server + * 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 array $parameters The key value pairs to be sent in the body + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param array $parameters The key value pairs to be sent in the body. + * @param array $headers The request headers. * - * @return string Raw response from the server + * @return string Raw response from the server. * - * @throws FacebookSDKException + * @throws \Facebook\Exceptions\FacebookSDKException */ - public function send($url, $method = 'GET', $parameters = array()) + public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { - $this->openConnection($url, $method, $parameters); + $this->openConnection($url, $method, $parameters, $headers); $this->tryToSendRequest(); // Need to verify the peer @@ -153,13 +138,14 @@ public function send($url, $method = 'GET', $parameters = array()) } /** - * Opens a new curl connection + * Opens a new curl connection. * - * @param string $url The endpoint to send the request to - * @param string $method The request method - * @param array $parameters The key value pairs to be sent in the body + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param array $parameters The key value pairs to be sent in the body. + * @param array $headers The request headers. */ - public function openConnection($url, $method = 'GET', $parameters = array()) + public function openConnection($url, $method = 'GET', array $parameters = [], array $headers = []) { $options = array( CURLOPT_URL => $url, @@ -176,8 +162,8 @@ public function openConnection($url, $method = 'GET', $parameters = array()) $options[CURLOPT_CUSTOMREQUEST] = $method; } - if (!empty($this->requestHeaders)) { - $options[CURLOPT_HTTPHEADER] = $this->compileRequestHeaders(); + if (count($headers) > 0) { + $options[CURLOPT_HTTPHEADER] = $this->compileRequestHeaders($headers); } self::$facebookCurl->init(); @@ -221,15 +207,17 @@ public function sendRequest() } /** - * Compiles the request headers into a curl-friendly format + * Compiles the request headers into a curl-friendly format. + * + * @param array $headers The request headers. * * @return array */ - public function compileRequestHeaders() + public function compileRequestHeaders(array $headers) { - $return = array(); + $return = []; - foreach ($this->requestHeaders as $key => $value) { + foreach ($headers as $key => $value) { $return[] = $key . ': ' . $value; } diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index 03a91c85a..52e6b863b 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -29,30 +29,26 @@ use GuzzleHttp\Exception\AdapterException; use GuzzleHttp\Exception\RequestException; -class FacebookGuzzleHttpClient implements FacebookHttpClientInterface { +class FacebookGuzzleHttpClient implements FacebookHttpClientInterface +{ /** - * @var array The headers to be sent with the request + * @var array The headers received from the response. */ - protected $requestHeaders = array(); + protected $responseHeaders = []; /** - * @var array The headers received from the response - */ - protected $responseHeaders = array(); - - /** - * @var int The HTTP status code returned from the server + * @var int The HTTP status code returned from the server. */ protected $responseHttpStatusCode = 0; /** - * @var \GuzzleHttp\Client The Guzzle client + * @var \GuzzleHttp\Client The Guzzle client. */ protected static $guzzleClient; /** - * @param \GuzzleHttp\Client|null The Guzzle client + * @param \GuzzleHttp\Client|null The Guzzle client. */ public function __construct(Client $guzzleClient = null) { @@ -60,18 +56,7 @@ public function __construct(Client $guzzleClient = null) } /** - * The headers we want to send with the request - * - * @param string $key - * @param string $value - */ - public function addRequestHeader($key, $value) - { - $this->requestHeaders[$key] = $value; - } - - /** - * The headers returned in the response + * The headers returned in the response. * * @return array */ @@ -81,7 +66,7 @@ public function getResponseHeaders() } /** - * The HTTP status response code + * The HTTP status response code. * * @return int */ @@ -91,17 +76,18 @@ public function getResponseHttpStatusCode() } /** - * Sends a request to the server + * 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 array $parameters The key value pairs to be sent in the body + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param array $parameters The key value pairs to be sent in the body. + * @param array $headers The request headers. * - * @return string Raw response from the server + * @return string Raw response from the server. * - * @throws FacebookSDKException + * @throws \Facebook\Exceptions\FacebookSDKException */ - public function send($url, $method = 'GET', $parameters = array()) + public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { $options = array(); if ($parameters) { @@ -110,7 +96,7 @@ public function send($url, $method = 'GET', $parameters = array()) $request = self::$guzzleClient->createRequest($method, $url, $options); - foreach($this->requestHeaders as $k => $v) { + foreach($headers as $k => $v) { $request->setHeader($k, $v); } diff --git a/src/Facebook/HttpClients/FacebookHttpClientInterface.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php index a0b475a34..f95b66603 100644 --- a/src/Facebook/HttpClients/FacebookHttpClientInterface.php +++ b/src/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -31,38 +31,31 @@ interface FacebookHttpClientInterface { /** - * The headers we want to send with the request - * - * @param string $key - * @param string $value - */ - public function addRequestHeader($key, $value); - - /** - * The headers returned in the response + * The headers returned in the response. * * @return array */ public function getResponseHeaders(); /** - * The HTTP status response code + * The HTTP status response code. * * @return int */ public function getResponseHttpStatusCode(); /** - * Sends a request to the server + * 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 array $parameters The key value pairs to be sent in the body + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param array $parameters The key value pairs to be sent in the body. + * @param array $headers The request headers. * - * @return string Raw response from the server + * @return string Raw response from the server. * * @throws \Facebook\Exceptions\FacebookSDKException */ - public function send($url, $method = 'GET', $parameters = array()); + public function send($url, $method = 'GET', array $parameters = [], array $headers = []); } diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index ada2da2c8..a45fb4c6c 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -25,30 +25,26 @@ use Facebook\Exceptions\FacebookSDKException; -class FacebookStreamHttpClient implements FacebookHttpClientInterface { +class FacebookStreamHttpClient implements FacebookHttpClientInterface +{ /** - * @var array The headers to be sent with the request + * @var array The headers received from the response. */ - protected $requestHeaders = array(); + protected $responseHeaders = []; /** - * @var array The headers received from the response - */ - protected $responseHeaders = array(); - - /** - * @var int The HTTP status code returned from the server + * @var int The HTTP status code returned from the server. */ protected $responseHttpStatusCode = 0; /** - * @var FacebookStream Procedural stream wrapper as object + * @var FacebookStream Procedural stream wrapper as object. */ protected static $facebookStream; /** - * @param FacebookStream|null Procedural stream wrapper as object + * @param FacebookStream|null Procedural stream wrapper as object. */ public function __construct(FacebookStream $facebookStream = null) { @@ -56,18 +52,7 @@ public function __construct(FacebookStream $facebookStream = null) } /** - * The headers we want to send with the request - * - * @param string $key - * @param string $value - */ - public function addRequestHeader($key, $value) - { - $this->requestHeaders[$key] = $value; - } - - /** - * The headers returned in the response + * The headers returned in the response. * * @return array */ @@ -77,7 +62,7 @@ public function getResponseHeaders() } /** - * The HTTP status response code + * The HTTP status response code. * * @return int */ @@ -87,17 +72,18 @@ public function getResponseHttpStatusCode() } /** - * Sends a request to the server + * 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 array $parameters The key value pairs to be sent in the body + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param array $parameters The key value pairs to be sent in the body. + * @param array $headers The request headers. * - * @return string Raw response from the server + * @return string Raw response from the server. * - * @throws FacebookSDKException + * @throws \Facebook\Exceptions\FacebookSDKException */ - public function send($url, $method = 'GET', $parameters = array()) + public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { $options = array( 'http' => array( @@ -114,10 +100,10 @@ public function send($url, $method = 'GET', $parameters = array()) if ($parameters) { $options['http']['content'] = http_build_query($parameters, null, '&'); - $this->addRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + $headers['Content-type'] = 'application/x-www-form-urlencoded'; } - $options['http']['header'] = $this->compileHeader(); + $options['http']['header'] = $this->compileHeader($headers); self::$facebookStream->streamContextCreate($options); $rawResponse = self::$facebookStream->fileGetContents($url); @@ -134,14 +120,16 @@ public function send($url, $method = 'GET', $parameters = array()) } /** - * Formats the headers for use in the stream wrapper + * Formats the headers for use in the stream wrapper. + * + * @param array $headers The request headers. * * @return string */ - public function compileHeader() + public function compileHeader(array $headers) { $header = []; - foreach($this->requestHeaders as $k => $v) { + foreach($headers as $k => $v) { $header[] = $k . ': ' . $v; } diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index c84189c29..bf0411632 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -24,9 +24,8 @@ namespace Facebook\Tests\Entities; use Mockery as m; -use Facebook\Tests\FacebookTestCredentials; +use Facebook\Entities\FacebookApp; use Facebook\Entities\AccessToken; -use Facebook\Tests\FacebookTestHelper; class AccessTokenTest extends \PHPUnit_Framework_TestCase { @@ -66,7 +65,8 @@ public function testATokenIsValidatedOnTheAppIdAndMachineIdAndTokenValidityAndTo $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock - ->shouldReceive('getAppId') + ->shouldReceive('getProperty') + ->with('app_id') ->once() ->andReturn('123'); $graphSessionInfoMock @@ -83,7 +83,8 @@ public function testATokenIsValidatedOnTheAppIdAndMachineIdAndTokenValidityAndTo ->twice() ->andReturn($dt); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, '123', 'foo_machine'); + $app = new FacebookApp('123', 'foo_secret'); + $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); $this->assertTrue($isValid, 'Expected access token to be valid.'); } @@ -96,9 +97,10 @@ public function testATokenWillNotBeValidIfTheAppIdDoesNotMatch() $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock - ->shouldReceive('getAppId') + ->shouldReceive('getProperty') + ->with('app_id') ->once() - ->andReturn('123'); + ->andReturn('1337'); $graphSessionInfoMock ->shouldReceive('getProperty') ->with('machine_id') @@ -113,7 +115,8 @@ public function testATokenWillNotBeValidIfTheAppIdDoesNotMatch() ->twice() ->andReturn($dt); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, '42', 'foo_machine'); + $app = new FacebookApp('123', 'foo_secret'); + $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because the app ID does not match.'); } @@ -126,7 +129,8 @@ public function testATokenWillNotBeValidIfTheMachineIdDoesNotMatch() $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock - ->shouldReceive('getAppId') + ->shouldReceive('getProperty') + ->with('app_id') ->once() ->andReturn('123'); $graphSessionInfoMock @@ -143,7 +147,8 @@ public function testATokenWillNotBeValidIfTheMachineIdDoesNotMatch() ->twice() ->andReturn($dt); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, '123', 'bar_machine'); + $app = new FacebookApp('123', 'foo_secret'); + $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'bar_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because the machine ID does not match.'); } @@ -156,7 +161,8 @@ public function testATokenWillNotBeValidIfTheCollectionTellsUsItsNotValid() $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock - ->shouldReceive('getAppId') + ->shouldReceive('getProperty') + ->with('app_id') ->once() ->andReturn('123'); $graphSessionInfoMock @@ -173,7 +179,8 @@ public function testATokenWillNotBeValidIfTheCollectionTellsUsItsNotValid() ->twice() ->andReturn($dt); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, '123', 'foo_machine'); + $app = new FacebookApp('123', 'foo_secret'); + $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because the collection says it is not valid.'); } @@ -186,7 +193,8 @@ public function testATokenWillNotBeValidIfTheTokenHasExpired() $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); $graphSessionInfoMock - ->shouldReceive('getAppId') + ->shouldReceive('getProperty') + ->with('app_id') ->once() ->andReturn('123'); $graphSessionInfoMock @@ -203,68 +211,115 @@ public function testATokenWillNotBeValidIfTheTokenHasExpired() ->twice() ->andReturn($dt); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, '123', 'foo_machine'); + $app = new FacebookApp('123', 'foo_secret'); + $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because it has expired.'); } public function testInfoAboutAnAccessTokenCanBeObtainedFromGraph() { - $testUserAccessToken = FacebookTestHelper::$testUserAccessToken; - - $accessToken = new AccessToken($testUserAccessToken); - $accessTokenInfo = $accessToken->getInfo(); - - $testAppId = FacebookTestCredentials::$appId; - $this->assertEquals($testAppId, $accessTokenInfo->getAppId()); + $app = new FacebookApp('123', 'foo_secret'); + $response = m::mock('Facebook\Entities\FacebookResponse'); + $response + ->shouldReceive('getGraphObject') + ->with('Facebook\GraphNodes\GraphSessionInfo') + ->once() + ->andReturn($response); + $response + ->shouldReceive('getExpiresAt') + ->once() + ->andReturn(null); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); - $testUserId = FacebookTestHelper::$testUserId; - $this->assertEquals($testUserId, $accessTokenInfo->getId()); + $accessToken = new AccessToken('foo_token'); + $accessTokenInfo = $accessToken->getInfo($app, $client); - $expectedScopes = FacebookTestHelper::$testUserPermissions; - $actualScopes = $accessTokenInfo->getPropertyAsArray('scopes'); - foreach ($expectedScopes as $scope) { - $this->assertTrue(in_array($scope, $actualScopes), - 'Expected the following permission to be present: '.$scope); - } + $this->assertSame($response, $accessTokenInfo); } public function testAShortLivedAccessTokenCabBeExtended() { - $testUserAccessToken = FacebookTestHelper::$testUserAccessToken; + $app = new FacebookApp('123', 'foo_secret'); + $response = m::mock('Facebook\Entities\FacebookResponse'); + $response + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'access_token' => 'long_token', + 'expires' => 123, + 'machine_id' => 'foo_machine', + ]); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); - $accessToken = new AccessToken($testUserAccessToken); - $longLivedAccessToken = $accessToken->extend(); + $accessToken = new AccessToken('foo_token'); + $longLivedAccessToken = $accessToken->extend($app, $client); $this->assertInstanceOf('Facebook\Entities\AccessToken', $longLivedAccessToken); + $this->assertEquals('long_token', (string)$longLivedAccessToken); + $this->assertEquals('foo_machine', $longLivedAccessToken->getMachineId()); + $this->assertEquals(time() + 123, $longLivedAccessToken->getExpiresAt()->getTimeStamp()); } public function testALongLivedAccessTokenCanBeUsedToObtainACode() { - $testUserAccessToken = FacebookTestHelper::$testUserAccessToken; - - $accessToken = new AccessToken($testUserAccessToken); - $longLivedAccessToken = $accessToken->extend(); + $app = new FacebookApp('123', 'foo_secret'); + $response = m::mock('Facebook\Entities\FacebookResponse'); + $response + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'code' => 'foo_code', + ]); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); - $code = AccessToken::getCodeFromAccessToken((string) $longLivedAccessToken); + $code = AccessToken::getCodeFromAccessToken('foo_token', $app, $client); - $this->assertTrue(is_string($code)); + $this->assertEquals('foo_code', $code); } public function testACodeCanBeUsedToObtainAnAccessToken() { - $testUserAccessToken = FacebookTestHelper::$testUserAccessToken; - - $accessToken = new AccessToken($testUserAccessToken); - $longLivedAccessToken = $accessToken->extend(); - - $code = AccessToken::getCodeFromAccessToken($longLivedAccessToken); - $accessTokenFromCode = AccessToken::getAccessTokenFromCode($code); + $app = new FacebookApp('123', 'foo_secret'); + $response = m::mock('Facebook\Entities\FacebookResponse'); + $response + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'access_token' => 'new_long_token', + 'expires' => 123, + 'machine_id' => 'foo_machine', + ]); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); + $accessTokenFromCode = AccessToken::getAccessTokenFromCode('foo_code', $app, $client); $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessTokenFromCode); + $this->assertEquals('new_long_token', (string)$accessTokenFromCode); + $this->assertEquals('foo_machine', $accessTokenFromCode->getMachineId()); + $this->assertEquals(time() + 123, $accessTokenFromCode->getExpiresAt()->getTimeStamp()); } - public function testSerialization() + public function testAccessTokenCanBeSerialized() { $accessToken = new AccessToken('foo', time(), 'bar'); $newAccessToken = unserialize(serialize($accessToken)); @@ -274,22 +329,4 @@ public function testSerialization() $this->assertEquals($accessToken->getMachineId(), $newAccessToken->getMachineId()); } - /** - * @dataProvider provideAccessTokenExpiration - */ - public function testIsExpired($expiresAt, $expected) - { - $accessToken = new AccessToken('foo', $expiresAt); - - $this->assertEquals($expected, $accessToken->isExpired()); - } - - public function provideAccessTokenExpiration() - { - return array( - array(time()+60, false), - array(time()-60, true), - array(0, false), - ); - } } diff --git a/tests/GraphNodes/GraphLocationTest.php b/tests/Entities/AppSecretProofTest.php old mode 100644 new mode 100755 similarity index 61% rename from tests/GraphNodes/GraphLocationTest.php rename to tests/Entities/AppSecretProofTest.php index a78bbbbf0..7c1c7ec64 --- a/tests/GraphNodes/GraphLocationTest.php +++ b/tests/Entities/AppSecretProofTest.php @@ -21,29 +21,25 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\GraphNodes; +namespace Facebook\Tests\Entities; -use Facebook\FacebookRequest; -use Facebook\GraphNodes\GraphLocation; -use Facebook\GraphNodes\GraphObject; -use Facebook\Tests\FacebookTestHelper; +use Facebook\Entities\AppSecretProof; -class GraphLocationTest extends \PHPUnit_Framework_TestCase +class AppSecretProofTest extends \PHPUnit_Framework_TestCase { - public function testLocation() + public function testAnAppSecretProofIsGeneratedAsExpected() { - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/104048449631599' - ))->execute()->getGraphObject(); - $this->assertTrue($response instanceof GraphObject); + $appSecretProof = AppSecretProof::make('foo_access_token', 'foo_app_secret'); - $location = $response->getProperty('location', GraphLocation::className()); - $this->assertTrue(is_float($location->getLatitude())); - $this->assertTrue(is_float($location->getLongitude())); + $this->assertEquals('12f5dcbb7557d24b1d37fd180c45991c5999f325ece0af331c00a85d762f2b95', $appSecretProof); + } + + public function testAnAppSecretProofEntityCanBeReturnedAsAString() + { + $appSecretProof = new AppSecretProof('foo_access_token', 'foo_app_secret'); + + $this->assertEquals('12f5dcbb7557d24b1d37fd180c45991c5999f325ece0af331c00a85d762f2b95', (string) $appSecretProof); } } diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/Entities/FacebookBatchRequestTest.php new file mode 100755 index 000000000..4c44fa08a --- /dev/null +++ b/tests/Entities/FacebookBatchRequestTest.php @@ -0,0 +1,367 @@ +requestHeaders = []; + foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { + $this->requestHeaders[] = $name . ': ' . $value; + } + } + + public function testEmptyBatchRequestEntitiesCanBeInstantiated() + { + $batchRequest = new FacebookBatchRequest(); + $this->assertInstanceOf('Facebook\Entities\FacebookBatchRequest', $batchRequest); + } + + public function testABatchRequestWillInstantiateWithTheProperProperties() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token', [], 'v0.1337'); + + $batchApp = $batchRequest->getApp(); + $accessToken = $batchRequest->getAccessToken(); + $method = $batchRequest->getMethod(); + $endpoint = $batchRequest->getEndpoint(); + $graphVersion = $batchRequest->getGraphVersion(); + + $this->assertSame($app, $batchApp); + $this->assertEquals('foo_token', $accessToken); + $this->assertEquals('POST', $method); + $this->assertEquals('', $endpoint); + $this->assertEquals('v0.1337', $graphVersion); + } + + public function testMissingAppOrAccessTokensOnRequestObjectsWillFallbackToBatchDefaults() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + $requestTotallyEmpty = new FacebookRequest(); + $batchRequest->addFallbackDefaults($requestTotallyEmpty); + $appTotallyEmpty = $requestTotallyEmpty->getApp(); + $accessTokenTotallyEmpty = $requestTotallyEmpty->getAccessToken(); + + $this->assertSame($app, $appTotallyEmpty); + $this->assertEquals('foo_token', $accessTokenTotallyEmpty); + + $requestTokenOnly = new FacebookRequest(null, 'bar_token'); + $batchRequest->addFallbackDefaults($requestTokenOnly); + $appTokenOnly = $requestTokenOnly->getApp(); + $accessTokenTokenOnly = $requestTokenOnly->getAccessToken(); + + $this->assertSame($app, $appTokenOnly); + $this->assertEquals('bar_token', $accessTokenTokenOnly); + + $myApp = new FacebookApp('1337', 'bar_secret'); + $requestAppOnly = new FacebookRequest($myApp); + $batchRequest->addFallbackDefaults($requestAppOnly); + $appAppOnly = $requestAppOnly->getApp(); + $accessTokenAppOnly = $requestAppOnly->getAccessToken(); + + $this->assertSame($myApp, $appAppOnly); + $this->assertEquals('foo_token', $accessTokenAppOnly); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testWillThrowWhenNoThereIsNoAppFallback() + { + $batchRequest = new FacebookBatchRequest(); + + $requestTotallyEmpty = new FacebookRequest(null, 'foo_token'); + $batchRequest->addFallbackDefaults($requestTotallyEmpty); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testWillThrowWhenNoThereIsNoAccessTokenFallback() + { + $batchRequest = new FacebookBatchRequest(); + + $app = new FacebookApp('123', 'foo_secret'); + $requestTotallyEmpty = new FacebookRequest($app); + $batchRequest->addFallbackDefaults($requestTotallyEmpty); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnInvalidTypeGivenToAddWillThrow() + { + $batchRequest = new FacebookBatchRequest(); + + $batchRequest->add('foo'); + } + + public function testAddingRequestsWillBeFormattedInAnArrayProperly() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + $requestOne = new FacebookRequest(null, null, 'GET', '/foo'); + $requestTwo = new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']); + $requestThree = new FacebookRequest(null, null, 'DELETE', '/baz'); + + $batchRequest->add($requestOne); + $batchRequest->add($requestTwo, 'my-second-request'); + $batchRequest->add($requestThree, 'my-third-request'); + + $requests = $batchRequest->getRequests(); + + $expectedRequests = [ + [ + 'name' => null, + 'request' => $requestOne, + ], + [ + 'name' => 'my-second-request', + 'request' => $requestTwo, + ], + [ + 'name' => 'my-third-request', + 'request' => $requestThree, + ], + ]; + $this->assertEquals($expectedRequests, $requests); + } + + public function testANumericArrayOfRequestsCanBeAdded() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + $requests = [ + new FacebookRequest(null, null, 'GET', '/foo'), + new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $batchRequest->add($requests); + $formattedRequests = $batchRequest->getRequests(); + + $expectedRequests = [ + [ + 'name' => 0, + 'request' => $requests[0], + ], + [ + 'name' => 1, + 'request' => $requests[1], + ], + [ + 'name' => 2, + 'request' => $requests[2], + ], + ]; + $this->assertEquals($expectedRequests, $formattedRequests); + } + + public function testAnAssociativeArrayOfRequestsCanBeAdded() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + $requests = [ + 'req-one' => new FacebookRequest(null, null, 'GET', '/foo'), + 'req-two' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + 'req-three' => new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $batchRequest->add($requests); + $formattedRequests = $batchRequest->getRequests(); + + $expectedRequests = [ + [ + 'name' => 'req-one', + 'request' => $requests['req-one'], + ], + [ + 'name' => 'req-two', + 'request' => $requests['req-two'], + ], + [ + 'name' => 'req-three', + 'request' => $requests['req-three'], + ], + ]; + $this->assertEquals($expectedRequests, $formattedRequests); + } + + public function testRequestsCanBeInjectedIntoConstructor() + { + $requests = [ + new FacebookRequest(null, null, 'GET', '/foo'), + new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token', $requests); + + $formattedRequests = $batchRequest->getRequests(); + + $expectedRequests = [ + [ + 'name' => 0, + 'request' => $requests[0], + ], + [ + 'name' => 1, + 'request' => $requests[1], + ], + [ + 'name' => 2, + 'request' => $requests[2], + ], + ]; + $this->assertEquals($expectedRequests, $formattedRequests); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAZeroRequestCountWithThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + $batchRequest->validateBatchRequestCount(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testMoreThanFiftyRequestsWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + for ($i=0; $i<=50; $i++) { + $batchRequest->add(new FacebookRequest()); + } + $batchRequest->validateBatchRequestCount(); + } + + public function testLessThanFiftyRequestsWillNotThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + for ($i=0; $i<50; $i++) { + $batchRequest->add(new FacebookRequest()); + } + $batchRequest->validateBatchRequestCount(); + } + + public function testBatchRequestEntitiesProperlyGetConvertedToAnArrayForJsonEncodingForEachMethod() + { + $app = new FacebookApp('123', 'foo_secret'); + + // GET request + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + $batchRequest->add(new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), 'foo_name'); + + $requests = $batchRequest->getRequests(); + $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); + + $expectedArray = [ + 'headers' => $this->requestHeaders, + 'method' => 'GET', + 'relative_url' => '/'.FacebookRequest::getDefaultGraphApiVersion().'/foo?foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ]; + + $this->assertEquals($expectedArray, $batchRequestArray); + + // POST request + $batchRequest = new FacebookBatchRequest($app, 'bar_token'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['bar' => 'baz']), 'bar_name'); + + $requests = $batchRequest->getRequests(); + $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); + + $expectedArray = [ + 'headers' => $this->requestHeaders, + 'method' => 'POST', + 'relative_url' => '/'.FacebookRequest::getDefaultGraphApiVersion().'/bar', + 'body' => 'bar=baz&access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd', + 'name' => 'bar_name', + ]; + + $this->assertEquals($expectedArray, $batchRequestArray); + + // DELETE request + $batchRequest = new FacebookBatchRequest($app, 'bar_token'); + $batchRequest->add(new FacebookRequest(null, null, 'DELETE', '/bar'), 'bar_name'); + + $requests = $batchRequest->getRequests(); + $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); + + $expectedArray = [ + 'headers' => $this->requestHeaders, + 'method' => 'DELETE', + 'relative_url' => '/'.FacebookRequest::getDefaultGraphApiVersion().'/bar?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd', + 'name' => 'bar_name', + ]; + + $this->assertEquals($expectedArray, $batchRequestArray); + } + + public function testPreppingABatchRequestProperlySetsThePostParams() + { + $app = new FacebookApp('123', 'foo_secret'); + $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + + $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar'])); + + $batchRequest->prepareRequestsForBatch(); + $params = $batchRequest->getParams(); + + $expectedHeaders = json_encode($this->requestHeaders); + $version = FacebookRequest::getDefaultGraphApiVersion(); + $expectedBatchParams = [ + 'batch' => '[{"headers":'.$expectedHeaders.',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' + .'{"headers":'.$expectedHeaders.',"method":"POST","relative_url":"\\/' . $version . '\\/bar","body":"foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9"}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + +} diff --git a/tests/Entities/FacebookBatchResponseTest.php b/tests/Entities/FacebookBatchResponseTest.php new file mode 100755 index 000000000..cc7e9106b --- /dev/null +++ b/tests/Entities/FacebookBatchResponseTest.php @@ -0,0 +1,98 @@ +getResponses(); + + // Single Graph object. + $this->assertFalse($decodedResponses[0]->isError(), 'Did not expect Response to return an error for single Graph object.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[0]->getGraphObject()); + // Paginated list of Graph objects. + $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); + $graphList = $decodedResponses[1]->getGraphObjectList(); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[1]); + /* + // Endpoint not found. + $this->assertTrue($decodedResponses[2]->isError(), 'Expected Response to return an error for endpoint not found.'); + $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $decodedResponses[2]->getThrownException()); + // Invalid access token. + $this->assertTrue($decodedResponses[3]->isError(), 'Expected Response to return an error for invalid access token.'); + $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $decodedResponses[3]->getThrownException()); + // After POST operation. + $this->assertFalse($decodedResponses[4]->isError(), 'Did not expect Response to return an error for POST operation.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[4]->getGraphObject()); + // After DELETE operation. + $this->assertFalse($decodedResponses[5]->isError(), 'Did not expect Response to return an error for DELETE operation.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[5]->getGraphObject()); + */ + } + + + public function testABatchResponseCanBeIteratedOver() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $app = new FacebookApp('123', 'foo_secret'); + $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $batchResponse = new FacebookBatchResponse($response); + + $this->assertInstanceOf('IteratorAggregate', $batchResponse); + + foreach ($batchResponse as $responseEntity) { + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $responseEntity); + } + } + +} diff --git a/tests/Entities/FacebookRequestTest.php b/tests/Entities/FacebookRequestTest.php new file mode 100755 index 000000000..f7b7732b6 --- /dev/null +++ b/tests/Entities/FacebookRequestTest.php @@ -0,0 +1,196 @@ +assertInstanceOf('Facebook\Entities\FacebookRequest', $request); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAMissingAccessTokenWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $request->validateAccessToken(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAMissingMethodWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $request->validateMethod(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnInvalidMethodWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'FOO'); + + $request->validateMethod(); + } + + public function testGetHeadersWillAutoAppendETag() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'GET', '/foo', [], 'fooETag'); + + $headers = $request->getHeaders(); + + $expectedHeaders = FacebookRequest::getDefaultHeaders(); + $expectedHeaders['If-None-Match'] = 'fooETag'; + + $this->assertEquals($expectedHeaders, $headers); + } + + public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo', ['foo' => 'bar']); + + $params = $request->getParams(); + + $this->assertEquals([ + 'foo' => 'bar', + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ], $params); + } + + public function testAProperUrlWillBeGenerated() + { + $app = new FacebookApp('123', 'foo_secret'); + $getRequest = new FacebookRequest($app, 'foo_token', 'GET', '/foo', ['foo' => 'bar']); + + $getUrl = $getRequest->getUrl(); + $expectedParams = 'foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; + $expectedUrl = '/' . FacebookRequest::getDefaultGraphApiVersion() . '/foo?' . $expectedParams; + + $this->assertEquals($expectedUrl, $getUrl); + + $postRequest = new FacebookRequest($app, 'foo_token', 'POST', '/bar', ['foo' => 'bar']); + + $postUrl = $postRequest->getUrl(); + $expectedUrl = '/' . FacebookRequest::getDefaultGraphApiVersion() . '/bar'; + + $this->assertEquals($expectedUrl, $postUrl); + } + + public function testParamsAreNotOverwritten() + { + $app = new FacebookApp('123', 'foo_secret'); + + $request = new FacebookRequest( + $app, + $accessToken = 'foo_token', + $method = 'GET', + $endpoint = '/foo', + $params = [ + 'access_token' => 'bar_access_token', + 'appsecret_proof' => 'bar_app_secret', + ] + ); + + $url = $request->getUrl(); + + $expectedParams = 'access_token=bar_access_token&appsecret_proof=bar_app_secret'; + $expectedUrl = '/' . FacebookRequest::getDefaultGraphApiVersion() . '/foo?' . $expectedParams; + $this->assertEquals($expectedUrl, $url); + + $params = $request->getParams(); + + $expectedParams = [ + 'access_token' => 'bar_access_token', + 'appsecret_proof' => 'bar_app_secret', + ]; + $this->assertEquals($expectedParams, $params); + } + + public function testGracefullyHandlesUrlAppending() + { + $params = []; + $url = 'https://www.foo.com/'; + $processed_url = FacebookRequest::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/'; + $processed_url = FacebookRequest::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + + $params = [ + 'access_token' => 'foo', + 'bar' => 'baz', + ]; + $url = 'https://www.foo.com/?foo=bar'; + $processed_url = FacebookRequest::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/?foo=bar&access_token=bar'; + $processed_url = FacebookRequest::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + } + + public function testSlashesAreProperlyPrepended() + { + $slashTestOne = FacebookRequest::forceSlashPrefix('foo'); + $slashTestTwo = FacebookRequest::forceSlashPrefix('/foo'); + $slashTestThree = FacebookRequest::forceSlashPrefix('foo/bar'); + $slashTestFour = FacebookRequest::forceSlashPrefix('/foo/bar'); + $slashTestFive = FacebookRequest::forceSlashPrefix(null); + $slashTestSix = FacebookRequest::forceSlashPrefix(''); + + $this->assertEquals('/foo', $slashTestOne); + $this->assertEquals('/foo', $slashTestTwo); + $this->assertEquals('/foo/bar', $slashTestThree); + $this->assertEquals('/foo/bar', $slashTestFour); + $this->assertEquals(null, $slashTestFive); + $this->assertEquals('', $slashTestSix); + } + +} diff --git a/tests/Entities/FacebookResponseTest.php b/tests/Entities/FacebookResponseTest.php new file mode 100755 index 000000000..ddf298c73 --- /dev/null +++ b/tests/Entities/FacebookResponseTest.php @@ -0,0 +1,131 @@ +assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + } + + public function testAnETagCanBeProperlyAccessed() + { + $app = new FacebookApp('123', 'foo_secret'); + $response = new FacebookResponse($app, 200, ['ETag' => 'foo_tag']); + + $eTag = $response->getETag(); + + $this->assertEquals('foo_tag', $eTag); + } + + public function testAProperAppSecretProofCanBeGenerated() + { + $app = new FacebookApp('123', 'foo_secret'); + $response = new FacebookResponse($app, 200, [], '', 'foo_token'); + + $appSecretProof = $response->getAppSecretProof(); + + $this->assertEquals('df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', $appSecretProof); + } + + public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() + { + $app = new FacebookApp('123', 'foo_secret'); + $graphResponseJson = '{"id":"123","name":"Foo"}'; + $response = new FacebookResponse($app, 200, [], $graphResponseJson); + + $decodedResponse = $response->getDecodedBody(); + $graphObject = $response->getGraphObject(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo', + ], $decodedResponse); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + } + + public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() + { + $app = new FacebookApp('123', 'foo_secret'); + $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; + $response = new FacebookResponse($app, 200, [], $graphResponseJson); + + $graphObjectList = $response->getGraphObjectList(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[1]); + } + + public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() + { + $app = new FacebookApp('123', 'foo_secret'); + $graphResponseKeyValuePairs = 'id=123&name=Foo'; + $response = new FacebookResponse($app, 200, [], $graphResponseKeyValuePairs); + + $decodedResponse = $response->getDecodedBody(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo', + ], $decodedResponse); + } + + public function testASuccessfulBooleanResponseWillBeDecoded() + { + $app = new FacebookApp('123', 'foo_secret'); + $graphResponse = 'true'; + $response = new FacebookResponse($app, 200, [], $graphResponse); + + $decodedResponse = $response->getDecodedBody(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals(['was_successful' => true], $decodedResponse); + } + + /* + public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() + { + $app = new FacebookApp('123', 'foo_secret'); + $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; + $response = new FacebookResponse($app, 401, [], $graphResponse); + + $exception = $response->getThrownException(); + + $this->assertTrue($response->isError(), 'Expected Response to return an error.'); + $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $exception); + } + */ + +} diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 6d2a37d75..ac30cfaea 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -30,7 +30,6 @@ use Facebook\Exceptions\FacebookPermissionException; use Facebook\Exceptions\FacebookClientException; use Facebook\Exceptions\FacebookThrottleException; -use Facebook\FacebookSession; class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase { @@ -268,22 +267,4 @@ public function testOtherException() $this->assertEquals(200, $exception->getHttpStatusCode()); } - public function testValidateThrowsException() - { - $bogusSession = new FacebookSession('invalid-token'); - $this->setExpectedException( - 'Facebook\\Exceptions\\FacebookSDKException', 'Session has expired' - ); - $bogusSession->validate(); - } - - public function testInvalidCredentialsException() - { - $bogusSession = new FacebookSession('invalid-token'); - $this->setExpectedException( - 'Facebook\\Exceptions\\FacebookAuthorizationException', 'Invalid OAuth access token' - ); - $bogusSession->validate('invalid-app-id', 'invalid-app-secret'); - } - } diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php new file mode 100644 index 000000000..c4ce34ce3 --- /dev/null +++ b/tests/FacebookClientTest.php @@ -0,0 +1,288 @@ +httpClientMock = m::mock('Facebook\HttpClients\FacebookHttpClientInterface'); + } + + public function testACustomHttpClientCanBeInjected() + { + $client = new FacebookClient($this->httpClientMock); + $httpHandler = $client->getHttpClientHandler(); + + $this->assertInstanceOf('Mockery\MockInterface', $httpHandler); + $this->assertSame($this->httpClientMock, $httpHandler); + } + + public function testTheHttpClientWillFallbackToDefault() + { + $client = new FacebookClient(); + $httpHandler = $client->getHttpClientHandler(); + + if (function_exists('curl_init')) { + $this->assertInstanceOf('Facebook\HttpClients\FacebookCurlHttpClient', $httpHandler); + } else { + $this->assertInstanceOf('Facebook\HttpClients\FacebookStreamHttpClient', $httpHandler); + } + } + + public function testBetaModeCanBeDisabledOrEnabledViaConstructor() + { + $client = new FacebookClient(null, false); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); + + $client = new FacebookClient(null, true); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); + } + + public function testBetaModeCanBeDisabledOrEnabledViaMethod() + { + $client = new FacebookClient(); + $client->enableBetaMode(false); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); + + $client->enableBetaMode(true); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); + } + + public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() + { + $facebookApp = new FacebookApp('123', 'foo_secret'); + $facebookRequest = m::mock('Facebook\Entities\FacebookRequest'); + $facebookRequest + ->shouldReceive('getUrl') + ->once() + ->andReturn('/foo'); + $facebookRequest + ->shouldReceive('getMethod') + ->once() + ->andReturn('GET'); + $facebookRequest + ->shouldReceive('getPostParams') + ->once() + ->andReturn([]); + $facebookRequest + ->shouldReceive('getHeaders') + ->once() + ->andReturn(['request_header' => 'foo']); + $facebookRequest + ->shouldReceive('getAccessToken') + ->once() + ->andReturn('foo_token'); + $facebookRequest + ->shouldReceive('getApp') + ->once() + ->andReturn($facebookApp); + + $this->httpClientMock + ->shouldReceive('send') + ->with(FacebookClient::BASE_GRAPH_URL . '/foo', 'GET', [], ['request_header' => 'foo']) + ->once() + ->andReturn('foo_response'); + $this->httpClientMock + ->shouldReceive('getResponseHttpStatusCode') + ->once() + ->andReturn(200); + $this->httpClientMock + ->shouldReceive('getResponseHeaders') + ->once() + ->andReturn(['response_header' => 'bar']); + + $client = new FacebookClient($this->httpClientMock); + $response = $client->sendRequest($facebookRequest); + + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + } + + public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() + { + $facebookApp = new FacebookApp('123', 'foo_secret'); + $facebookBatchRequest = m::mock('Facebook\Entities\FacebookBatchRequest'); + $facebookBatchRequest + ->shouldReceive('prepareRequestsForBatch') + ->once() + ->andReturn(null); + $facebookBatchRequest + ->shouldReceive('getUrl') + ->once() + ->andReturn(''); + $facebookBatchRequest + ->shouldReceive('getMethod') + ->once() + ->andReturn('POST'); + $facebookBatchRequest + ->shouldReceive('getPostParams') + ->once() + ->andReturn([]); + $facebookBatchRequest + ->shouldReceive('getHeaders') + ->once() + ->andReturn(['request_header' => 'foo']); + $facebookBatchRequest + ->shouldReceive('getAccessToken') + ->once() + ->andReturn('foo_token'); + $facebookBatchRequest + ->shouldReceive('getApp') + ->once() + ->andReturn($facebookApp); + + $this->httpClientMock + ->shouldReceive('send') + ->with(FacebookClient::BASE_GRAPH_URL, 'POST', [], ['request_header' => 'foo']) + ->once() + ->andReturn('[]'); + $this->httpClientMock + ->shouldReceive('getResponseHttpStatusCode') + ->once() + ->andReturn(200); + $this->httpClientMock + ->shouldReceive('getResponseHeaders') + ->once() + ->andReturn(['response_header' => 'bar']); + + $client = new FacebookClient($this->httpClientMock); + $response = $client->sendBatchRequest($facebookBatchRequest); + + $this->assertInstanceOf('Facebook\Entities\FacebookBatchResponse', $response); + } + + /** + * @group integration + */ + public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() + { + $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)->getGraphObject(); + + $testUserId = $response->getProperty('id'); + $testUserAccessToken = $response->getProperty('access_token'); + + // Get the test user's profile + $request = new FacebookRequest( + static::$testFacebookApp, + $testUserAccessToken, + 'GET', + '/me'); + $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertNotNull($graphObject->getProperty('id')); + $this->assertEquals('Foo Phpunit User', $graphObject->getProperty('name')); + + // Delete test user + $request = new FacebookRequest( + static::$testFacebookApp, + static::$testFacebookApp->getAccessToken(), + 'DELETE', + '/' . $testUserId); + $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + + $this->assertTrue($graphObject->getProperty('was_successful')); + } + + public function initializeTestApp() + { + 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 deleted file mode 100644 index dcaa29c8b..000000000 --- a/tests/FacebookRequestTest.php +++ /dev/null @@ -1,165 +0,0 @@ -execute()->getGraphObject(); - $this->assertNotNull($response->getProperty('id')); - $this->assertNotNull($response->getProperty('name')); - } - - public function testCanPostAndDelete() - { - // Create a test user - $params = array( - 'name' => 'Foo User', - ); - $response = ( - new FacebookRequest( - new FacebookSession(FacebookTestHelper::getAppToken()), - 'POST', - '/' . FacebookTestCredentials::$appId . '/accounts/test-users', - $params - ))->execute()->getGraphObject(); - $user_id = $response->getProperty('id'); - $this->assertNotNull($user_id); - - // Delete test user - $response = ( - new FacebookRequest( - new FacebookSession(FacebookTestHelper::getAppToken()), - 'DELETE', - '/' . $user_id - ))->execute()->getGraphObject()->asArray(); - $this->assertTrue($response); - } - - public function testETagHit() - { - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/104048449631599' - ))->execute(); - - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/104048449631599', - null, - null, - $response->getETag() - ))->execute(); - - $this->assertTrue($response->isETagHit()); - $this->assertNull($response->getETag()); - } - - public function testETagMiss() - { - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/104048449631599', - null, - null, - 'someRandomValue' - ))->execute(); - - $this->assertFalse($response->isETagHit()); - $this->assertNotNull($response->getETag()); - } - - public function testGracefullyHandlesUrlAppending() - { - $params = array(); - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/', $processed_url); - - $params = array( - 'access_token' => 'foo', - ); - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); - - $params = array( - 'access_token' => 'foo', - 'bar' => 'baz', - ); - $url = 'https://www.foo.com/?foo=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); - - $params = array( - 'access_token' => 'foo', - ); - $url = 'https://www.foo.com/?foo=bar&access_token=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); - } - - public function testAppSecretProof() - { - $enableAppSecretProof = FacebookSession::useAppSecretProof(); - - FacebookSession::enableAppSecretProof(true); - $request = new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/me' - ); - $this->assertTrue(isset($request->getParameters()['appsecret_proof'])); - - - FacebookSession::enableAppSecretProof(false); - $request = new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/me' - ); - $this->assertFalse(isset($request->getParameters()['appsecret_proof'])); - - FacebookSession::enableAppSecretProof($enableAppSecretProof); - } - -} \ No newline at end of file diff --git a/tests/FacebookSessionTest.php b/tests/FacebookSessionTest.php deleted file mode 100644 index 5ca273c10..000000000 --- a/tests/FacebookSessionTest.php +++ /dev/null @@ -1,103 +0,0 @@ -assertEquals( - FacebookTestHelper::getAppToken(), $session->getToken() - ); - } - - public function testGetSessionInfo() - { - $response = FacebookTestHelper::$testSession->getSessionInfo(); - $this->assertTrue($response instanceof GraphSessionInfo); - $this->assertNotNull($response->getAppId()); - $this->assertTrue($response->isValid()); - $scopes = $response->getPropertyAsArray('scopes'); - $this->assertTrue(is_array($scopes)); - $this->assertEquals(5, count($scopes)); - } - - public function testExtendAccessToken() - { - $response = FacebookTestHelper::$testSession->getLongLivedSession(); - $this->assertTrue($response instanceof FacebookSession); - $info = $response->getSessionInfo(); - $nextWeek = time() + (60 * 60 * 24 * 7); - $this->assertTrue( - $info->getProperty('expires_at') > $nextWeek - ); - } - - public function testSessionFromSignedRequest() - { - $signedRequest = m::mock('Facebook\Entities\SignedRequest'); - $signedRequest - ->shouldReceive('get') - ->with('code') - ->once() - ->andReturn(null); - $signedRequest - ->shouldReceive('get') - ->with('oauth_token') - ->once() - ->andReturn('foo_token'); - $signedRequest - ->shouldReceive('get') - ->with('expires', 0) - ->once() - ->andReturn(time() + (60 * 60 * 24)); - $signedRequest - ->shouldReceive('getUserId') - ->once() - ->andReturn('123'); - - $session = FacebookSession::newSessionFromSignedRequest($signedRequest); - $this->assertInstanceOf('Facebook\FacebookSession', $session); - $this->assertEquals('foo_token', $session->getToken()); - $this->assertEquals('123', $session->getUserId()); - } - - public function testAppSessionValidates() - { - $session = FacebookSession::newAppSession(); - try { - $session->validate(); - } catch (\Facebook\FacebookSDKException $ex) { - $this->fail('Exception thrown validating app session.'); - } - } - -} diff --git a/tests/FacebookTestHelper.php b/tests/FacebookTestHelper.php deleted file mode 100644 index 9e1e9371c..000000000 --- a/tests/FacebookTestHelper.php +++ /dev/null @@ -1,98 +0,0 @@ - true, - 'name' => 'Foo Phpunit User', - 'locale' => 'en_US', - 'permissions' => implode(',', static::$testUserPermissions), - ); - - $request = new FacebookRequest(static::getAppSession(), 'POST', $testUserPath, $params); - $response = $request->execute()->getGraphObject(); - - static::$testUserId = $response->getProperty('id'); - static::$testUserAccessToken = $response->getProperty('access_token'); - } - - public static function getAppSession() - { - return new FacebookSession(static::getAppToken()); - } - - public static function getAppToken() - { - return FacebookTestCredentials::$appId . '|' . FacebookTestCredentials::$appSecret; - } - - public static function deleteTestUser() - { - if (!static::$testUserId) { - return; - } - $testUserPath = '/' . static::$testUserId; - $request = new FacebookRequest(static::getAppSession(), 'DELETE', $testUserPath); - $request->execute(); - } - -} diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 9a0f313c6..1f38eb8e1 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -23,55 +23,42 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphAlbum; -use Facebook\Tests\FacebookTestHelper; class GraphAlbumTest extends \PHPUnit_Framework_TestCase { - const ALBUM_DESCRIPTION = "Album Description"; - const ALBUM_NAME = "Album Name"; - - public function testMeReturnsGraphAlbum() + public function testDatesGetCastToDateTime() { - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'POST', - '/me/albums', - array( - 'name' => self::ALBUM_NAME, - 'message' => self::ALBUM_DESCRIPTION, - 'value' => 'everyone' - ) - ))->execute()->getGraphObject(); + $data = [ + 'created_time' => '2014-07-15T03:54:34+0000', + 'updated_time' => '2014-07-12T01:24:09+0000', + 'id' => '123', + 'name' => 'Bar', + ]; + $graphObject = new GraphAlbum($data); - $albumId = $response->getProperty('id'); + $createdTime = $graphObject->getCreatedTime(); + $updatedTime = $graphObject->getUpdatedTime(); - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/'.$albumId - ))->execute()->getGraphObject(GraphAlbum::className()); + $this->assertInstanceOf('DateTime', $createdTime); + $this->assertInstanceOf('DateTime', $updatedTime); + } - $this->assertTrue($response instanceof GraphAlbum); - $this->assertEquals($albumId, $response->getId()); - $this->assertTrue($response->getFrom() instanceof \Facebook\GraphNodes\GraphUser); - $this->assertTrue($response->canUpload()); - $this->assertEquals(0, $response->getCount()); - $this->assertEquals(self::ALBUM_NAME, $response->getName()); - $this->assertEquals(self::ALBUM_DESCRIPTION, $response->getDescription()); - $this->assertNotNull($response->getLink()); - $this->assertNotNull($response->getPrivacy()); + public function testFromGetsCastAsGraphUser() + { + $data = [ + 'id' => '123', + 'from' => [ + 'id' => '1337', + 'name' => 'Foo McBar', + ], + ]; + $graphObject = new GraphAlbum($data); - $type = array("profile", "mobile", "wall", "normal", "album"); - $this->assertTrue(in_array($response->getType(),$type)); + $from = $graphObject->getFrom(); - date_default_timezone_set('GMT'); - $this->assertTrue($response->getCreatedTime() instanceof \DateTime); - $this->assertTrue($response->getUpdatedTime() instanceof \DateTime); + $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $from); } } diff --git a/tests/GraphNodes/GraphObjectTest.php b/tests/GraphNodes/GraphObjectTest.php index 82a88124e..ee02410ae 100644 --- a/tests/GraphNodes/GraphObjectTest.php +++ b/tests/GraphNodes/GraphObjectTest.php @@ -23,99 +23,96 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphObject; -use Facebook\FacebookResponse; -use Facebook\GraphNodes\GraphUser; -use Facebook\Tests\FacebookTestHelper; + +class MyFooSubClassGraphObject extends GraphObject {} class GraphObjectTest extends \PHPUnit_Framework_TestCase { - public function testFriends() + public function testAnEmptyBaseGraphObjectCanInstantiate() { - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/me/friends' - ))->execute()->getGraphObjectList(); - $this->assertTrue(is_array($response)); + $graphObject = new GraphObject(); + $backingData = $graphObject->asArray(); + + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertEquals([], $backingData); } - public function testArrayProperties() + public function testAGraphObjectCanInstantiateWithData() { - $backingData = array( - 'id' => 42, - 'friends' => array( - 'data' => array( - array( - 'id' => 1, - 'name' => 'David' - ), - array( - 'id' => 2, - 'name' => 'Fosco' - ) - ), - 'paging' => array( - 'next' => 'nexturl' - ) - ) - ); - $obj = new GraphObject($backingData); - $friends = $obj->getPropertyAsArray('friends'); - $this->assertEquals(2, count($friends)); - $this->assertTrue($friends[0] instanceof GraphObject); - $this->assertTrue($friends[1] instanceof GraphObject); - $this->assertEquals('David', $friends[0]->getProperty('name')); - $this->assertEquals('Fosco', $friends[1]->getProperty('name')); - - $backingData = array( - 'id' => 42, - 'friends' => array( - array( - 'id' => 1, - 'name' => 'Ilya' - ), - array( - 'id' => 2, - 'name' => 'Kevin' - ) - ) - ); - $obj = new GraphObject($backingData); - $friends = $obj->getPropertyAsArray('friends'); - $this->assertEquals(2, count($friends)); - $this->assertTrue($friends[0] instanceof GraphObject); - $this->assertTrue($friends[1] instanceof GraphObject); - $this->assertEquals('Ilya', $friends[0]->getProperty('name')); - $this->assertEquals('Kevin', $friends[1]->getProperty('name')); + $graphObject = new GraphObject(['foo' => 'bar']); + $backingData = $graphObject->asArray(); + + $this->assertEquals(['foo' => 'bar'], $backingData); + } + public function testSomethingThatLooksLikeAListWillBeFlattened() + { + $dataFromGraph = [ + 'data' => [ + [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ], + ]; + $graphObject = new GraphObject($dataFromGraph); + + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + } + + public function testAnExistingPropertyCanBeAccessed() + { + $graphObject = new GraphObject(['foo' => 'bar']); + $property = $graphObject->getProperty('foo'); + + $this->assertEquals('bar', $property); + } + + public function testAMissingPropertyWillReturnNull() + { + $graphObject = new GraphObject(['foo' => 'bar']); + $property = $graphObject->getProperty('baz'); + + $this->assertNull($property, 'Expected the property to return null.'); + } + + public function testAMissingPropertyWillReturnTheDefault() + { + $graphObject = new GraphObject(['foo' => 'bar']); + $property = $graphObject->getProperty('baz', 'faz'); + + $this->assertEquals('faz', $property); + } + + public function testTheKeysFromTheGraphDataCanBeReturned() + { + $graphObject = new GraphObject([ + 'key1' => 'foo', + 'key2' => 'bar', + 'key3' => 'baz', + ]); + $propertyKeys = $graphObject->getPropertyNames(); + + $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); + } + + public function testAGraphObjectCanBeRecast() + { + $fooGraphObject = new GraphObject(['foo' => 'bar']); + $newFooGraphObject = $fooGraphObject->cast('Facebook\Tests\GraphNodes\MyFooSubClassGraphObject'); + $this->assertInstanceOf('Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $newFooGraphObject); } - public function testAsList() + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testTryingToRecastToAGraphObjectThatDoesntExistWillThrow() { - $backingData = array( - 'data' => array( - array( - 'id' => 1, - 'name' => 'David' - ), - array( - 'id' => 2, - 'name' => 'Fosco' - ) - ) - ); - $enc = json_encode($backingData); - $response = new FacebookResponse(null, json_decode($enc), $enc); - $list = $response->getGraphObjectList(GraphUser::className()); - $this->assertEquals(2, count($list)); - $this->assertTrue($list[0] instanceof GraphObject); - $this->assertTrue($list[1] instanceof GraphObject); - $this->assertEquals('David', $list[0]->getName()); - $this->assertEquals('Fosco', $list[1]->getName()); + $graphObject = new GraphObject(['foo' => 'bar']); + $graphObject->cast('FooClass'); } } diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index ff3ca4ad9..3c0709987 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -24,27 +24,35 @@ namespace Facebook\Tests\GraphNodes; use Facebook\GraphNodes\GraphSessionInfo; -use Facebook\FacebookRequest; -use Facebook\FacebookSession; -use Facebook\Tests\FacebookTestHelper; class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase { - public function testSessionInfo() + public function testDatesGetCastToDateTime() { - $params = array( - 'input_token' => FacebookTestHelper::$testSession->getToken() - ); - $response = (new FacebookRequest( - new FacebookSession(FacebookTestHelper::getAppToken()), - 'GET', - '/debug_token', - $params - ))->execute()->getGraphObject(GraphSessionInfo::className()); - $this->assertTrue($response instanceof GraphSessionInfo); - $this->assertNotNull($response->getAppId()); - $this->assertTrue($response->isValid()); + $data = [ + 'expires_at' => 123, + 'issued_at' => 1337, + ]; + $graphObject = new GraphSessionInfo($data); + + $expires = $graphObject->getExpiresAt(); + $issuedAt = $graphObject->getIssuedAt(); + + $this->assertInstanceOf('DateTime', $expires); + $this->assertInstanceOf('DateTime', $issuedAt); + } + + public function testScopesAreReturnedAsArray() + { + $data = [ + 'scopes' => ['foo', 'bar'], + ]; + $graphObject = new GraphSessionInfo($data); + + $scopes = $graphObject->getScopes(); + + $this->assertEquals(['foo', 'bar'], $scopes); } } diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index f12ba619c..fc3974687 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -23,29 +23,36 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphUser; -use Facebook\Tests\FacebookTestHelper; class GraphUserTest extends \PHPUnit_Framework_TestCase { - public function testMeReturnsGraphUser() + public function testDatesGetCastToDateTime() { - $response = ( - new FacebookRequest( - FacebookTestHelper::$testSession, - 'GET', - '/me' - ))->execute()->getGraphObject(GraphUser::className()); - - $info = FacebookTestHelper::$testSession->getSessionInfo(); - - $this->assertTrue($response instanceof GraphUser); - $this->assertEquals($info->getId(), $response->getId()); - $this->assertNotNull($response->getName()); - $this->assertNotNull($response->getLastName()); - $this->assertNotNull($response->getLink()); + $data = [ + 'birthday' => '1984-01-01', + ]; + $graphObject = new GraphUser($data); + + $birthday = $graphObject->getBirthday(); + + $this->assertInstanceOf('DateTime', $birthday); + } + + public function testLocationGetsCastAsLocationObject() + { + $data = [ + 'location' => [ + 'id' => '123', + 'name' => 'Bar', + ], + ]; + $graphObject = new GraphUser($data); + + $location = $graphObject->getLocation(); + + $this->assertInstanceOf('Facebook\GraphNodes\GraphLocation', $location); } } diff --git a/tests/Helpers/FacebookCanvasLoginHelperTest.php b/tests/Helpers/FacebookCanvasLoginHelperTest.php index 2445f4996..90ad7579b 100644 --- a/tests/Helpers/FacebookCanvasLoginHelperTest.php +++ b/tests/Helpers/FacebookCanvasLoginHelperTest.php @@ -23,17 +23,23 @@ */ namespace Facebook\Tests\Helpers; +use Facebook\Entities\FacebookApp; use Facebook\Helpers\FacebookCanvasLoginHelper; class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase { public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + + /** + * @var FacebookCanvasLoginHelper + */ protected $helper; public function setUp() { - $this->helper = new FacebookCanvasLoginHelper('123', 'foo_app_secret'); + $app = new FacebookApp('123', 'foo_app_secret'); + $this->helper = new FacebookCanvasLoginHelper($app); } public function testSignedRequestDataCanBeRetrievedFromPostData() diff --git a/tests/Helpers/FacebookJavaScriptLoginHelperTest.php b/tests/Helpers/FacebookJavaScriptLoginHelperTest.php index 0928d8cb8..2663e80c9 100644 --- a/tests/Helpers/FacebookJavaScriptLoginHelperTest.php +++ b/tests/Helpers/FacebookJavaScriptLoginHelperTest.php @@ -23,20 +23,20 @@ */ namespace Facebook\Tests\Helpers; +use Facebook\Entities\FacebookApp; use Facebook\Helpers\FacebookJavaScriptLoginHelper; class FacebookJavaScriptLoginHelperTest extends \PHPUnit_Framework_TestCase { - public $appId = '123'; - public $appSecret = 'foo_app_secret'; public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; public function testARawSignedRequestCanBeRetrievedFromCookieData() { $_COOKIE['fbsr_123'] = $this->rawSignedRequestAuthorized; - $helper = new FacebookJavaScriptLoginHelper($this->appId, $this->appSecret); + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookJavaScriptLoginHelper($app); $rawSignedRequest = $helper->getRawSignedRequest(); diff --git a/tests/Helpers/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php index 9a7d9a6c4..9133d9f21 100644 --- a/tests/Helpers/FacebookPageTabHelperTest.php +++ b/tests/Helpers/FacebookPageTabHelperTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\Helpers; +use Facebook\Entities\FacebookApp; use Facebook\Helpers\FacebookPageTabHelper; class FacebookPageTabHelperTest extends \PHPUnit_Framework_TestCase @@ -32,8 +33,10 @@ class FacebookPageTabHelperTest extends \PHPUnit_Framework_TestCase public function testPageDataCanBeAccessed() { - $_GET['signed_request'] = $this->rawSignedRequestAuthorized; - $helper = new FacebookPageTabHelper('123', 'foo_app_secret'); + $_POST['signed_request'] = $this->rawSignedRequestAuthorized; + + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookPageTabHelper($app); $this->assertTrue($helper->isLiked()); $this->assertFalse($helper->isAdmin()); diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index ecd053a70..76cf28d57 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -23,10 +23,10 @@ */ namespace Facebook\Tests\Helpers; -use Facebook\Tests\FacebookTestCredentials; +use Mockery as m; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Helpers\FacebookRedirectLoginHelper; -use Facebook\FacebookRequest; -use Facebook\Tests\FacebookTestHelper; class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase { @@ -35,22 +35,23 @@ class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase public function testLoginURL() { - $helper = new FacebookRedirectLoginHelper( - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookRedirectLoginHelper($app); $helper->disableSessionStatusCheck(); - $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); - $state = $_SESSION['FBRLH_state']; - $params = array( - 'client_id' => FacebookTestCredentials::$appId, + + $scope = ['foo','bar']; + $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL, $scope, true, 'v1337'); + + $expectedUrl = 'https://www.facebook.com/v1337/dialog/oauth?'; + $this->assertTrue(strpos($loginUrl, $expectedUrl) === 0, 'Unexpected base login URL returned from getLoginUrl().'); + + $params = [ + 'client_id' => '123', 'redirect_uri' => self::REDIRECT_URL, - 'state' => $state, + 'state' => $_SESSION['FBRLH_state'], 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, - 'scope' => implode(',', array()) - ); - $expectedUrl = 'https://www.facebook.com/v2.0/dialog/oauth?'; - $this->assertTrue(strpos($loginUrl, $expectedUrl) !== false); + 'scope' => implode(',', $scope), + ]; foreach ($params as $key => $value) { $this->assertTrue( strpos($loginUrl, $key . '=' . urlencode($value)) !== false @@ -60,36 +61,63 @@ public function testLoginURL() public function testLogoutURL() { - $helper = new FacebookRedirectLoginHelper( - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookRedirectLoginHelper($app); $helper->disableSessionStatusCheck(); - $logoutUrl = $helper->getLogoutUrl( - FacebookTestHelper::$testSession, self::REDIRECT_URL - ); - $params = array( - 'next' => self::REDIRECT_URL, - 'access_token' => FacebookTestHelper::$testSession->getToken() - ); + + $logoutUrl = $helper->getLogoutUrl('foo_token', self::REDIRECT_URL); $expectedUrl = 'https://www.facebook.com/logout.php?'; - $this->assertTrue(strpos($logoutUrl, $expectedUrl) !== false); + $this->assertTrue(strpos($logoutUrl, $expectedUrl) === 0, 'Unexpected base logout URL returned from getLogoutUrl().'); + + $params = [ + 'next' => self::REDIRECT_URL, + 'access_token' => 'foo_token', + ]; foreach ($params as $key => $value) { $this->assertTrue( strpos($logoutUrl, $key . '=' . urlencode($value)) !== false ); } } + + public function testAnAccessTokenCanBeObtainedFromRedirect() + { + $_SESSION['FBRLH_state'] = 'foo_state'; + $_GET['state'] = 'foo_state'; + $_GET['code'] = 'foo_code'; + + $response = m::mock('Facebook\Entities\FacebookResponse'); + $response + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'access_token' => 'access_token_from_code', + 'expires' => 555, + ]); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); + + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookRedirectLoginHelper($app); + $helper->disableSessionStatusCheck(); + + $accessToken = $helper->getAccessTokenFromRedirect($client, self::REDIRECT_URL); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('access_token_from_code', (string) $accessToken); + } /** * @dataProvider provideUris */ - public function testGetFilterdUriRemoveFacebookQueryParams($uri, $expected) + public function testGetFilteredUriRemoveFacebookQueryParams($uri, $expected) { - $helper = new FacebookRedirectLoginHelper( - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookRedirectLoginHelper($app); $helper->disableSessionStatusCheck(); $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); @@ -102,40 +130,38 @@ public function testGetFilterdUriRemoveFacebookQueryParams($uri, $expected) public function provideUris() { - return array( - array( + return [ + [ 'http://localhost/something?state=0000&foo=bar&code=abcd', 'http://localhost/something?foo=bar', - ), - array( + ], + [ 'https://localhost/something?state=0000&foo=bar&code=abcd', 'https://localhost/something?foo=bar', - ), - array( + ], + [ 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', 'http://localhost/something?foo=bar', - ), - array( + ], + [ 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', 'https://localhost/something?foo=bar', - ), - array( + ], + [ 'http://localhost/something?state=0000&foo=bar&error=abcd', 'http://localhost/something?state=0000&foo=bar&error=abcd', - ), - array( + ], + [ 'https://localhost/something?state=0000&foo=bar&error=abcd', 'https://localhost/something?state=0000&foo=bar&error=abcd', - ), - ); + ], + ]; } public function testCSPRNG() { - $helper = new FacebookRedirectLoginHelper( - FacebookTestCredentials::$appId, - FacebookTestCredentials::$appSecret - ); + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookRedirectLoginHelper($app); $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); $method = $class->getMethod('random'); diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index d850731d0..f3f2970d9 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -23,6 +23,8 @@ */ namespace Facebook\Tests\Helpers; +use Mockery as m; +use Facebook\Entities\FacebookApp; use Facebook\Helpers\FacebookSignedRequestFromInputHelper; class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper { @@ -34,13 +36,19 @@ public function getRawSignedRequest() { class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCase { + /** + * @var FooSignedRequestHelper + */ protected $helper; - public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + + public $rawSignedRequestAuthorizedWithAccessToken = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; public $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; public function setUp() { - $this->helper = new FooSignedRequestHelper('123', 'foo_app_secret'); + $app = new FacebookApp('123', 'foo_app_secret'); + $this->helper = new FooSignedRequestHelper($app); } public function testSignedRequestDataCanBeRetrievedFromGetData() @@ -70,21 +78,55 @@ public function testSignedRequestDataCanBeRetrievedFromCookieData() $this->assertEquals('foo_signed_request', $rawSignedRequest); } - public function testSessionWillBeNullWhenAUserHasNotYetAuthorizedTheApp() + public function testAccessTokenWillBeNullWhenAUserHasNotYetAuthorizedTheApp() { + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->never(); + $this->helper->instantiateSignedRequest($this->rawSignedRequestUnauthorized); - $session = $this->helper->getSession(); + $accessToken = $this->helper->getAccessToken($client); - $this->assertNull($session); + $this->assertNull($accessToken); } - public function testAFacebookSessionCanBeInstantiatedWhenAUserHasAuthorizedTheApp() + public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessToken() { - $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorized); - $session = $this->helper->getSession(); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->never(); + + $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); + $accessToken = $this->helper->getAccessToken($client); - $this->assertInstanceOf('Facebook\FacebookSession', $session); - $this->assertEquals('foo_token', $session->getToken()); + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('foo_token', (string) $accessToken); + } + + public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() + { + $response = m::mock('Facebook\Entities\FacebookResponse'); + $response + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'access_token' => 'access_token_from_code', + 'expires' => 555, + ]); + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); + + $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); + $accessToken = $this->helper->getAccessToken($client); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('access_token_from_code', (string) $accessToken); } } diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 54f85fd6d..3b4b9b5a1 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -23,16 +23,20 @@ */ namespace Facebook\Tests\HttpClients; -require_once __DIR__ . '/AbstractTestHttpClient.php'; - use Mockery as m; -use Facebook\Tests\HttpClients\AbstractTestHttpClient; use Facebook\HttpClients\FacebookCurlHttpClient; class FacebookCurlHttpClientTest extends AbstractTestHttpClient { + /** + * @var \Facebook\HttpClients\FacebookCurl + */ protected $curlMock; + + /** + * @var FacebookCurlHttpClient + */ protected $curlClient; const CURL_VERSION_STABLE = 0x072400; @@ -67,7 +71,7 @@ public function testCanOpenGetCurlConnection() ->once() ->andReturn(null); - $this->curlClient->openConnection('http://foo.com', 'GET', array()); + $this->curlClient->openConnection('http://foo.com', 'GET', [], []); } public function testCanOpenGetCurlConnectionWithHeaders() @@ -78,21 +82,18 @@ public function testCanOpenGetCurlConnectionWithHeaders() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with(array( + ->with([ CURLOPT_URL => 'http://foo.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, - CURLOPT_HTTPHEADER => array( - 'X-foo: bar', - ), - )) + CURLOPT_HTTPHEADER => ['X-foo: bar'], + ]) ->once() ->andReturn(null); - $this->curlClient->addRequestHeader('X-foo', 'bar'); - $this->curlClient->openConnection('http://foo.com', 'GET', array()); + $this->curlClient->openConnection('http://foo.com', 'GET', [], ['X-foo' => 'bar']); } public function testCanOpenPostCurlConnection() @@ -116,7 +117,7 @@ public function testCanOpenPostCurlConnection() ->once() ->andReturn(null); - $this->curlClient->openConnection('http://bar.com', 'POST', array('baz' => 'bar')); + $this->curlClient->openConnection('http://bar.com', 'POST', ['baz' => 'bar'], []); } public function testCanOpenPutCurlConnection() @@ -141,7 +142,7 @@ public function testCanOpenPutCurlConnection() ->once() ->andReturn(null); - $this->curlClient->openConnection('http://baz.com', 'PUT', array('baz' => 'bar')); + $this->curlClient->openConnection('http://baz.com', 'PUT', ['baz' => 'bar'], []); } public function testCanOpenDeleteCurlConnection() @@ -166,7 +167,7 @@ public function testCanOpenDeleteCurlConnection() ->once() ->andReturn(null); - $this->curlClient->openConnection('http://faz.com', 'DELETE', array('baz' => 'bar')); + $this->curlClient->openConnection('http://faz.com', 'DELETE', ['baz' => 'bar'], []); } public function testCanAddBundledCert() @@ -215,23 +216,12 @@ public function testTrySendRequest() public function testProperlyCompilesRequestHeaders() { - $headers = $this->curlClient->compileRequestHeaders(); - $expectedHeaders = array(); - $this->assertEquals($expectedHeaders, $headers); - - $this->curlClient->addRequestHeader('X-foo', 'bar'); - $headers = $this->curlClient->compileRequestHeaders(); - $expectedHeaders = array( - 'X-foo: bar', - ); + $headers = $this->curlClient->compileRequestHeaders([]); + $expectedHeaders = []; $this->assertEquals($expectedHeaders, $headers); - $this->curlClient->addRequestHeader('X-bar', 'baz'); - $headers = $this->curlClient->compileRequestHeaders(); - $expectedHeaders = array( - 'X-foo: bar', - 'X-bar: baz', - ); + $headers = $this->curlClient->compileRequestHeaders(['X-foo' => 'bar']); + $expectedHeaders = ['X-foo: bar']; $this->assertEquals($expectedHeaders, $headers); } diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index 7c82f0f94..0b5750505 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -23,16 +23,20 @@ */ namespace Facebook\Tests\HttpClients; -require_once __DIR__ . '/AbstractTestHttpClient.php'; - use Mockery as m; -use Facebook\Tests\HttpClients\AbstractTestHttpClient; use Facebook\HttpClients\FacebookGuzzleHttpClient; class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient { + /** + * @var \GuzzleHttp\Client + */ protected $guzzleMock; + + /** + * @var FacebookGuzzleHttpClient + */ protected $guzzleClient; public function setUp() @@ -72,7 +76,7 @@ public function testCanSendNormalRequest() $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', array()) + ->with('GET', 'http://foo.com/', []) ->andReturn($requestMock); $this->guzzleMock ->shouldReceive('send') @@ -80,8 +84,7 @@ public function testCanSendNormalRequest() ->with($requestMock) ->andReturn($responseMock); - $this->guzzleClient->addRequestHeader('X-foo', 'bar'); - $responseBody = $this->guzzleClient->send('http://foo.com/'); + $responseBody = $this->guzzleClient->send('http://foo.com/', 'GET', [], ['X-foo' => 'bar']); $this->assertEquals($responseBody, $this->fakeRawBody); $this->assertEquals($this->guzzleClient->getResponseHeaders(), $this->fakeHeadersAsArray); @@ -106,7 +109,7 @@ public function testThrowsExceptionOnClientError() $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', array()) + ->with('GET', 'http://foo.com/', []) ->andReturn($requestMock); $this->guzzleMock ->shouldReceive('send') diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index a320a4b75..f47b41b43 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -23,16 +23,20 @@ */ namespace Facebook\Tests\HttpClients; -require_once __DIR__ . '/AbstractTestHttpClient.php'; - use Mockery as m; -use Facebook\Tests\HttpClients\AbstractTestHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; class FacebookStreamHttpClientTest extends AbstractTestHttpClient { + /** + * @var \Facebook\HttpClients\FacebookStream + */ protected $streamMock; + + /** + * @var FacebookStreamHttpClient + */ protected $streamClient; public function setUp() @@ -48,9 +52,11 @@ public function tearDown() public function testCanCompileHeader() { - $this->streamClient->addRequestHeader('X-foo', 'bar'); - $this->streamClient->addRequestHeader('X-bar', 'faz'); - $header = $this->streamClient->compileHeader(); + $headers = [ + 'X-foo' => 'bar', + 'X-bar' => 'faz', + ]; + $header = $this->streamClient->compileHeader($headers); $this->assertEquals("X-foo: bar\r\nX-bar: faz", $header); } @@ -107,8 +113,7 @@ public function testCanSendNormalRequest() ->with('http://foo.com/') ->andReturn($this->fakeRawBody); - $this->streamClient->addRequestHeader('X-foo', 'bar'); - $responseBody = $this->streamClient->send('http://foo.com/'); + $responseBody = $this->streamClient->send('http://foo.com/', 'GET', [], ['X-foo' => 'bar']); $this->assertEquals($responseBody, $this->fakeRawBody); $this->assertEquals($this->streamClient->getResponseHeaders(), $this->fakeHeadersAsArray); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c33fe29f2..d32858641 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -23,32 +23,10 @@ */ require_once __DIR__ . '/../vendor/autoload.php'; -use Facebook\Exceptions\FacebookSDKException; -use Facebook\Tests\FacebookTestHelper; - -if (!file_exists(__DIR__ . '/FacebookTestCredentials.php')) { - throw new FacebookSDKException( - 'You must create a FacebookTestCredentials.php file from FacebookTestCredentials.php.dist' - ); -} - -// Uncomment two lines to force functional test curl implementation -//use Facebook\HttpClients\FacebookCurlHttpClient; -//FacebookRequest::setHttpClientHandler(new FacebookCurlHttpClient()); - -// Uncomment two lines to force functional test stream wrapper implementation -//use Facebook\HttpClients\FacebookStreamHttpClient; -//FacebookRequest::setHttpClientHandler(new FacebookStreamHttpClient()); - -// Uncomment two lines to force functional test Guzzle implementation -//use Facebook\HttpClients\FacebookGuzzleHttpClient; -//FacebookRequest::setHttpClientHandler(new FacebookGuzzleHttpClient()); - -// Create a temp test user to use for testing -FacebookTestHelper::initialize(); +use Facebook\FacebookClient; // Delete the temp test user after all tests have fired register_shutdown_function(function () { - FacebookTestHelper::deleteTestUser(); + //echo "\nTotal requests made to Graph: " . FacebookClient::$requestCount . "\n\n"; }); From 0cbd11cc5ca856536a9aaa90a10c2ed832210776 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sat, 23 Aug 2014 22:34:55 -0500 Subject: [PATCH 037/407] Started to update docs to 4.1 syntax --- README.md | 47 ++-- docs/FacebookCanvasLoginHelper.fbmd | 105 +++++++-- docs/FacebookJavaScriptLoginHelper.fbmd | 6 +- docs/FacebookPageTabHelper.fbmd | 9 + docs/FacebookRedirectLoginHelper.fbmd | 10 +- docs/FacebookRequest.fbmd | 4 +- docs/FacebookRequestException.fbmd | 8 +- docs/FacebookResponse.fbmd | 2 +- docs/FacebookSession.fbmd | 2 +- docs/post_links.fbmd | 6 +- docs/retrieve_user_profile.fbmd | 6 +- docs/sdk_downloads.fbmd | 70 ++++++ docs/sdk_getting_started.fbmd | 284 ++++++++++++++++++------ docs/sdk_landing_page.fbmd | 28 +-- docs/sdk_reference.fbmd | 213 ++++++++++++++++++ docs/upload_photo.fbmd | 6 +- 16 files changed, 648 insertions(+), 158 deletions(-) create mode 100644 docs/FacebookPageTabHelper.fbmd create mode 100644 docs/sdk_downloads.fbmd create mode 100644 docs/sdk_reference.fbmd diff --git a/README.md b/README.md index d1f071587..f3b7f43b1 100644 --- a/README.md +++ b/README.md @@ -11,38 +11,41 @@ Platform from your PHP app. Usage ----- -This version of the Facebook SDK for PHP requires PHP 5.4 or greater. +> **Note:** This version of the Facebook SDK for PHP requires PHP 5.4 or greater. -Minimal example: +Simple GET example of a user's profile. ```php -use Facebook\FacebookSession; -use Facebook\FacebookRequest; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\FacebookClient; use Facebook\GraphNodes\GraphUser; -use Facebook\Exceptions\FacebookRequestException; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; -FacebookSession::setDefaultApplication('YOUR_APP_ID','YOUR_APP_SECRET'); +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); -// Use one of the helper classes to get a FacebookSession object. -// FacebookRedirectLoginHelper -// FacebookCanvasLoginHelper -// FacebookJavaScriptLoginHelper -// or create a FacebookSession with a valid access token: -$session = new FacebookSession('access-token-here'); +// Use one of the helper classes to get a Facebook\Entities\AccessToken entity. +// Facebook\Helpers\FacebookRedirectLoginHelper +// Facebook\Helpers\FacebookJavaScriptLoginHelper +// Facebook\Helpers\FacebookCanvasLoginHelper +// Facebook\Helpers\FacebookPageTabHelper -// Get the GraphUser object for the current user: +// Get the Facebook\GraphNodes\GraphUser object for the current user: +$facebookClient = new FacebookClient(); +$request = new FacebookRequest($facebookApp, '{access-token}', 'GET', '/me'); try { - $me = (new FacebookRequest( - $session, 'GET', '/me' - ))->execute()->getGraphObject(GraphUser::className()); - echo $me->getName(); -} catch (FacebookRequestException $e) { - // The Graph API returned an error -} catch (\Exception $e) { - // Some other error occurred + $facebookResponse = $facebookClient->sendRequest($request); + $me = $facebookResponse->getGraphObject(GraphUser::className()); + echo 'Logged in as ' . $me->getName(); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { + // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); } - ``` Complete documentation, installation instructions, and examples are available at: diff --git a/docs/FacebookCanvasLoginHelper.fbmd b/docs/FacebookCanvasLoginHelper.fbmd index c3e64c76d..27fbba7e9 100644 --- a/docs/FacebookCanvasLoginHelper.fbmd +++ b/docs/FacebookCanvasLoginHelper.fbmd @@ -1,37 +1,106 @@ -# FacebookCanvasLoginHelper for the Facebook SDK for PHP +# Facebook\Helpers\FacebookCanvasLoginHelper -A helper class for getting a FacebookSession in a Canvas app +The `FacebookCanvasLoginHelper` 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). + +~~~ +Facebook\Helpers\FacebookCanvasLoginHelper( Facebook\Entities\FacebookApp $facebookApp ) +~~~ -## Facebook\FacebookCanvasLoginHelper {#overview} +## Usage {#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. + +~~~ +use Facebook\Entities\FacebookApp; +use Facebook\Helpers\FacebookCanvasLoginHelper; + +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); + +$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); +$signedRequest = $canvasHelper->getSignedRequest(); + +if ($signedRequest) { + $payload = $signedRequest->getPayload(); + var_dump($payload); +} +~~~ -If your app is loaded through Canvas, Facebook sends a POST request with a signed request. This helper class will handle processing and validating that information with Facebook, and returns a `FacebookSession`. +If a user has already authenticated your app, you can also obtain an access token. -Usage: +~~~ +use Facebook\Entities\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookCanvasLoginHelper; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; -~~~~ +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); -$helper = new FacebookCanvasLoginHelper(); +$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); + +$facebookClient = new FacebookClient(); +$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); try { - $session = $helper->getSession(); -} catch (FacebookRequestException $ex) { - // When Facebook returns an error -} catch (\Exception $ex) { - // When validation fails or other local issues + $accessToken = $canvasHelper->getAccessToken($facebookClient); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { + // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); } -if ($session) { + +if (isset($accessToken)) { // Logged in. } - -~~~~ +~~~ ## Instance Methods {#instance-methods} -### getSession {#getsession} -`getSession()` -Processes the POST request from Facebook, if present. Returns a `FacebookSession` or `null`. +`getAccessToken()` +Checks the signed request for authentication data and tries to obtain an access token access token. + +~~~ +public getAccessToken( Facebook\FacebookClient $client ) +~~~ + +Returns a `Facebook\Entities\AccessToken` entity or `null`. + + + +`getAppData()` +Gets what ever value is set in the `app_data` property if present. + +~~~ +public getAppData( void ) +~~~ + +Returns the `app_data` value or `null`. + + + +`getSignedRequest()` +Validates and decrypts the signed request that was sent via POST if present. + +~~~ +public getSignedRequest( void ) +~~~ + +Returns a `Facebook\Entities\SignedRequest` entity or `null`. + + + +`getRawSignedRequest()` +Gets the raw, unencrypted signed request that was sent via POST if present. + +~~~ +public getRawSignedRequest( void ) +~~~ + +Returns a an encrypted signed request `string` or `null`. \ No newline at end of file diff --git a/docs/FacebookJavaScriptLoginHelper.fbmd b/docs/FacebookJavaScriptLoginHelper.fbmd index e63499802..5bda7fbaf 100644 --- a/docs/FacebookJavaScriptLoginHelper.fbmd +++ b/docs/FacebookJavaScriptLoginHelper.fbmd @@ -1,7 +1,7 @@ -# FacebookJavaScriptLoginHelper for the Facebook SDK for PHP +# Facebook\Helpers\FacebookJavaScriptHelper -A helper class for getting a FacebookSession using the session from the Facebook SDK for JavaScript. +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. @@ -16,7 +16,7 @@ Usage: $helper = new FacebookJavaScriptLoginHelper(); try { $session = $helper->getSession(); -} catch(FacebookRequestException $ex) { +} catch(FacebookResponseException $ex) { // When Facebook returns an error } catch(\Exception $ex) { // When validation fails or other local issues diff --git a/docs/FacebookPageTabHelper.fbmd b/docs/FacebookPageTabHelper.fbmd new file mode 100644 index 000000000..0b5d6cdfe --- /dev/null +++ b/docs/FacebookPageTabHelper.fbmd @@ -0,0 +1,9 @@ + +# 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 {#usage} + diff --git a/docs/FacebookRedirectLoginHelper.fbmd b/docs/FacebookRedirectLoginHelper.fbmd index 35124be14..115ef8b3a 100644 --- a/docs/FacebookRedirectLoginHelper.fbmd +++ b/docs/FacebookRedirectLoginHelper.fbmd @@ -1,18 +1,16 @@ -# FacebookRedirectLoginHelper for the Facebook SDK for PHP +# Facebook\Helpers\FacebookRedirectLoginHelper -A helper class for getting a FacebookSession using the OAuth protocol. +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. -## Facebook\FacebookRedirectLoginHelper {#overview} +## Usage {#usage} If your web app uses Facebook Login on the back-end, you'll need to redirect your visitors to a URL at Facebook to initiate a login request. Facebook then redirects the user to your apps callback URL, providing session data. This helper class will generate the login URL for you, and can process and validate the data from Facebook, returning a `FacebookSession` on success. This class can be extended, and the `storeState($state)` and `loadState()` methods overridden, to store the state check using another method besides the default `$_SESSION`. -Usage: - ~~~~ $helper = new FacebookRedirectLoginHelper($redirect_url, $appId = NULL, $appSecret = NULL); @@ -27,7 +25,7 @@ Then, in your callback page (at the redirect url) when Facebook sends the user b $helper = new FacebookRedirectLoginHelper($redirect_url); try { $session = $helper->getSessionFromRedirect(); -} catch(FacebookRequestException $ex) { +} catch(FacebookResponseException $ex) { // When Facebook returns an error } catch(\Exception $ex) { // When validation fails or other local issues diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index 30ef9c995..8eea7db5e 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -27,7 +27,7 @@ try { $response = (new FacebookRequest($session, 'GET', '/me'))->execute(); $object = $response->getGraphObject(); echo $object->getProperty('name'); -} catch (FacebookRequestException $ex) { +} catch (FacebookResponseException $ex) { echo $ex->getMessage(); } catch (\Exception $ex) { echo $ex->getMessage(); @@ -46,7 +46,7 @@ echo $me->getName(); ### execute {#execute} `execute()` -Returns a `Facebook\FacebookResponse` from this request, from which a strongly-typed result can be retrieved. Throws an exception if the request fails. If the error is returned from Facebook, as opposed to a networking issue, a `Facebook\FacebookRequestException` is thrown. +Returns a `Facebook\FacebookResponse` from this request, from which a strongly-typed result can be retrieved. Throws an exception if the request fails. If the error is returned from Facebook, as opposed to a networking issue, a `Facebook\FacebookResponseException` is thrown. ### getPath {#getpath} `getPath()` Returns a copy of the path for the request, not including the version. diff --git a/docs/FacebookRequestException.fbmd b/docs/FacebookRequestException.fbmd index e9257c345..43e535e26 100644 --- a/docs/FacebookRequestException.fbmd +++ b/docs/FacebookRequestException.fbmd @@ -1,11 +1,11 @@ -# FacebookRequestException for the Facebook SDK for PHP +# FacebookResponseException for the Facebook SDK for PHP Represents an exception thrown by executing a Facebook request. -## Facebook\FacebookRequestException {#overview} +## Facebook\FacebookResponseException {#overview} This base class has several subclasses: @@ -16,14 +16,14 @@ This base class has several subclasses: `FacebookThrottleException` `FacebookOtherException` -Whenever a FacebookRequestException is thrown, it will be one of these types. +Whenever a FacebookResponseException is thrown, it will be one of these types. They are derived from the error information here: https://developers.facebook.com/docs/graph-api/using-graph-api/#errors ## Instance Methods {#instance-methods} -`FacebookRequestException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. +`FacebookResponseException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. ### getHttpStatusCode {#gethttpstatus} `getHttpStatusCode()` diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index c3f9d61cf..4e1cef9d7 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -22,7 +22,7 @@ try { // If this response has multiple pages, you can get a request for the next or previous pages: $nextPageRequest = $response->getRequestForNextPage(); $previousPageRequest = $response->getRequestForPreviousPage(); -} catch (FacebookRequestException $ex) { +} catch (FacebookResponseException $ex) { echo $ex->getMessage(); } catch (\Exception $ex) { echo $ex->getMessage(); diff --git a/docs/FacebookSession.fbmd b/docs/FacebookSession.fbmd index 9378c66c1..8de267e74 100644 --- a/docs/FacebookSession.fbmd +++ b/docs/FacebookSession.fbmd @@ -23,7 +23,7 @@ $session = FacebookSession::newAppSession(); // To validate the session: try { $session->validate(); -} catch (FacebookRequestException $ex) { +} catch (FacebookResponseException $ex) { // Session not valid, Graph API returned an exception with the reason. echo $ex->getMessage(); } catch (\Exception $ex) { diff --git a/docs/post_links.fbmd b/docs/post_links.fbmd index a4866f560..7271e5024 100644 --- a/docs/post_links.fbmd +++ b/docs/post_links.fbmd @@ -5,7 +5,7 @@ This example covers posting a link to the current user's timeline using the Grap It assumes that you've already set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). You must have requested the `publish_actions` scope when logging in the user for this to work. -For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookRequestException`](/docs/php/FacebookRequestException). +For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookResponseException`](/docs/php/FacebookResponseException). @@ -14,7 +14,7 @@ For more information, see the documentation for [`GraphObject`](/docs/php/GraphO ~~~~ use Facebook\FacebookRequest; use Facebook\GraphObject; -use Facebook\FacebookRequestException; +use Facebook\FacebookResponseException; if($session) { @@ -29,7 +29,7 @@ if($session) { echo "Posted with id: " . $response->getProperty('id'); - } catch(FacebookRequestException $e) { + } catch(FacebookResponseException $e) { echo "Exception occured, code: " . $e->getCode(); echo " with message: " . $e->getMessage(); diff --git a/docs/retrieve_user_profile.fbmd b/docs/retrieve_user_profile.fbmd index 83393d260..b94cce047 100644 --- a/docs/retrieve_user_profile.fbmd +++ b/docs/retrieve_user_profile.fbmd @@ -5,7 +5,7 @@ This example covers getting profile information for the current user and printin It assumes that you've already set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). -For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`GraphUser`](/docs/php/GraphObject/#user-instance-methods), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookRequestException`](/docs/php/FacebookRequestException). +For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`GraphUser`](/docs/php/GraphObject/#user-instance-methods), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookResponseException`](/docs/php/FacebookResponseException). @@ -14,7 +14,7 @@ For more information, see the documentation for [`GraphObject`](/docs/php/GraphO ~~~~ use Facebook\FacebookRequest; use Facebook\GraphUser; -use Facebook\FacebookRequestException; +use Facebook\FacebookResponseException; if($session) { @@ -26,7 +26,7 @@ if($session) { echo "Name: " . $user_profile->getName(); - } catch(FacebookRequestException $e) { + } catch(FacebookResponseException $e) { echo "Exception occured, code: " . $e->getCode(); echo " with message: " . $e->getMessage(); diff --git a/docs/sdk_downloads.fbmd b/docs/sdk_downloads.fbmd new file mode 100644 index 000000000..80676122d --- /dev/null +++ b/docs/sdk_downloads.fbmd @@ -0,0 +1,70 @@ + +# Downloads for the Facebook SDK 4.x for PHP + +FB(devsite:markdown-wiki:table { + columns: ['Package','Date','Change Log',], + rows: [ + [ + '[Facebook SDK 4.1.0](https://github.com/facebook/facebook-php-sdk-v4/archive/4.1.0.zip)', + 'TBD', + '', + ], + [ + '[Facebook SDK 4.0.10](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.10.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.9](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.9.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.8](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.8.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.7](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.7.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.6](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.6.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.5](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.5.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.4](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.4.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.3](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.3.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.2](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.2.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.1](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.1.zip)', + '', + '', + ], + [ + '[Facebook SDK 4.0.0](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.0.zip)', + 'April 30, 2014', + '', + ], + ], +}) + + diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index e31c55970..1267df0bd 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -5,131 +5,281 @@ The Facebook SDK for PHP provides developers with a modern, native library for a -## Download the SDK {#download} +## Autoloading & namespaces {#psr-4} -%FB(devsite:markdown-wiki:info-card { - content: "The Facebook SDK for PHP v4 requires PHP 5.4 or greater.", - type: 'warning', -}) +The Facebook PHP SDK v4.x 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 {#requirements} + +- PHP 5.4 or greater +- The [mbstring](http://php.net/manual/en/book.mbstring.php) extension +- [Composer](https://getcomposer.org/) *(optional)* + + + +## Installing the Facebook SDK for PHP {#installation} + +There are two methods to install the Facebook PHP SDK. The preferred method is with [Composer](https://getcomposer.org/). If are unable to use Composer for your project, you can still install the SDK manually by downloading the source files and including the autoloader. + + + +## Installation Method 1 (recommended) {#composer} -If you're using [Composer](https://getcomposer.org/) as a package manager for PHP, which we recommend, installing the SDK is as easy as adding a require entry for the Facebook SDK for PHP to the composer.json file in the root of your project: +### Installing with Composer -~~~~ +[Composer](https://getcomposer.org/) is the recommended way to install the Facebook SDK for PHP. Simply add the following "require" entry to the `composer.json` file in the root of your project. + +~~~ { "require" : { - "facebook/php-sdk-v4" : "4.0.*" + "facebook/php-sdk-v4" : "~4.1" } } -~~~~ +~~~ -Then run composer with the install parameter, and it will download the newest version. If you're using the autoloader as part of Composer, the Facebook namespace will be available for use without adding require statements for all of the files. +Then run `composer install` from the command line, and composer will download the latest version of the SDK and put it in the `/vendor/` directory. -If you're not using Composer, you can download the SDK from our GitHub: +Make sure to include the Composer autoloader at the top of your script. + +~~~ +require_once __DIR__ . '/vendor/autoload.php'; +~~~ + + + +## Installation Method 2 (if you really have to) {#autoloader} + +### Manually installing with the autoloader + +First, download the source code and unzip it wherever you like in your project. %FB(devsite:markdown-wiki:button { - text: 'Download the PHP SDK', - href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/4.0-dev.zip', + text: 'Download the PHP SDK v4.1', + href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/4.1-dev.zip', size: 'large', use: 'special', }) + +Then include the autoloader provided in the SDK at the top of your script. + +~~~ +require_once __DIR__ . '/path/to/facebook-php-sdk-v4/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. + +%FB(devsite:markdown-wiki:info-card { + content: "For this example we'll assume the root of your website is `/var/html`.", + type: 'warning', +}) + +After downloading the source code with the button above, extract the files in a temporary directory. Find the file called `autoloader.php` and move it into the `src/Facebook` folder. + +Move the folder `src/Facebook` to the root of your website installation or where ever you like to put 3rd-party code. For this example we'll now rename the `Facebook` directory to `facebook-sdk-v4.1`. + +The path the the core SDK files should now be located in `/var/html/facebook-sdk-v4.1` and inside will also be the `autolaoder.php` file. + +Assuming we have a script called `index.php` in the root of our web project, we need to include the autoloader. But before we do, we need to define the new location of the source code before the `require_once` statement. We put his at the top of our script. + +~~~ +define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v4.1/'); +require_once __DIR__ . '/facebook-sdk-v4.1/autoload.php'; +~~~ -## Initializing {#init} +## Configuration and setup {#setup} -You will need to have configured a Facebook App, which you can obtain from the [App Dashboard](http://developers.facebook.com/apps). +%FB(devsite:markdown-wiki:info-card { + content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](http://developers.facebook.com/apps).", + type: 'warning', +}) + +### The `FacebookApp` entity + +Before we can send requests to the Graph API, we need to load our app configuration into a `Facebook\Entities\FacebookApp` entity. + +~~~ +use Facebook\Entities\FacebookApp; + +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +~~~ + +The `FacebookApp` entity is one of the core dependencies that we need to pass along to the other objects. + +### The `FacebookClient` service -Then, initialize the SDK with your app ID and secret: +In order to send requests to Graph we need to use the `Facebook\FacebookClient` service. ~~~ -FacebookSession::setDefaultApplication('YOUR_APP_ID', 'YOUR_APP_SECRET'); +use Facebook\FacebookClient; + +$facebookClient = new FacebookClient(); ~~~ ## Authentication and authorization {#authentication} -The SDK can be used to support login your site using a Facebook account. On the server-side, the SDK provides helper classes for the most common scenarios. +The SDK can be used to support logging into your site using a Facebook account. On the server-side, the SDK provides helper classes for the most common scenarios. + +Most all request made to the Graph API require an access token. We can obtain access tokens with the SDK using the [helper classes](/docs/php/reference#helpers). + +For most websites, you'll use the `[Facebook\Helpers\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper)` 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. -For most websites, you'll use the [FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper). Generate the login URL to redirect visitors to with the `getLoginUrl()` method, redirect them, and then process the response from Facebook with the `getSessionFromRedirect()` method, which returns a `FacebookSession`. +%FB(devsite:markdown-wiki:info-card { + content: "For this example we'll assume `login.php` will present the login link and the user will be redirect to `login-callback.php` where we will obtain the access token.", + type: 'warning', +}) + +~~~ +# login.php +use Facebook\Entities\FacebookApp; +use Facebook\Helpers\FacebookRedirectLoginHelper; + +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); + +$helper = new FacebookRedirectLoginHelper($facebookApp); +$permissions = ['email', 'user_likes']; // optional +$loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions); + +echo 'Log in with Facebook!'; +~~~ + +~~~ +# login-callback.php +use Facebook\Entities\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookRedirectLoginHelper; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; -~~~~ -$helper = new FacebookRedirectLoginHelper('your redirect URL here'); -$loginUrl = $helper->getLoginUrl(); -// Use the login url on a link or button to redirect to Facebook for authentication -~~~~ +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); -~~~~ +$facebookClient = new FacebookClient(); $helper = new FacebookRedirectLoginHelper(); try { - $session = $helper->getSessionFromRedirect(); -} catch(FacebookRequestException $ex) { - // When Facebook returns an error -} catch(\Exception $ex) { + $accessToken = $helper->getAccessTokenFromRedirect($facebookClient); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); } -if ($session) { + +if (isset($accessToken)) { // Logged in } -~~~~ +~~~ + +If your app is on Facebook Canvas, use the `getAccessToken()` method on [FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) to get an `Facebook\Entities\AccessToken` entity for the user. + +~~~ +use Facebook\Entities\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookCanvasLoginHelper; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; + +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); -If your app is on Facebook Canvas, use the `getSession()` method on [FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) to get a `FacebookSession` for the user. +$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); -~~~~ -$helper = new FacebookCanvasLoginHelper(); +$facebookClient = new FacebookClient(); +$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); try { - $session = $helper->getSession(); -} catch(FacebookRequestException $ex) { - // When Facebook returns an error -} catch(\Exception $ex) { + $accessToken = $canvasHelper->getAccessToken($facebookClient); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); } -if ($session) { - // Logged in + +if (isset($accessToken)) { + // Logged in. } -~~~~ +~~~ + +If you're already using the Facebook SDK for JavaScript to authenticate users, you can also log them in on the server side with the [FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper). The `getAccessToken()` method will return a `Facebook\Entities\AccessToken` entity. + +~~~ +use Facebook\Entities\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Helpers\FacebookJavaScriptLoginHelper; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; -If you're already using the Facebook SDK for JavaScript to authenticate users, you can also log them in on the server side with the [FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper). The `getSession()` method will return a `FacebookSession`. +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); -~~~~ -$helper = new FacebookJavaScriptLoginHelper(); +$facebookClient = new FacebookClient(); +$helper = new FacebookJavaScriptLoginHelper($facebookApp); try { - $session = $helper->getSession(); -} catch(FacebookRequestException $ex) { - // When Facebook returns an error -} catch(\Exception $ex) { + $accessToken = $helper->getAccessToken($facebookClient); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); } -if ($session) { + +if (isset($accessToken)) { // Logged in } -~~~~ +~~~ + +You can also create a `Facebook\Entities\AccessToken` entity with an access token you've acquired through some other means, by passing it to the constructor. -You can also create a `FacebookSession` with an access token you've acquired through some other means, by passing it to the constructor. +~~~ +use Facebook\Entities\AccessToken; -~~~~ -$session = new FacebookSession('access token here'); -~~~~ +$accessToken = new AccessToken('{access-token}'); +~~~ ## Making Requests to the Graph API {#making-requests} -Once you have a `FacebookSession` you can begin making calls to the Graph API with [FacebookRequest](/docs/php/FacebookRequest). +Once you have created a `Facebook\Entities\FacebookApp` entity, instantiated a `Facebook\FacebookClient` and obtained an access token, you can begin making calls to the Graph API with the [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) entity. -~~~~ -$request = new FacebookRequest($session, 'GET', '/me'); -$response = $request->execute(); -$graphObject = $response->getGraphObject(); -~~~~ +~~~ +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\FacebookClient; +use Facebook\GraphNodes\GraphUser; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; -You can also chain these methods: +$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); -~~~~ -$me = (new FacebookRequest( - $session, 'GET', '/me' -))->execute()->getGraphObject(GraphUser::className()); -~~~~ +// Get the Facebook\GraphNodes\GraphUser object for the current user: +$facebookClient = new FacebookClient(); +$request = new FacebookRequest($facebookApp, '{access-token}', 'GET', '/me'); + +try { + $facebookResponse = $facebookClient->sendRequest($request); + $me = $facebookResponse->getGraphObject(GraphUser::className()); + echo 'Logged in as ' . $me->getName(); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { + // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); +} +~~~ -For more details, see the examples and API reference for all of these classes listed on the [landing page for the Facebook SDK for PHP](/docs/reference/php). +For a full list of classes, see the [API reference page](/docs/php/reference). \ No newline at end of file diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd index f38aea86e..30ddc8f97 100644 --- a/docs/sdk_landing_page.fbmd +++ b/docs/sdk_landing_page.fbmd @@ -1,5 +1,5 @@ -# Facebook SDK for PHP +# Facebook SDK v4.1 for PHP The Facebook SDK for PHP provides developers with a modern, native library for accessing the Graph API and taking advantage of Facebook Login. Usually this means you're developing with PHP for a Facebook Canvas app, building your own website, or adding server-side functionality to an app that already uses the [Facebook SDK for JavaScript](/docs/reference/javascript/). @@ -16,30 +16,8 @@ Take a look through our guide, [Getting Started with the Facebook SDK for PHP](/ -## API Reference - Facebook namespace {#reference} +## API Reference {#reference} -[Facebook\FacebookSession](/docs/php/FacebookSession) -An access token backed session used when making requests against the Graph API. - -[Facebook\FacebookRequest](/docs/php/FacebookRequest) -Makes requests against the Graph API. - -[Facebook\FacebookResponse](/docs/php/FacebookResponse) -A successful response from the Graph API resulting from a FacebookRequest. - -[Facebook\FacebookRequestException](/docs/php/FacebookRequestException) -An error returned by the Graph API during a FacebookRequest. Subclasses: FacebookClientException, FacebookServerException, FacebookAuthorizationException, FacebookPermissionException, FacebookThrottleException, FacebookOtherException. - -[Facebook\GraphObject](/docs/php/GraphObject) -Represents an object returned by the Graph API. Subclasses: GraphUser, GraphLocation, GraphSessionInfo - -[Facebook\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper) -A helper class for getting a FacebookSession using the OAuth protocol. - -[Facebook\FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) -A helper class for getting a FacebookSession from Facebook Canvas. - -[Facebook\FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper) -A helper class for getting a FacebookSession from the Facebook SDK for JavaScript. +For a full list of classes, see the API [reference page](/docs/php/reference). \ No newline at end of file diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd new file mode 100644 index 000000000..1da96809f --- /dev/null +++ b/docs/sdk_reference.fbmd @@ -0,0 +1,213 @@ + +# Facebook SDK for PHP Reference (v4.1) + +Below is the API reference for the Facebook PHP SDK. + + + +# Services {#services} + +Services orchestrate multiple components of the SDK. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\FacebookClient](/docs/php/FacebookClient)`', + 'A service object to send requests and receive responses from the Graph API.', + ], + ], +}) + + + +# Entities {#entities} + +Entities are representations of "real-world things". + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\Entities\AccessToken](/docs/php/AccessToken)`', + 'An entity that represents an access token and is required to send requests to Graph.', + ], + [ + '`[Facebook\Entities\FacebookApp](/docs/php/FacebookApp)`', + 'An entity that represents a Facebook app and is required to send requests to Graph.', + ], + [ + '`[Facebook\Entities\FacebookBatchRequest](/docs/php/FacebookBatchRequest)`', + 'An entity that represents a batch request to be sent to Graph.', + ], + [ + '`[Facebook\Entities\FacebookBatchResponse](/docs/php/FacebookBatchResponse)`', + 'An entity that represents a response from Graph after sending a batch request.', + ], + [ + '`[Facebook\Entities\FacebookRequest](/docs/php/FacebookRequest)`', + 'An entity that represents a request to be sent to Graph.', + ], + [ + '`[Facebook\Entities\FacebookResponse](/docs/php/FacebookResponse)`', + 'An entity that represents a response from Graph.', + ], + [ + '`[Facebook\Entities\SignedRequest](/docs/php/SignedRequest)`', + 'An entity that represents a signed request.', + ], + ], +}) + + + +# Exceptions {#exeptions} + +When an error occurs, the SDK will throw an exception. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\Exceptions\FacebookAuthorizationException](/docs/php/FacebookAuthorizationException)`', + 'Thrown when Graph returns an authorization error.', + ], + [ + '`[Facebook\Exceptions\FacebookClientException](/docs/php/FacebookClientException)`', + 'Thrown when Graph returns a duplicate post error.', + ], + [ + '`[Facebook\Exceptions\FacebookOtherException](/docs/php/FacebookOtherException)`', + 'Thrown when Graph returns an error that is unknown to the SDK.', + ], + [ + '`[Facebook\Exceptions\FacebookPermissionException](/docs/php/FacebookPermissionException)`', + 'Thrown when Graph returns a user permissions error.', + ], + [ + '`[Facebook\Exceptions\FacebookResponseException](/docs/php/FacebookResponseException)`', + 'The base exception to all Graph error responses. This exception is never thrown directly.', + ], + [ + '`[Facebook\Exceptions\FacebookSDKException](/docs/php/FacebookSDKException)`', + 'The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error.', + ], + [ + '`[Facebook\Exceptions\FacebookServerException](/docs/php/FacebookServerException)`', + 'Thrown when Graph returns a server error.', + ], + [ + '`[Facebook\Exceptions\FacebookThrottleException](/docs/php/FacebookThrottleException)`', + 'Thrown when Graph returns a throttle error.', + ], + ], +}) + + + +# Graph nodes {#graph-nodes} + +Graph nodes are collections that represent nodes returned by Graph. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\GraphNodes\GraphAlbum](/docs/php/GraphAlbum)`', + 'A collection that represents an album node.', + ], + [ + '`[Facebook\GraphNodes\GraphLocation](/docs/php/GraphLocation)`', + 'A collection that represents a location node.', + ], + [ + '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', + 'The base collection object that represents a generic node.', + ], + [ + '`[Facebook\GraphNodes\GraphPage](/docs/php/GraphPage)`', + 'A collection that represents a page node.', + ], + [ + '`[Facebook\GraphNodes\GraphSessionInfo](/docs/php/GraphSessionInfo)`', + '*(Deprecated)* A collection that represents a an access token node.', + ], + [ + '`[Facebook\GraphNodes\GraphUser](/docs/php/GraphUser)`', + 'A collection that represents a user node.', + ], + [ + '`[Facebook\GraphNodes\GraphUserPage](/docs/php/GraphUserPage)`', + '*(Deprecated)* A collection that represents a user page node.', + ], + ], +}) + + + +# Helpers {#helpers} + +Helpers allow you to obtain access tokens and signed requests in various contexts. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\Helpers\FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper)`', + 'Used to obtain an access token or signed request within the context of an app canvas.', + ], + [ + '`[Facebook\Helpers\FacebookJavaScriptHelper](/docs/php/FacebookJavaScriptHelper)`', + 'Used to obtain an access token or signed request from the cookie set by the JavaScript SDK.', + ], + [ + '`[Facebook\Helpers\FacebookPageTabHelper](/docs/php/FacebookPageTabHelper)`', + 'Used to obtain an access token or signed request within the context of a page tab.', + ], + [ + '`[Facebook\Helpers\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper)`', + 'Used to obtain a user access token from a redirect using a "Log in with Facebook" link.', + ], + ], +}) + + + +# HTTP clients {#http-clients} + +Various HTTP clients that can be implemented to send and return requests to Graph. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\HttpClients\FacebookHttpCurlClient](/docs/php/FacebookHttpCurlClient)`', + 'The cURL HTTP client implementation. This is the default implementation.', + ], + [ + '`[Facebook\HttpClients\FacebookStreamHttpClient](/docs/php/FacebookStreamHttpClient)`', + 'The stream wrapper HTTP client implementation. This is the fallback implementation if cURL is not detected.', + ], + [ + '`[Facebook\HttpClients\FacebookGuzzleHttpClient](/docs/php/FacebookGuzzleHttpClient)`', + 'The Guzzle HTTP client implementation. Requires installing Guzzle with Composer.', + ], + ], +}) + + + +# Interfaces {#interfaces} + +Interfaces you can code to. + +FB(devsite:markdown-wiki:table { + columns: ['Interface name','Description',], + rows: [ + [ + '`[Facebook\HttpClients\FacebookHttpClientInterface](/docs/php/FacebookHttpClientInterface)`', + 'Interface to code your own HTTP client implementation.', + ], + ], +}) + diff --git a/docs/upload_photo.fbmd b/docs/upload_photo.fbmd index d2555c0ff..989ac46b4 100644 --- a/docs/upload_photo.fbmd +++ b/docs/upload_photo.fbmd @@ -5,7 +5,7 @@ This example covers uploading a photo to the current User's profile using the Gr It assumes that you've already set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). You must have requested the `publish_actions` scope when logging in the user for this to work. -For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookRequestException`](/docs/php/FacebookRequestException). +For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookResponseException`](/docs/php/FacebookResponseException). @@ -14,7 +14,7 @@ For more information, see the documentation for [`GraphObject`](/docs/php/GraphO ~~~~ use Facebook\FacebookRequest; use Facebook\GraphObject; -use Facebook\FacebookRequestException; +use Facebook\FacebookResponseException; if($session) { @@ -35,7 +35,7 @@ if($session) { echo "Posted with id: " . $response->getProperty('id'); - } catch(FacebookRequestException $e) { + } catch(FacebookResponseException $e) { echo "Exception occured, code: " . $e->getCode(); echo " with message: " . $e->getMessage(); From 8eef393a57bb75b660efd2b8a2b1e830a0182fb9 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 00:20:40 -0500 Subject: [PATCH 038/407] Added TravisCI --- .travis.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100755 index 000000000..1dcaaf77c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: php + +php: + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - composer self-update + - composer install --prefer-source --no-interaction --dev + +script: + - phpunit --coverage-text --exclude-group integration + +matrix: + allow_failures: + - php: hhvm + fast_finish: true \ No newline at end of file From 4f9647651b5511cece2b5604e9c62744eb239f9e Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 00:28:57 -0500 Subject: [PATCH 039/407] Fix for tests always failing when default timezone not set --- tests/bootstrap.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d32858641..646a11e6d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -21,6 +21,10 @@ * DEALINGS IN THE SOFTWARE. * */ +if ( ! ini_get('date.timezone')) { + date_default_timezone_set('America/Los_Angeles'); +} + require_once __DIR__ . '/../vendor/autoload.php'; use Facebook\FacebookClient; From bb9a936c35cbd64efb0abe192f64172369e1d21a Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 00:40:47 -0500 Subject: [PATCH 040/407] Moved the autoloader so that it is easier to strip the non-production stuff --- autoload.php => src/Facebook/autoload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename autoload.php => src/Facebook/autoload.php (98%) diff --git a/autoload.php b/src/Facebook/autoload.php similarity index 98% rename from autoload.php rename to src/Facebook/autoload.php index e96ec6504..f620fd13d 100644 --- a/autoload.php +++ b/src/Facebook/autoload.php @@ -46,7 +46,7 @@ $prefix = 'Facebook\\'; // base directory for the namespace prefix - $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/src/Facebook/'; + $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/'; // does the class use the namespace prefix? $len = strlen($prefix); From 50533770891a82f0c6367c1b85591d34517e9e0f Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 01:26:05 -0500 Subject: [PATCH 041/407] Updated timezone to be near to @yguedidi since time starts with him! :) --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 646a11e6d..9b1e36495 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -22,7 +22,7 @@ * */ if ( ! ini_get('date.timezone')) { - date_default_timezone_set('America/Los_Angeles'); + date_default_timezone_set('Europe/Paris'); } require_once __DIR__ . '/../vendor/autoload.php'; From 9184bbafaa78a1f2f2d058f354b08c9aa772e0f3 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 00:14:29 -0500 Subject: [PATCH 042/407] Added a much needed CHANGELOG --- CHANGELOG.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..8c1a9583b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,89 @@ +# CHANGELOG + +As you may have already noticed, the Facebook SDK v4 does not follow strict [semver](http://semver.org/). The versioning format used for this SDK is more like `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions are squashed together but there shouldn't be any breaking changes between `MINOR|PATCH` releases. + + +## 4.1.x + +- 4.1.0 (2014-??-??) + - Added batch support + - Added `graph.beta.facebook.com` support + - Moved exception classes to `Exception\*` directory + - Moved response collection objects to `GraphNodes\*` directory + - Moved helpers to `Helpers\*` directory + - Moved `FacebookRequest` and `FacebookResponse` to `Entities\*` directory + - Killed `FacebookSession` in favor of `Facebook\Entities\AccessToken` + - Added `FacebookClient` service + - Renamed `FacebookRequestException` to `FacebookResponseException` + - Renamed `FacebookHttpable` to `FacebookHttpClientInterface` + - Updated the API for the helpers. + - Refactored request/response handling + - Added support for "rerequest" authorization + - [`AccessToken`] Added serialization support + - Added `ext-mbstring` to composer require + - Added `Facebook\Entities\FacebookApp` entity + - Namespaced tests + - Grouped functional tests under `functional` group + - Added this CHANGELOG. Hi! :) + + +## 4.0.x + +- 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` +- 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 +- 4.0.8 (2014-06-10) + - 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 +- 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 +- 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 +- 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 +- 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` +- 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 +- 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 +- 4.0.0 (2014-04-30) + - Initial release. Yay! From a1d02c1b2ae33fd43b5df760ad865956075b58d8 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 01:39:38 -0500 Subject: [PATCH 043/407] Renamed FacebookRedirectLoginHelper method to be consistent with other helpers --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 +- tests/Helpers/FacebookRedirectLoginHelperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index d9d401e85..c43799774 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -132,7 +132,7 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') * * @return AccessToken|null */ - public function getAccessTokenFromRedirect(FacebookClient $client, $redirectUrl = null) + public function getAccessToken(FacebookClient $client, $redirectUrl = null) { if ($this->isValidRedirect()) { $code = $this->getCode(); diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 76cf28d57..c826f4bb8 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -105,7 +105,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $helper = new FacebookRedirectLoginHelper($app); $helper->disableSessionStatusCheck(); - $accessToken = $helper->getAccessTokenFromRedirect($client, self::REDIRECT_URL); + $accessToken = $helper->getAccessToken($client, self::REDIRECT_URL); $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); $this->assertEquals('access_token_from_code', (string) $accessToken); From 1ad719cbec820ed2d22327729eb620ed860aafa4 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 4 Sep 2014 14:47:08 -0500 Subject: [PATCH 044/407] Added smart-casting of GraphObjects for Graph responses --- src/Facebook/Entities/AccessToken.php | 11 +- src/Facebook/Entities/FacebookResponse.php | 132 ++++-- src/Facebook/GraphNodes/Collection.php | 208 +++++++++ src/Facebook/GraphNodes/GraphAlbum.php | 288 ++++++------ .../{GraphUserPage.php => GraphList.php} | 51 +-- src/Facebook/GraphNodes/GraphObject.php | 186 ++++---- .../GraphNodes/GraphObjectFactory.php | 339 ++++++++++++++ src/Facebook/GraphNodes/GraphPage.php | 62 ++- src/Facebook/GraphNodes/GraphSessionInfo.php | 18 +- src/Facebook/GraphNodes/GraphUser.php | 44 +- tests/Entities/AccessTokenTest.php | 13 +- tests/Entities/FacebookBatchResponseTest.php | 2 +- tests/Entities/FacebookResponseTest.php | 2 +- tests/GraphNodes/CollectionTest.php | 114 +++++ tests/GraphNodes/GraphAlbumTest.php | 58 ++- tests/GraphNodes/GraphObjectFactoryTest.php | 418 ++++++++++++++++++ tests/GraphNodes/GraphObjectTest.php | 116 +++-- tests/GraphNodes/GraphPageTest.php | 97 ++++ tests/GraphNodes/GraphSessionInfoTest.php | 36 +- tests/GraphNodes/GraphUserTest.php | 72 ++- 20 files changed, 1852 insertions(+), 415 deletions(-) create mode 100644 src/Facebook/GraphNodes/Collection.php rename src/Facebook/GraphNodes/{GraphUserPage.php => GraphList.php} (55%) create mode 100644 src/Facebook/GraphNodes/GraphObjectFactory.php create mode 100755 tests/GraphNodes/CollectionTest.php create mode 100644 tests/GraphNodes/GraphObjectFactoryTest.php create mode 100644 tests/GraphNodes/GraphPageTest.php diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 46c6e5f18..41beb55f0 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -166,7 +166,7 @@ public static function validateAccessToken(GraphSessionInfo $tokenInfo, { $appIdIsValid = $tokenInfo->getProperty('app_id') == $app->getId(); $machineIdIsValid = $tokenInfo->getProperty('machine_id') == $machineId; - $accessTokenIsValid = $tokenInfo->isValid(); + $accessTokenIsValid = $tokenInfo->getIsValid(); // Not all access tokens return an expiration. E.g. an app access token. if ($tokenInfo->getExpiresAt() instanceof \DateTime) { @@ -362,14 +362,15 @@ public function getInfo(FacebookApp $app, FacebookClient $client) '/debug_token', $params ); - $response = $client->sendRequest($request)->getGraphObject(GraphSessionInfo::className()); + $response = $client->sendRequest($request); + $graphObject = $response->getGraphSessionInfo(); // Update the data on this token - if ($response->getExpiresAt()) { - $this->expiresAt = $response->getExpiresAt(); + if ($graphObject->getExpiresAt()) { + $this->expiresAt = $graphObject->getExpiresAt(); } - return $response; + return $graphObject; } /** diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index aef857ebf..112e6902f 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -23,9 +23,9 @@ */ namespace Facebook\Entities; +use Facebook\GraphNodes\GraphObjectFactory; use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; -use Facebook\GraphNodes\GraphObject; /** * Class Response @@ -50,9 +50,9 @@ class FacebookResponse protected $body; /** - * @var mixed The decoded body of the Graph response. + * @var array The decoded body of the Graph response. */ - protected $decodedBody; + protected $decodedBody = []; /** * @var string The access token that was used. @@ -148,50 +148,13 @@ public function getBody() /** * Return the decoded body response. * - * @return mixed + * @return array */ public function getDecodedBody() { return $this->decodedBody; } - /** - * @TODO Make this smarter - casting recursively. - * - * Gets the result as a GraphObject. If a type is specified, returns the - * strongly-typed subclass of GraphObject for the data. - * - * @param string $type - * - * @return mixed - */ - public function getGraphObject($type = 'Facebook\GraphNodes\GraphObject') - { - return (new GraphObject($this->decodedBody))->cast($type); - } - - /** - * @TODO This will soon return a GraphList object. - * - * Returns an array of GraphObject returned by the request. If a type is - * specified, returns the strongly-typed subclass of GraphObject for the data. - * - * @param string $type - * - * @return array|null - */ - public function getGraphObjectList($type = 'Facebook\GraphNodes\GraphObject') - { - if (!isset($this->decodedBody['data'])) { - return null; - } - $out = []; - foreach ($this->decodedBody['data'] as $graphObject) { - $out[] = (new GraphObject($graphObject))->cast($type); - } - return $out; - } - /** * Get the app secret proof that was used for this response. * @@ -283,9 +246,96 @@ public function decodeBody() $this->decodedBody = ['was_successful' => $this->decodedBody]; } + if ( ! is_array($this->decodedBody)) { + $this->decodedBody = []; + } + if ($this->isError()) { $this->makeException(); } } + /** + * Instantiate a new GraphObject from response. + * + * @param string|null $subclassName The GraphObject sub class to cast to. + * + * @return \Facebook\GraphNodes\GraphObject + * + * @throws FacebookSDKException + */ + public function getGraphObject($subclassName = null) + { + $factory = new GraphObjectFactory($this); + return $factory->makeGraphObject($subclassName); + } + + /** + * Convenience method for creating a GraphAlbum collection. + * + * @return \Facebook\GraphNodes\GraphAlbum + * + * @throws FacebookSDKException + */ + public function getGraphAlbum() + { + $factory = new GraphObjectFactory($this); + return $factory->makeGraphAlbum(); + } + + /** + * Convenience method for creating a GraphPage collection. + * + * @return \Facebook\GraphNodes\GraphPage + * + * @throws FacebookSDKException + */ + public function getGraphPage() + { + $factory = new GraphObjectFactory($this); + return $factory->makeGraphPage(); + } + + /** + * Convenience method for creating a GraphSessionInfo collection. + * + * @return \Facebook\GraphNodes\GraphSessionInfo + * + * @throws FacebookSDKException + */ + public function getGraphSessionInfo() + { + $factory = new GraphObjectFactory($this); + return $factory->makeGraphSessionInfo(); + } + + /** + * Convenience method for creating a GraphUser collection. + * + * @return \Facebook\GraphNodes\GraphUser + * + * @throws FacebookSDKException + */ + public function getGraphUser() + { + $factory = new GraphObjectFactory($this); + return $factory->makeGraphUser(); + } + + /** + * Instantiate a new GraphList from response. + * + * @param string|null $subclassName The GraphObject sub class to cast list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return \Facebook\GraphNodes\GraphList + * + * @throws FacebookSDKException + */ + public function getGraphList($subclassName = null, $auto_prefix = true) + { + $factory = new GraphObjectFactory($this); + return $factory->makeGraphList($subclassName, $auto_prefix); + } + } diff --git a/src/Facebook/GraphNodes/Collection.php b/src/Facebook/GraphNodes/Collection.php new file mode 100644 index 000000000..f737bd975 --- /dev/null +++ b/src/Facebook/GraphNodes/Collection.php @@ -0,0 +1,208 @@ +items = $items; + } + + /** + * 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 + */ + public function getProperty($name, $default = null) + { + if (isset($this->items[$name])) { + return $this->items[$name]; + } + return $default ?: null; + } + + /** + * Returns a list of all properties set on the object. + * + * @return array + */ + public function getPropertyNames() + { + return array_keys($this->items); + } + + /** + * Get all of the items in the collection. + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function asArray() + { + return array_map(function($value) + { + return $value instanceof Collection ? $value->asArray() : $value; + + }, $this->items); + } + + /** + * Run a map over each of the items. + * + * @param \Closure $callback + * @return static + */ + public function map(\Closure $callback) + { + 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) + { + return json_encode($this->asArray(), $options); + } + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count() + { + return count($this->items); + } + + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->items); + } + + /** + * Determine if an item exists at an offset. + * + * @param mixed $key + * @return bool + */ + public function offsetExists($key) + { + return array_key_exists($key, $this->items); + } + + /** + * Get an item at a given offset. + * + * @param mixed $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->items[$key]; + } + + /** + * Set the item at a given offset. + * + * @param mixed $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + if (is_null($key)) { + $this->items[] = $value; + } else { + $this->items[$key] = $value; + } + } + + /** + * Unset the item at a given offset. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + unset($this->items[$key]); + } + + /** + * Convert the collection to its string representation. + * + * @return string + */ + public function __toString() + { + return $this->asJson(); + } + +} diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index e9346df3c..4b7db406d 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -31,143 +31,153 @@ class GraphAlbum extends GraphObject { - /** - * Returns the ID for the album. - * - * @return string|null - */ - public function getId() - { - return $this->getProperty('id'); - } - - /** - * Returns whether the viewer can upload photos to this album. - * - * @return boolean|null - */ - public function getCanUpload() - { - return $this->getProperty('can_upload'); - } - - /** - * Returns the number of photos in this album. - * - * @return int|null - */ - public function getCount() - { - return $this->getProperty('count'); - } - - /** - * Returns the ID of the album's cover photo. - * - * @return string|null - */ - public function getCoverPhoto() - { - return $this->getProperty('cover_photo'); - } - - /** - * Returns the time the album was initially created. - * - * @return \DateTime|null - */ - public function getCreatedTime() - { - $value = $this->getProperty('created_time'); - if ($value) { - return new \DateTime($value); - } - return null; - } - - /** - * Returns the time the album was updated. - * - * @return \DateTime|null - */ - public function getUpdatedTime() - { - $value = $this->getProperty('updated_time'); - if ($value) { - return new \DateTime($value); - } - return null; - } - - /** - * Returns the description of the album. - * - * @return string|null - */ - public function getDescription() - { - return $this->getProperty('description'); - } - - /** - * Returns profile that created the album. - * - * @return GraphUser|null - */ - public function getFrom() - { - return $this->getProperty('from', null, GraphUser::className()); - } - - /** - * Returns a link to this album on Facebook. - * - * @return string|null - */ - public function getLink() - { - return $this->getProperty('link'); - } - - /** - * Returns the textual location of the album. - * - * @return string|null - */ - public function getLocation() - { - return $this->getProperty('location'); - } - - /** - * Returns the title of the album. - * - * @return string|null - */ - public function getName() - { - return $this->getProperty('name'); - } - - /** - * Returns the privacy settings for the album. - * - * @return string|null - */ - public function getPrivacy() - { - return $this->getProperty('privacy'); - } - - /** - * Returns the type of the album. enum{profile, mobile, wall, normal, album} - * - * @return string|null - */ - public function getType() - { - return $this->getProperty('type'); - } - - //TODO: public function getPlace() that should return GraphPage + /** + * @var array Maps object key names to Graph object types. + */ + protected static $graphObjectMap = [ + 'from' => '\\Facebook\\GraphNodes\\GraphUser', + 'place' => '\\Facebook\\GraphNodes\\GraphPage', + ]; + + /** + * Returns the ID for the album. + * + * @return string|null + */ + public function getId() + { + return $this->getProperty('id'); + } + + /** + * Returns whether the viewer can upload photos to this album. + * + * @return boolean|null + */ + public function getCanUpload() + { + return $this->getProperty('can_upload'); + } + + /** + * Returns the number of photos in this album. + * + * @return int|null + */ + public function getCount() + { + return $this->getProperty('count'); + } + + /** + * Returns the ID of the album's cover photo. + * + * @return string|null + */ + public function getCoverPhoto() + { + return $this->getProperty('cover_photo'); + } + + /** + * Returns the time the album was initially created. + * + * @return \DateTime|null + */ + public function getCreatedTime() + { + return $this->getProperty('created_time'); + } + + /** + * Returns the time the album was updated. + * + * @return \DateTime|null + */ + public function getUpdatedTime() + { + return $this->getProperty('updated_time'); + } + + /** + * Returns the description of the album. + * + * @return string|null + */ + public function getDescription() + { + return $this->getProperty('description'); + } + + /** + * Returns profile that created the album. + * + * @return GraphUser|null + */ + public function getFrom() + { + return $this->getProperty('from'); + } + + /** + * Returns profile that created the album. + * + * @return GraphPage|null + */ + public function getPlace() + { + return $this->getProperty('place'); + } + + /** + * Returns a link to this album on Facebook. + * + * @return string|null + */ + public function getLink() + { + return $this->getProperty('link'); + } + + /** + * Returns the textual location of the album. + * + * @return string|null + */ + public function getLocation() + { + return $this->getProperty('location'); + } + + /** + * Returns the title of the album. + * + * @return string|null + */ + public function getName() + { + return $this->getProperty('name'); + } + + /** + * Returns the privacy settings for the album. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getProperty('privacy'); + } + + /** + * Returns the type of the album. + * enum{ profile, mobile, wall, normal, album } + * + * @return string|null + */ + public function getType() + { + return $this->getProperty('type'); + } + } diff --git a/src/Facebook/GraphNodes/GraphUserPage.php b/src/Facebook/GraphNodes/GraphList.php similarity index 55% rename from src/Facebook/GraphNodes/GraphUserPage.php rename to src/Facebook/GraphNodes/GraphList.php index 08f11a477..743138e4f 100644 --- a/src/Facebook/GraphNodes/GraphUserPage.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -24,61 +24,46 @@ namespace Facebook\GraphNodes; /** - * Class GraphUserPage + * Class GraphList * @package Facebook - * @author Artur Luiz */ -class GraphUserPage extends GraphObject +class GraphList extends Collection { /** - * Returns the ID for the user's page as a string if present. - * - * @return string|null + * @var array $metaData An array of Graph meta data like pagination, etc. */ - public function getId() - { - return $this->getProperty('id'); - } + protected $metaData = []; /** - * Returns the Category for the user's page as a string if present. + * Init this collection of GraphObject's. * - * @return string|null + * @param array $data An array of GraphObject's. + * @param array $metaData An array of Graph meta data like pagination, etc. */ - public function getCategory() + public function __construct(array $data = [], array $metaData = []) { - return $this->getProperty('category'); - } + $this->metaData = $metaData; - /** - * Returns the Name of the user's page as a string if present. - * - * @return string|null - */ - public function getName() - { - return $this->getProperty('name'); + parent::__construct($data); } /** - * Returns the Access Token used to access the user's page as a string if present. + * Get the next page of results of this list of Graph objects. * - * @return string|null + * @TODO */ - public function getAccessToken() + public function next() { - return $this->getProperty('access_token'); } - + /** - * Returns the Permissions for the user's page as an array if present. + * Get the previous page of results of this list of Graph objects. * - * @return array|null + * @TODO */ - public function getPerms() + public function previous() { - return $this->getProperty('perms'); } -} \ No newline at end of file +} diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index 8264d21f4..ce8c3288d 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -23,148 +23,162 @@ */ namespace Facebook\GraphNodes; -use Facebook\Exceptions\FacebookSDKException; - /** * Class GraphObject * @package Facebook * @author Fosco Marotto * @author David Poll */ -class GraphObject +class GraphObject extends Collection { /** - * @var array - Holds the raw associative data for this object + * @var array Maps object key names to Graph object types. */ - protected $backingData = []; + protected static $graphObjectMap = []; /** - * Creates a GraphObject using the data provided. + * Init this Graph object. * - * @param array $raw + * @param array $data */ - public function __construct(array $raw = []) + public function __construct(array $data = []) { - $this->backingData = $raw; - - if (isset($this->backingData['data']) && count($this->backingData) === 1) { - if ($this->backingData['data'] instanceof \stdClass) { - $this->backingData = get_object_vars($this->backingData['data']); - } else { - $this->backingData = $this->backingData['data']; - } - } + $items = $this->castItems($data); + parent::__construct($items); } /** - * cast - Return a new instance of a FacebookGraphObject subclass for this - * objects underlying data. + * Iterates over an array and detects the types each node + * should be cast to and returns all the items as an array. * - * @param string $type The GraphObject subclass to cast to + * @TODO Add auto-casting to AccessToken entities. * - * @return GraphObject + * @param array $data The array to iterate over. * - * @throws FacebookSDKException + * @return array */ - public function cast($type) + public function castItems(array $data) { - if ($this instanceof $type) { - return $this; - } - if (is_subclass_of($type, GraphObject::className())) { - return new $type($this->backingData); - } else { - throw new FacebookSDKException( - 'Cannot cast to an object that is not a GraphObject subclass', 620 - ); + $items = []; + + foreach ($data as $k => $v) { + if ( + $this->shouldCastAsDateTime($k) + && (is_numeric($v) || $this->isIso8601DateString($v)) + ) { + $items[$k] = $this->castToDateTime($v); + } else { + $items[$k] = $v; + } } + + return $items; } /** - * asArray - Return a key-value associative array for the given graph object. + * Uncasts any auto-casted datatypes. + * Basically the reverse of castItems(). * * @return array */ - public function asArray() + public function uncastItems() { - return $this->backingData; + $items = $this->asArray(); + return array_map(function ($v) { + $returnVal = $v; + if ($v instanceof \DateTime) { + $returnVal = $v->format(\DateTime::ISO8601); + } + return $returnVal; + }, $items); } /** - * getProperty - Gets the value of the named property for this graph object, - * cast to the appropriate subclass type if provided. + * Get the collection of items as JSON. * - * @param string $name The property to retrieve. - * @param mixed|null $default The default return value. - * @param string $type The subclass of GraphObject, optionally. - * - * @return mixed + * @param int $options + * @return string */ - public function getProperty($name, $default = null, $type = 'Facebook\GraphNodes\GraphObject') + public function asJson($options = 0) { - if (isset($this->backingData[$name])) { - $value = $this->backingData[$name]; - if (is_scalar($value)) { - return $value; - } else { - return (new GraphObject($value))->cast($type); - } - } - return $default; + $items = $this->uncastItems(); + return json_encode($items, $options); } /** - * getPropertyAsArray - Get the list value of a named property for this graph - * object, where each item has been cast to the appropriate subclass type - * if provided. + * Detects an ISO 8601 formatted string. * - * Calling this for a property that is not an array, the behavior - * is undefined, so don’t do this. + * @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 * - * @param string $name The property to retrieve - * @param string $type The subclass of GraphObject, optionally + * @param string $string * - * @return array + * @return boolean */ - public function getPropertyAsArray($name, $type = 'Facebook\GraphNodes\GraphObject') + public function isIso8601DateString($string) { - $target = array(); - if (isset($this->backingData[$name]['data'])) { - $target = $this->backingData[$name]['data']; - } else if (isset($this->backingData[$name]) - && !is_scalar($this->backingData[$name])) { - $target = $this->backingData[$name]; - } - $out = array(); - foreach ($target as $key => $value) { - if (is_scalar($value)) { - $out[$key] = $value; - } else { - $out[$key] = (new GraphObject($value))->cast($type); - } - } - return $out; + // 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; } /** - * getPropertyNames - Returns a list of all properties set on the object. + * Determines if a value from Graph should be cast to DateTime. * - * @return array + * @param string $key + * + * @return boolean */ - public function getPropertyNames() + public function shouldCastAsDateTime($key) { - return array_keys($this->backingData); + return in_array($key, [ + 'created_time', + 'updated_time', + 'start_time', + 'end_time', + 'backdated_time', + 'issued_at', + 'expires_at', + 'birthday', + ], true); } /** - * Returns the string class name of the GraphObject or subclass. + * Casts a date value from Graph to DateTime. * - * @return string + * @param int|string $value + * + * @return \DateTime + */ + public function castToDateTime($value) + { + if (is_int($value)) { + $dt = new \DateTime(); + $dt->setTimestamp($value); + } else { + $dt = new \DateTime($value); + } + return $dt; + } + + /** + * Getter for $graphObjectMap. + * + * @return array */ - public static function className() + public static function getObjectMap() { - return get_called_class(); + return static::$graphObjectMap; } -} \ No newline at end of file +} diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php new file mode 100644 index 000000000..0d580ab0b --- /dev/null +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -0,0 +1,339 @@ +decodedBody = $response->getDecodedBody(); + } + + /** + * Tries to convert a FacebookResponse entity into a GraphObject. + * + * @param string|null $subclassName The GraphObject sub class to cast to. + * + * @return GraphObject + * + * @throws FacebookSDKException + */ + public function makeGraphObject($subclassName = null) + { + $this->validateResponseAsArray(); + $this->validateResponseCastableAsGraphObject(); + + // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key + if (isset($this->decodedBody['data'])) { + $this->decodedBody = $this->decodedBody['data']; + } + + return $this->safelyMakeGraphObject($this->decodedBody, $subclassName); + } + + /** + * Convenience method for creating a GraphAlbum collection. + * + * @return GraphAlbum + * + * @throws FacebookSDKException + */ + public function makeGraphAlbum() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); + } + + /** + * Convenience method for creating a GraphPage collection. + * + * @return GraphPage + * + * @throws FacebookSDKException + */ + public function makeGraphPage() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); + } + + /** + * Convenience method for creating a GraphSessionInfo collection. + * + * @return GraphSessionInfo + * + * @throws FacebookSDKException + */ + public function makeGraphSessionInfo() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); + } + + /** + * Convenience method for creating a GraphUser collection. + * + * @return GraphUser + * + * @throws FacebookSDKException + */ + public function makeGraphUser() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); + } + + /** + * Tries to convert a FacebookResponse entity into a GraphList. + * + * @param string|null $subclassName The GraphObject sub class to cast the list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return GraphList + * + * @throws FacebookSDKException + */ + public function makeGraphList($subclassName = null, $auto_prefix = true) + { + $this->validateResponseAsArray(); + $this->validateResponseCastableAsGraphList(); + + if ($subclassName && $auto_prefix) { + $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; + } + + return $this->safelyMakeGraphList($this->decodedBody, $subclassName); + } + + /** + * Validates the decoded body. + * + * @throws FacebookSDKException + */ + public function validateResponseAsArray() + { + if ( ! is_array($this->decodedBody)) { + throw new FacebookSDKException( + 'Unable to get response from Graph as array.', 620 + ); + } + } + + /** + * Validates that the return data can be cast as a GraphObject. + * + * @throws FacebookSDKException + */ + public function validateResponseCastableAsGraphObject() + { + if (isset($this->decodedBody['data']) + && static::isCastableAsGraphList($this->decodedBody['data'])) { + throw new FacebookSDKException( + 'Unable to convert response from Graph to a GraphObject ' . + 'because the response looks like a GraphList. ' . + 'Try using GraphObjectFactory::makeGraphList() instead.', 620 + ); + } + } + + /** + * Validates that the return data can be cast as a GraphList. + * + * @throws FacebookSDKException + */ + public function validateResponseCastableAsGraphList() + { + if ( ! (isset($this->decodedBody['data']) + && static::isCastableAsGraphList($this->decodedBody['data']) ) ) { + throw new FacebookSDKException( + 'Unable to convert response from Graph to a GraphList ' . + 'because the response does not look like a GraphList. ' . + 'Try using GraphObjectFactory::makeGraphObject() instead.', 620 + ); + } + } + + /** + * Safely instantiates a GraphObject of $subclassName. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The subclass to cast this collection to. + * + * @return GraphObject + * + * @throws FacebookSDKException + */ + public function safelyMakeGraphObject(array $data, $subclassName = null) + { + $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; + static::validateSubclass($subclassName); + + $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 GraphObject 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 GraphList or GraphObject + $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass); + } else { + $items[$k] = $v; + } + } + + return new $subclassName($items); + } + + /** + * Takes an array of values and determines how to cast each node. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The subclass to cast this collection to. + * + * @return GraphObject|GraphList + * + * @throws FacebookSDKException + */ + public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) + { + if (isset($data['data'])) { + // Create GraphList + if (static::isCastableAsGraphList($data['data'])) { + return $this->safelyMakeGraphList($data, $subclassName); + } + // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key + $data = $data['data']; + } + + // Create GraphObject + return $this->safelyMakeGraphObject($data, $subclassName); + } + + /** + * Return an array of GraphObject's. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. + * + * @return GraphList + * + * @throws FacebookSDKException + */ + public function safelyMakeGraphList(array $data, $subclassName = null) + { + if ( ! isset($data['data'])) { + throw new FacebookSDKException( + 'Cannot cast data to GraphList. Expected a "data" key.', 620 + ); + } + + $dataList = []; + foreach ($data['data'] as $graphNode) { + $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName); + } + + // @TODO: Look for meta data here + $metaData = []; + + return new GraphList($dataList, $metaData); + } + + /** + * Determines whether or not the data should be cast as a GraphList. + * + * @param array $data + * + * @return boolean + */ + public static function isCastableAsGraphList(array $data) + { + if ($data === []) { + return true; + } + // Checks for a sequential numeric array which would be a GraphList + return array_keys($data) === range(0, count($data) - 1); + } + + /** + * Ensures that the subclass in question is valid. + * + * @param string $subclassName The GraphObject subclass to validate. + * + * @throws FacebookSDKException + */ + public static function validateSubclass($subclassName) + { + if ($subclassName == static::BASE_GRAPH_OBJECT_CLASS + || is_subclass_of($subclassName, static::BASE_GRAPH_OBJECT_CLASS)) { + return; + } + + throw new FacebookSDKException( + 'The given subclass "' . $subclassName . '" is not valid. ' + . 'Cannot cast to an object that is not a GraphObject subclass.', 620 + ); + } + +} diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index a3da2d463..e88ed2d34 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -30,6 +30,14 @@ */ class GraphPage extends GraphObject { + /** + * @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', + ]; /** * Returns the ID for the user's page as a string if present. @@ -61,4 +69,56 @@ public function getName() return $this->getProperty('name'); } -} \ No newline at end of file + /** + * Returns the best available Page on Facebook. + * + * @return GraphPage|null + */ + public function getBestPage() + { + return $this->getProperty('best_page'); + } + + /** + * Returns the brand's global (parent) Page. + * + * @return GraphPage|null + */ + public function getGlobalBrandParentPage() + { + return $this->getProperty('global_brand_parent_page'); + } + + /** + * Returns the location of this place. + * + * @return GraphLocation|null + */ + public function getLocation() + { + return $this->getProperty('location'); + } + + /** + * Returns the page access token for the admin user. + * Only available in the `/me/accounts` context. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->getProperty('access_token'); + } + + /** + * Returns the roles of the page admin user. + * Only available in the `/me/accounts` context. + * + * @return array|null + */ + public function getPerms() + { + return $this->getProperty('perms'); + } + +} diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index 94c690520..094497ff7 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -59,12 +59,7 @@ public function getApplication() */ public function getExpiresAt() { - $stamp = $this->getProperty('expires_at'); - if ($stamp) { - return (new \DateTime())->setTimestamp($stamp); - } else { - return null; - } + return $this->getProperty('expires_at'); } /** @@ -84,12 +79,7 @@ public function getIsValid() */ public function getIssuedAt() { - $stamp = $this->getProperty('issued_at'); - if ($stamp) { - return (new \DateTime())->setTimestamp($stamp); - } else { - return null; - } + return $this->getProperty('issued_at'); } /** @@ -99,7 +89,7 @@ public function getIssuedAt() */ public function getScopes() { - return $this->getPropertyAsArray('scopes'); + return $this->getProperty('scopes'); } /** @@ -112,4 +102,4 @@ public function getUserId() return $this->getProperty('user_id'); } -} \ No newline at end of file +} diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 59f6f05ba..607225ed0 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -32,6 +32,15 @@ class GraphUser extends GraphObject { + /** + * @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', + ]; + /** * Returns the ID for the user as a string if present. * @@ -99,22 +108,37 @@ public function getLink() */ public function getBirthday() { - $value = $this->getProperty('birthday'); - if ($value) { - return new \DateTime($value); - } - return null; + return $this->getProperty('birthday'); } /** - * Returns the current location of the user as a FacebookGraphLocation - * if available. + * Returns the current location of the user as a GraphPage. * - * @return GraphLocation|null + * @return GraphPage|null */ public function getLocation() { - return $this->getProperty('location', null, GraphLocation::className()); + return $this->getProperty('location'); + } + + /** + * Returns the current location of the user as a GraphPage. + * + * @return GraphPage|null + */ + public function getHometown() + { + return $this->getProperty('hometown'); + } + + /** + * Returns the current location of the user as a GraphUser. + * + * @return GraphUser|null + */ + public function getSignificantOther() + { + return $this->getProperty('significant_other'); } -} \ No newline at end of file +} diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index bf0411632..ad0c093f1 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -75,7 +75,7 @@ public function testATokenIsValidatedOnTheAppIdAndMachineIdAndTokenValidityAndTo ->once() ->andReturn('foo_machine'); $graphSessionInfoMock - ->shouldReceive('isValid') + ->shouldReceive('getIsValid') ->once() ->andReturn(true); $graphSessionInfoMock @@ -107,7 +107,7 @@ public function testATokenWillNotBeValidIfTheAppIdDoesNotMatch() ->once() ->andReturn('foo_machine'); $graphSessionInfoMock - ->shouldReceive('isValid') + ->shouldReceive('getIsValid') ->once() ->andReturn(true); $graphSessionInfoMock @@ -139,7 +139,7 @@ public function testATokenWillNotBeValidIfTheMachineIdDoesNotMatch() ->once() ->andReturn('foo_machine'); $graphSessionInfoMock - ->shouldReceive('isValid') + ->shouldReceive('getIsValid') ->once() ->andReturn(true); $graphSessionInfoMock @@ -171,7 +171,7 @@ public function testATokenWillNotBeValidIfTheCollectionTellsUsItsNotValid() ->once() ->andReturn('foo_machine'); $graphSessionInfoMock - ->shouldReceive('isValid') + ->shouldReceive('getIsValid') ->once() ->andReturn(false); $graphSessionInfoMock @@ -203,7 +203,7 @@ public function testATokenWillNotBeValidIfTheTokenHasExpired() ->once() ->andReturn('foo_machine'); $graphSessionInfoMock - ->shouldReceive('isValid') + ->shouldReceive('getIsValid') ->once() ->andReturn(true); $graphSessionInfoMock @@ -222,8 +222,7 @@ public function testInfoAboutAnAccessTokenCanBeObtainedFromGraph() $app = new FacebookApp('123', 'foo_secret'); $response = m::mock('Facebook\Entities\FacebookResponse'); $response - ->shouldReceive('getGraphObject') - ->with('Facebook\GraphNodes\GraphSessionInfo') + ->shouldReceive('getGraphSessionInfo') ->once() ->andReturn($response); $response diff --git a/tests/Entities/FacebookBatchResponseTest.php b/tests/Entities/FacebookBatchResponseTest.php index cc7e9106b..fd7ddb694 100755 --- a/tests/Entities/FacebookBatchResponseTest.php +++ b/tests/Entities/FacebookBatchResponseTest.php @@ -57,7 +57,7 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[0]->getGraphObject()); // Paginated list of Graph objects. $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); - $graphList = $decodedResponses[1]->getGraphObjectList(); + $graphList = $decodedResponses[1]->getGraphList(); $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[0]); $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[1]); /* diff --git a/tests/Entities/FacebookResponseTest.php b/tests/Entities/FacebookResponseTest.php index ddf298c73..e67821461 100755 --- a/tests/Entities/FacebookResponseTest.php +++ b/tests/Entities/FacebookResponseTest.php @@ -80,7 +80,7 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $graphObjectList = $response->getGraphObjectList(); + $graphObjectList = $response->getGraphList(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[0]); diff --git a/tests/GraphNodes/CollectionTest.php b/tests/GraphNodes/CollectionTest.php new file mode 100755 index 000000000..3eefcd61c --- /dev/null +++ b/tests/GraphNodes/CollectionTest.php @@ -0,0 +1,114 @@ + 'bar']); + $property = $graphObject->getProperty('foo'); + + $this->assertEquals('bar', $property); + } + + public function testAMissingPropertyWillReturnNull() + { + $graphObject = new Collection(['foo' => 'bar']); + $property = $graphObject->getProperty('baz'); + + $this->assertNull($property, 'Expected the property to return null.'); + } + + public function testAMissingPropertyWillReturnTheDefault() + { + $graphObject = new Collection(['foo' => 'bar']); + $property = $graphObject->getProperty('baz', 'faz'); + + $this->assertEquals('faz', $property); + } + + public function testTheKeysFromTheCollectionCanBeReturned() + { + $graphObject = new Collection([ + 'key1' => 'foo', + 'key2' => 'bar', + 'key3' => 'baz', + ]); + $propertyKeys = $graphObject->getPropertyNames(); + + $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); + } + + public function testAnArrayCanBeInjectedViaTheConstructor() + { + $collection = new Collection(['foo', 'bar']); + $this->assertEquals(['foo', 'bar'], $collection->asArray()); + } + + public function testACollectionCanBeConvertedToProperJson() + { + $collection = new Collection(['foo', 'bar', 123]); + + $collectionAsString = $collection->asJson(); + + $this->assertEquals('["foo","bar",123]', $collectionAsString); + } + + public function testACollectionCanBeCounted() + { + $collection = new Collection(['foo', 'bar', 'baz']); + + $collectionCount = count($collection); + + $this->assertEquals(3, $collectionCount); + } + + public function testACollectionCanBeAccessedAsAnArray() + { + $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); + + $this->assertEquals('bar', $collection['foo']); + $this->assertEquals('baz', $collection['faz']); + } + + public function testACollectionCanBeIteratedOver() + { + $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); + + $this->assertInstanceOf('IteratorAggregate', $collection); + + $newArray = []; + + foreach ($collection as $k => $v) { + $newArray[$k] = $v; + } + + $this->assertEquals(['foo' => 'bar', 'faz' => 'baz'], $newArray); + } + +} diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 1f38eb8e1..32c065866 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -23,20 +23,37 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\GraphNodes\GraphAlbum; +use Mockery as m; +use Facebook\GraphNodes\GraphObjectFactory; class GraphAlbumTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\Entities\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + } + public function testDatesGetCastToDateTime() { - $data = [ + $dataFromGraph = [ 'created_time' => '2014-07-15T03:54:34+0000', 'updated_time' => '2014-07-12T01:24:09+0000', 'id' => '123', 'name' => 'Bar', ]; - $graphObject = new GraphAlbum($data); + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphAlbum(); $createdTime = $graphObject->getCreatedTime(); $updatedTime = $graphObject->getUpdatedTime(); @@ -47,18 +64,47 @@ public function testDatesGetCastToDateTime() public function testFromGetsCastAsGraphUser() { - $data = [ + $dataFromGraph = [ 'id' => '123', 'from' => [ 'id' => '1337', 'name' => 'Foo McBar', ], ]; - $graphObject = new GraphAlbum($data); + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphAlbum(); $from = $graphObject->getFrom(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $from); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $from); + } + + public function testPlacePropertyWillGetCastAsGraphPageObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Album', + 'place' => [ + 'id' => '1', + 'name' => 'For Bar Place', + ] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphAlbum(); + + $place = $graphObject->getPlace(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $place); } } diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php new file mode 100644 index 000000000..7d583af68 --- /dev/null +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -0,0 +1,418 @@ + '\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', + ]; +} + +class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \Facebook\Entities\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testADecodedResponseThatIsNotAnArrayWillThrow() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn('foo'); + + $factory = new GraphObjectFactory($this->responseMock); + $factory->validateResponseAsArray(); + } + + public function testAValidGraphObjectResponseWillNotThrow() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn(['id' => '123', 'name' => 'foo']); + + $factory = new GraphObjectFactory($this->responseMock); + $factory->validateResponseCastableAsGraphObject(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testANonGraphObjectResponseWillThrow() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'data' => [ + ['id' => '123', 'name' => 'foo'], + ['id' => '1337', 'name' => 'bar'], + ] + ]); + + $factory = new GraphObjectFactory($this->responseMock); + $factory->validateResponseCastableAsGraphObject(); + } + + public function testAValidGraphListResponseWillNotThrow() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'data' => [ + ['id' => '123', 'name' => 'foo'], + ['id' => '1337', 'name' => 'bar'], + ] + ]); + + $factory = new GraphObjectFactory($this->responseMock); + $factory->validateResponseCastableAsGraphList(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testANonGraphListResponseWillThrow() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn(['id' => '123', 'name' => 'foo']); + + $factory = new GraphObjectFactory($this->responseMock); + $factory->validateResponseCastableAsGraphList(); + } + + public function testOnlyNumericArraysAreCastableAsAGraphList() + { + $shouldPassOne = GraphObjectFactory::isCastableAsGraphList([]); + $shouldPassTwo = GraphObjectFactory::isCastableAsGraphList(['foo', 'bar']); + $shouldFail = GraphObjectFactory::isCastableAsGraphList(['faz' => 'baz']); + + $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphList.'); + $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphList.'); + $this->assertFalse($shouldFail, 'Expected the given array to not be castable as a GraphList.'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidSubClassesWillThrow() + { + GraphObjectFactory::validateSubclass('FooSubClass'); + } + + public function testValidSubClassesWillNotThrow() + { + GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphObject'); + GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphAlbum'); + GraphObjectFactory::validateSubclass('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + } + + public function testCastingAsASubClassObjectWillInstantiateTheSubClass() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn(['id' => '123', 'name' => 'foo']); + + $factory = new GraphObjectFactory($this->responseMock); + $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + + $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); + } + + public function testASubClassMappingWillAutomaticallyInstantiateSubClass() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'id' => '123', + 'name' => 'Foo Name', + 'foo_object' => [ + 'id' => '1337', + 'name' => 'Should be sub classed!', + ], + ]); + + $factory = new GraphObjectFactory($this->responseMock); + $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $fooObject = $mySubClassObject->getProperty('foo_object'); + + $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', $fooObject); + } + + public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn([ + 'id' => '123', + 'name' => 'Foo Name', + 'unknown_object' => [ + 'id' => '1337', + 'name' => 'Should be generic!', + ], + ]); + + $factory = new GraphObjectFactory($this->responseMock); + + $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $unknownObject = $mySubClassObject->getProperty('unknown_object'); + + $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $unknownObject); + $this->assertNotInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $unknownObject); + } + + public function testAListFromGraphWillBeCastAsAGraphList() + { + $dataFromGraph = [ + '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', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + + $factory = new GraphObjectFactory($this->responseMock); + + $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]); + } + + public function testAGraphObjectWillBeCastAsAGraphObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + + $factory = new GraphObjectFactory($this->responseMock); + + $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 testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() + { + $dataFromGraph = [ + 'data' => [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + + $factory = new GraphObjectFactory($this->responseMock); + + $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 testACollectionWillBeCastRecursively() + { + $someUser = [ + 'id' => '123', + 'name' => 'Foo McBar', + ]; + $likesCollection = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + 'is_sexy' => true, + ], + [ + 'id' => '2', + 'name' => 'Yassine Guedidi', + 'is_sexy' => true, + ], + [ + 'id' => '3', + 'name' => 'Fosco Marotto', + 'is_sexy' => true, + ], + [ + 'id' => '4', + 'name' => 'Foo McUgly', + 'is_sexy' => false, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next_likes', + 'previous' => 'http://facebook/prev_likes', + ], + ]; + $commentsCollection = [ + 'data' => [ + [ + 'id' => '42_1', + 'from' => $someUser, + 'message' => 'Foo comment.', + 'created_time' => '2014-07-15T03:54:34+0000', + 'likes' => $likesCollection, + ], + [ + 'id' => '42_2', + 'from' => $someUser, + 'message' => 'Bar comment.', + 'created_time' => '2014-07-15T04:11:24+0000', + 'likes' => $likesCollection, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next_comments', + 'previous' => 'http://facebook/prev_comments', + ], + ]; + $dataFromGraph = [ + 'data' => [ + [ + 'id' => '1337_1', + 'from' => $someUser, + 'story' => 'Some great foo story.', + 'likes' => $likesCollection, + 'comments' => $commentsCollection, + ], + [ + 'id' => '1337_2', + 'from' => $someUser, + 'to' => [ + 'data' => [$someUser], + ], + 'message' => 'Some great bar message.', + 'likes' => $likesCollection, + 'comments' => $commentsCollection, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + + $factory = new GraphObjectFactory($this->responseMock); + + $graphObject = $factory->makeGraphList(); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphObject); + + // Story + $storyObject = $graphObject[0]; + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $storyObject['from']); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['likes']); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['comments']); + + // Story Comments + $storyComments = $storyObject['comments']; + $firstStoryComment = $storyComments[0]; + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $firstStoryComment['from']); + + // Message + $messageObject = $graphObject[1]; + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $messageObject['to']); + $toUsers = $messageObject['to']; + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $toUsers[0]); + } + +} diff --git a/tests/GraphNodes/GraphObjectTest.php b/tests/GraphNodes/GraphObjectTest.php index ee02410ae..9ddea1d75 100644 --- a/tests/GraphNodes/GraphObjectTest.php +++ b/tests/GraphNodes/GraphObjectTest.php @@ -25,8 +25,6 @@ use Facebook\GraphNodes\GraphObject; -class MyFooSubClassGraphObject extends GraphObject {} - class GraphObjectTest extends \PHPUnit_Framework_TestCase { @@ -35,7 +33,6 @@ public function testAnEmptyBaseGraphObjectCanInstantiate() $graphObject = new GraphObject(); $backingData = $graphObject->asArray(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([], $backingData); } @@ -47,72 +44,97 @@ public function testAGraphObjectCanInstantiateWithData() $this->assertEquals(['foo' => 'bar'], $backingData); } - public function testSomethingThatLooksLikeAListWillBeFlattened() + public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() { - $dataFromGraph = [ - 'data' => [ - [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], - ], - ]; - $graphObject = new GraphObject($dataFromGraph); - - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); - } + $graphObject = new GraphObject(); - public function testAnExistingPropertyCanBeAccessed() - { - $graphObject = new GraphObject(['foo' => 'bar']); - $property = $graphObject->getProperty('foo'); + // Should pass + $shouldPass = $graphObject->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 = $graphObject->isIso8601DateString('1999-12-31'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); - $this->assertEquals('bar', $property); + $shouldPass = $graphObject->isIso8601DateString('2009-05-19T14:39Z'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + $shouldPass = $graphObject->isIso8601DateString('2014-W36'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + // Should fail + $shouldFail = $graphObject->isIso8601DateString('2009-05-19T14a39r'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + + $shouldFail = $graphObject->isIso8601DateString('foo_time'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); } - public function testAMissingPropertyWillReturnNull() + public function testATimeStampCanBeConvertedToADateTimeObject() { - $graphObject = new GraphObject(['foo' => 'bar']); - $property = $graphObject->getProperty('baz'); + $someTimeStampFromGraph = 1405547020; + $graphObject = new GraphObject(); + $dateTime = $graphObject->castToDateTime($someTimeStampFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); - $this->assertNull($property, 'Expected the property to return null.'); + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); + $this->assertEquals(1405547020, $timeStamp); } - public function testAMissingPropertyWillReturnTheDefault() + public function testAGraphDateStringCanBeConvertedToADateTimeObject() { - $graphObject = new GraphObject(['foo' => 'bar']); - $property = $graphObject->getProperty('baz', 'faz'); + $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; + $graphObject = new GraphObject(); + $dateTime = $graphObject->castToDateTime($someDateStringFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); - $this->assertEquals('faz', $property); + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); + $this->assertEquals(1405395893, $timeStamp); } - public function testTheKeysFromTheGraphDataCanBeReturned() + public function testUncastingAGraphObjectWillUncastTheDateTimeObject() { - $graphObject = new GraphObject([ - 'key1' => 'foo', - 'key2' => 'bar', - 'key3' => 'baz', + $collectionOne = new GraphObject(['foo', 'bar']); + $collectionTwo = new GraphObject([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'some_collection' => $collectionOne, ]); - $propertyKeys = $graphObject->getPropertyNames(); - $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); + $uncastArray = $collectionTwo->uncastItems(); + + $this->assertEquals([ + 'id' => '123', + 'date' => '2014-07-15T03:44:53+0000', + 'some_collection' => ['foo', 'bar'], + ], $uncastArray); } - public function testAGraphObjectCanBeRecast() + public function testGettingGraphObjectAsAnArrayWillNotUncastTheDateTimeObject() { - $fooGraphObject = new GraphObject(['foo' => 'bar']); - $newFooGraphObject = $fooGraphObject->cast('Facebook\Tests\GraphNodes\MyFooSubClassGraphObject'); - $this->assertInstanceOf('Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $newFooGraphObject); + $collection = new GraphObject([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsArray = $collection->asArray(); + + $this->assertInstanceOf('DateTime', $collectionAsArray['date']); } - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testTryingToRecastToAGraphObjectThatDoesntExistWillThrow() + public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() { - $graphObject = new GraphObject(['foo' => 'bar']); - $graphObject->cast('FooClass'); + $collection = new GraphObject([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsString = $collection->asJson(); + + $this->assertEquals('{"id":"123","date":"2014-07-15T03:44:53+0000"}', $collectionAsString); } } diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php new file mode 100644 index 000000000..bb88e07b0 --- /dev/null +++ b/tests/GraphNodes/GraphPageTest.php @@ -0,0 +1,97 @@ +responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + } + + public function testPagePropertiesReturnGraphPageObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Page', + 'best_page' => [ + 'id' => '1', + 'name' => 'Bar Page', + ], + 'global_brand_parent_page' => [ + 'id' => '2', + 'name' => 'Faz Page', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphPage(); + + $bestPage = $graphObject->getBestPage(); + $globalBrandParentPage = $graphObject->getGlobalBrandParentPage(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $bestPage); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $globalBrandParentPage); + } + + public function testLocationPropertyWillGetCastAsGraphLocationObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Page', + 'location' => [ + 'city' => 'Washington', + 'country' => 'United States', + 'latitude' => 38.881634205431, + 'longitude' => -77.029121075722, + 'state' => 'DC', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphPage(); + + $location = $graphObject->getLocation(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphLocation', $location); + } + +} diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index 3c0709987..34939a403 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -23,18 +23,36 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\GraphNodes\GraphSessionInfo; +use Mockery as m; +use Facebook\GraphNodes\GraphObjectFactory; class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\Entities\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + } + public function testDatesGetCastToDateTime() { - $data = [ + $dataFromGraph = [ 'expires_at' => 123, 'issued_at' => 1337, ]; - $graphObject = new GraphSessionInfo($data); + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + + $graphObject = $factory->makeGraphSessionInfo(); $expires = $graphObject->getExpiresAt(); $issuedAt = $graphObject->getIssuedAt(); @@ -43,16 +61,4 @@ public function testDatesGetCastToDateTime() $this->assertInstanceOf('DateTime', $issuedAt); } - public function testScopesAreReturnedAsArray() - { - $data = [ - 'scopes' => ['foo', 'bar'], - ]; - $graphObject = new GraphSessionInfo($data); - - $scopes = $graphObject->getScopes(); - - $this->assertEquals(['foo', 'bar'], $scopes); - } - } diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index fc3974687..8f7de1ea4 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -23,36 +23,90 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\GraphNodes\GraphUser; +use Mockery as m; +use Facebook\GraphNodes\GraphObjectFactory; class GraphUserTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\Entities\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + } + public function testDatesGetCastToDateTime() { - $data = [ + $dataFromGraph = [ 'birthday' => '1984-01-01', ]; - $graphObject = new GraphUser($data); + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); $birthday = $graphObject->getBirthday(); $this->assertInstanceOf('DateTime', $birthday); } - public function testLocationGetsCastAsLocationObject() + public function testPagePropertiesWillGetCastAsGraphPageObjects() { - $data = [ + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'hometown' => [ + 'id' => '1', + 'name' => 'Foo Place', + ], 'location' => [ - 'id' => '123', - 'name' => 'Bar', + 'id' => '2', + 'name' => 'Bar Place', ], ]; - $graphObject = new GraphUser($data); + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $hometown = $graphObject->getHometown(); $location = $graphObject->getLocation(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphLocation', $location); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $hometown); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $location); + } + + public function testUserPropertiesWillGetCastAsGraphUserObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'significant_other' => [ + 'id' => '1337', + 'name' => 'Bar User', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $significantOther = $graphObject->getSignificantOther(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); } } From cdf28c7f96bf2ccd3d6c06b19980e415db4f9b2e Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 24 Aug 2014 01:18:39 -0500 Subject: [PATCH 045/407] Added support for Graph 2.1 --- src/Facebook/Entities/FacebookRequest.php | 2 +- src/Facebook/Entities/FacebookResponse.php | 19 ++++++++++++++----- .../Helpers/FacebookPageTabHelper.php | 3 +++ tests/Entities/FacebookResponseTest.php | 14 -------------- tests/FacebookClientTest.php | 2 +- tests/Helpers/FacebookPageTabHelperTest.php | 1 - 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 4006cdc7c..5191c53f1 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -41,7 +41,7 @@ class FacebookRequest /** * @var string Default Graph API version for requests. */ - protected static $defaultGraphApiVersion = 'v2.0'; + protected static $defaultGraphApiVersion = 'v2.1'; /** * @var FacebookApp The Facebook app entity. diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index aef857ebf..e95f96571 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -266,11 +266,13 @@ public function getThrownException() /** * Convert the raw response into an array if possible. * - * Graph will return 3 types of responses: + * Graph will return 2 types of responses: * - JSON(P) + * Most responses from Grpah are JSON(P) * - application/x-www-form-urlencoded key/value pairs - * - The string "true" - * ... And sometimes nothing :/ but that'd be a bug. + * Happens on the `/oauth/access_token` endpoint when exchanging + * a short-lived access token for a long-lived access token + * - And sometimes nothing :/ but that'd be a bug. */ public function decodeBody() { @@ -279,8 +281,15 @@ public function decodeBody() if ($this->decodedBody === null) { $this->decodedBody = []; parse_str($this->body, $this->decodedBody); - } elseif (is_bool($this->decodedBody)) { - $this->decodedBody = ['was_successful' => $this->decodedBody]; + } + + // Backwards compatibility for Graph < 2.1. + // Mimics 2.1 responses. + // @TODO Remove this after Graph 2.0 is no longer supported + elseif (is_bool($this->decodedBody)) { + $this->decodedBody = ['success' => $this->decodedBody]; + } elseif (is_numeric($this->decodedBody)) { + $this->decodedBody = ['id' => $this->decodedBody]; } if ($this->isError()) { diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 5eac7e35d..78eb4bfa0 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -71,6 +71,9 @@ public function getPageData($key, $default = null) } /** + * @TODO Deprecated: Remove after November 5, 2014 + * @see https://developers.facebook.com/blog/post/2014/08/07/Graph-API-v2.1/ + * * Returns true if the page is liked by the user. * * @return boolean diff --git a/tests/Entities/FacebookResponseTest.php b/tests/Entities/FacebookResponseTest.php index ddf298c73..91a3a2bac 100755 --- a/tests/Entities/FacebookResponseTest.php +++ b/tests/Entities/FacebookResponseTest.php @@ -102,19 +102,6 @@ public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() ], $decodedResponse); } - public function testASuccessfulBooleanResponseWillBeDecoded() - { - $app = new FacebookApp('123', 'foo_secret'); - $graphResponse = 'true'; - $response = new FacebookResponse($app, 200, [], $graphResponse); - - $decodedResponse = $response->getDecodedBody(); - - $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertEquals(['was_successful' => true], $decodedResponse); - } - - /* public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() { $app = new FacebookApp('123', 'foo_secret'); @@ -126,6 +113,5 @@ public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() $this->assertTrue($response->isError(), 'Expected Response to return an error.'); $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $exception); } - */ } diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index c4ce34ce3..8996d443f 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -249,7 +249,7 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() '/' . $testUserId); $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); - $this->assertTrue($graphObject->getProperty('was_successful')); + $this->assertTrue($graphObject->getProperty('success')); } public function initializeTestApp() diff --git a/tests/Helpers/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php index 9133d9f21..5c2e4e12a 100644 --- a/tests/Helpers/FacebookPageTabHelperTest.php +++ b/tests/Helpers/FacebookPageTabHelperTest.php @@ -38,7 +38,6 @@ public function testPageDataCanBeAccessed() $app = new FacebookApp('123', 'foo_app_secret'); $helper = new FacebookPageTabHelper($app); - $this->assertTrue($helper->isLiked()); $this->assertFalse($helper->isAdmin()); $this->assertEquals('42', $helper->getPageId()); $this->assertEquals('42', $helper->getPageData('id')); From b42c0733892a24d4071d5b0c62dbdf1d7c5cecaf Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 4 Sep 2014 16:59:32 -0500 Subject: [PATCH 046/407] Renamed the Canvas and JavaScript helpers --- ...cebookCanvasLoginHelper.php => FacebookCanvasHelper.php} | 2 +- ...vaScriptLoginHelper.php => FacebookJavaScriptHelper.php} | 2 +- src/Facebook/Helpers/FacebookPageTabHelper.php | 2 +- ...nvasLoginHelperTest.php => FacebookCanvasHelperTest.php} | 6 +++--- ...LoginHelperTest.php => FacebookJavaScriptHelperTest.php} | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename src/Facebook/Helpers/{FacebookCanvasLoginHelper.php => FacebookCanvasHelper.php} (95%) rename src/Facebook/Helpers/{FacebookJavaScriptLoginHelper.php => FacebookJavaScriptHelper.php} (94%) rename tests/Helpers/{FacebookCanvasLoginHelperTest.php => FacebookCanvasHelperTest.php} (92%) rename tests/Helpers/{FacebookJavaScriptLoginHelperTest.php => FacebookJavaScriptHelperTest.php} (94%) diff --git a/src/Facebook/Helpers/FacebookCanvasLoginHelper.php b/src/Facebook/Helpers/FacebookCanvasHelper.php similarity index 95% rename from src/Facebook/Helpers/FacebookCanvasLoginHelper.php rename to src/Facebook/Helpers/FacebookCanvasHelper.php index a2eab27e8..72cc33580 100644 --- a/src/Facebook/Helpers/FacebookCanvasLoginHelper.php +++ b/src/Facebook/Helpers/FacebookCanvasHelper.php @@ -29,7 +29,7 @@ * @author Fosco Marotto * @author David Poll */ -class FacebookCanvasLoginHelper extends FacebookSignedRequestFromInputHelper +class FacebookCanvasHelper extends FacebookSignedRequestFromInputHelper { /** diff --git a/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php b/src/Facebook/Helpers/FacebookJavaScriptHelper.php similarity index 94% rename from src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php rename to src/Facebook/Helpers/FacebookJavaScriptHelper.php index f72cb1729..042fb2ad9 100644 --- a/src/Facebook/Helpers/FacebookJavaScriptLoginHelper.php +++ b/src/Facebook/Helpers/FacebookJavaScriptHelper.php @@ -29,7 +29,7 @@ * @author Fosco Marotto * @author David Poll */ -class FacebookJavaScriptLoginHelper extends FacebookSignedRequestFromInputHelper +class FacebookJavaScriptHelper extends FacebookSignedRequestFromInputHelper { /** diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 5eac7e35d..97b3a7783 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -30,7 +30,7 @@ * @package Facebook * @author Fosco Marotto */ -class FacebookPageTabHelper extends FacebookCanvasLoginHelper +class FacebookPageTabHelper extends FacebookCanvasHelper { /** diff --git a/tests/Helpers/FacebookCanvasLoginHelperTest.php b/tests/Helpers/FacebookCanvasHelperTest.php similarity index 92% rename from tests/Helpers/FacebookCanvasLoginHelperTest.php rename to tests/Helpers/FacebookCanvasHelperTest.php index 90ad7579b..d436838ab 100644 --- a/tests/Helpers/FacebookCanvasLoginHelperTest.php +++ b/tests/Helpers/FacebookCanvasHelperTest.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\Helpers; use Facebook\Entities\FacebookApp; -use Facebook\Helpers\FacebookCanvasLoginHelper; +use Facebook\Helpers\FacebookCanvasHelper; class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase { @@ -32,14 +32,14 @@ class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; /** - * @var FacebookCanvasLoginHelper + * @var FacebookCanvasHelper */ protected $helper; public function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); - $this->helper = new FacebookCanvasLoginHelper($app); + $this->helper = new FacebookCanvasHelper($app); } public function testSignedRequestDataCanBeRetrievedFromPostData() diff --git a/tests/Helpers/FacebookJavaScriptLoginHelperTest.php b/tests/Helpers/FacebookJavaScriptHelperTest.php similarity index 94% rename from tests/Helpers/FacebookJavaScriptLoginHelperTest.php rename to tests/Helpers/FacebookJavaScriptHelperTest.php index 2663e80c9..1e1f10275 100644 --- a/tests/Helpers/FacebookJavaScriptLoginHelperTest.php +++ b/tests/Helpers/FacebookJavaScriptHelperTest.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\Helpers; use Facebook\Entities\FacebookApp; -use Facebook\Helpers\FacebookJavaScriptLoginHelper; +use Facebook\Helpers\FacebookJavaScriptHelper; class FacebookJavaScriptLoginHelperTest extends \PHPUnit_Framework_TestCase { @@ -36,7 +36,7 @@ public function testARawSignedRequestCanBeRetrievedFromCookieData() $_COOKIE['fbsr_123'] = $this->rawSignedRequestAuthorized; $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookJavaScriptLoginHelper($app); + $helper = new FacebookJavaScriptHelper($app); $rawSignedRequest = $helper->getRawSignedRequest(); From 1255da3a055691ac42d331994811ae22030d97a9 Mon Sep 17 00:00:00 2001 From: Keyvan Akbary Date: Wed, 10 Sep 2014 20:36:46 +0100 Subject: [PATCH 047/407] Remove unnecessary parameter for Mockery listener --- phpunit.xml.dist | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 1d9a820b7..370a34f10 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -17,8 +17,6 @@ - - + From 820adbf42677817891c7ba41d60033b09be70560 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 10 Sep 2014 15:25:40 -0500 Subject: [PATCH 048/407] Fix to allow FacebookRedirectLoginHelper->getAccessToken() to throw --- src/Facebook/Entities/AccessToken.php | 6 ++++++ src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 8 +++----- .../Helpers/FacebookSignedRequestFromInputHelper.php | 2 ++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 41beb55f0..2785ed38d 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -188,6 +188,8 @@ public static function validateAccessToken(GraphSessionInfo $tokenInfo, * @param string|null $machineId * * @return AccessToken + * + * @throws FacebookSDKException */ public static function getAccessTokenFromCode($code, FacebookApp $app, @@ -216,6 +218,8 @@ public static function getAccessTokenFromCode($code, * @param string|null $redirectUri * * @return AccessToken + * + * @throws FacebookSDKException */ public static function getCodeFromAccessToken($accessToken, FacebookApp $app, @@ -239,6 +243,8 @@ public static function getCodeFromAccessToken($accessToken, * @param FacebookClient $client The Facebook client. * * @return AccessToken + * + * @throws FacebookSDKException */ public function extend(FacebookApp $app, FacebookClient $client) { diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index c43799774..6f99cc97c 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -131,6 +131,8 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') * @param string $redirectUrl The redirect URL. * * @return AccessToken|null + * + * @throws FacebookSDKException */ public function getAccessToken(FacebookClient $client, $redirectUrl = null) { @@ -139,11 +141,7 @@ public function getAccessToken(FacebookClient $client, $redirectUrl = null) $redirectUrl = $redirectUrl ?: $this->getCurrentUri(); $redirectUrl = $this->getFilteredUri($redirectUrl); - try { - return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); - } catch (FacebookSDKException $e) { - return null; - } + return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); } return null; } diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index df3b5a6e8..072685e35 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -84,6 +84,8 @@ public function instantiateSignedRequest($rawSignedRequest = null) * @param FacebookClient $client The Facebook client. * * @return AccessToken|null + * + * @throws \Facebook\Exceptions\FacebookSDKException */ public function getAccessToken(FacebookClient $client) { From f49ba8fbd36124a3c41ef88eef9873ce82997ccf Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 10 Sep 2014 15:51:04 -0500 Subject: [PATCH 049/407] Updated array syntax to 5.4 --- docs/post_links.fbmd | 4 +- docs/upload_photo.fbmd | 4 +- src/Facebook/Entities/FacebookApp.php | 2 +- .../Exceptions/FacebookResponseException.php | 2 +- .../Helpers/FacebookRedirectLoginHelper.php | 8 +-- .../HttpClients/FacebookCurlHttpClient.php | 6 +- .../HttpClients/FacebookGuzzleHttpClient.php | 4 +- .../HttpClients/FacebookStreamHttpClient.php | 14 ++--- tests/Entities/SignedRequestTest.php | 6 +- .../FacebookResponseExceptionTest.php | 56 +++++++++---------- tests/HttpClients/AbstractTestHttpClient.php | 4 +- .../FacebookCurlHttpClientTest.php | 40 ++++++------- .../FacebookGuzzleHttpClientTest.php | 4 +- .../FacebookStreamHttpClientTest.php | 4 +- 14 files changed, 79 insertions(+), 79 deletions(-) diff --git a/docs/post_links.fbmd b/docs/post_links.fbmd index 7271e5024..851e6d350 100644 --- a/docs/post_links.fbmd +++ b/docs/post_links.fbmd @@ -21,10 +21,10 @@ if($session) { try { $response = (new FacebookRequest( - $session, 'POST', '/me/feed', array( + $session, 'POST', '/me/feed', [ 'link' => 'www.example.com', 'message' => 'User provided message' - ) + ] ))->execute()->getGraphObject(); echo "Posted with id: " . $response->getProperty('id'); diff --git a/docs/upload_photo.fbmd b/docs/upload_photo.fbmd index 989ac46b4..e6aa073e5 100644 --- a/docs/upload_photo.fbmd +++ b/docs/upload_photo.fbmd @@ -24,10 +24,10 @@ if($session) { // first album in the profile. You can also upload to // a specific album by using /ALBUM_ID as the path $response = (new FacebookRequest( - $session, 'POST', '/me/photos', array( + $session, 'POST', '/me/photos', [ 'source' => new CURLFile('path/to/file.name', 'image/png'), 'message' => 'User provided message' - ) + ] ))->execute()->getGraphObject(); // If you're not using PHP 5.5 or later, change the file reference to: diff --git a/src/Facebook/Entities/FacebookApp.php b/src/Facebook/Entities/FacebookApp.php index d7b9f316c..ff5e0c8c1 100644 --- a/src/Facebook/Entities/FacebookApp.php +++ b/src/Facebook/Entities/FacebookApp.php @@ -71,7 +71,7 @@ public function getAccessToken() public function serialize() { - return serialize(array($this->id, $this->secret)); + return serialize([$this->id, $this->secret]); } public function unserialize($serialized) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 41e5b76d2..59b7760e9 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -78,7 +78,7 @@ public static function create($raw, $data, $statusCode) { $data = self::convertToArray($data); if (!isset($data['error']['code']) && isset($data['code'])) { - $data = array('error' => $data); + $data = ['error' => $data]; } $code = (isset($data['error']['code']) ? $data['error']['code'] : null); diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index c43799774..24907a3b2 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -238,19 +238,19 @@ protected function getFilteredUri($uri) $query = ''; if (isset($parts['query'])) { - $full_query = array(); + $full_query = []; parse_str($parts['query'], $full_query); // remove Facebook appended query params - $toDrop = array(); + $toDrop = []; if (isset($full_query['state']) && isset($full_query['code'])) { - $toDrop = array('state', 'code'); + $toDrop = ['state', 'code']; } elseif (isset($full_query['state']) && isset($full_query['error']) && isset($full_query['error_reason']) && isset($full_query['error_description']) && isset($full_query['error_code'])) { - $toDrop = array('state', 'error', 'error_reason', 'error_description', 'error_code'); + $toDrop = ['state', 'error', 'error_reason', 'error_description', 'error_code']; } $real_query = array_diff_key($full_query, array_flip($toDrop)); diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index ffd215985..6d05fc524 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -147,13 +147,13 @@ public function send($url, $method = 'GET', array $parameters = [], array $heade */ public function openConnection($url, $method = 'GET', array $parameters = [], array $headers = []) { - $options = array( + $options = [ CURLOPT_URL => $url, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects CURLOPT_HEADER => true, // Enable header processing - ); + ]; if ($method !== "GET") { $options[CURLOPT_POSTFIELDS] = $parameters; @@ -248,7 +248,7 @@ public function extractResponseHeadersAndBody() */ public static function headersToArray($rawHeaders) { - $headers = array(); + $headers = []; // Normalize line breaks $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index 52e6b863b..da7dd9e33 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -89,9 +89,9 @@ public function getResponseHttpStatusCode() */ public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { - $options = array(); + $options = []; if ($parameters) { - $options = array('body' => $parameters); + $options = ['body' => $parameters]; } $request = self::$guzzleClient->createRequest($method, $url, $options); diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index a45fb4c6c..f58f0260c 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -85,17 +85,17 @@ public function getResponseHttpStatusCode() */ public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { - $options = array( - 'http' => array( + $options = [ + 'http' => [ 'method' => $method, 'timeout' => 60, 'ignore_errors' => true - ), - 'ssl' => array( + ], + 'ssl' => [ 'verify_peer' => true, 'cafile' => dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt', - ), - ); + ], + ]; if ($parameters) { $options['http']['content'] = http_build_query($parameters, null, '&'); @@ -146,7 +146,7 @@ public function compileHeader(array $headers) */ public static function formatHeadersToArray(array $rawHeaders) { - $headers = array(); + $headers = []; foreach ($rawHeaders as $line) { if (strpos($line, ':') === false) { diff --git a/tests/Entities/SignedRequestTest.php b/tests/Entities/SignedRequestTest.php index 202a222d2..67096fdcf 100644 --- a/tests/Entities/SignedRequestTest.php +++ b/tests/Entities/SignedRequestTest.php @@ -32,7 +32,7 @@ class SignedRequestTest extends \PHPUnit_Framework_TestCase public $rawSignedRequest = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; - public $payloadData = array( + public $payloadData = [ 'oauth_token' => 'foo_token', 'algorithm' => 'HMAC-SHA256', 'issued_at' => 321, @@ -40,7 +40,7 @@ class SignedRequestTest extends \PHPUnit_Framework_TestCase 'state' => 'foo_state', 'user_id' => 123, 'foo' => 'bar', - ); + ]; public function testValidSignedRequestsWillPassFormattingValidation() { @@ -97,7 +97,7 @@ public function testAValidEncodedPayloadCanBeDecoded() { $decodedPayload = SignedRequest::decodePayload('WyJwYXlsb2FkIl0='); - $this->assertEquals(array('payload'), $decodedPayload); + $this->assertEquals(['payload'], $decodedPayload); } /** diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index ac30cfaea..91e35e9ca 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -36,14 +36,14 @@ class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase public function testAuthorizationExceptions() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 100, 'message' => 'errmsg', 'error_subcode' => 0, 'type' => 'exception' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); @@ -101,14 +101,14 @@ public function testAuthorizationExceptions() public function testServerExceptions() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 1, 'message' => 'errmsg', 'error_subcode' => 0, 'type' => 'exception' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 500); $this->assertTrue($exception instanceof FacebookServerException); @@ -128,14 +128,14 @@ public function testServerExceptions() public function testThrottleExceptions() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 4, 'message' => 'errmsg', 'error_subcode' => 0, 'type' => 'exception' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookThrottleException); @@ -161,14 +161,14 @@ public function testThrottleExceptions() public function testUserIssueExceptions() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 230, 'message' => 'errmsg', 'error_subcode' => 459, 'type' => 'exception' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookAuthorizationException); @@ -188,14 +188,14 @@ public function testUserIssueExceptions() public function testPermissionExceptions() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 10, 'message' => 'errmsg', 'error_subcode' => 0, 'type' => 'exception' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookPermissionException); @@ -227,14 +227,14 @@ public function testPermissionExceptions() public function testClientExceptions() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 506, 'message' => 'errmsg', 'error_subcode' => 0, 'type' => 'exception' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 401); $this->assertTrue($exception instanceof FacebookClientException); @@ -248,14 +248,14 @@ public function testClientExceptions() public function testOtherException() { - $params = array( - 'error' => array( + $params = [ + 'error' => [ 'code' => 42, 'message' => 'ship love', 'error_subcode' => 0, 'type' => 'feature' - ) - ); + ], + ]; $json = json_encode($params); $exception = FacebookResponseException::create($json, $params, 200); $this->assertTrue($exception instanceof FacebookOtherException); diff --git a/tests/HttpClients/AbstractTestHttpClient.php b/tests/HttpClients/AbstractTestHttpClient.php index 9fca42be8..98c6a7770 100644 --- a/tests/HttpClients/AbstractTestHttpClient.php +++ b/tests/HttpClients/AbstractTestHttpClient.php @@ -45,7 +45,7 @@ abstract class AbstractTestHttpClient extends \PHPUnit_Framework_TestCase 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 = array( + protected $fakeHeadersAsArray = [ 'http_code' => 'HTTP/1.1 200 OK', 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', 'Content-Type' => 'text/javascript; charset=UTF-8', @@ -58,6 +58,6 @@ abstract class AbstractTestHttpClient extends \PHPUnit_Framework_TestCase 'Content-Length' => '29', 'Cache-Control' => 'private, no-cache, no-store, must-revalidate', 'Access-Control-Allow-Origin' => '*', - ); + ]; } diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 3b4b9b5a1..4e725c9db 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -61,13 +61,13 @@ public function testCanOpenGetCurlConnection() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with(array( + ->with([ CURLOPT_URL => 'http://foo.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, - )) + ]) ->once() ->andReturn(null); @@ -104,16 +104,16 @@ public function testCanOpenPostCurlConnection() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with(array( + ->with([ CURLOPT_URL => 'http://bar.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, - CURLOPT_POSTFIELDS => array( + CURLOPT_POSTFIELDS => [ 'baz' => 'bar', - ), - )) + ], + ]) ->once() ->andReturn(null); @@ -128,17 +128,17 @@ public function testCanOpenPutCurlConnection() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with(array( + ->with([ CURLOPT_URL => 'http://baz.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_CUSTOMREQUEST => 'PUT', - CURLOPT_POSTFIELDS => array( + CURLOPT_POSTFIELDS => [ 'baz' => 'bar', - ), - )) + ], + ]) ->once() ->andReturn(null); @@ -153,17 +153,17 @@ public function testCanOpenDeleteCurlConnection() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with(array( + ->with([ CURLOPT_URL => 'http://faz.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_CUSTOMREQUEST => 'DELETE', - CURLOPT_POSTFIELDS => array( + CURLOPT_POSTFIELDS => [ 'baz' => 'bar', - ), - )) + ], + ]) ->once() ->andReturn(null); @@ -235,7 +235,7 @@ public function testIsolatesTheHeaderAndBody() $this->curlMock ->shouldReceive('version') ->once() - ->andReturn(array('version_number' => self::CURL_VERSION_STABLE)); + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('exec') ->once() @@ -266,7 +266,7 @@ public function testProperlyHandlesProxyHeaders() $this->curlMock ->shouldReceive('version') ->once() - ->andReturn(array('version_number' => self::CURL_VERSION_STABLE)); + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('exec') ->once() @@ -294,7 +294,7 @@ public function testProperlyHandlesProxyHeadersWithCurlBug() $this->curlMock ->shouldReceive('version') ->once() - ->andReturn(array('version_number' => self::CURL_VERSION_BUGGY)); + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); $this->curlMock ->shouldReceive('exec') ->once() @@ -322,7 +322,7 @@ public function testProperlyHandlesProxyHeadersWithCurlBug2() $this->curlMock ->shouldReceive('version') ->once() - ->andReturn(array('version_number' => self::CURL_VERSION_BUGGY)); + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); $this->curlMock ->shouldReceive('exec') ->once() @@ -350,7 +350,7 @@ public function testProperlyHandlesRedirectHeaders() $this->curlMock ->shouldReceive('version') ->once() - ->andReturn(array('version_number' => self::CURL_VERSION_STABLE)); + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('exec') ->once() @@ -402,7 +402,7 @@ public function testCanSendNormalRequest() $this->curlMock ->shouldReceive('version') ->once() - ->andReturn(array('version_number' => self::CURL_VERSION_STABLE)); + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('close') ->once() diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index 0b5750505..9ec3a6e8f 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -99,12 +99,12 @@ public function testThrowsExceptionOnClientError() $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); $exceptionMock = m::mock( 'GuzzleHttp\Exception\RequestException', - array( + [ 'Foo Error', $requestMock, null, m::mock('GuzzleHttp\Exception\AdapterException'), - )); + ]); $this->guzzleMock ->shouldReceive('createRequest') diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index f47b41b43..9b979e58b 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -83,12 +83,12 @@ public function testCanSendNormalRequest() return false; } - if ($arg['http'] !== array( + if ($arg['http'] !== [ 'method' => 'GET', 'timeout' => 60, 'ignore_errors' => true, 'header' => 'X-foo: bar', - )) { + ]) { return false; } From 5f365bcf8d6fc5f9268d802872f253ec1ad3524f Mon Sep 17 00:00:00 2001 From: Keyvan Akbary Date: Wed, 10 Sep 2014 22:03:35 +0100 Subject: [PATCH 050/407] Test refactor --- tests/Entities/AccessTokenTest.php | 284 ++++++++++------------------- 1 file changed, 96 insertions(+), 188 deletions(-) diff --git a/tests/Entities/AccessTokenTest.php b/tests/Entities/AccessTokenTest.php index ad0c093f1..26b702c7a 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/Entities/AccessTokenTest.php @@ -26,6 +26,7 @@ use Mockery as m; use Facebook\Entities\FacebookApp; use Facebook\Entities\AccessToken; +use Facebook\GraphNodes\GraphSessionInfo; class AccessTokenTest extends \PHPUnit_Framework_TestCase { @@ -49,8 +50,7 @@ public function testShortLivedAccessTokensCanBeDetected() public function testLongLivedAccessTokensCanBeDetected() { - $aWeek = time() + (60 * 60 * 24 * 7); - $accessToken = new AccessToken('foo_token', $aWeek); + $accessToken = new AccessToken('foo_token', $this->aWeekFromNow()); $isLongLived = $accessToken->isLongLived(); @@ -59,160 +59,51 @@ public function testLongLivedAccessTokensCanBeDetected() public function testATokenIsValidatedOnTheAppIdAndMachineIdAndTokenValidityAndTokenExpiration() { - $aWeek = time() + (60 * 60 * 24 * 7); - $dt = new \DateTime(); - $dt->setTimestamp($aWeek); - - $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('app_id') - ->once() - ->andReturn('123'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('machine_id') - ->once() - ->andReturn('foo_machine'); - $graphSessionInfoMock - ->shouldReceive('getIsValid') - ->once() - ->andReturn(true); - $graphSessionInfoMock - ->shouldReceive('getExpiresAt') - ->twice() - ->andReturn($dt); - + $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', true, $this->aWeekFromNow()); $app = new FacebookApp('123', 'foo_secret'); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); + + $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); $this->assertTrue($isValid, 'Expected access token to be valid.'); } public function testATokenWillNotBeValidIfTheAppIdDoesNotMatch() { - $aWeek = time() + (60 * 60 * 24 * 7); - $dt = new \DateTime(); - $dt->setTimestamp($aWeek); - - $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('app_id') - ->once() - ->andReturn('1337'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('machine_id') - ->once() - ->andReturn('foo_machine'); - $graphSessionInfoMock - ->shouldReceive('getIsValid') - ->once() - ->andReturn(true); - $graphSessionInfoMock - ->shouldReceive('getExpiresAt') - ->twice() - ->andReturn($dt); - + $graphSession = $this->createGraphSessionInfo('1337', 'foo_machine', true, $this->aWeekFromNow()); $app = new FacebookApp('123', 'foo_secret'); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); + + $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because the app ID does not match.'); } public function testATokenWillNotBeValidIfTheMachineIdDoesNotMatch() { - $aWeek = time() + (60 * 60 * 24 * 7); - $dt = new \DateTime(); - $dt->setTimestamp($aWeek); - - $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('app_id') - ->once() - ->andReturn('123'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('machine_id') - ->once() - ->andReturn('foo_machine'); - $graphSessionInfoMock - ->shouldReceive('getIsValid') - ->once() - ->andReturn(true); - $graphSessionInfoMock - ->shouldReceive('getExpiresAt') - ->twice() - ->andReturn($dt); - + $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', true, $this->aWeekFromNow()); $app = new FacebookApp('123', 'foo_secret'); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'bar_machine'); + + $isValid = AccessToken::validateAccessToken($graphSession, $app, 'bar_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because the machine ID does not match.'); } public function testATokenWillNotBeValidIfTheCollectionTellsUsItsNotValid() { - $aWeek = time() + (60 * 60 * 24 * 7); - $dt = new \DateTime(); - $dt->setTimestamp($aWeek); - - $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('app_id') - ->once() - ->andReturn('123'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('machine_id') - ->once() - ->andReturn('foo_machine'); - $graphSessionInfoMock - ->shouldReceive('getIsValid') - ->once() - ->andReturn(false); - $graphSessionInfoMock - ->shouldReceive('getExpiresAt') - ->twice() - ->andReturn($dt); - + $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', false, $this->aWeekFromNow()); $app = new FacebookApp('123', 'foo_secret'); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); + + $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because the collection says it is not valid.'); } public function testATokenWillNotBeValidIfTheTokenHasExpired() { - $lastWeek = time() - (60 * 60 * 24 * 7); - $dt = new \DateTime(); - $dt->setTimestamp($lastWeek); - - $graphSessionInfoMock = m::mock('Facebook\GraphNodes\GraphSessionInfo'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('app_id') - ->once() - ->andReturn('123'); - $graphSessionInfoMock - ->shouldReceive('getProperty') - ->with('machine_id') - ->once() - ->andReturn('foo_machine'); - $graphSessionInfoMock - ->shouldReceive('getIsValid') - ->once() - ->andReturn(true); - $graphSessionInfoMock - ->shouldReceive('getExpiresAt') - ->twice() - ->andReturn($dt); - + $expiredTime = time() - (60 * 60 * 24 * 7); + $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', true, $expiredTime); $app = new FacebookApp('123', 'foo_secret'); - $isValid = AccessToken::validateAccessToken($graphSessionInfoMock, $app, 'foo_machine'); + + $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); $this->assertFalse($isValid, 'Expected access token to be invalid because it has expired.'); } @@ -220,23 +111,10 @@ public function testATokenWillNotBeValidIfTheTokenHasExpired() public function testInfoAboutAnAccessTokenCanBeObtainedFromGraph() { $app = new FacebookApp('123', 'foo_secret'); - $response = m::mock('Facebook\Entities\FacebookResponse'); - $response - ->shouldReceive('getGraphSessionInfo') - ->once() - ->andReturn($response); - $response - ->shouldReceive('getExpiresAt') - ->once() - ->andReturn(null); - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) - ->once() - ->andReturn($response); - + $response = $this->createFacebookResponseMockWithNoExpiresAt(); + $client = $this->createFacebookClientMockWithResponse($response); $accessToken = new AccessToken('foo_token'); + $accessTokenInfo = $accessToken->getInfo($app, $client); $this->assertSame($response, $accessTokenInfo); @@ -245,23 +123,14 @@ public function testInfoAboutAnAccessTokenCanBeObtainedFromGraph() public function testAShortLivedAccessTokenCabBeExtended() { $app = new FacebookApp('123', 'foo_secret'); - $response = m::mock('Facebook\Entities\FacebookResponse'); - $response - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'access_token' => 'long_token', - 'expires' => 123, - 'machine_id' => 'foo_machine', - ]); - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) - ->once() - ->andReturn($response); - + $response = $this->createFacebookResponseMockWithDecodedBody([ + 'access_token' => 'long_token', + 'expires' => 123, + 'machine_id' => 'foo_machine', + ]); + $client = $this->createFacebookClientMockWithResponse($response); $accessToken = new AccessToken('foo_token'); + $longLivedAccessToken = $accessToken->extend($app, $client); $this->assertInstanceOf('Facebook\Entities\AccessToken', $longLivedAccessToken); @@ -273,19 +142,10 @@ public function testAShortLivedAccessTokenCabBeExtended() public function testALongLivedAccessTokenCanBeUsedToObtainACode() { $app = new FacebookApp('123', 'foo_secret'); - $response = m::mock('Facebook\Entities\FacebookResponse'); - $response - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'code' => 'foo_code', - ]); - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) - ->once() - ->andReturn($response); + $response = $this->createFacebookResponseMockWithDecodedBody([ + 'code' => 'foo_code', + ]); + $client = $this->createFacebookClientMockWithResponse($response); $code = AccessToken::getCodeFromAccessToken('foo_token', $app, $client); @@ -295,21 +155,13 @@ public function testALongLivedAccessTokenCanBeUsedToObtainACode() public function testACodeCanBeUsedToObtainAnAccessToken() { $app = new FacebookApp('123', 'foo_secret'); - $response = m::mock('Facebook\Entities\FacebookResponse'); - $response - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'access_token' => 'new_long_token', - 'expires' => 123, - 'machine_id' => 'foo_machine', - ]); - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) - ->once() - ->andReturn($response); + $response = $this->createFacebookResponseMockWithDecodedBody([ + 'access_token' => 'new_long_token', + 'expires' => 123, + 'machine_id' => 'foo_machine', + ]); + $client = $this->createFacebookClientMockWithResponse($response); + $accessTokenFromCode = AccessToken::getAccessTokenFromCode('foo_code', $app, $client); $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessTokenFromCode); @@ -321,11 +173,67 @@ public function testACodeCanBeUsedToObtainAnAccessToken() public function testAccessTokenCanBeSerialized() { $accessToken = new AccessToken('foo', time(), 'bar'); + $newAccessToken = unserialize(serialize($accessToken)); - $this->assertEquals((string)$accessToken, (string)$newAccessToken); + $this->assertEquals((string) $accessToken, (string) $newAccessToken); $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); $this->assertEquals($accessToken->getMachineId(), $newAccessToken->getMachineId()); } + private function createGraphSessionInfo($appId, $machineId, $isValid, $expiresAt) + { + return new GraphSessionInfo([ + 'app_id' => $appId, + 'machine_id' => $machineId, + 'is_valid' => $isValid, + 'expires_at' => $expiresAt + ]); + } + + private function aWeekFromNow() + { + return time() + (60 * 60 * 24 * 7);//a week from now + } + + private function createFacebookClientMockWithResponse($response) + { + $client = m::mock('Facebook\FacebookClient'); + $client + ->shouldReceive('sendRequest') + ->with(m::type('Facebook\Entities\FacebookRequest')) + ->once() + ->andReturn($response); + return $client; + } + + private function createFacebookResponseMockWithDecodedBody($decodedBody) + { + $response = $this->createFacebookResponseMock(); + $response + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($decodedBody); + return $response; + } + + private function createFacebookResponseMock() + { + return m::mock('Facebook\Entities\FacebookResponse'); + } + + private function createFacebookResponseMockWithNoExpiresAt() + { + $response = $this->createFacebookResponseMock(); + $response + ->shouldReceive('getGraphSessionInfo') + ->once() + ->andReturn($response); + $response + ->shouldReceive('getExpiresAt') + ->once() + ->andReturn(null); + return $response; + } + } From dbd863e05b664c66764bb04288571fcff98279d8 Mon Sep 17 00:00:00 2001 From: Keyvan Akbary Date: Fri, 12 Sep 2014 00:16:33 +0100 Subject: [PATCH 051/407] Tests refactor --- tests/Entities/FacebookAppTest.php | 23 +- tests/Entities/FacebookBatchRequestTest.php | 353 +++++++++----------- 2 files changed, 164 insertions(+), 212 deletions(-) diff --git a/tests/Entities/FacebookAppTest.php b/tests/Entities/FacebookAppTest.php index 8b434feff..34e6caf4a 100644 --- a/tests/Entities/FacebookAppTest.php +++ b/tests/Entities/FacebookAppTest.php @@ -27,33 +27,34 @@ class FacebookAppTest extends \PHPUnit_Framework_TestCase { - public function testGetId() + private $app; + + public function setUp() { - $app = new FacebookApp('id', 'secret'); + $this->app = new FacebookApp('id', 'secret'); + } - $this->assertEquals('id', $app->getId()); + public function testGetId() + { + $this->assertEquals('id', $this->app->getId()); } public function testGetSecret() { - $app = new FacebookApp('id', 'secret'); - - $this->assertEquals('secret', $app->getSecret()); + $this->assertEquals('secret', $this->app->getSecret()); } public function testGetAccessToken() { - $app = new FacebookApp('id', 'secret'); - $accessToken = $app->getAccessToken(); + $accessToken = $this->app->getAccessToken(); $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); - $this->assertEquals('id|secret', (string)$accessToken); + $this->assertEquals('id|secret', (string) $accessToken); } public function testSerialization() { - $app = new FacebookApp('id', 'secret'); - $newApp = unserialize(serialize($app)); + $newApp = unserialize(serialize($this->app)); $this->assertInstanceOf('Facebook\Entities\FacebookApp', $newApp); $this->assertEquals('id', $newApp->getId()); diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/Entities/FacebookBatchRequestTest.php index 4c44fa08a..f77c36016 100755 --- a/tests/Entities/FacebookBatchRequestTest.php +++ b/tests/Entities/FacebookBatchRequestTest.php @@ -30,69 +30,50 @@ class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase { - protected $requestHeaders = []; + private $app; public function setUp() { - $this->requestHeaders = []; - foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { - $this->requestHeaders[] = $name . ': ' . $value; - } + $this->app = new FacebookApp('123', 'foo_secret'); } - public function testEmptyBatchRequestEntitiesCanBeInstantiated() + public function testABatchRequestWillInstantiateWithTheProperProperties() { - $batchRequest = new FacebookBatchRequest(); - $this->assertInstanceOf('Facebook\Entities\FacebookBatchRequest', $batchRequest); + $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', [], 'v0.1337'); + + $this->assertSame($this->app, $batchRequest->getApp()); + $this->assertEquals('foo_token', $batchRequest->getAccessToken()); + $this->assertEquals('POST', $batchRequest->getMethod()); + $this->assertEquals('', $batchRequest->getEndpoint()); + $this->assertEquals('v0.1337', $batchRequest->getGraphVersion()); } - public function testABatchRequestWillInstantiateWithTheProperProperties() + public function testEmptyRequestWillFallbackToBatchDefaults() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token', [], 'v0.1337'); - - $batchApp = $batchRequest->getApp(); - $accessToken = $batchRequest->getAccessToken(); - $method = $batchRequest->getMethod(); - $endpoint = $batchRequest->getEndpoint(); - $graphVersion = $batchRequest->getGraphVersion(); - - $this->assertSame($app, $batchApp); - $this->assertEquals('foo_token', $accessToken); - $this->assertEquals('POST', $method); - $this->assertEquals('', $endpoint); - $this->assertEquals('v0.1337', $graphVersion); + $request = new FacebookRequest(); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $this->app, 'foo_token'); } - public function testMissingAppOrAccessTokensOnRequestObjectsWillFallbackToBatchDefaults() + public function testRequestWithTokenOnlyWillFallbackToBatchDefaults() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + $request = new FacebookRequest(null, 'bar_token'); - $requestTotallyEmpty = new FacebookRequest(); - $batchRequest->addFallbackDefaults($requestTotallyEmpty); - $appTotallyEmpty = $requestTotallyEmpty->getApp(); - $accessTokenTotallyEmpty = $requestTotallyEmpty->getAccessToken(); + $this->createBatchRequest()->addFallbackDefaults($request); - $this->assertSame($app, $appTotallyEmpty); - $this->assertEquals('foo_token', $accessTokenTotallyEmpty); - - $requestTokenOnly = new FacebookRequest(null, 'bar_token'); - $batchRequest->addFallbackDefaults($requestTokenOnly); - $appTokenOnly = $requestTokenOnly->getApp(); - $accessTokenTokenOnly = $requestTokenOnly->getAccessToken(); + $this->assertRequestContainsAppAndToken($request, $this->app, 'bar_token'); + } - $this->assertSame($app, $appTokenOnly); - $this->assertEquals('bar_token', $accessTokenTokenOnly); + public function testRequestWithAppOnlyWillFallbackToBatchDefaults() + { + $customApp = new FacebookApp('1337', 'bar_secret'); + $request = new FacebookRequest($customApp); - $myApp = new FacebookApp('1337', 'bar_secret'); - $requestAppOnly = new FacebookRequest($myApp); - $batchRequest->addFallbackDefaults($requestAppOnly); - $appAppOnly = $requestAppOnly->getApp(); - $accessTokenAppOnly = $requestAppOnly->getAccessToken(); + $this->createBatchRequest()->addFallbackDefaults($request); - $this->assertSame($myApp, $appAppOnly); - $this->assertEquals('foo_token', $accessTokenAppOnly); + $this->assertRequestContainsAppAndToken($request, $customApp, 'foo_token'); } /** @@ -102,8 +83,7 @@ public function testWillThrowWhenNoThereIsNoAppFallback() { $batchRequest = new FacebookBatchRequest(); - $requestTotallyEmpty = new FacebookRequest(null, 'foo_token'); - $batchRequest->addFallbackDefaults($requestTotallyEmpty); + $batchRequest->addFallbackDefaults(new FacebookRequest(null, 'foo_token')); } /** @@ -111,11 +91,9 @@ public function testWillThrowWhenNoThereIsNoAppFallback() */ public function testWillThrowWhenNoThereIsNoAccessTokenFallback() { - $batchRequest = new FacebookBatchRequest(); + $request = new FacebookBatchRequest(); - $app = new FacebookApp('123', 'foo_secret'); - $requestTotallyEmpty = new FacebookRequest($app); - $batchRequest->addFallbackDefaults($requestTotallyEmpty); + $request->addFallbackDefaults(new FacebookRequest($this->app)); } /** @@ -123,103 +101,53 @@ public function testWillThrowWhenNoThereIsNoAccessTokenFallback() */ public function testAnInvalidTypeGivenToAddWillThrow() { - $batchRequest = new FacebookBatchRequest(); + $request = new FacebookBatchRequest(); - $batchRequest->add('foo'); + $request->add('foo'); } public function testAddingRequestsWillBeFormattedInAnArrayProperly() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); - - $requestOne = new FacebookRequest(null, null, 'GET', '/foo'); - $requestTwo = new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']); - $requestThree = new FacebookRequest(null, null, 'DELETE', '/baz'); + $requests = [ + null => new FacebookRequest(null, null, 'GET', '/foo'), + 'my-second-request' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + 'my-third-request' => new FacebookRequest(null, null, 'DELETE', '/baz') + ]; - $batchRequest->add($requestOne); - $batchRequest->add($requestTwo, 'my-second-request'); - $batchRequest->add($requestThree, 'my-third-request'); + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($requests[null]); + $batchRequest->add($requests['my-second-request'], 'my-second-request'); + $batchRequest->add($requests['my-third-request'], 'my-third-request'); - $requests = $batchRequest->getRequests(); + $formattedRequests = $batchRequest->getRequests(); - $expectedRequests = [ - [ - 'name' => null, - 'request' => $requestOne, - ], - [ - 'name' => 'my-second-request', - 'request' => $requestTwo, - ], - [ - 'name' => 'my-third-request', - 'request' => $requestThree, - ], - ]; - $this->assertEquals($expectedRequests, $requests); + $this->assertRequestsMatch($requests, $formattedRequests); } public function testANumericArrayOfRequestsCanBeAdded() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); - $requests = [ new FacebookRequest(null, null, 'GET', '/foo'), new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), new FacebookRequest(null, null, 'DELETE', '/baz'), - ]; + ]; - $batchRequest->add($requests); - $formattedRequests = $batchRequest->getRequests(); + $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); - $expectedRequests = [ - [ - 'name' => 0, - 'request' => $requests[0], - ], - [ - 'name' => 1, - 'request' => $requests[1], - ], - [ - 'name' => 2, - 'request' => $requests[2], - ], - ]; - $this->assertEquals($expectedRequests, $formattedRequests); + $this->assertRequestsMatch($requests, $formattedRequests); } public function testAnAssociativeArrayOfRequestsCanBeAdded() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); - $requests = [ 'req-one' => new FacebookRequest(null, null, 'GET', '/foo'), 'req-two' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), 'req-three' => new FacebookRequest(null, null, 'DELETE', '/baz'), - ]; + ]; - $batchRequest->add($requests); - $formattedRequests = $batchRequest->getRequests(); + $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); - $expectedRequests = [ - [ - 'name' => 'req-one', - 'request' => $requests['req-one'], - ], - [ - 'name' => 'req-two', - 'request' => $requests['req-two'], - ], - [ - 'name' => 'req-three', - 'request' => $requests['req-three'], - ], - ]; - $this->assertEquals($expectedRequests, $formattedRequests); + $this->assertRequestsMatch($requests, $formattedRequests); } public function testRequestsCanBeInjectedIntoConstructor() @@ -230,26 +158,10 @@ public function testRequestsCanBeInjectedIntoConstructor() new FacebookRequest(null, null, 'DELETE', '/baz'), ]; - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token', $requests); - + $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', $requests); $formattedRequests = $batchRequest->getRequests(); - $expectedRequests = [ - [ - 'name' => 0, - 'request' => $requests[0], - ], - [ - 'name' => 1, - 'request' => $requests[1], - ], - [ - 'name' => 2, - 'request' => $requests[2], - ], - ]; - $this->assertEquals($expectedRequests, $formattedRequests); + $this->assertRequestsMatch($requests, $formattedRequests); } /** @@ -257,8 +169,8 @@ public function testRequestsCanBeInjectedIntoConstructor() */ public function testAZeroRequestCountWithThrow() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + $batchRequest = new FacebookBatchRequest($this->app, 'foo_token'); + $batchRequest->validateBatchRequestCount(); } @@ -267,92 +179,82 @@ public function testAZeroRequestCountWithThrow() */ public function testMoreThanFiftyRequestsWillThrow() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + $batchRequest = $this->createBatchRequest(); + + $this->createAndAppendRequestsTo($batchRequest, 51); - for ($i=0; $i<=50; $i++) { - $batchRequest->add(new FacebookRequest()); - } $batchRequest->validateBatchRequestCount(); } - public function testLessThanFiftyRequestsWillNotThrow() + public function testLessOrEqualThanFiftyRequestsWillNotThrow() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); + $batchRequest = $this->createBatchRequest(); + + $this->createAndAppendRequestsTo($batchRequest, 50); - for ($i=0; $i<50; $i++) { - $batchRequest->add(new FacebookRequest()); - } $batchRequest->validateBatchRequestCount(); } - public function testBatchRequestEntitiesProperlyGetConvertedToAnArrayForJsonEncodingForEachMethod() + /** + * @dataProvider requestsAndExpectedResponsesProvider + */ + public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $expectedArray) { - $app = new FacebookApp('123', 'foo_secret'); - - // GET request - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); - $batchRequest->add(new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), 'foo_name'); + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, 'foo_name'); $requests = $batchRequest->getRequests(); $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); - $expectedArray = [ - 'headers' => $this->requestHeaders, - 'method' => 'GET', - 'relative_url' => '/'.FacebookRequest::getDefaultGraphApiVersion().'/foo?foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - 'name' => 'foo_name', - ]; - $this->assertEquals($expectedArray, $batchRequestArray); + } - // POST request - $batchRequest = new FacebookBatchRequest($app, 'bar_token'); - $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['bar' => 'baz']), 'bar_name'); - - $requests = $batchRequest->getRequests(); - $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); - - $expectedArray = [ - 'headers' => $this->requestHeaders, - 'method' => 'POST', - 'relative_url' => '/'.FacebookRequest::getDefaultGraphApiVersion().'/bar', - 'body' => 'bar=baz&access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd', - 'name' => 'bar_name', - ]; - - $this->assertEquals($expectedArray, $batchRequestArray); - - // DELETE request - $batchRequest = new FacebookBatchRequest($app, 'bar_token'); - $batchRequest->add(new FacebookRequest(null, null, 'DELETE', '/bar'), 'bar_name'); - - $requests = $batchRequest->getRequests(); - $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); - - $expectedArray = [ - 'headers' => $this->requestHeaders, - 'method' => 'DELETE', - 'relative_url' => '/'.FacebookRequest::getDefaultGraphApiVersion().'/bar?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd', - 'name' => 'bar_name', + public function requestsAndExpectedResponsesProvider() + { + $headers = $this->defaultHeaders(); + $apiVersion = FacebookRequest::getDefaultGraphApiVersion(); + return [ + [ + new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), + [ + 'headers' => $headers, + 'method' => 'GET', + 'relative_url' => '/' . $apiVersion . '/foo?foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + [ + new FacebookRequest(null, null, 'POST', '/bar', ['bar' => 'baz']), + [ + 'headers' => $headers, + 'method' => 'POST', + 'relative_url' => '/' . $apiVersion . '/bar', + 'body' => 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + [ + new FacebookRequest(null, null, 'DELETE', '/bar'), + [ + 'headers' => $headers, + 'method' => 'DELETE', + 'relative_url' => '/' . $apiVersion . '/bar?access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], ]; - - $this->assertEquals($expectedArray, $batchRequestArray); } public function testPreppingABatchRequestProperlySetsThePostParams() { - $app = new FacebookApp('123', 'foo_secret'); - $batchRequest = new FacebookBatchRequest($app, 'foo_token'); - + $batchRequest = $this->createBatchRequest(); $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar'])); - $batchRequest->prepareRequestsForBatch(); + $params = $batchRequest->getParams(); - $expectedHeaders = json_encode($this->requestHeaders); + $expectedHeaders = json_encode($this->defaultHeaders()); $version = FacebookRequest::getDefaultGraphApiVersion(); $expectedBatchParams = [ 'batch' => '[{"headers":'.$expectedHeaders.',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' @@ -364,4 +266,53 @@ public function testPreppingABatchRequestProperlySetsThePostParams() $this->assertEquals($expectedBatchParams, $params); } + private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) + { + $app = $request->getApp(); + $token = $request->getAccessToken(); + + $this->assertSame($expectedApp, $app); + $this->assertEquals($expectedToken, $token); + } + + private function defaultHeaders() + { + $headers = []; + foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { + $headers[] = $name . ': ' . $value; + } + return $headers; + } + + private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $number) + { + for ($i = 0; $i < $number; $i++) { + $batchRequest->add(new FacebookRequest()); + } + } + + private function createBatchRequest() + { + return new FacebookBatchRequest($this->app, 'foo_token'); + } + + private function createBatchRequestWithRequests(array $requests) + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($requests); + return $batchRequest; + } + + private function assertRequestsMatch($requests, $formattedRequests) + { + $expectedRequests = []; + foreach ($requests as $name => $request) { + $expectedRequests[] = [ + 'name' => $name, + 'request' => $request + ]; + } + $this->assertEquals($expectedRequests, $formattedRequests); + } + } From 8cdb3f1500d7984b042375cf9b02ca7030879774 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 9 Oct 2014 03:48:35 -0500 Subject: [PATCH 052/407] Fixed birthday not being converted to DateTime --- src/Facebook/GraphNodes/GraphObject.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index ce8c3288d..63292b5fc 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -65,7 +65,9 @@ public function castItems(array $data) foreach ($data as $k => $v) { if ( $this->shouldCastAsDateTime($k) - && (is_numeric($v) || $this->isIso8601DateString($v)) + && (is_numeric($v) + || $k === 'birthday' + || $this->isIso8601DateString($v)) ) { $items[$k] = $this->castToDateTime($v); } else { From 2081faf8c5cadc15ab722d50657909c324d643f0 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 9 Oct 2014 03:20:12 -0500 Subject: [PATCH 053/407] Added Facebook super service class --- README.md | 20 +- src/Facebook/Entities/FacebookRequest.php | 39 +- src/Facebook/Facebook.php | 379 ++++++++++++++++++ src/Facebook/GraphNodes/GraphObject.php | 4 +- .../Helpers/FacebookRedirectLoginHelper.php | 6 +- tests/Entities/FacebookBatchRequestTest.php | 5 +- tests/Entities/FacebookRequestTest.php | 7 +- tests/FacebookTest.php | 141 +++++++ .../FacebookRedirectLoginHelperTest.php | 4 +- 9 files changed, 547 insertions(+), 58 deletions(-) create mode 100644 src/Facebook/Facebook.php create mode 100644 tests/FacebookTest.php diff --git a/README.md b/README.md index f3b7f43b1..ce39bb6f9 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,15 @@ Usage Simple GET example of a user's profile. ```php -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\FacebookClient; -use Facebook\GraphNodes\GraphUser; +use Facebook\Facebook; use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +$fb = new Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + // 'default_access_token' => '{access-token}', // optional +]); // Use one of the helper classes to get a Facebook\Entities\AccessToken entity. // Facebook\Helpers\FacebookRedirectLoginHelper @@ -31,13 +32,10 @@ $facebookApp = new FacebookApp('{app-id}', '{app-secret}'); // Facebook\Helpers\FacebookCanvasLoginHelper // Facebook\Helpers\FacebookPageTabHelper -// Get the Facebook\GraphNodes\GraphUser object for the current user: -$facebookClient = new FacebookClient(); -$request = new FacebookRequest($facebookApp, '{access-token}', 'GET', '/me'); - try { - $facebookResponse = $facebookClient->sendRequest($request); - $me = $facebookResponse->getGraphObject(GraphUser::className()); + // Get the Facebook\GraphNodes\GraphUser object for the current user: + $response = $fb->get('/me', '{access-token}'); + $me = $response->getGraphUser(); echo 'Logged in as ' . $me->getName(); } catch(FacebookResponseException $e) { // When Graph returns an error diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 5191c53f1..558502ea4 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Entities; +use Facebook\Facebook; use Facebook\Exceptions\FacebookSDKException; /** @@ -32,17 +33,6 @@ class FacebookRequest { - /** - * @TODO Move this to a global `Facebook` class. - * @const string Version number of the Facebook PHP SDK. - */ - const VERSION = '4.1.0-dev'; - - /** - * @var string Default Graph API version for requests. - */ - protected static $defaultGraphApiVersion = 'v2.1'; - /** * @var FacebookApp The Facebook app entity. */ @@ -105,7 +95,7 @@ public function __construct( $this->setEndpoint($endpoint); $this->setParams($params); $this->setETag($eTag); - $this->graphVersion = $graphVersion ?: static::getDefaultGraphApiVersion(); + $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; } /** @@ -386,29 +376,6 @@ public static function forceSlashPrefix($string) return strpos($string, '/') === 0 ? $string : '/'.$string; } - /** - * Returns the default Graph version. - * - * @param string|null $graphApiVersion The Graph version we want to use. - * - * @return string - */ - public static function getDefaultGraphApiVersion($graphApiVersion = null) - { - return $graphApiVersion ?: static::$defaultGraphApiVersion; - } - - /** - * Sets the default Graph API version. - * - * @param string $graphApiVersion - */ - public static function setDefaultGraphApiVersion($graphApiVersion) - { - static::$defaultGraphApiVersion = $graphApiVersion; - } - - /** * Return the default headers that every request should use. * @@ -417,7 +384,7 @@ public static function setDefaultGraphApiVersion($graphApiVersion) public static function getDefaultHeaders() { return [ - 'User-Agent' => 'fb-php-' . static::VERSION, + 'User-Agent' => 'fb-php-' . Facebook::VERSION, 'Accept-Encoding' => '*', ]; } diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php new file mode 100644 index 000000000..b34dd9723 --- /dev/null +++ b/src/Facebook/Facebook.php @@ -0,0 +1,379 @@ +app = new FacebookApp($appId, $appSecret); + + $httpClientHandler = null; + if (isset($config['http_client_handler'])) { + if ( $config['http_client_handler'] instanceof FacebookHttpClientInterface) { + $httpClientHandler = $config['http_client_handler']; + } elseif ($config['http_client_handler'] === 'curl') { + $httpClientHandler = new FacebookCurlHttpClient(); + } elseif ($config['http_client_handler'] === 'stream') { + $httpClientHandler = new FacebookStreamHttpClient(); + } elseif ($config['http_client_handler'] === 'guzzle') { + $httpClientHandler = new FacebookGuzzleHttpClient(); + } else { + throw new \InvalidArgumentException( + 'The http_client_handler must be set to "curl", "stream", "guzzle", ' + . ' or be an instance of Facebook\HttpClients\FacebookHttpClientInterface' + ); + } + } + $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; + $this->client = new FacebookClient($httpClientHandler, $enableBeta); + + if (isset($config['default_access_token'])) { + if (is_string($config['default_access_token'])) { + $this->defaultAccessToken = new AccessToken($config['default_access_token']); + } elseif ( ! $config['default_access_token'] instanceof AccessToken) { + throw new \InvalidArgumentException( + 'The "default_access_token" provided must be of type "string"' + . ' or Facebook\Entities\AccessToken' + ); + } + } + + $this->defaultGraphVersion = isset($config['default_graph_version']) + ? $config['default_graph_version'] + : static::DEFAULT_GRAPH_VERSION; + } + + /** + * Returns the FacebookApp entity. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Returns the FacebookClient service. + * + * @return FacebookClient + */ + public function getClient() + { + return $this->client; + } + + /** + * Returns the default AccessToken entity. + * + * @return AccessToken|null + */ + public function getDefaultAccessToken() + { + return $this->defaultAccessToken; + } + + /** + * Returns the default Graph version. + * + * @return string + */ + public function getDefaultGraphVersion() + { + return $this->defaultGraphVersion; + } + + /** + * Sends a GET request to Graph and returns the result. + * + * @param string $endpoint + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function get( + $endpoint, + $accessToken = null, + $eTag = null, + $graphVersion = null) + { + return $this->sendRequest( + 'GET', + $endpoint, + $params = [], + $accessToken, + $eTag, + $graphVersion); + } + + /** + * Sends a POST request to Graph and returns the result. + * + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function post( + $endpoint, + array $params = [], + $accessToken = null, + $eTag = null, + $graphVersion = null) + { + return $this->sendRequest( + 'POST', + $endpoint, + $params, + $accessToken, + $eTag, + $graphVersion); + } + + /** + * Sends a DELETE request to Graph and returns the result. + * + * @param string $endpoint + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function delete( + $endpoint, + $accessToken = null, + $eTag = null, + $graphVersion = null) + { + return $this->sendRequest( + 'DELETE', + $endpoint, + $params = [], + $accessToken, + $eTag, + $graphVersion); + } + + /** + * Sends a request to Graph and returns the result. + * + * @param string $method + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function sendRequest( + $method, + $endpoint, + array $params = [], + $accessToken = null, + $eTag = null, + $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); + return $this->client->sendRequest($request); + } + + /** + * Sends a batched request to Graph and returns the result. + * + * @param array $requests + * @param AccessToken|string|null $accessToken + * @param string|null $graphVersion + * + * @return FacebookBatchResponse + * + * @throws FacebookSDKException + */ + public function sendBatchRequest( + array $requests, + $accessToken = null, + $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $batchRequest = new FacebookBatchRequest( + $this->app, + $accessToken, + $requests, + $graphVersion + ); + + return $this->client->sendBatchRequest($batchRequest); + } + + /** + * 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) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + return new FacebookRequest( + $this->app, + $accessToken, + $method, + $endpoint, + $params, + $eTag, + $graphVersion + ); + } + +} diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index ce8c3288d..63292b5fc 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -65,7 +65,9 @@ public function castItems(array $data) foreach ($data as $k => $v) { if ( $this->shouldCastAsDateTime($k) - && (is_numeric($v) || $this->isIso8601DateString($v)) + && (is_numeric($v) + || $k === 'birthday' + || $this->isIso8601DateString($v)) ) { $items[$k] = $this->castToDateTime($v); } else { diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 14890cb3b..b464e0d68 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -23,9 +23,9 @@ */ namespace Facebook\Helpers; +use Facebook\Facebook; use Facebook\Entities\AccessToken; use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookClient; @@ -86,14 +86,14 @@ public function getLoginUrl($redirectUrl, $version = null, $separator = '&') { - $version = FacebookRequest::getDefaultGraphApiVersion($version); + $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; $state = $this->generateState(); $this->storeState($state); $params = [ 'client_id' => $this->app->getId(), 'redirect_uri' => $redirectUrl, 'state' => $state, - 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, + 'sdk' => 'php-sdk-' . Facebook::VERSION, 'scope' => implode(',', $scope) ]; diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/Entities/FacebookBatchRequestTest.php index f77c36016..f2659b1ac 100755 --- a/tests/Entities/FacebookBatchRequestTest.php +++ b/tests/Entities/FacebookBatchRequestTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\Entities; +use Facebook\Facebook; use Facebook\Entities\FacebookApp; use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookBatchRequest; @@ -212,7 +213,7 @@ public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, public function requestsAndExpectedResponsesProvider() { $headers = $this->defaultHeaders(); - $apiVersion = FacebookRequest::getDefaultGraphApiVersion(); + $apiVersion = Facebook::DEFAULT_GRAPH_VERSION; return [ [ new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), @@ -255,7 +256,7 @@ public function testPreppingABatchRequestProperlySetsThePostParams() $params = $batchRequest->getParams(); $expectedHeaders = json_encode($this->defaultHeaders()); - $version = FacebookRequest::getDefaultGraphApiVersion(); + $version = Facebook::DEFAULT_GRAPH_VERSION; $expectedBatchParams = [ 'batch' => '[{"headers":'.$expectedHeaders.',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' .'{"headers":'.$expectedHeaders.',"method":"POST","relative_url":"\\/' . $version . '\\/bar","body":"foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9"}]', diff --git a/tests/Entities/FacebookRequestTest.php b/tests/Entities/FacebookRequestTest.php index f7b7732b6..9c089ddd9 100755 --- a/tests/Entities/FacebookRequestTest.php +++ b/tests/Entities/FacebookRequestTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\Entities; +use Facebook\Facebook; use Facebook\Entities\FacebookApp; use Facebook\Entities\FacebookRequest; @@ -104,14 +105,14 @@ public function testAProperUrlWillBeGenerated() $getUrl = $getRequest->getUrl(); $expectedParams = 'foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; - $expectedUrl = '/' . FacebookRequest::getDefaultGraphApiVersion() . '/foo?' . $expectedParams; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; $this->assertEquals($expectedUrl, $getUrl); $postRequest = new FacebookRequest($app, 'foo_token', 'POST', '/bar', ['foo' => 'bar']); $postUrl = $postRequest->getUrl(); - $expectedUrl = '/' . FacebookRequest::getDefaultGraphApiVersion() . '/bar'; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar'; $this->assertEquals($expectedUrl, $postUrl); } @@ -134,7 +135,7 @@ public function testParamsAreNotOverwritten() $url = $request->getUrl(); $expectedParams = 'access_token=bar_access_token&appsecret_proof=bar_app_secret'; - $expectedUrl = '/' . FacebookRequest::getDefaultGraphApiVersion() . '/foo?' . $expectedParams; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; $this->assertEquals($expectedUrl, $url); $params = $request->getParams(); diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php new file mode 100644 index 000000000..3bb9d2a36 --- /dev/null +++ b/tests/FacebookTest.php @@ -0,0 +1,141 @@ + 'bar']; } + public function getResponseHttpStatusCode() { return 1337; } + public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { return 'foo_response'; } +} + +class FacebookTest extends \PHPUnit_Framework_TestCase +{ + + protected $config = [ + 'app_id' => '1337', + 'app_secret' => 'foo_secret', + ]; + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInstantiatingWithoutAppIdThrows() + { + $config = [ + 'app_secret' => 'foo_secret', + ]; + $fb = new Facebook($config); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInstantiatingWithoutAppSecretThrows() + { + $config = [ + 'app_id' => 'foo_id', + ]; + $fb = new Facebook($config); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidHttpClientHandlerThrows() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testCurlHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'curl' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\HttpClients\FacebookCurlHttpClient', + $fb->getClient()->getHttpClientHandler()); + } + + public function testStreamHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'stream' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\HttpClients\FacebookStreamHttpClient', + $fb->getClient()->getHttpClientHandler()); + } + + public function testGuzzleHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'guzzle' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\HttpClients\FacebookGuzzleHttpClient', + $fb->getClient()->getHttpClientHandler()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnAccessThatIsNotStringOrAccessTokenThrows() + { + $config = array_merge($this->config, [ + 'default_access_token' => 123, + ]); + $fb = new Facebook($config); + } + + public function testCreatingANewRequestWillDefaultToTheProperConfig() + { + $config = array_merge($this->config, [ + 'default_access_token' => 'foo_token', + 'http_client_handler' => new FooClientInterface(), + 'enable_beta_mode' => true, + 'default_graph_version' => 'v1337', + ]); + $fb = new Facebook($config); + + $request = $fb->request('FOO_VERB', '/foo'); + $this->assertInstanceOf('Facebook\Tests\FooClientInterface', + $fb->getClient()->getHttpClientHandler()); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, + $fb->getClient()->getBaseGraphUrl()); + $this->assertEquals('1337', $request->getApp()->getId()); + $this->assertEquals('foo_secret', $request->getApp()->getSecret()); + $this->assertEquals('foo_token', (string) $request->getAccessToken()); + $this->assertEquals('v1337', $request->getGraphVersion()); + } + +} diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index c826f4bb8..7118edc46 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -24,8 +24,8 @@ namespace Facebook\Tests\Helpers; use Mockery as m; +use Facebook\Facebook; use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; use Facebook\Helpers\FacebookRedirectLoginHelper; class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase @@ -49,7 +49,7 @@ public function testLoginURL() 'client_id' => '123', 'redirect_uri' => self::REDIRECT_URL, 'state' => $_SESSION['FBRLH_state'], - 'sdk' => 'php-sdk-' . FacebookRequest::VERSION, + 'sdk' => 'php-sdk-' . Facebook::VERSION, 'scope' => implode(',', $scope), ]; foreach ($params as $key => $value) { From 81fd86fc9c575e2c6117c4d34dc4c74fb3d63cb6 Mon Sep 17 00:00:00 2001 From: Nick Escobedo Date: Sat, 18 Oct 2014 18:43:24 -0500 Subject: [PATCH 054/407] Fixed testing timezone bug. --- tests/bootstrap.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9b1e36495..dfc4c4da2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -21,9 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -if ( ! ini_get('date.timezone')) { - date_default_timezone_set('Europe/Paris'); -} +date_default_timezone_set('Europe/Paris'); require_once __DIR__ . '/../vendor/autoload.php'; From a0b3f0177aa84841fdd224d579ce46407186111e Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 4 Nov 2014 11:41:55 -0600 Subject: [PATCH 055/407] Got 4.1 documentation a bit more up-to-date --- CHANGELOG.md | 8 + README.md | 2 +- docs/Facebook.fbmd | 265 ++++++++++++++++++ docs/FacebookCanvasHelper.fbmd | 135 +++++++++ docs/FacebookCanvasLoginHelper.fbmd | 106 ------- docs/FacebookJavaScriptHelper.fbmd | 125 +++++++++ docs/FacebookJavaScriptLoginHelper.fbmd | 39 --- docs/FacebookRequest.fbmd | 23 +- ...on.fbmd => FacebookResponseException.fbmd} | 0 docs/post_links.fbmd | 42 ++- docs/sdk_downloads.fbmd | 58 ++-- docs/sdk_reference.fbmd | 12 +- 12 files changed, 610 insertions(+), 205 deletions(-) create mode 100644 docs/Facebook.fbmd create mode 100644 docs/FacebookCanvasHelper.fbmd delete mode 100644 docs/FacebookCanvasLoginHelper.fbmd create mode 100644 docs/FacebookJavaScriptHelper.fbmd delete mode 100644 docs/FacebookJavaScriptLoginHelper.fbmd rename docs/{FacebookRequestException.fbmd => FacebookResponseException.fbmd} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c1a9583b..9f44da0c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,11 +24,19 @@ As you may have already noticed, the Facebook SDK v4 does not follow strict [sem - Added `Facebook\Entities\FacebookApp` entity - Namespaced tests - Grouped functional tests under `functional` group + - Added `Facebook\Facebook` super service - Added this CHANGELOG. Hi! :) ## 4.0.x +- 4.0.12 (2014-10-30) + - Added Graph v2.2 support + - 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 - 4.0.10 (2014-08-12) - [`GraphObject`] Fixed improper usage of `stdClass` - Fixed warnings when `open_basedir` directive set diff --git a/README.md b/README.md index ce39bb6f9..0a79f4537 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ use Facebook\Exceptions\FacebookSDKException; $fb = new Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - // 'default_access_token' => '{access-token}', // optional + //'default_access_token' => '{access-token}', // optional ]); // Use one of the helper classes to get a Facebook\Entities\AccessToken entity. diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd new file mode 100644 index 000000000..6b76ed196 --- /dev/null +++ b/docs/Facebook.fbmd @@ -0,0 +1,265 @@ + +# 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 {#overview} + +To instantiate a new `Facebook\Facebook` service, pass an array of configuration options to the constructor. + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + // . . . + ]); +~~~~ + +Usage: + +~~~~ +// 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. + +~~~~ +$res = $fb->get('/me', '{access-token}'); +$res = $fb->post('/me/feed', ['foo' => 'bar'], '{access-token}'); +$res = $fb->delete('/{node-id}', '{access-token}'); +~~~~ + + + +## Configuration options {#config} + +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: + +~~~~ +$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.2', + 'http_client_handler' => 'guzzle', +]); +~~~~ + +### `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\Entities\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/support/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.0`. Defaults to the latest version of Graph. + +### `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](/docs/php/FacebookHttpClientInterface)` and set this value to an instance of your custom client. + +~~~~ +$fb = new Facebook([ + 'http_client_handler' => new MyCustomHttpClient(), +]); +~~~~ + +If any other value is provided an `InvalidArgumentException` will be thrown. + + + +## Environment variables fallback {#env-vars} + +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. + +~~~~ +$fb = new Facebook\Facebook(); +~~~~ + + + +## Instance Methods {#instance-methods} + +### getApp() {#get-app} +~~~~ +public FacebookApp getApp() +~~~~ +Returns the instance of `Facebook\Entities\FacebookApp` for the instantiated service. + + + +### getClient() {#get-client} +~~~~ +public FacebookClient getClient() +~~~~ +Returns the instance of `Facebook\FacebookClient` for the instantiated service. + + + +### getDefaultAccessToken() {#get-default-access-token} +~~~~ +public AccessToken|null getDefaultAccessToken() +~~~~ +Returns the default `Facebook\Entities\AccessToken` entity if the configuration option `default_access_token` was set. + + + +### getDefaultGraphVersion() {#get-default-graph-version} +~~~~ +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() {#get} +~~~~ +public Facebook\Entities\FacebookResponse get( + string $endpoint, + string|AccessToken|null $accessToken, + string|null $eTag, + string|null $graphVersion +) +~~~~ + +Sends a GET request to Graph and returns a `Facebook\Entities\FacebookResponse`. + +`$endpoint` +The url to send to Graph without the version prefix (required). + +~~~ +$fb->get('/me'); +~~~ + +`$accessToken` +The access token (as a `string` or `Facebook\Entities\AccessToken`) 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/reference/ads-api/etags-reference/). Set this to the eTag from a previous request to get a `304 Not Modified` response if the data has not changed. + +`$graphVersion` +Set the Graph version to something other than what was set in the `default_graph_version` configuration option or `Facebook\Facebook::DEFAULT_GRAPH_VERSION`. + + + +### post() {#post} +~~~~ +public Facebook\Entities\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\Entities\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. + +~~~~ +$response = $fb->post('/me/feed', ['message' => 'Foo message']); +~~~~ + + + +### delete() {#delete} +~~~~ +public Facebook\Entities\FacebookResponse delete( + string $endpoint, + string|AccessToken|null $accessToken, + string|null $eTag, + string|null $graphVersion +) +~~~~ + +Sends a DELETE request to Graph and returns a `Facebook\Entities\FacebookResponse`. + +The arguments are the same as `get()` above. + +~~~~ +$response = $fb->delete('/{node-id}'); +~~~~ + + + +### request() {#request} +~~~~ +public Facebook\Entities\FacebookRequest request( + string $method, + string $endpoint, + array $params, + string|AccessToken|null $accessToken, + string|null $eTag, + string|null $graphVersion +) +~~~~ + +Instantiates a new `Facebook\Entities\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. + +~~~~ +$request = $fb->request('GET', '/{node-id}'); +~~~~ + + + +### sendBatchRequest() {#send-batch-request} +~~~~ +public Facebook\Entities\FacebookBatchResponse sendBatchRequest( + array $requests, + string|AccessToken|null $accessToken, + string|null $graphVersion +) +~~~~ + +Sends an array of `Facebook\Entities\FacebookRequest` entities as a batch request to Graph. + +The `$accessToken` and `$graphVersion` arguments are the same as `get()` above. + +`$requests` +An array of `Facebook\Entities\FacebookRequest` entities. This can be a numeric or associative array but every value of the array has to be of type `Facebook\Entities\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/#operations). + +~~~~ +$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); +~~~~ + diff --git a/docs/FacebookCanvasHelper.fbmd b/docs/FacebookCanvasHelper.fbmd new file mode 100644 index 000000000..2f879b500 --- /dev/null +++ b/docs/FacebookCanvasHelper.fbmd @@ -0,0 +1,135 @@ + +# 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). + +~~~ +Facebook\Helpers\FacebookCanvasHelper( Facebook\Entities\FacebookApp $facebookApp ) +~~~ + + + +## Usage {#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. + +~~~ +use Facebook\Helpers\FacebookCanvasHelper; + +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + ]); +$facebookApp = $fb->getApp(); + +$canvasHelper = new FacebookCanvasHelper($facebookApp); +$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. + +~~~ +use Facebook\Helpers\FacebookCanvasHelper; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; + +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + ]); +$facebookApp = $fb->getApp(); +$facebookClient = $fb->getClient(); + +try { + $canvasHelper = new FacebookCanvasHelper($facebookApp); + $accessToken = $canvasHelper->getAccessToken($facebookClient); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { + // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); +} + +if (isset($accessToken)) { + // Logged in. +} +~~~ + + + +## Instance Methods {#instance-methods} + +### __construct() {#construct} +~~~~ +public FacebookCanvasHelper __construct( Facebook\Entities\FacebookApp $app ) +~~~~ +Upon instantiation, `FacebookCanvasHelper` validates and decrypts the signed request that was sent via POST if present. + + + +### getAccessToken() {#get-access-token} +~~~ +public Facebook\Entities\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) +~~~ +Checks the signed request for authentication data and tries to obtain an access token access token. + + + +### getUserId() {#get-user-id} +~~~ +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. + +~~~ +$userId = $canvasHelper->getUserId(); + +if ($userId) { + // User is logged in +} +~~~ + +This is equivalent to accessing the user ID from the signed request entity. + +~~~ +$signedRequest = $canvasHelper->getSignedRequest(); + +if ($signedRequest) { + $userId = $signedRequest->getUserId(); + // OR + $userId = $signedRequest->get('user_id'); +} +~~~ + + + +### getAppData() {#get-app-data} +~~~ +public string|null getAppData() +~~~ +Gets the value that is set in the `app_data` property if present. + + + +### getSignedRequest() {#get-signed-request} +~~~ +public Facebook\Entities\SignedRequest|null getSignedRequest() +~~~ +Returns the signed request as a [`Facebook\Entities\SignedRequest`](/docs/php/SignedRequest) entity if present. + + + +### getRawSignedRequest() {#get-raw-signed-request} +~~~ +public string|null getRawSignedRequest() +~~~ +Gets the raw, unencrypted signed request that was sent via POST if present. + +Returns a an encrypted signed request as a `string` or `null`. + \ No newline at end of file diff --git a/docs/FacebookCanvasLoginHelper.fbmd b/docs/FacebookCanvasLoginHelper.fbmd deleted file mode 100644 index 27fbba7e9..000000000 --- a/docs/FacebookCanvasLoginHelper.fbmd +++ /dev/null @@ -1,106 +0,0 @@ - -# Facebook\Helpers\FacebookCanvasLoginHelper - -The `FacebookCanvasLoginHelper` 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). - -~~~ -Facebook\Helpers\FacebookCanvasLoginHelper( Facebook\Entities\FacebookApp $facebookApp ) -~~~ - - - -## Usage {#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. - -~~~ -use Facebook\Entities\FacebookApp; -use Facebook\Helpers\FacebookCanvasLoginHelper; - -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); - -$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); -$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. - -~~~ -use Facebook\Entities\FacebookApp; -use Facebook\FacebookClient; -use Facebook\Helpers\FacebookCanvasLoginHelper; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; - -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); - -$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); - -$facebookClient = new FacebookClient(); -$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); -try { - $accessToken = $canvasHelper->getAccessToken($facebookClient); -} catch(FacebookResponseException $e) { - // When Graph returns an error - echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { - // When validation fails or other local issues - echo 'Facebook SDK returned an error: ' . $e->getMessage(); -} - -if (isset($accessToken)) { - // Logged in. -} -~~~ - - - -## Instance Methods {#instance-methods} - -`getAccessToken()` -Checks the signed request for authentication data and tries to obtain an access token access token. - -~~~ -public getAccessToken( Facebook\FacebookClient $client ) -~~~ - -Returns a `Facebook\Entities\AccessToken` entity or `null`. - - - -`getAppData()` -Gets what ever value is set in the `app_data` property if present. - -~~~ -public getAppData( void ) -~~~ - -Returns the `app_data` value or `null`. - - - -`getSignedRequest()` -Validates and decrypts the signed request that was sent via POST if present. - -~~~ -public getSignedRequest( void ) -~~~ - -Returns a `Facebook\Entities\SignedRequest` entity or `null`. - - - -`getRawSignedRequest()` -Gets the raw, unencrypted signed request that was sent via POST if present. - -~~~ -public getRawSignedRequest( void ) -~~~ - -Returns a an encrypted signed request `string` or `null`. - \ No newline at end of file diff --git a/docs/FacebookJavaScriptHelper.fbmd b/docs/FacebookJavaScriptHelper.fbmd new file mode 100644 index 000000000..14f0d853e --- /dev/null +++ b/docs/FacebookJavaScriptHelper.fbmd @@ -0,0 +1,125 @@ + +# 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 {#usage} + +This helper will handle validating and decrypting the signed request from the cookie set by the JavaScript SDK. + +~~~ +use Facebook\Helpers\FacebookJavaScriptHelper; + +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + ]); +$facebookApp = $fb->getApp(); + +$jsHelper = new FacebookJavaScriptHelper($facebookApp); +$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. + +~~~ +use Facebook\Helpers\FacebookJavaScriptHelper; +use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookSDKException; + +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + ]); +$facebookApp = $fb->getApp(); +$facebookClient = $fb->getClient(); + +try { + $jsHelper = new FacebookJavaScriptHelper($facebookApp); + $accessToken = $jsHelper->getAccessToken($facebookClient); +} catch(FacebookResponseException $e) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); +} catch(FacebookSDKException $e) { + // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); +} + +if (isset($accessToken)) { + // Logged in. +} +~~~ + +It's important to note that on first access, or if a session has since expired, these methods will operate on data that is one request-cycle stale. 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 {#instance-methods} + +### __construct() {#construct} +~~~~ +public FacebookJavaScriptHelper __construct( Facebook\Entities\FacebookApp $app ) +~~~~ +Upon instantiation, `FacebookJavaScriptHelper` validates and decrypts the signed request that exists in the cookie set by the JavaScript SDK if present. + + + +### getAccessToken() {#get-access-token} +~~~ +public Facebook\Entities\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) +~~~ +Checks the signed request for authentication data and tries to obtain an access token access token. + + + +### getUserId() {#get-user-id} +~~~ +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. + +~~~ +$userId = $jsHelper->getUserId(); + +if ($userId) { + // User is logged in +} +~~~ + +This is equivalent to accessing the user ID from the signed request entity. + +~~~ +$signedRequest = $jsHelper->getSignedRequest(); + +if ($signedRequest) { + $userId = $signedRequest->getUserId(); + // OR + $userId = $signedRequest->get('user_id'); +} +~~~ + + + +### getSignedRequest() {#get-signed-request} +~~~ +public Facebook\Entities\SignedRequest|null getSignedRequest() +~~~ +Returns the signed request as a [`Facebook\Entities\SignedRequest`](/docs/php/SignedRequest) entity if present. + + + +### getRawSignedRequest() {#get-raw-signed-request} +~~~ +public string|null getRawSignedRequest() +~~~ +Gets the raw, unencrypted signed request that was sent via POST if present. + +Returns a an encrypted signed request as a `string` or `null`. + \ No newline at end of file diff --git a/docs/FacebookJavaScriptLoginHelper.fbmd b/docs/FacebookJavaScriptLoginHelper.fbmd deleted file mode 100644 index 5bda7fbaf..000000000 --- a/docs/FacebookJavaScriptLoginHelper.fbmd +++ /dev/null @@ -1,39 +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. - - - -## Facebook\FacebookJavaScriptLoginHelper {#overview} - -If your web app uses the Facebook SDK for JavaScript, you can access that in your PHP code as well. This helper class will process and validate the cookie data used by the Facebook SDK for JavaScript, returning a `FacebookSession` on success. - -Usage: - -~~~~ - -$helper = new FacebookJavaScriptLoginHelper(); -try { - $session = $helper->getSession(); -} catch(FacebookResponseException $ex) { - // When Facebook returns an error -} catch(\Exception $ex) { - // When validation fails or other local issues -} -if ($session) { - // Logged in. -} - -~~~~ - -It's important to note that on first access, or if a session has since expired, these methods will operate on data that is one request-cycle stale. 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 {#instance-methods} - -### getSession {#getsession} -`getSession()` -Processes the data available from the Facebook SDK for JavaScript, if present. Returns a `FacebookSession` or `null`. - \ No newline at end of file diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index 8eea7db5e..f04759b66 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -1,24 +1,31 @@ # FacebookRequest for the Facebook SDK for PHP -Represents a request that will be made against the Graph API. +Represents a request that will be sent to the Graph API. -## Facebook\FacebookRequest {#overview} +## Facebook\Entities\FacebookRequest {#overview} -Constructor: +You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. ~~~~ +use Facebook\Entities\FacebookRequest; + $request = new FacebookRequest( - FacebookSession $session, - string $httpMethod, - string $path, - array $params = NULL, - string $version = NULL + FacebookApp $app, + string $accessToken, + string $method, + string $endpoint, + array $params, + string $eTag, + string $graphVersion ); ~~~~ +Alternatively, you can make use of the `Facebook\Facebook::request()` factory to create new `FacebookRequest` instances. [See full `Facebook\Facebook` reference](/docs/php/Facebook) + + Usage: ~~~~ diff --git a/docs/FacebookRequestException.fbmd b/docs/FacebookResponseException.fbmd similarity index 100% rename from docs/FacebookRequestException.fbmd rename to docs/FacebookResponseException.fbmd diff --git a/docs/post_links.fbmd b/docs/post_links.fbmd index 851e6d350..e1ea71c0a 100644 --- a/docs/post_links.fbmd +++ b/docs/post_links.fbmd @@ -3,42 +3,36 @@ 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 set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). You must have requested the `publish_actions` scope when logging in the user for this to work. - -For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookResponseException`](/docs/php/FacebookResponseException). +It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/reference#helpers). You must have requested the `publish_actions` permission when logging in the user for this to work. +For more information, see the documentation for [`Facebook`](/docs/php/Facebook), [`GraphObject`](/docs/php/GraphObject), and [`FacebookResponseException`](/docs/php/FacebookResponseException). ~~~~ -use Facebook\FacebookRequest; -use Facebook\GraphObject; -use Facebook\FacebookResponseException; - -if($session) { - - try { +use Facebook\Exceptions\FacebookResponseException; - $response = (new FacebookRequest( - $session, 'POST', '/me/feed', [ - 'link' => 'www.example.com', - 'message' => 'User provided message' - ] - ))->execute()->getGraphObject(); +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + ]); - echo "Posted with id: " . $response->getProperty('id'); +$linkData = [ + 'link' => 'http://www.example.com', + 'message' => 'User provided message', + ]; - } catch(FacebookResponseException $e) { +try { + $response = $fb->post('/me/feed', $linkData, '{access-token}'); + $graphObject = $response->getGraphObject(); - echo "Exception occured, code: " . $e->getCode(); - echo " with message: " . $e->getMessage(); - - } + echo 'Posted with id: ' . $graphObject['id']; +} catch(FacebookResponseException $e) { + echo 'There was an error: ' . $e->getMessage(); } ~~~~ 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). - - \ No newline at end of file + diff --git a/docs/sdk_downloads.fbmd b/docs/sdk_downloads.fbmd index 80676122d..30ff20cd2 100644 --- a/docs/sdk_downloads.fbmd +++ b/docs/sdk_downloads.fbmd @@ -1,68 +1,80 @@ # Downloads for the Facebook SDK 4.x for PHP +For full details on what changed between each version release, see the [CHANGELOG](https://github.com/facebook/facebook-php-sdk-v4/blob/master/CHANGELOG.md). + FB(devsite:markdown-wiki:table { - columns: ['Package','Date','Change Log',], + columns: ['Package','Date','Change Summary',], rows: [ [ '[Facebook SDK 4.1.0](https://github.com/facebook/facebook-php-sdk-v4/archive/4.1.0.zip)', 'TBD', - '', + 'New API, removed statics', + ], + [ + '[Facebook SDK 4.0.12](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.12.zip)', + 'October 30, 2014', + 'Graph v2.2 support', + ], + [ + '[Facebook SDK 4.0.11](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.11.zip)', + 'August 25, 2014', + 'Re-request support', ], [ '[Facebook SDK 4.0.10](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.10.zip)', - '', - '', + 'August 12, 2014', + 'Bug fixes', ], [ '[Facebook SDK 4.0.9](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.9.zip)', - '', - '', + 'June 27, 2014', + 'Improved security, added autoloader', ], [ '[Facebook SDK 4.0.8](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.8.zip)', - '', - '', + 'June 10, 2014', + 'Added stream wrapper and Guzzle HTTP clients', ], [ '[Facebook SDK 4.0.7](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.7.zip)', - '', - '', + 'May 31, 2014', + 'Added `FacebookPageTabHelper`', ], [ '[Facebook SDK 4.0.6](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.6.zip)', - '', - '', + 'May 24, 2014', + 'Custom HTTP clients', ], [ '[Facebook SDK 4.0.5](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.5.zip)', - '', - '', + 'May 19, 2014', + 'Added stream wrapper fallback', ], [ '[Facebook SDK 4.0.4](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.4.zip)', - '', - '', + 'May 15, 2014', + 'Added more error codes', ], [ '[Facebook SDK 4.0.3](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.3.zip)', - '', - '', + 'May 14, 2014', + 'Bug fixes', ], [ '[Facebook SDK 4.0.2](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.2.zip)', - '', - '', + 'May 7, 2014', + 'Added PSR-4, eTags', ], [ '[Facebook SDK 4.0.1](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.1.zip)', - '', - '', + 'May 5, 2014', + 'Improved signed request parsing', ], [ '[Facebook SDK 4.0.0](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.0.zip)', 'April 30, 2014', - '', + 'Initial release. Yay!', ], ], }) diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 1da96809f..2a1018d37 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -12,6 +12,10 @@ Services orchestrate multiple components of the SDK. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ + [ + '`[Facebook\Facebook](/docs/php/Facebook)`', + 'The main service object that helps tie all the SDK components together.', + ], [ '`[Facebook\FacebookClient](/docs/php/FacebookClient)`', 'A service object to send requests and receive responses from the Graph API.', @@ -153,8 +157,8 @@ FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\Helpers\FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper)`', - 'Used to obtain an access token or signed request within the context of an app canvas.', + '`[Facebook\Helpers\FacebookCanvasHelper](/docs/php/FacebookCanvasHelper)`', + 'Used to obtain an access token or signed request from within the context of an app canvas.', ], [ '`[Facebook\Helpers\FacebookJavaScriptHelper](/docs/php/FacebookJavaScriptHelper)`', @@ -162,7 +166,7 @@ FB(devsite:markdown-wiki:table { ], [ '`[Facebook\Helpers\FacebookPageTabHelper](/docs/php/FacebookPageTabHelper)`', - 'Used to obtain an access token or signed request within the context of a page tab.', + 'Used to obtain an access token or signed request from within the context of a page tab.', ], [ '`[Facebook\Helpers\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper)`', @@ -175,7 +179,7 @@ FB(devsite:markdown-wiki:table { # HTTP clients {#http-clients} -Various HTTP clients that can be implemented to send and return requests to Graph. +Various HTTP clients that can be implemented to send and return requests to and from Graph. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], From 12a9602fe4f456c9b2091cd65b859a531e3c8362 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 4 Nov 2014 11:52:55 -0600 Subject: [PATCH 056/407] Added Graph v2.2 support --- src/Facebook/Facebook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index b34dd9723..552b9e80e 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -52,7 +52,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.1'; + const DEFAULT_GRAPH_VERSION = 'v2.2'; /** * @const string The name of the environment variable From ce2f6a1bd6f5891779f8b0691548ac6c755c4257 Mon Sep 17 00:00:00 2001 From: Veres Lajos Date: Fri, 7 Nov 2014 22:18:57 +0000 Subject: [PATCH 057/407] typo fixes - https://github.com/vlajos/misspell_fixer --- docs/retrieve_user_profile.fbmd | 2 +- docs/upload_photo.fbmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/retrieve_user_profile.fbmd b/docs/retrieve_user_profile.fbmd index b94cce047..37f6cad9a 100644 --- a/docs/retrieve_user_profile.fbmd +++ b/docs/retrieve_user_profile.fbmd @@ -28,7 +28,7 @@ if($session) { } catch(FacebookResponseException $e) { - echo "Exception occured, code: " . $e->getCode(); + echo "Exception occurred, code: " . $e->getCode(); echo " with message: " . $e->getMessage(); } diff --git a/docs/upload_photo.fbmd b/docs/upload_photo.fbmd index e6aa073e5..477726e32 100644 --- a/docs/upload_photo.fbmd +++ b/docs/upload_photo.fbmd @@ -37,7 +37,7 @@ if($session) { } catch(FacebookResponseException $e) { - echo "Exception occured, code: " . $e->getCode(); + echo "Exception occurred, code: " . $e->getCode(); echo " with message: " . $e->getMessage(); } From 7e5cecbb5d8fcb952309d5a086732b9f666929ac Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 7 Nov 2014 20:52:32 -0600 Subject: [PATCH 058/407] Added persistent data handler --- docs/Facebook.fbmd | 29 +++++++ docs/PersistentDataInterface.fbmd | 78 +++++++++++++++++++ docs/sdk_reference.fbmd | 4 + src/Facebook/Facebook.php | 35 ++++++++- .../Helpers/FacebookRedirectLoginHelper.php | 52 +++++-------- .../FacebookMemoryPersistentDataHandler.php | 56 +++++++++++++ .../FacebookSessionPersistentDataHandler.php | 75 ++++++++++++++++++ .../PersistentDataInterface.php | 50 ++++++++++++ tests/FacebookTest.php | 32 ++++++++ .../FacebookRedirectLoginHelperTest.php | 27 ++++--- ...acebookMemoryPersistentDataHandlerTest.php | 48 ++++++++++++ ...cebookSessionPersistentDataHandlerTest.php | 64 +++++++++++++++ 12 files changed, 506 insertions(+), 44 deletions(-) create mode 100644 docs/PersistentDataInterface.fbmd create mode 100644 src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php create mode 100644 src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php create mode 100644 src/Facebook/PersistentData/PersistentDataInterface.php create mode 100644 tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php create mode 100644 tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 6b76ed196..b8adc9f4f 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -54,6 +54,7 @@ $fb = new Facebook\Facebook([ 'enable_beta_mode' => true, 'default_graph_version' => 'v2.2', 'http_client_handler' => 'guzzle', + 'persistent_data_handler' => 'memory', ]); ~~~~ @@ -87,6 +88,21 @@ $fb = new Facebook([ ]); ~~~~ +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](/docs/php/PersistentDataInterface)` and set the value of `persistent_data_handler` to an instance of your custom handler. + +~~~~ +$fb = new Facebook([ + 'persistent_data_handler' => new MyCustomPersistentDataHandler(), +]); +~~~~ + If any other value is provided an `InvalidArgumentException` will be thrown. @@ -263,3 +279,16 @@ $requests = [ $batchResponse = $fb->sendBatchRequest($requests); ~~~~ + + +### getRedirectLoginHelper() {#get-redirect-login-helper} +~~~~ +public Facebook\Helpers\FacebookRedirectLoginHelper getRedirectLoginHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) which is used to generate a "Login with Facebook" link and obtain an access token from a redirect. + +~~~~ +$helper = $fb->getRedirectLoginHelper(); +~~~~ + diff --git a/docs/PersistentDataInterface.fbmd b/docs/PersistentDataInterface.fbmd new file mode 100644 index 000000000..8dbb605f1 --- /dev/null +++ b/docs/PersistentDataInterface.fbmd @@ -0,0 +1,78 @@ + +# 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 PHP SDK uses native PHP sessions to store the persistent data. You can overwrite this behavior by coding to the `Facebook\PersistentData\PersistentDataInterface`. + + + +## Facebook\PersistentData\PersistentDataInterface {#overview} + +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: + +~~~~ +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. + +~~~~ +$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. + +~~~~ +use Facebook\Helpers\FacebookRedirectLoginHelper; + +$myPersistentDataHandler = new MyLaravelPersistentDataHandler(); +$helper = new FacebookRedirectLoginHelper($fbApp, $myPersistentDataHandler); +~~~~ + + + +## Method Reference {#method-reference} + +### get() {#get} +~~~~ +public mixed get(string $key) +~~~~ +Returns a value from the persistent data store or `null` if the value does not exist. + + + +### set() {#set} +~~~~ +public void set(string $key, mixed $value) +~~~~ +Sets a value to the persistent data store. + diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 2a1018d37..4786813ce 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -212,6 +212,10 @@ FB(devsite:markdown-wiki:table { '`[Facebook\HttpClients\FacebookHttpClientInterface](/docs/php/FacebookHttpClientInterface)`', 'Interface to code your own HTTP client implementation.', ], + [ + '`[Facebook\PersistentData\PersistentDataInterface](/docs/php/PersistentDataInterface)`', + 'Interface to code your own persistent data storage implementation.', + ], ], }) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 552b9e80e..a934f50de 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -33,6 +33,10 @@ use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; use Facebook\HttpClients\FacebookGuzzleHttpClient; +use Facebook\PersistentData\PersistentDataInterface; +use Facebook\PersistentData\FacebookSessionPersistentDataHandler; +use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\Exceptions\FacebookSDKException; /** @@ -86,9 +90,13 @@ class Facebook */ protected $defaultGraphVersion; + /** + * @var PersistentDataInterface|null The persistent data handler. + */ + protected $persistentDataHandler; + /** * @TODO Add FacebookInputInterface - * @TODO Add FacebookSessionInterface * @TODO Add FacebookUrlInterface * @TODO Add FacebookRandomGeneratorInterface * @TODO Add FacebookRequestInterface @@ -146,6 +154,21 @@ public function __construct(array $config = []) $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; $this->client = new FacebookClient($httpClientHandler, $enableBeta); + if (isset($config['persistent_data_handler'])) { + if ( $config['persistent_data_handler'] instanceof PersistentDataInterface) { + $this->persistentDataHandler = $config['persistent_data_handler']; + } elseif ($config['persistent_data_handler'] === 'session') { + $this->persistentDataHandler = new FacebookSessionPersistentDataHandler(); + } elseif ($config['persistent_data_handler'] === 'memory') { + $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); + } else { + throw new \InvalidArgumentException( + 'The persistent_data_handler must be set to "session", "memory", ' + . ' or be an instance of Facebook\PersistentData\PersistentDataInterface' + ); + } + } + if (isset($config['default_access_token'])) { if (is_string($config['default_access_token'])) { $this->defaultAccessToken = new AccessToken($config['default_access_token']); @@ -202,6 +225,16 @@ public function getDefaultGraphVersion() return $this->defaultGraphVersion; } + /** + * Returns the redirect login helper. + * + * @return FacebookRedirectLoginHelper + */ + public function getRedirectLoginHelper() + { + return new FacebookRedirectLoginHelper($this->app, $this->persistentDataHandler); + } + /** * Sends a GET request to Graph and returns the result. * diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index b464e0d68..b369f4008 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -26,6 +26,8 @@ use Facebook\Facebook; use Facebook\Entities\AccessToken; use Facebook\Entities\FacebookApp; +use Facebook\PersistentData\PersistentDataInterface; +use Facebook\PersistentData\FacebookSessionPersistentDataHandler; use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookClient; @@ -44,23 +46,30 @@ class FacebookRedirectLoginHelper protected $app; /** - * @var string Prefix to use for session variables. + * @var PersistentDataInterface The persistent data handler. */ - protected $sessionPrefix = 'FBRLH_'; - - /** - * @var boolean Toggle for PHP session status check. - */ - protected $checkForSessionStatus = true; + protected $persistentDataHandler; /** * Constructs a RedirectLoginHelper for a given appId. * * @param FacebookApp $app The FacebookApp entity. + * @param PersistentDataInterface|null $persistentDataHandler The persistent data handler. */ - public function __construct(FacebookApp $app) + public function __construct(FacebookApp $app, PersistentDataInterface $persistentDataHandler = null) { $this->app = $app; + $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); + } + + /** + * Returns the persistent data handler. + * + * @return PersistentDataInterface + */ + public function getPersistentDataHandler() + { + return $this->persistentDataHandler; } /** @@ -188,13 +197,7 @@ protected function generateState() */ protected function storeState($state) { - if ($this->checkForSessionStatus === true - && session_status() !== PHP_SESSION_ACTIVE) { - throw new FacebookSDKException( - 'Session not active, could not store state.', 720 - ); - } - $_SESSION[$this->sessionPrefix . 'state'] = $state; + $this->persistentDataHandler->set('state', $state); } /** @@ -208,16 +211,7 @@ protected function storeState($state) */ protected function loadState() { - if ($this->checkForSessionStatus === true - && session_status() !== PHP_SESSION_ACTIVE) { - throw new FacebookSDKException( - 'Session not active, could not load state.', 721 - ); - } - if (isset($_SESSION[$this->sessionPrefix . 'state'])) { - return $_SESSION[$this->sessionPrefix . 'state']; - } - return null; + return $this->persistentDataHandler->get('state'); } /** @@ -342,12 +336,4 @@ private function random($bytes) return bin2hex(substr($buf, 0, $bytes)); } - /** - * Disables the session_status() check when using $_SESSION. - */ - public function disableSessionStatusCheck() - { - $this->checkForSessionStatus = false; - } - } diff --git a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php new file mode 100644 index 000000000..fef9b6d69 --- /dev/null +++ b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php @@ -0,0 +1,56 @@ +sessionData[$key]) + ? $this->sessionData[$key] + : null; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + $this->sessionData[$key] = $value; + } + +} diff --git a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php new file mode 100644 index 000000000..087fa72bf --- /dev/null +++ b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php @@ -0,0 +1,75 @@ +sessionPrefix . $key]) + ? $_SESSION[$this->sessionPrefix . $key] + : null; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + $_SESSION[$this->sessionPrefix . $key] = $value; + } + +} diff --git a/src/Facebook/PersistentData/PersistentDataInterface.php b/src/Facebook/PersistentData/PersistentDataInterface.php new file mode 100644 index 000000000..53dc5731c --- /dev/null +++ b/src/Facebook/PersistentData/PersistentDataInterface.php @@ -0,0 +1,50 @@ +getClient()->getHttpClientHandler()); } + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidPersistentDataHandlerThrows() + { + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testPersistentDataHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\PersistentData\FacebookMemoryPersistentDataHandler', + $fb->getRedirectLoginHelper()->getPersistentDataHandler()); + } + /** * @expectedException \InvalidArgumentException */ @@ -122,6 +151,7 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $config = array_merge($this->config, [ 'default_access_token' => 'foo_token', 'http_client_handler' => new FooClientInterface(), + 'persistent_data_handler' => new FooPersistentDataInterface(), 'enable_beta_mode' => true, 'default_graph_version' => 'v1337', ]); @@ -130,6 +160,8 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $request = $fb->request('FOO_VERB', '/foo'); $this->assertInstanceOf('Facebook\Tests\FooClientInterface', $fb->getClient()->getHttpClientHandler()); + $this->assertInstanceOf('Facebook\Tests\FooPersistentDataInterface', + $fb->getRedirectLoginHelper()->getPersistentDataHandler()); $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $fb->getClient()->getBaseGraphUrl()); $this->assertEquals('1337', $request->getApp()->getId()); diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 7118edc46..07c88d498 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -27,17 +27,27 @@ use Facebook\Facebook; use Facebook\Entities\FacebookApp; use Facebook\Helpers\FacebookRedirectLoginHelper; +use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookMemoryPersistentDataHandler + */ + protected $persistentDataHandler; + const REDIRECT_URL = 'http://invalid.zzz'; + public function setUp() + { + $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); + } + public function testLoginURL() { $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app); - $helper->disableSessionStatusCheck(); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); $scope = ['foo','bar']; $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL, $scope, true, 'v1337'); @@ -62,8 +72,7 @@ public function testLoginURL() public function testLogoutURL() { $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app); - $helper->disableSessionStatusCheck(); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); $logoutUrl = $helper->getLogoutUrl('foo_token', self::REDIRECT_URL); $expectedUrl = 'https://www.facebook.com/logout.php?'; @@ -82,7 +91,7 @@ public function testLogoutURL() public function testAnAccessTokenCanBeObtainedFromRedirect() { - $_SESSION['FBRLH_state'] = 'foo_state'; + $this->persistentDataHandler->set('state', 'foo_state'); $_GET['state'] = 'foo_state'; $_GET['code'] = 'foo_code'; @@ -102,8 +111,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() ->andReturn($response); $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app); - $helper->disableSessionStatusCheck(); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); $accessToken = $helper->getAccessToken($client, self::REDIRECT_URL); @@ -117,8 +125,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() public function testGetFilteredUriRemoveFacebookQueryParams($uri, $expected) { $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app); - $helper->disableSessionStatusCheck(); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); $method = $class->getMethod('getFilteredUri'); @@ -161,7 +168,7 @@ public function provideUris() public function testCSPRNG() { $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); $method = $class->getMethod('random'); diff --git a/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php b/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php new file mode 100644 index 000000000..6940864db --- /dev/null +++ b/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php @@ -0,0 +1,48 @@ +set('foo', 'bar'); + $value = $handler->get('foo'); + + $this->assertEquals('bar', $value); + } + + public function testGettingAValueThatDoesntExistWillReturnNull() + { + $handler = new FacebookMemoryPersistentDataHandler(); + $value = $handler->get('does_not_exist'); + + $this->assertNull($value); + } + +} diff --git a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php new file mode 100644 index 000000000..1035d72f6 --- /dev/null +++ b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php @@ -0,0 +1,64 @@ +set('foo', 'bar'); + + $this->assertEquals('bar', $_SESSION['FBRLH_foo']); + } + + public function testCanGetAValue() + { + $_SESSION['FBRLH_faz'] = 'baz'; + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $value = $handler->get('faz'); + + $this->assertEquals('baz', $value); + } + + public function testGettingAValueThatDoesntExistWillReturnNull() + { + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $value = $handler->get('does_not_exist'); + + $this->assertNull($value); + } + +} From f713befe1578810d85db2aec0167ea27947fbe56 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 9 Nov 2014 16:22:57 -0600 Subject: [PATCH 059/407] Updated version constraint for 4.1 --- docs/sdk_getting_started.fbmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 1267df0bd..c9698aa75 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -36,7 +36,7 @@ There are two methods to install the Facebook PHP SDK. The preferred method is w ~~~ { "require" : { - "facebook/php-sdk-v4" : "~4.1" + "facebook/php-sdk-v4" : "~4.1.0" } } ~~~ From 6173e525ea0477f45d43c997632865a00023ab4b Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 11 Nov 2014 15:01:30 -0600 Subject: [PATCH 060/407] Started to implment url handler --- src/Facebook/Facebook.php | 34 +++- .../Helpers/FacebookRedirectLoginHelper.php | 106 ++++------- src/Facebook/Url/FacebookUrlHandler.php | 171 ++++++++++++++++++ src/Facebook/Url/FacebookUrlManipulator.php | 67 +++++++ src/Facebook/Url/UrlInterface.php | 40 ++++ 5 files changed, 341 insertions(+), 77 deletions(-) create mode 100755 src/Facebook/Url/FacebookUrlHandler.php create mode 100755 src/Facebook/Url/FacebookUrlManipulator.php create mode 100755 src/Facebook/Url/UrlInterface.php diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 552b9e80e..f4b9b5c1d 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -29,6 +29,8 @@ use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookResponse; use Facebook\Entities\FacebookBatchResponse; +use Facebook\Url\UrlInterface; +use Facebook\Url\FacebookUrlHandler; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; @@ -76,6 +78,11 @@ class Facebook */ protected $client; + /** + * @var UrlInterface The URL handler. + */ + protected $urlHandler; + /** * @var AccessToken|null The default access token to use with requests. */ @@ -89,7 +96,6 @@ class Facebook /** * @TODO Add FacebookInputInterface * @TODO Add FacebookSessionInterface - * @TODO Add FacebookUrlInterface * @TODO Add FacebookRandomGeneratorInterface * @TODO Add FacebookRequestInterface * @TODO Add FacebookResponseInterface @@ -128,7 +134,7 @@ public function __construct(array $config = []) $httpClientHandler = null; if (isset($config['http_client_handler'])) { - if ( $config['http_client_handler'] instanceof FacebookHttpClientInterface) { + if ($config['http_client_handler'] instanceof FacebookHttpClientInterface) { $httpClientHandler = $config['http_client_handler']; } elseif ($config['http_client_handler'] === 'curl') { $httpClientHandler = new FacebookCurlHttpClient(); @@ -146,6 +152,16 @@ public function __construct(array $config = []) $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; $this->client = new FacebookClient($httpClientHandler, $enableBeta); + if (isset($config['url_handler'])) { + if ($config['url_handler'] instanceof UrlInterface) { + $this->urlHandler = $config['url_handler']; + } else { + throw new \InvalidArgumentException( + 'The url_handler must be an instance of Facebook\Url\UrlInterface' + ); + } + } + if (isset($config['default_access_token'])) { if (is_string($config['default_access_token'])) { $this->defaultAccessToken = new AccessToken($config['default_access_token']); @@ -182,6 +198,20 @@ public function getClient() return $this->client; } + /** + * Returns the URL handler. + * + * @return UrlInterface + */ + public function getUrlHandler() + { + if ( ! $this->urlHandler) { + $this->urlHandler = new FacebookUrlHandler(); + } + + return $this->urlHandler; + } + /** * Returns the default AccessToken entity. * diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index b464e0d68..ab7ee62be 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -26,6 +26,8 @@ use Facebook\Facebook; use Facebook\Entities\AccessToken; use Facebook\Entities\FacebookApp; +use Facebook\Url\UrlInterface; +use Facebook\Url\FacebookUrlManipulator; use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookClient; @@ -43,6 +45,16 @@ class FacebookRedirectLoginHelper */ protected $app; + /** + * @var UrlInterface The URL handler. + */ + protected $urlHandler; + + /** + * @var FacebookUrlManipulator The URL manipulator. + */ + protected $urlManipulator; + /** * @var string Prefix to use for session variables. */ @@ -57,10 +69,16 @@ class FacebookRedirectLoginHelper * Constructs a RedirectLoginHelper for a given appId. * * @param FacebookApp $app The FacebookApp entity. + * @param UrlInterface $urlHandler The URL handler. + * @param FacebookUrlManipulator $urlManipulator The URL manipulator. */ - public function __construct(FacebookApp $app) + public function __construct(FacebookApp $app, + UrlInterface $urlHandler, + FacebookUrlManipulator $urlManipulator) { $this->app = $app; + $this->urlHandler = $urlHandler; + $this->urlManipulator = $urlManipulator; } /** @@ -128,7 +146,7 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') * Takes a valid code from a login redirect, and returns an AccessToken entity. * * @param FacebookClient $client The Facebook client. - * @param string $redirectUrl The redirect URL. + * @param string|null $redirectUrl The redirect URL. * * @return AccessToken|null * @@ -138,8 +156,17 @@ public function getAccessToken(FacebookClient $client, $redirectUrl = null) { if ($this->isValidRedirect()) { $code = $this->getCode(); - $redirectUrl = $redirectUrl ?: $this->getCurrentUri(); - $redirectUrl = $this->getFilteredUri($redirectUrl); + $redirectUrl = $redirectUrl ?: $this->urlHandler->getCurrentUrl(); + + $paramsToFilter = [ + 'state', + 'code', + 'error', + 'error_reason', + 'error_description', + 'error_code', + ]; + $redirectUrl = $this->urlManipulator->removeParamsFromUrl($redirectUrl, $paramsToFilter); return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); } @@ -220,77 +247,6 @@ protected function loadState() return null; } - /** - * Return a URL with the Facebook-appended params removed. - * - * @param string $uri The URL to filter. - * - * @return string - */ - protected function getFilteredUri($uri) - { - $parts = parse_url($uri); - $scheme = isset($parts['scheme']) ? $parts['scheme'] : $this->getHttpScheme(); - - $path = isset($parts['path']) ? $parts['path'] : ''; - - $query = ''; - if (isset($parts['query'])) { - $full_query = []; - parse_str($parts['query'], $full_query); - - // remove Facebook appended query params - $toDrop = []; - if (isset($full_query['state']) && isset($full_query['code'])) { - $toDrop = ['state', 'code']; - } elseif (isset($full_query['state']) - && isset($full_query['error']) - && isset($full_query['error_reason']) - && isset($full_query['error_description']) - && isset($full_query['error_code'])) { - $toDrop = ['state', 'error', 'error_reason', 'error_description', 'error_code']; - } - $real_query = array_diff_key($full_query, array_flip($toDrop)); - - $query = ''; - if (!empty($real_query)) { - $query = '?' . http_build_query($real_query, null, '&'); - } - } - - // use port if non default - $port = isset($parts['port']) ? ':' . $parts['port'] : ''; - - // rebuild - return $scheme . '://' . $parts['host'] . $port . $path . $query; - } - - /** - * Returns the current URI. - * - * @return string - */ - protected function getCurrentUri() - { - return $this->getHttpScheme() . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - } - - /** - * Returns the HTTP Protocol. - * - * @return string - */ - protected function getHttpScheme() { - $scheme = 'http'; - if (isset($_SERVER['HTTPS']) && - ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1) - || isset($_SERVER['SERVER_PORT']) && - ($_SERVER['SERVER_PORT'] === '443')) { - $scheme = 'https'; - } - return $scheme; - } - /** * Generate a cryptographically secure pseudrandom number. * diff --git a/src/Facebook/Url/FacebookUrlHandler.php b/src/Facebook/Url/FacebookUrlHandler.php new file mode 100755 index 000000000..c56185413 --- /dev/null +++ b/src/Facebook/Url/FacebookUrlHandler.php @@ -0,0 +1,171 @@ +getCurrentHttpScheme() . '://' + . $this->getHostName() + . $this->getServerVar('REQUEST_URI'); + } + + /** + * Get the currently active URL scheme. + * + * @return string + */ + public function getCurrentHttpScheme() + { + return $this->isBehindSsl() ? 'https' : 'http'; + } + + /** + * Tries to detect if the server is running behind an SSL. + * + * @return boolean + */ + public function isBehindSsl() + { + // Check for proxy first + $protocol = $this->getHeader('X_FORWARDED_PROTO'); + if ($protocol) { + return $this->protocolWithActiveSsl($protocol); + } + + $protocol = $this->getServerVar('HTTPS'); + if ($protocol) { + return $this->protocolWithActiveSsl($protocol); + } + + return (string) $this->getServerVar('SERVER_PORT') === '443'; + } + + /** + * Detects an active SSL protocol value. + * + * @param string $protocol + * + * @return boolean + */ + public function protocolWithActiveSsl($protocol) + { + $protocol = strtolower((string) $protocol); + return ( + $protocol === 'on' + || $protocol === '1' + || $protocol === 'https' + || $protocol === 'ssl' + ); + } + + /** + * Tries to detect the host name of the server. + * Some elements adapted from + * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php + * + * @return string + */ + public function getHostName() + { + // Check for proxy first + if ($host = $this->getHeader('X_FORWARDED_HOST')) { + $elements = explode(',', $host); + $host = $elements[count($elements) - 1]; + } elseif ( ! $host = $this->getHeader('HOST')) { + if ( ! $host = $this->getServerVar('SERVER_NAME')) { + $host = $this->getServerVar('SERVER_ADDR'); + } + } + + // trim and remove port number from host + // host is lowercase as per RFC 952/2181 + $host = strtolower(preg_replace('/:\d+$/', '', trim($host))); + + // Port number + $scheme = $this->getCurrentHttpScheme(); + $port = $this->getCurrentPort(); + $appendPort = ''; + + // Append port number if it's not normal port. + if ( + ($scheme == 'http' && $port == '80') + || ($scheme == 'https' && $port == '443') + ) { + $appendPort = ':' . $port; + } + + return $host . $appendPort; + } + + public function getCurrentPort() + { + // Check for proxy first + $port = $this->getHeader('X_FORWARDED_PORT'); + if ($port) { + return (string) $port; + } + + $protocol = (string) $this->getHeader('X_FORWARDED_PROTO'); + if ($protocol === 'https') { + return '443'; + } + + return (string) $this->getServerVar('SERVER_PORT'); + } + + /** + * Returns the a value from the $_SERVER super global. + * + * @param string $key + * + * @return string + */ + public function getServerVar($key) + { + return isset($_SERVER[$key]) ? $_SERVER[$key] : ''; + } + + /** + * Gets a value from the HTTP request headers. + * + * @param string $key + * + * @return string + */ + public function getHeader($key) + { + return $this->getServerVar('HTTP_' . $key); + } + +} diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php new file mode 100755 index 000000000..ceec5250f --- /dev/null +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -0,0 +1,67 @@ + 0) { + $query = '?' . http_build_query($params, null, '&'); + } + } + + $port = isset($parts['port']) ? ':' . $parts['port'] : ''; + $path = isset($parts['path']) ? $parts['path'] : ''; + $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; + + return $parts['scheme'] . '://' . $parts['host'] . $port . $path . $query . $fragment; + } + +} diff --git a/src/Facebook/Url/UrlInterface.php b/src/Facebook/Url/UrlInterface.php new file mode 100755 index 000000000..cbf93c476 --- /dev/null +++ b/src/Facebook/Url/UrlInterface.php @@ -0,0 +1,40 @@ + Date: Wed, 12 Nov 2014 17:06:04 -0600 Subject: [PATCH 061/407] Added url detection interface --- docs/Facebook.fbmd | 14 ++ docs/UrlDetectionInterface.fbmd | 57 ++++++++ docs/sdk_reference.fbmd | 4 + src/Facebook/Facebook.php | 12 +- .../Helpers/FacebookRedirectLoginHelper.php | 14 +- ...er.php => FacebookUrlDetectionHandler.php} | 16 +- ...nterface.php => UrlDetectionInterface.php} | 4 +- tests/FacebookTest.php | 27 +++- .../FacebookRedirectLoginHelperTest.php | 46 ------ tests/Url/FacebookUrlDetectionHandlerTest.php | 137 ++++++++++++++++++ tests/Url/FacebookUrlManipulatorTest.php | 94 ++++++++++++ 11 files changed, 355 insertions(+), 70 deletions(-) create mode 100644 docs/UrlDetectionInterface.fbmd rename src/Facebook/Url/{FacebookUrlHandler.php => FacebookUrlDetectionHandler.php} (92%) rename src/Facebook/Url/{UrlInterface.php => UrlDetectionInterface.php} (94%) create mode 100644 tests/Url/FacebookUrlDetectionHandlerTest.php create mode 100644 tests/Url/FacebookUrlManipulatorTest.php diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index b8adc9f4f..9981b1320 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -55,6 +55,7 @@ $fb = new Facebook\Facebook([ 'default_graph_version' => 'v2.2', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', + 'url_detection_handler' => new MyUrlDetectionHandler(), ]); ~~~~ @@ -103,6 +104,19 @@ $fb = new Facebook([ ]); ~~~~ +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](/docs/php/UrlDetectionInterface)` and set the value of `url_detection_handler` to an instance of your custom URL detector. + +~~~~ +$fb = new Facebook([ + 'url_detection_handler' => new MyUrlDetectionHandler(), +]); +~~~~ + If any other value is provided an `InvalidArgumentException` will be thrown. diff --git a/docs/UrlDetectionInterface.fbmd b/docs/UrlDetectionInterface.fbmd new file mode 100644 index 000000000..2f93d3907 --- /dev/null +++ b/docs/UrlDetectionInterface.fbmd @@ -0,0 +1,57 @@ + +# 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 {#overview} + +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: + +~~~~ +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. + +~~~~ +$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. + +~~~~ +use Facebook\Helpers\FacebookRedirectLoginHelper; + +$myUrlDetectionHandler = new MyLaravelUrlDetectionHandler(); +$helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); +~~~~ + + + +## Method Reference {#method-reference} + +### getCurrentUrl() {#get-current-url} +~~~~ +public string getCurrentUrl() +~~~~ +Returns the full and currently active URL. + diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 4786813ce..13f27b7f8 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -216,6 +216,10 @@ FB(devsite:markdown-wiki:table { '`[Facebook\PersistentData\PersistentDataInterface](/docs/php/PersistentDataInterface)`', 'Interface to code your own persistent data storage implementation.', ], + [ + '`[Facebook\Url\UrlDetectionInterface](/docs/php/UrlDetectionInterface)`', + 'Interface to code your own URL detection logic.', + ], ], }) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index c59ea4721..77afce198 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -29,8 +29,8 @@ use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookResponse; use Facebook\Entities\FacebookBatchResponse; -use Facebook\Url\UrlInterface; -use Facebook\Url\FacebookUrlHandler; +use Facebook\Url\UrlDetectionInterface; +use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; @@ -83,7 +83,7 @@ class Facebook protected $client; /** - * @var UrlInterface|null The URL handler. + * @var UrlDetectionInterface|null The URL handler. */ protected $urlHandler; @@ -161,7 +161,7 @@ public function __construct(array $config = []) $this->client = new FacebookClient($httpClientHandler, $enableBeta); if (isset($config['url_handler'])) { - if ($config['url_handler'] instanceof UrlInterface) { + if ($config['url_handler'] instanceof UrlDetectionInterface) { $this->urlHandler = $config['url_handler']; } else { throw new \InvalidArgumentException( @@ -224,12 +224,12 @@ public function getClient() /** * Returns the URL handler. * - * @return UrlInterface + * @return UrlDetectionInterface */ public function getUrlHandler() { if ( ! $this->urlHandler) { - $this->urlHandler = new FacebookUrlHandler(); + $this->urlHandler = new FacebookUrlDetectionHandler(); } return $this->urlHandler; diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index dcae60ba9..8bb7d4664 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -26,8 +26,8 @@ use Facebook\Facebook; use Facebook\Entities\AccessToken; use Facebook\Entities\FacebookApp; -use Facebook\Url\UrlInterface; -use Facebook\Url\FacebookUrlHandler; +use Facebook\Url\UrlDetectionInterface; +use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\Url\FacebookUrlManipulator; use Facebook\PersistentData\PersistentDataInterface; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; @@ -49,7 +49,7 @@ class FacebookRedirectLoginHelper protected $app; /** - * @var UrlInterface The URL handler. + * @var UrlDetectionInterface The URL handler. */ protected $urlHandler; @@ -63,15 +63,15 @@ class FacebookRedirectLoginHelper * * @param FacebookApp $app The FacebookApp entity. * @param PersistentDataInterface|null $persistentDataHandler The persistent data handler. - * @param UrlInterface|null $urlHandler The URL handler. + * @param UrlDetectionInterface|null $urlHandler The URL handler. */ public function __construct(FacebookApp $app, PersistentDataInterface $persistentDataHandler = null, - UrlInterface $urlHandler = null) + UrlDetectionInterface $urlHandler = null) { $this->app = $app; $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); - $this->urlHandler = $urlHandler ?: new FacebookUrlHandler(); + $this->urlHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); } /** @@ -87,7 +87,7 @@ public function getPersistentDataHandler() /** * Returns the URL handler. * - * @return UrlInterface + * @return UrlDetectionInterface */ public function getUrlHandler() { diff --git a/src/Facebook/Url/FacebookUrlHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php similarity index 92% rename from src/Facebook/Url/FacebookUrlHandler.php rename to src/Facebook/Url/FacebookUrlDetectionHandler.php index c56185413..f07b6ba9c 100755 --- a/src/Facebook/Url/FacebookUrlHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -24,10 +24,10 @@ namespace Facebook\Url; /** - * Class FacebookUrlHandler + * Class FacebookUrlDetectionHandler * @package Facebook */ -class FacebookUrlHandler implements UrlInterface +class FacebookUrlDetectionHandler implements UrlDetectionInterface { /** @@ -35,7 +35,7 @@ class FacebookUrlHandler implements UrlInterface */ public function getCurrentUrl() { - return $this->getCurrentHttpScheme() . '://' + return $this->getHttpScheme() . '://' . $this->getHostName() . $this->getServerVar('REQUEST_URI'); } @@ -45,7 +45,7 @@ public function getCurrentUrl() * * @return string */ - public function getCurrentHttpScheme() + public function getHttpScheme() { return $this->isBehindSsl() ? 'https' : 'http'; } @@ -113,16 +113,16 @@ public function getHostName() $host = strtolower(preg_replace('/:\d+$/', '', trim($host))); // Port number - $scheme = $this->getCurrentHttpScheme(); + $scheme = $this->getHttpScheme(); $port = $this->getCurrentPort(); - $appendPort = ''; + $appendPort = ':' . $port; - // Append port number if it's not normal port. + // Don't append port number if a normal port. if ( ($scheme == 'http' && $port == '80') || ($scheme == 'https' && $port == '443') ) { - $appendPort = ':' . $port; + $appendPort = ''; } return $host . $appendPort; diff --git a/src/Facebook/Url/UrlInterface.php b/src/Facebook/Url/UrlDetectionInterface.php similarity index 94% rename from src/Facebook/Url/UrlInterface.php rename to src/Facebook/Url/UrlDetectionInterface.php index cbf93c476..dbe44e92b 100755 --- a/src/Facebook/Url/UrlInterface.php +++ b/src/Facebook/Url/UrlDetectionInterface.php @@ -24,10 +24,10 @@ namespace Facebook\Url; /** - * Interface UrlInterface + * Interface UrlDetectionInterface * @package Facebook */ -interface UrlInterface +interface UrlDetectionInterface { /** diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 55c9389e0..8151612e7 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -28,7 +28,7 @@ use Facebook\FacebookClient; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\PersistentData\PersistentDataInterface; - +use Facebook\Url\UrlDetectionInterface; class FooClientInterface implements FacebookHttpClientInterface { @@ -43,6 +43,11 @@ public function get($key) { return 'foo'; } public function set($key, $value) {} } +class FooUrlDetectionInterface implements UrlDetectionInterface +{ + public function getCurrentUrl() { return 'https://foo.bar'; } +} + class FacebookTest extends \PHPUnit_Framework_TestCase { @@ -135,6 +140,23 @@ public function testPersistentDataHandlerCanBeForced() $fb->getRedirectLoginHelper()->getPersistentDataHandler()); } + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidUrlHandlerThrows() + { + $config = array_merge($this->config, [ + 'url_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testDefaultUrlHandlerWillBeLazyLoaded() + { + $fb = new Facebook($this->config); + $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlHandler()); + } + /** * @expectedException \InvalidArgumentException */ @@ -152,6 +174,7 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() 'default_access_token' => 'foo_token', 'http_client_handler' => new FooClientInterface(), 'persistent_data_handler' => new FooPersistentDataInterface(), + 'url_handler' => new FooUrlDetectionInterface(), 'enable_beta_mode' => true, 'default_graph_version' => 'v1337', ]); @@ -162,6 +185,8 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $fb->getClient()->getHttpClientHandler()); $this->assertInstanceOf('Facebook\Tests\FooPersistentDataInterface', $fb->getRedirectLoginHelper()->getPersistentDataHandler()); + $this->assertInstanceOf('Facebook\Tests\FooUrlDetectionInterface', + $fb->getRedirectLoginHelper()->getUrlHandler()); $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $fb->getClient()->getBaseGraphUrl()); $this->assertEquals('1337', $request->getApp()->getId()); diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 07c88d498..a61e6e8ed 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -119,52 +119,6 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $this->assertEquals('access_token_from_code', (string) $accessToken); } - /** - * @dataProvider provideUris - */ - public function testGetFilteredUriRemoveFacebookQueryParams($uri, $expected) - { - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); - - $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); - $method = $class->getMethod('getFilteredUri'); - $method->setAccessible(true); - - $currentUri = $method->invoke($helper, $uri); - $this->assertEquals($expected, $currentUri); - } - - public function provideUris() - { - return [ - [ - 'http://localhost/something?state=0000&foo=bar&code=abcd', - 'http://localhost/something?foo=bar', - ], - [ - 'https://localhost/something?state=0000&foo=bar&code=abcd', - 'https://localhost/something?foo=bar', - ], - [ - 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', - 'http://localhost/something?foo=bar', - ], - [ - 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', - 'https://localhost/something?foo=bar', - ], - [ - 'http://localhost/something?state=0000&foo=bar&error=abcd', - 'http://localhost/something?state=0000&foo=bar&error=abcd', - ], - [ - 'https://localhost/something?state=0000&foo=bar&error=abcd', - 'https://localhost/something?state=0000&foo=bar&error=abcd', - ], - ]; - } - public function testCSPRNG() { $app = new FacebookApp('123', 'foo_app_secret'); diff --git a/tests/Url/FacebookUrlDetectionHandlerTest.php b/tests/Url/FacebookUrlDetectionHandlerTest.php new file mode 100644 index 000000000..43439d5ac --- /dev/null +++ b/tests/Url/FacebookUrlDetectionHandlerTest.php @@ -0,0 +1,137 @@ +getCurrentUrl(); + + $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesSecureUrlFromCommonScenario() + { + $_SERVER['HTTP_HOST'] = 'foo.bar'; + $_SERVER['SERVER_PORT'] = '443'; + $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesUrlFromProxy() + { + $_SERVER['HTTP_X_FORWARDED_PORT'] = '80'; + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; + $_SERVER['HTTP_HOST'] = 'foo.bar'; + $_SERVER['SERVER_PORT'] = '80'; + $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesSecureUrlFromProxy() + { + $_SERVER['HTTP_X_FORWARDED_PORT'] = '443'; + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'; + $_SERVER['HTTP_HOST'] = 'foo.bar'; + $_SERVER['SERVER_PORT'] = '80'; + $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesUrlWithCustomPort() + { + $_SERVER['HTTP_HOST'] = 'foo.bar'; + $_SERVER['SERVER_PORT'] = '1337'; + $_SERVER['REQUEST_URI'] = '/foo.php'; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar:1337/foo.php', $currentUri); + } + + public function testProperlyGeneratesSecureUrlWithCustomPort() + { + $_SERVER['HTTP_HOST'] = 'foo.bar'; + $_SERVER['SERVER_PORT'] = '1337'; + $_SERVER['REQUEST_URI'] = '/foo.php'; + $_SERVER['HTTPS'] = 'On'; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar:1337/foo.php', $currentUri); + } + + public function testProperlyGeneratesUrlWithCustomPortFromProxy() + { + $_SERVER['HTTP_X_FORWARDED_PORT'] = '8888'; + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; + $_SERVER['HTTP_HOST'] = 'foo.bar'; + $_SERVER['SERVER_PORT'] = '80'; + $_SERVER['REQUEST_URI'] = '/foo.php'; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar:8888/foo.php', $currentUri); + } + +} diff --git a/tests/Url/FacebookUrlManipulatorTest.php b/tests/Url/FacebookUrlManipulatorTest.php new file mode 100644 index 000000000..b540d60b7 --- /dev/null +++ b/tests/Url/FacebookUrlManipulatorTest.php @@ -0,0 +1,94 @@ +assertEquals($expectedCleanUrl, $currentUri); + } + + public function provideUris() + { + return [ + [ + 'http://localhost/something?state=0000&foo=bar&code=abcd', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&code=abcd', + 'https://localhost/something?foo=bar', + ], + [ + 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'https://localhost/something?foo=bar', + ], + [ + 'http://localhost/something?state=0000&foo=bar&error=abcd', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&error=abcd', + 'https://localhost/something?foo=bar', + ], + [ + 'https://localhost:1337/something?state=0000&foo=bar&error=abcd', + 'https://localhost:1337/something?foo=bar', + ], + [ + 'https://localhost:1337/something?state=0000&code=foo', + 'https://localhost:1337/something', + ], + [ + 'https://localhost/something/?state=0000&code=foo&foo=bar', + 'https://localhost/something/?foo=bar', + ], + [ + 'https://localhost/something/?state=0000&code=foo', + 'https://localhost/something/', + ], + ]; + } + +} From 941bdc2868ee34ed12a17a0836f2ba3d5fc0fa65 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 12 Nov 2014 17:15:41 -0600 Subject: [PATCH 062/407] Finished naming --- src/Facebook/Facebook.php | 24 +++++++++---------- .../Helpers/FacebookRedirectLoginHelper.php | 16 ++++++------- tests/FacebookTest.php | 8 +++---- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 77afce198..0be895087 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -83,9 +83,9 @@ class Facebook protected $client; /** - * @var UrlDetectionInterface|null The URL handler. + * @var UrlDetectionInterface|null The URL detection handler. */ - protected $urlHandler; + protected $urlDetectionHandler; /** * @var AccessToken|null The default access token to use with requests. @@ -160,12 +160,12 @@ public function __construct(array $config = []) $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; $this->client = new FacebookClient($httpClientHandler, $enableBeta); - if (isset($config['url_handler'])) { - if ($config['url_handler'] instanceof UrlDetectionInterface) { - $this->urlHandler = $config['url_handler']; + if (isset($config['url_detection_handler'])) { + if ($config['url_detection_handler'] instanceof UrlDetectionInterface) { + $this->urlDetectionHandler = $config['url_detection_handler']; } else { throw new \InvalidArgumentException( - 'The url_handler must be an instance of Facebook\Url\UrlInterface' + 'The url_detection_handler must be an instance of Facebook\Url\UrlDetectionInterface' ); } } @@ -222,17 +222,17 @@ public function getClient() } /** - * Returns the URL handler. + * Returns the URL detection handler. * * @return UrlDetectionInterface */ - public function getUrlHandler() + public function getUrlDetectionHandler() { - if ( ! $this->urlHandler) { - $this->urlHandler = new FacebookUrlDetectionHandler(); + if ( ! $this->urlDetectionHandler) { + $this->urlDetectionHandler = new FacebookUrlDetectionHandler(); } - return $this->urlHandler; + return $this->urlDetectionHandler; } /** @@ -265,7 +265,7 @@ public function getRedirectLoginHelper() return new FacebookRedirectLoginHelper( $this->app, $this->persistentDataHandler, - $this->urlHandler + $this->urlDetectionHandler ); } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 8bb7d4664..8ccc9c1da 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -49,9 +49,9 @@ class FacebookRedirectLoginHelper protected $app; /** - * @var UrlDetectionInterface The URL handler. + * @var UrlDetectionInterface The URL detection handler. */ - protected $urlHandler; + protected $urlDetectionHandler; /** * @var PersistentDataInterface The persistent data handler. @@ -63,7 +63,7 @@ class FacebookRedirectLoginHelper * * @param FacebookApp $app The FacebookApp entity. * @param PersistentDataInterface|null $persistentDataHandler The persistent data handler. - * @param UrlDetectionInterface|null $urlHandler The URL handler. + * @param UrlDetectionInterface|null $urlHandler The URL detection handler. */ public function __construct(FacebookApp $app, PersistentDataInterface $persistentDataHandler = null, @@ -71,7 +71,7 @@ public function __construct(FacebookApp $app, { $this->app = $app; $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); - $this->urlHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); + $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); } /** @@ -85,13 +85,13 @@ public function getPersistentDataHandler() } /** - * Returns the URL handler. + * Returns the URL detection handler. * * @return UrlDetectionInterface */ - public function getUrlHandler() + public function getUrlDetectionHandler() { - return $this->urlHandler; + return $this->urlDetectionHandler; } /** @@ -169,7 +169,7 @@ public function getAccessToken(FacebookClient $client, $redirectUrl = null) { if ($this->isValidRedirect()) { $code = $this->getCode(); - $redirectUrl = $redirectUrl ?: $this->urlHandler->getCurrentUrl(); + $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); $paramsToFilter = [ 'state', diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 8151612e7..f86e1a700 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -146,7 +146,7 @@ public function testPersistentDataHandlerCanBeForced() public function testSettingAnInvalidUrlHandlerThrows() { $config = array_merge($this->config, [ - 'url_handler' => 'foo_handler', + 'url_detection_handler' => 'foo_handler', ]); $fb = new Facebook($config); } @@ -154,7 +154,7 @@ public function testSettingAnInvalidUrlHandlerThrows() public function testDefaultUrlHandlerWillBeLazyLoaded() { $fb = new Facebook($this->config); - $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlHandler()); + $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); } /** @@ -174,7 +174,7 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() 'default_access_token' => 'foo_token', 'http_client_handler' => new FooClientInterface(), 'persistent_data_handler' => new FooPersistentDataInterface(), - 'url_handler' => new FooUrlDetectionInterface(), + 'url_detection_handler' => new FooUrlDetectionInterface(), 'enable_beta_mode' => true, 'default_graph_version' => 'v1337', ]); @@ -186,7 +186,7 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $this->assertInstanceOf('Facebook\Tests\FooPersistentDataInterface', $fb->getRedirectLoginHelper()->getPersistentDataHandler()); $this->assertInstanceOf('Facebook\Tests\FooUrlDetectionInterface', - $fb->getRedirectLoginHelper()->getUrlHandler()); + $fb->getRedirectLoginHelper()->getUrlDetectionHandler()); $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $fb->getClient()->getBaseGraphUrl()); $this->assertEquals('1337', $request->getApp()->getId()); From c1537d93d3cbd5e8fba3d04ba55ef24367d731ff Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 19 Nov 2014 13:15:43 -0600 Subject: [PATCH 063/407] Tweaks after code review from @yguedidi --- src/Facebook/Facebook.php | 2 +- .../Helpers/FacebookRedirectLoginHelper.php | 10 ---------- src/Facebook/Url/FacebookUrlDetectionHandler.php | 14 +++++++------- tests/FacebookTest.php | 2 +- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 0be895087..e634956a8 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -228,7 +228,7 @@ public function getClient() */ public function getUrlDetectionHandler() { - if ( ! $this->urlDetectionHandler) { + if ( ! $this->urlDetectionHandler instanceof UrlDetectionInterface) { $this->urlDetectionHandler = new FacebookUrlDetectionHandler(); } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 8ccc9c1da..5f0a0d8be 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -171,16 +171,6 @@ public function getAccessToken(FacebookClient $client, $redirectUrl = null) $code = $this->getCode(); $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); - $paramsToFilter = [ - 'state', - 'code', - 'error', - 'error_reason', - 'error_description', - 'error_code', - ]; - $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, $paramsToFilter); - return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); } return null; diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index f07b6ba9c..90e5925d0 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -45,7 +45,7 @@ public function getCurrentUrl() * * @return string */ - public function getHttpScheme() + protected function getHttpScheme() { return $this->isBehindSsl() ? 'https' : 'http'; } @@ -55,7 +55,7 @@ public function getHttpScheme() * * @return boolean */ - public function isBehindSsl() + protected function isBehindSsl() { // Check for proxy first $protocol = $this->getHeader('X_FORWARDED_PROTO'); @@ -78,7 +78,7 @@ public function isBehindSsl() * * @return boolean */ - public function protocolWithActiveSsl($protocol) + protected function protocolWithActiveSsl($protocol) { $protocol = strtolower((string) $protocol); return ( @@ -96,7 +96,7 @@ public function protocolWithActiveSsl($protocol) * * @return string */ - public function getHostName() + protected function getHostName() { // Check for proxy first if ($host = $this->getHeader('X_FORWARDED_HOST')) { @@ -128,7 +128,7 @@ public function getHostName() return $host . $appendPort; } - public function getCurrentPort() + protected function getCurrentPort() { // Check for proxy first $port = $this->getHeader('X_FORWARDED_PORT'); @@ -151,7 +151,7 @@ public function getCurrentPort() * * @return string */ - public function getServerVar($key) + protected function getServerVar($key) { return isset($_SERVER[$key]) ? $_SERVER[$key] : ''; } @@ -163,7 +163,7 @@ public function getServerVar($key) * * @return string */ - public function getHeader($key) + protected function getHeader($key) { return $this->getServerVar('HTTP_' . $key); } diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index f86e1a700..85ec11751 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -151,7 +151,7 @@ public function testSettingAnInvalidUrlHandlerThrows() $fb = new Facebook($config); } - public function testDefaultUrlHandlerWillBeLazyLoaded() + public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() { $fb = new Facebook($this->config); $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); From dc893dbbbe41f72feabe8a7d69158fa8abe1cb3e Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 19 Nov 2014 13:24:39 -0600 Subject: [PATCH 064/407] Updated tests --- tests/Url/FacebookUrlDetectionHandlerTest.php | 85 +++++++++---------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/tests/Url/FacebookUrlDetectionHandlerTest.php b/tests/Url/FacebookUrlDetectionHandlerTest.php index 43439d5ac..77c16ea62 100644 --- a/tests/Url/FacebookUrlDetectionHandlerTest.php +++ b/tests/Url/FacebookUrlDetectionHandlerTest.php @@ -28,26 +28,13 @@ class FacebookUrlDetectionHandlerTest extends \PHPUnit_Framework_TestCase { - public function setUp() - { - unset( - $_SERVER['REQUEST_URI'], - $_SERVER['HTTPS'], - $_SERVER['SERVER_PORT'], - $_SERVER['SERVER_NAME'], - $_SERVER['SERVER_ADDR'], - $_SERVER['HTTP_HOST'], - $_SERVER['HTTP_X_FORWARDED_HOST'], - $_SERVER['HTTP_X_FORWARDED_PORT'], - $_SERVER['HTTP_X_FORWARDED_PROTO'] - ); - } - public function testProperlyGeneratesUrlFromCommonScenario() { - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '80'; - $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); @@ -57,9 +44,11 @@ public function testProperlyGeneratesUrlFromCommonScenario() public function testProperlyGeneratesSecureUrlFromCommonScenario() { - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '443'; - $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '443', + 'REQUEST_URI' => '/baz?foo=123', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); @@ -69,11 +58,13 @@ public function testProperlyGeneratesSecureUrlFromCommonScenario() public function testProperlyGeneratesUrlFromProxy() { - $_SERVER['HTTP_X_FORWARDED_PORT'] = '80'; - $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '80'; - $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '80', + 'HTTP_X_FORWARDED_PROTO' => 'http', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); @@ -83,11 +74,13 @@ public function testProperlyGeneratesUrlFromProxy() public function testProperlyGeneratesSecureUrlFromProxy() { - $_SERVER['HTTP_X_FORWARDED_PORT'] = '443'; - $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'; - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '80'; - $_SERVER['REQUEST_URI'] = '/baz?foo=123'; + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '443', + 'HTTP_X_FORWARDED_PROTO' => 'https', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); @@ -97,9 +90,11 @@ public function testProperlyGeneratesSecureUrlFromProxy() public function testProperlyGeneratesUrlWithCustomPort() { - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '1337'; - $_SERVER['REQUEST_URI'] = '/foo.php'; + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '1337', + 'REQUEST_URI' => '/foo.php', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); @@ -109,10 +104,12 @@ public function testProperlyGeneratesUrlWithCustomPort() public function testProperlyGeneratesSecureUrlWithCustomPort() { - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '1337'; - $_SERVER['REQUEST_URI'] = '/foo.php'; - $_SERVER['HTTPS'] = 'On'; + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '1337', + 'REQUEST_URI' => '/foo.php', + 'HTTPS' => 'On', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); @@ -122,11 +119,13 @@ public function testProperlyGeneratesSecureUrlWithCustomPort() public function testProperlyGeneratesUrlWithCustomPortFromProxy() { - $_SERVER['HTTP_X_FORWARDED_PORT'] = '8888'; - $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; - $_SERVER['HTTP_HOST'] = 'foo.bar'; - $_SERVER['SERVER_PORT'] = '80'; - $_SERVER['REQUEST_URI'] = '/foo.php'; + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '8888', + 'HTTP_X_FORWARDED_PROTO' => 'http', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/foo.php', + ]; $urlHandler = new FacebookUrlDetectionHandler(); $currentUri = $urlHandler->getCurrentUrl(); From ee71746b3ff92a9213222a3abc3e7cf889fa5467 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 9 Nov 2014 01:52:49 -0600 Subject: [PATCH 065/407] Added pagination and deep pagination support --- docs/Facebook.fbmd | 53 +++ docs/GraphList.fbmd | 71 ++++ docs/GraphObject.fbmd | 75 ++-- docs/sdk_reference.fbmd | 16 +- src/Facebook/Entities/AccessToken.php | 7 +- .../Entities/FacebookBatchRequest.php | 51 ++- .../Entities/FacebookBatchResponse.php | 83 ++++- src/Facebook/Entities/FacebookRequest.php | 131 ++++--- src/Facebook/Entities/FacebookResponse.php | 44 +-- src/Facebook/Facebook.php | 76 ++++- src/Facebook/FacebookClient.php | 9 +- src/Facebook/GraphNodes/GraphList.php | 147 +++++++- .../GraphNodes/GraphObjectFactory.php | 61 +++- src/Facebook/Url/FacebookUrlManipulator.php | 101 +++++- tests/Entities/FacebookBatchRequestTest.php | 11 +- tests/Entities/FacebookBatchResponseTest.php | 62 +++- tests/Entities/FacebookRequestTest.php | 78 ++--- tests/Entities/FacebookResponseTest.php | 37 +- tests/FacebookClientTest.php | 18 - tests/FacebookTest.php | 39 ++- tests/GraphNodes/GraphListTest.php | 117 +++++++ tests/GraphNodes/GraphObjectFactoryTest.php | 319 +++++++++--------- tests/Url/FacebookUrlManipulatorTest.php | 125 +++++++ 23 files changed, 1323 insertions(+), 408 deletions(-) create mode 100644 docs/GraphList.fbmd create mode 100644 tests/GraphNodes/GraphListTest.php diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 9981b1320..3ed3a4ff0 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -150,6 +150,14 @@ public FacebookClient getClient() Returns the instance of `Facebook\FacebookClient` for the instantiated service. + +### getLastResponse() {#get-last-response} +~~~~ +public Facebook\Entities\FacebookResponse|Facebook\Entities\FacebookBatchResponse|null getLastResponse() +~~~~ +Returns the last response received from the Graph API in the form of a `Facebook\Entities\FacebookResponse` or `Facebook\Entities\FacebookBatchResponse`. + + ### getDefaultAccessToken() {#get-default-access-token} ~~~~ @@ -306,3 +314,48 @@ Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRed $helper = $fb->getRedirectLoginHelper(); ~~~~ + + +### next() {#next} +~~~~ +public Facebook\GraphNodes\GraphList|null next(Facebook\GraphNodes\GraphList $graphList) +~~~~ + +Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) object. If the next page returns no results, `null` will be returned. + +~~~~ +// Iterate over 5 pages max +$maxPages = 5; + +// Get a list of photo objects +$response = $fb->get('/me/photos?fields=id,source,likes&limit=5'); + +$photosList = $response->getGraphList(); + +if (count($photosList) > 0) { + $pageCount = 0; + do { + foreach ($photosList as $photo) { + var_dump($photo->asArray()); + + // Deep pagination is supported on child GraphList's + $likes = $photo['likes']; + do { + echo '

Likes:

' . "\n\n"; + var_dump($likes->asArray()); + } while ($likes = $fqb->next($likes)); + } + $pageCount++; + } while ($pageCount < $maxPages && $photosList = $fb->next($photosList)); +} +~~~~ +
+ + +### previous() {#previous} +~~~~ +public Facebook\GraphNodes\GraphList|null previous(Facebook\GraphNodes\GraphList $graphList) +~~~~ + +Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` object. Functions just like `next()` above, but in the opposite direction of pagination. + diff --git a/docs/GraphList.fbmd b/docs/GraphList.fbmd new file mode 100644 index 000000000..7ad738df6 --- /dev/null +++ b/docs/GraphList.fbmd @@ -0,0 +1,71 @@ + +# GraphList for the Facebook SDK for PHP + +When a list of nodes is returned from a Graph request, it can be cast as a `GraphList` which provides convenient ways of interacting with the data which includes pagination. + + + +## Facebook\GraphNodes\GraphList {#overview} + +You can grab a `GraphList` from a response from Graph. + +~~~~ +$graphList = $request->getGraphList(); +~~~~ + +Usage: + +~~~~ +// Iterate over all the GraphObject in the list +foreach ($graphList as $graphObject) { + // . . . +} +~~~~ + + + +## Pagination {#pagination} + +With the help of the `Facebook\Facebook` super service class, the `GraphList` collection can grab the next and previous sets of data. + +~~~~ +$listOfAlbums = $response->getGraphList(); + +// Get the next page of results +$nextPageOfAlbums = $fb->next($listOfAlbums); +// 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 {#deep-pagination} + +Sometimes Graph will return a list of nodes within a node. Paginating on these sub lists can be non-trivial. Fortunately, the `GraphList` collection takes the guesswork out and allows you to paginate deeply within a `GraphList`. + +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. + +~~~~ +$listOfPages = $response->getGraphList(); +// Only grab 5 pages +$maxPages = 5; +$pageCount = 0; + +do { + echo '

Page #' . $page_count . ':

' . "\n\n"; + + foreach ($listOfPages 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 && $listOfPages = $fb->next($listOfPages)); +~~~~ +
diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd index 99517b895..2829d0ff9 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphObject.fbmd @@ -1,17 +1,19 @@ # GraphObject for the Facebook SDK for PHP -Represents an object returned by the Graph API. +A `GraphObject` is a collection that represents a node returned by the Graph API. ## Facebook\GraphObject {#overview} -This base class has several subclasses, some are provided by default: +This base class has several subclasses: -[__GraphUser__](#user-instance-methods) -[__GraphLocation__](#location-instance-methods) +[__GraphUser__](#user-instance-methods) +[__GraphPage__](#page-instance-methods) +[__GraphAlbum__](#album-instance-methods) +[__GraphLocation__](#location-instance-methods) [__GraphSessionInfo__](#sessioninfo-instance-methods) Usage: @@ -21,14 +23,10 @@ Usage: $object = $response->getGraphObject(); // Get the response typed as a GraphUser -$user = $response->getGraphObject(GraphUser::className()); -// or convert the base object previously accessed -// $user = $object->cast(GraphUser::className()); +$user = $response->getGraphUser()); -// Get the response typed as a GraphLocation -$loc = $response->getGraphObject(GraphLocation::className()); -// or convert the base object previously accessed -// $loc = $object->cast(GraphLocation::className()); +// Get the response typed as a GraphPage +$page = $response->getGraphPage(); // User example echo $object->getProperty('name'); @@ -40,7 +38,31 @@ echo $loc->getCountry(); // SessionInfo example $info = $session->getSessionInfo()); -echo $info->getxpiresAt(); +echo $info->getExpiresAt(); +~~~~ + + + + +## SPL Libraries {#spl} + +The `GraphObject` 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 `GraphObject`. + +~~~~ +$graphObject = $response->getGraphObject(); + +// Array access +$id = $graphObject['id']; + +// Iteration +foreach ($graphObject as $key => $value) { + // . . . +} + +// Counting +$total = count($graphObject); ~~~~ @@ -48,25 +70,32 @@ echo $info->getxpiresAt(); ## GraphObject Instance Methods {#instance-methods} -### cast {#cast} -`cast(string $type)` -Returns a new instance of a GraphObject subclass with this objects underlying data. -### asArray {#asarray} +### asArray {#as-array} `asArray()` Returns the raw representation (associative arrays, nested) of this objects underlying data. -### getProperty {#getproperty} -`getProperty(string $name, string $type = 'Facebook\GraphObject')` -Gets the value of a named key for this graph object. 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 GraphObject cast to the appropriate subclass type if provided. -### getPropertyAsArray {#getproparray} -`getPropertyAsArray()` -Gets the contents of a named array property on this graph object. If the values are scalar (strings, numbers, etc.) they will be returned as-is. If the values are associative arrays, they will be returned as GraphObjects cast to the appropriate subclass type if provided. +### asJson {#as-json} +`asJson()` +Returns the data as a JSON string. + + +### getProperty {#get-property} +`getProperty(string $name, string $default = 'foo')` +Gets the value of a named key for this graph object. 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 GraphObject. -### getPropertyNames +The second argument lets you define a default value to return if the property doesn't exist. + + +### getPropertyNames {#get-property-names} `getPropertyNames()` Returns an array with the names of all properties present on this graph object. + + +### map {#map} +`map(Closure $callback)` +Provides a way to map over the data within the collection just like `array_map()`. diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 13f27b7f8..0f6d74643 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -116,6 +116,14 @@ Graph nodes are collections that represent nodes returned by Graph. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ + [ + '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', + 'The base collection object that represents a generic node.', + ], + [ + '`[Facebook\GraphNodes\GraphList](/docs/php/GraphList)`', + 'A list of GraphObject's with special methods to help paginate over the list.', + ], [ '`[Facebook\GraphNodes\GraphAlbum](/docs/php/GraphAlbum)`', 'A collection that represents an album node.', @@ -124,10 +132,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\GraphNodes\GraphLocation](/docs/php/GraphLocation)`', 'A collection that represents a location node.', ], - [ - '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', - 'The base collection object that represents a generic node.', - ], [ '`[Facebook\GraphNodes\GraphPage](/docs/php/GraphPage)`', 'A collection that represents a page node.', @@ -140,10 +144,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\GraphNodes\GraphUser](/docs/php/GraphUser)`', 'A collection that represents a user node.', ], - [ - '`[Facebook\GraphNodes\GraphUserPage](/docs/php/GraphUserPage)`', - '*(Deprecated)* A collection that represents a user page node.', - ], ], }) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 2785ed38d..ea4eeb607 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -343,9 +343,12 @@ protected static function request($endpoint, array $params, FacebookApp $app, Fa $app, $app->getAccessToken(), 'GET', - $endpoint, - $params + $endpoint ); + // We know what we're doing here. + // We want to send the access token as a param. + $request->dangerouslySetParams($params); + return $client->sendRequest($request); } diff --git a/src/Facebook/Entities/FacebookBatchRequest.php b/src/Facebook/Entities/FacebookBatchRequest.php index fc2aee2a5..87e2518b7 100755 --- a/src/Facebook/Entities/FacebookBatchRequest.php +++ b/src/Facebook/Entities/FacebookBatchRequest.php @@ -23,13 +23,16 @@ */ namespace Facebook\Entities; +use ArrayIterator; +use IteratorAggregate; +use ArrayAccess; use Facebook\Exceptions\FacebookSDKException; /** * Class BatchRequest * @package Facebook */ -class FacebookBatchRequest extends FacebookRequest +class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, ArrayAccess { /** @@ -41,14 +44,14 @@ class FacebookBatchRequest extends FacebookRequest * Creates a new Request entity. * * @param FacebookApp|null $app - * @param AccessToken|string|null $accessToken * @param array $requests + * @param AccessToken|string|null $accessToken * @param string|null $graphVersion */ public function __construct( FacebookApp $app = null, - $accessToken = null, array $requests = [], + $accessToken = null, $graphVersion = null ) { @@ -216,4 +219,46 @@ public static function requestEntityToBatchArray(FacebookRequest $request, $requ return $batch; } + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->requests); + } + + /** + * @return @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->add($value, $offset); + } + + /** + * @return @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->requests[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->requests[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->requests[$offset]['request']) ? $this->requests[$offset]['request'] : null; + } + } diff --git a/src/Facebook/Entities/FacebookBatchResponse.php b/src/Facebook/Entities/FacebookBatchResponse.php index e13d56749..d43c2eb2a 100755 --- a/src/Facebook/Entities/FacebookBatchResponse.php +++ b/src/Facebook/Entities/FacebookBatchResponse.php @@ -25,14 +25,20 @@ use ArrayIterator; use IteratorAggregate; +use ArrayAccess; /** * Class BatchResponse * @package Facebook */ -class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate +class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate, ArrayAccess { + /** + * @var FacebookBatchRequest The original entity that made the batch request. + */ + protected $batchRequest; + /** * @var array An array of FacebookResponse entities. */ @@ -41,18 +47,21 @@ class FacebookBatchResponse extends FacebookResponse implements IteratorAggregat /** * Creates a new Response entity. * + * @param FacebookBatchRequest $batchRequest * @param FacebookResponse $response */ public function __construct( + FacebookBatchRequest $batchRequest, FacebookResponse $response ) { - $app = $response->getApp(); + $this->batchRequest = $batchRequest; + + $request = $response->getRequest(); + $body = $response->getBody(); $httpStatusCode = $response->getHttpStatusCode(); $headers = $response->getHeaders(); - $body = $response->getBody(); - $accessToken = $response->getAccessToken(); - parent::__construct($app, $httpStatusCode, $headers, $body, $accessToken); + parent::__construct($request, $body, $httpStatusCode, $headers); $responses = $response->getDecodedBody(); $this->setResponses($responses); @@ -77,24 +86,70 @@ public function getResponses() public function setResponses(array $responses) { $this->responses = []; - foreach ($responses as $graphResponse) { - $httpResponseCode = isset($graphResponse['code']) ? $graphResponse['code'] : null; - $httpResponseHeaders = isset($graphResponse['headers']) ? $graphResponse['headers'] : []; - $httpResponseBody = isset($graphResponse['body']) ? $graphResponse['body'] : null; - // @TODO Figure out an elegant way to get the access token that was used with this response. - $accessToken = null; - $this->responses[] = new FacebookResponse($this->app, $httpResponseCode, $httpResponseHeaders, $httpResponseBody, $accessToken); + foreach ($responses as $k => $graphResponse) { + $this->addResponse($graphResponse, $k); } } /** - * Get an iterator for the items. + * Add a response to the list. * - * @return ArrayIterator + * @param array $response + * @param mixed|null $key + */ + public function addResponse(array $response, $key = null) + { + $originalRequest = isset($this->batchRequest[$key]) ? $this->batchRequest[$key] : $this->batchRequest; + + $httpResponseBody = isset($response['body']) ? $response['body'] : null; + $httpResponseCode = isset($response['code']) ? $response['code'] : null; + $httpResponseHeaders = isset($response['headers']) ? $response['headers'] : []; + + $this->responses[] = new FacebookResponse( + $originalRequest, + $httpResponseBody, + $httpResponseCode, + $httpResponseHeaders); + } + + /** + * @return @inheritdoc */ public function getIterator() { return new ArrayIterator($this->responses); } + /** + * @return @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->addResponse($value, $offset); + } + + /** + * @return @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->responses[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->responses[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->responses[$offset]) ? $this->responses[$offset] : null; + } + } diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 558502ea4..7cac7d9ae 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -24,6 +24,7 @@ namespace Facebook\Entities; use Facebook\Facebook; +use Facebook\Url\FacebookUrlManipulator; use Facebook\Exceptions\FacebookSDKException; /** @@ -113,6 +114,30 @@ public function setAccessToken($accessToken) return $this; } + /** + * Sets the access token with one harvested from a URL or POST params. + * + * @param string $accessToken The access token. + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setAccessTokenFromParams($accessToken) + { + $existingAccessToken = $this->getAccessToken(); + if ( ! $existingAccessToken) { + $this->setAccessToken($accessToken); + } elseif ($accessToken !== $existingAccessToken) { + throw new FacebookSDKException( + 'Access token mismatch. The access token provided in the FacebookRequest ' . + 'and the one provided in the URL or POST params do not match.' + ); + } + + return $this; + } + /** * Return the access token for this request. * @@ -143,6 +168,16 @@ public function getApp() return $this->app; } + /** + * Generate an app secret proof to sign this request. + * + * @return string + */ + public function getAppSecretProof() + { + return AppSecretProof::make($this->getAccessToken(), $this->app->getSecret()); + } + /** * Validate that an access token exists for this request. * @@ -210,10 +245,21 @@ public function validateMethod() * @param string * * @return FacebookRequest + * + * @throws FacebookSDKException */ public function setEndpoint($endpoint) { - $this->endpoint = $endpoint; + // Harvest the access token from the endpoint to keep things in sync + $params = FacebookUrlManipulator::getParamsAsArray($endpoint); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Clean the token & app secret proof from the endpoint. + $filterParams = ['access_token', 'appsecret_proof']; + $this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams); + return $this; } @@ -260,12 +306,34 @@ public function setETag($eTag) * @param array $params * * @return FacebookRequest + * + * @throws FacebookSDKException */ public function setParams(array $params = []) { - if (is_array($params)) { - $this->params = array_merge($this->params, $params); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); } + + // Don't let these buggers slip in. + unset($params['access_token'], $params['appsecret_proof']); + + $this->dangerouslySetParams($params); + + return $this; + } + + /** + * Set the params for this request without filtering them first. + * + * @param array $params + * + * @return FacebookRequest + */ + public function dangerouslySetParams(array $params = []) + { + $this->params = array_merge($this->params, $params); + return $this; } @@ -278,11 +346,10 @@ public function getParams() { $params = $this->params; - if (!isset($params['access_token']) && $this->getAccessToken()) { - $params['access_token'] = $this->getAccessToken(); - } - if (!isset($params['appsecret_proof']) && isset($params['access_token'])) { - $params['appsecret_proof'] = AppSecretProof::make($params['access_token'], $this->app->getSecret()); + $accessToken = $this->getAccessToken(); + if ($accessToken) { + $params['access_token'] = $accessToken; + $params['appsecret_proof'] = $this->getAppSecretProof(); } return $params; @@ -321,61 +388,19 @@ public function getUrl() { $this->validateMethod(); - $graphVersion = static::forceSlashPrefix($this->graphVersion); - $endpoint = static::forceSlashPrefix($this->getEndpoint()); + $graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion); + $endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint()); $url = $graphVersion.$endpoint; if ($this->getMethod() !== 'POST') { $params = $this->getParams(); - $url = static::appendParamsToUrl($url, $params); + $url = FacebookUrlManipulator::appendParamsToUrl($url, $params); } return $url; } - /** - * Gracefully appends params to the URL. - * - * @param string $url - * @param array $params - * - * @return string - */ - public static function appendParamsToUrl($url, $params = []) - { - if (!$params) { - return $url; - } - - if (strpos($url, '?') === false) { - return $url . '?' . http_build_query($params, null, '&'); - } - - list($path, $query_string) = explode('?', $url, 2); - parse_str($query_string, $query_array); - - // Favor params from the original URL over $params - $params = array_merge($params, $query_array); - - return $path . '?' . http_build_query($params, null, '&'); - } - - /** - * Check for a "/" prefix and prepend it if not exists. - * - * @param string|null $string - * - * @return string|null - */ - public static function forceSlashPrefix($string) - { - if (!$string) { - return $string; - } - return strpos($string, '/') === 0 ? $string : '/'.$string; - } - /** * Return the default headers that every request should use. * diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index cfae8aa35..55a1e9bab 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -28,7 +28,7 @@ use Facebook\Exceptions\FacebookSDKException; /** - * Class Response + * Class FacebookResponse * @package Facebook */ class FacebookResponse @@ -55,14 +55,9 @@ class FacebookResponse protected $decodedBody = []; /** - * @var string The access token that was used. + * @var FacebookRequest The original request that returned this response. */ - protected $accessToken; - - /** - * @var FacebookApp The facebook app entity. - */ - protected $app; + protected $request; /** * @var FacebookSDKException The exception thrown by this request. @@ -72,29 +67,36 @@ class FacebookResponse /** * Creates a new Response entity. * - * @param FacebookApp $app + * @param FacebookRequest $request + * @param string|null $body * @param int|null $httpStatusCode * @param array|null $headers - * @param string|null $body - * @param string|null $accessToken */ public function __construct( - FacebookApp $app, - $httpStatusCode = null, - array $headers = [], + FacebookRequest $request, $body = null, - $accessToken = null + $httpStatusCode = null, + array $headers = [] ) { - $this->app = $app; + $this->request = $request; + $this->body = $body; $this->httpStatusCode = $httpStatusCode; $this->headers = $headers; - $this->body = $body; - $this->accessToken = $accessToken; $this->decodeBody(); } + /** + * Return the original request that returned this response. + * + * @return FacebookRequest + */ + public function getRequest() + { + return $this->request; + } + /** * Return the FacebookApp entity used for this response. * @@ -102,7 +104,7 @@ public function __construct( */ public function getApp() { - return $this->app; + return $this->request->getApp(); } /** @@ -112,7 +114,7 @@ public function getApp() */ public function getAccessToken() { - return $this->accessToken; + return $this->request->getAccessToken(); } /** @@ -162,7 +164,7 @@ public function getDecodedBody() */ public function getAppSecretProof() { - return AppSecretProof::make($this->accessToken, $this->app->getSecret()); + return $this->request->getAppSecretProof(); } /** diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index e634956a8..c75dc80fd 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -29,6 +29,7 @@ use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookResponse; use Facebook\Entities\FacebookBatchResponse; +use Facebook\GraphNodes\GraphList; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\HttpClients\FacebookHttpClientInterface; @@ -102,6 +103,11 @@ class Facebook */ protected $persistentDataHandler; + /** + * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. + */ + protected $lastResponse; + /** * @TODO Add FacebookInputInterface * @TODO Add FacebookRandomGeneratorInterface @@ -221,6 +227,16 @@ public function getClient() return $this->client; } + /** + * Returns the last response returned from Graph. + * + * @return FacebookResponse|FacebookBatchResponse|null + */ + public function getLastResponse() + { + return $this->lastResponse; + } + /** * Returns the URL detection handler. * @@ -352,6 +368,60 @@ public function delete( $graphVersion); } + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function next(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'next'); + } + + /** + * Sends a request to Graph for the previous page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function previous(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'previous'); + } + + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * @param string $direction The direction of the pagination: next|previous. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function getPaginationResults(GraphList $graphList, $direction) + { + $paginationRequest = $graphList->getPaginationRequest($direction); + if ( ! $paginationRequest) { + return null; + } + + $this->lastResponse = $this->client->sendRequest($paginationRequest); + + // Keep the same GraphObject subclass + $subClassName = $graphList->getSubClassName(); + $graphList = $this->lastResponse->getGraphList($subClassName, false); + + return count($graphList) > 0 ? $graphList : null; + } + /** * Sends a request to Graph and returns the result. * @@ -377,7 +447,7 @@ public function sendRequest( $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); - return $this->client->sendRequest($request); + return $this->lastResponse = $this->client->sendRequest($request); } /** @@ -400,12 +470,12 @@ public function sendBatchRequest( $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $batchRequest = new FacebookBatchRequest( $this->app, - $accessToken, $requests, + $accessToken, $graphVersion ); - return $this->client->sendBatchRequest($batchRequest); + return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); } /** diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index f5ccdc793..c90ac5a88 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -152,17 +152,14 @@ public function sendRequest(FacebookRequest $request) // Should throw `FacebookSDKException` exception on HTTP client error. // Don't catch to allow it to bubble up. - $response = $this->httpClientHandler->send($url, $method, $params, $headers); + $responseBody = $this->httpClientHandler->send($url, $method, $params, $headers); static::$requestCount++; $httpResponseCode = $this->httpClientHandler->getResponseHttpStatusCode(); $httpResponseHeaders = $this->httpClientHandler->getResponseHeaders(); - $accessToken = $request->getAccessToken(); - $app = $request->getApp(); - - $returnResponse = new FacebookResponse($app, $httpResponseCode, $httpResponseHeaders, $response, $accessToken); + $returnResponse = new FacebookResponse($request, $responseBody, $httpResponseCode, $httpResponseHeaders); if ($returnResponse->isError()) { throw $returnResponse->getThrownException(); @@ -185,7 +182,7 @@ public function sendBatchRequest(FacebookBatchRequest $request) $request->prepareRequestsForBatch(); $facebookResponse = $this->sendRequest($request); - return new FacebookBatchResponse($facebookResponse); + return new FacebookBatchResponse($request, $facebookResponse); } } diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 743138e4f..142b1c80f 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -23,6 +23,10 @@ */ namespace Facebook\GraphNodes; +use Facebook\Entities\FacebookRequest; +use Facebook\Url\FacebookUrlManipulator; +use Facebook\Exceptions\FacebookSDKException; + /** * Class GraphList * @package Facebook @@ -31,39 +35,166 @@ class GraphList extends Collection { /** - * @var array $metaData An array of Graph meta data like pagination, etc. + * @var FacebookRequest The original request that generated this data. + */ + protected $request; + + /** + * @var array An array of Graph meta data like pagination, etc. */ protected $metaData = []; + /** + * @var string|null The parent Graph edge endpoint that generated the list. + */ + protected $parentEdgeEndpoint; + + /** + * @var string|null The subclass of the child GraphObject's. + */ + protected $subclassName; + /** * Init this collection of GraphObject's. * + * @param FacebookRequest $request The original request that generated this data. * @param array $data An array of GraphObject's. * @param array $metaData An array of Graph meta data like pagination, etc. + * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. + * @param string|null $subclassName The subclass of the child GraphObject's. */ - public function __construct(array $data = [], array $metaData = []) + public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) { + $this->request = $request; $this->metaData = $metaData; + $this->parentEdgeEndpoint = $parentEdgeEndpoint; + $this->subclassName = $subclassName; parent::__construct($data); } /** - * Get the next page of results of this list of Graph objects. + * Gets the parent Graph edge endpoint that generated the list. + * + * @return string|null + */ + public function getParentGraphEdge() + { + return $this->parentEdgeEndpoint; + } + + /** + * Gets the subclass name that the child GraphObject's are cast as. + * + * @return string|null + */ + public function getSubClassName() + { + return $this->subclassName; + } + + /** + * Generates a pagination URL based on a cursor. + * + * @param string $direction The direction of the page: next|previous + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function getPaginationUrl($direction) + { + $this->validateForPagination(); + + // Do we have a paging URL? + if (isset($this->metaData['paging'][$direction])) { + // Graph returns the full URL with all the original params. + // We just want the endpoint though. + $pageUrl = $this->metaData['paging'][$direction]; + return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); + } + + // Do we have a cursor to work with? + $cursorDirection = $direction === 'next' ? 'after' : 'before'; + if ( ! isset($this->metaData['paging']['cursors'][$cursorDirection])) { + return null; + } + + // If we don't know the ID of the parent node, this ain't gonna work. + if ( ! $this->parentEdgeEndpoint) { + return null; + } + + // We have the parent node ID, paging cursor & original request. + // These were the ingredients chosen to create the perfect little URL. + $cursor = $this->metaData['paging']['cursors'][$cursorDirection]; + + $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); + + // Pull in the original params + $originalUrl = $this->request->getUrl(); + $pageUrl = FacebookUrlManipulator::mergeUrlParams($originalUrl, $pageUrl); + + return FacebookUrlManipulator::forceSlashPrefix($pageUrl); + } + + /** + * Validates whether or not we can paginate on this request. * - * @TODO + * @throws FacebookSDKException */ - public function next() + public function validateForPagination() { + if ($this->request->getMethod() !== 'GET') { + throw new FacebookSDKException( + 'You can only paginate on a GET request.', 720 + ); + } } /** - * Get the previous page of results of this list of Graph objects. + * Gets the request object needed to make a next|previous page request. + * + * @param string $direction The direction of the page: next|previous + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPaginationRequest($direction) + { + $pageUrl = $this->getPaginationUrl($direction); + if ( ! $pageUrl) { + return null; + } + + $newRequest = clone $this->request; + $newRequest->setEndpoint($pageUrl); + return $newRequest; + } + + /** + * Gets the request object needed to make a "next" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getNextPageRequest() + { + return $this->getPaginationRequest('next'); + } + + /** + * Gets the request object needed to make a "previous" page request. + * + * @return FacebookRequest|null * - * @TODO + * @throws FacebookSDKException */ - public function previous() + public function getPreviousPageRequest() { + return $this->getPaginationRequest('previous'); } } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 0d580ab0b..98d11be2f 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -46,12 +46,17 @@ class GraphObjectFactory /** * @const string The base graph object class. */ - const BASE_GRAPH_OBJECT_CLASS = '\\Facebook\\GraphNodes\\GraphObject'; + const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; /** * @const string The graph object prefix. */ - const BASE_GRAPH_OBJECT_PREFIX = '\\Facebook\\GraphNodes\\'; + const BASE_GRAPH_OBJECT_PREFIX = '\Facebook\GraphNodes\\'; + + /** + * @var FacebookResponse The response entity from Graph. + */ + protected $response; /** * @var array The decoded body of the FacebookResponse entity from Graph. @@ -65,6 +70,7 @@ class GraphObjectFactory */ public function __construct(FacebookResponse $response) { + $this->response = $response; $this->decodedBody = $response->getDecodedBody(); } @@ -82,12 +88,7 @@ public function makeGraphObject($subclassName = null) $this->validateResponseAsArray(); $this->validateResponseCastableAsGraphObject(); - // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key - if (isset($this->decodedBody['data'])) { - $this->decodedBody = $this->decodedBody['data']; - } - - return $this->safelyMakeGraphObject($this->decodedBody, $subclassName); + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } /** @@ -157,7 +158,7 @@ public function makeGraphList($subclassName = null, $auto_prefix = true) $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; } - return $this->safelyMakeGraphList($this->decodedBody, $subclassName); + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } /** @@ -223,6 +224,9 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; static::validateSubclass($subclassName); + // Remember the parent node ID + $parentNodeId = isset($data['id']) ? $data['id'] : null; + $items = []; foreach ($data as $k => $v) { @@ -237,7 +241,7 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) : null; // Could be a GraphList or GraphObject - $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass); + $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); } else { $items[$k] = $v; } @@ -251,17 +255,19 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) * * @param array $data The array of data to iterate over. * @param string|null $subclassName The subclass to cast this collection to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. * * @return GraphObject|GraphList * * @throws FacebookSDKException */ - public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) + public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (isset($data['data'])) { // Create GraphList if (static::isCastableAsGraphList($data['data'])) { - return $this->safelyMakeGraphList($data, $subclassName); + return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); } // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key $data = $data['data']; @@ -276,12 +282,14 @@ public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) * * @param array $data The array of data to iterate over. * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. * * @return GraphList * * @throws FacebookSDKException */ - public function safelyMakeGraphList(array $data, $subclassName = null) + public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if ( ! isset($data['data'])) { throw new FacebookSDKException( @@ -291,13 +299,32 @@ public function safelyMakeGraphList(array $data, $subclassName = null) $dataList = []; foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName); + $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName, $parentKey, $parentNodeId); } - // @TODO: Look for meta data here - $metaData = []; + $metaData = $this->getMetaData($data); + + // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) + $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; + + return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + } + + /** + * Get the meta data from a list in a Graph response. + * + * @param array $data The Graph response. + * + * @return array + */ + public function getMetaData(array $data) + { + $meta_data = []; + if (isset($data['paging'])) { + $meta_data['paging'] = $data['paging']; + } - return new GraphList($dataList, $metaData); + return $meta_data; } /** diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index 2f79c49f3..f19eb3913 100755 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -57,11 +57,110 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) } } + $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; + $host = isset($parts['host']) ? $parts['host'] : ''; $port = isset($parts['port']) ? ':' . $parts['port'] : ''; $path = isset($parts['path']) ? $parts['path'] : ''; $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; - return $parts['scheme'] . '://' . $parts['host'] . $port . $path . $query . $fragment; + return $scheme . $host . $port . $path . $query . $fragment; + } + + /** + * Gracefully appends params to the URL. + * + * @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 = []) + { + if ( ! $newParams) { + return $url; + } + + if (strpos($url, '?') === false) { + return $url . '?' . http_build_query($newParams, null, '&'); + } + + list($path, $query) = explode('?', $url, 2); + $existingParams = []; + parse_str($query, $existingParams); + + // Favor params from the original URL over $newParams + $newParams = array_merge($newParams, $existingParams); + + // Sort for a predicable order + ksort($newParams); + + return $path . '?' . http_build_query($newParams, null, '&'); + } + + /** + * Returns the params from a URL in the form of an array. + * + * @param string $url The URL to parse the params from. + * + * @return array + */ + public static function getParamsAsArray($url) + { + $query = parse_url($url, PHP_URL_QUERY); + if ( ! $query) { + return []; + } + $params = []; + parse_str($query, $params); + + return $params; + } + + /** + * Adds the params of the first URL to the second URL. + * Any params that already exist in the second URL will go untouched. + * + * @param string $urlToStealFrom The URL harvest the params from. + * @param string $urlToAddTo The URL that will receive the new params. + * + * @return string The $urlToAddTo with any new params from $urlToStealFrom. + */ + public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) + { + $newParams = static::getParamsAsArray($urlToStealFrom); + // Nothing new to add, return as-is + if ( ! $newParams) { + return $urlToAddTo; + } + + return static::appendParamsToUrl($urlToAddTo, $newParams); + } + + /** + * Check for a "/" prefix and prepend it if not exists. + * + * @param string|null $string + * + * @return string|null + */ + public static function forceSlashPrefix($string) + { + if (!$string) { + return $string; + } + return strpos($string, '/') === 0 ? $string : '/' . $string; + } + + /** + * Trims off the hostname and Graph version from a URL. + * + * @param string $urlToTrim The URL the needs the surgery. + * + * @return string The $urlToTrim with the hostname and Graph version removed. + */ + public static function baseGraphUrlEndpoint($urlToTrim) + { + return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); } } diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/Entities/FacebookBatchRequestTest.php index f2659b1ac..b888ceadb 100755 --- a/tests/Entities/FacebookBatchRequestTest.php +++ b/tests/Entities/FacebookBatchRequestTest.php @@ -31,6 +31,9 @@ class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ private $app; public function setUp() @@ -40,7 +43,7 @@ public function setUp() public function testABatchRequestWillInstantiateWithTheProperProperties() { - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', [], 'v0.1337'); + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token', 'v0.1337'); $this->assertSame($this->app, $batchRequest->getApp()); $this->assertEquals('foo_token', $batchRequest->getAccessToken()); @@ -159,7 +162,7 @@ public function testRequestsCanBeInjectedIntoConstructor() new FacebookRequest(null, null, 'DELETE', '/baz'), ]; - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', $requests); + $batchRequest = new FacebookBatchRequest($this->app, $requests, 'foo_token'); $formattedRequests = $batchRequest->getRequests(); $this->assertRequestsMatch($requests, $formattedRequests); @@ -170,7 +173,7 @@ public function testRequestsCanBeInjectedIntoConstructor() */ public function testAZeroRequestCountWithThrow() { - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token'); + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token'); $batchRequest->validateBatchRequestCount(); } @@ -294,7 +297,7 @@ private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $ private function createBatchRequest() { - return new FacebookBatchRequest($this->app, 'foo_token'); + return new FacebookBatchRequest($this->app, [], 'foo_token'); } private function createBatchRequestWithRequests(array $requests) diff --git a/tests/Entities/FacebookBatchResponseTest.php b/tests/Entities/FacebookBatchResponseTest.php index fd7ddb694..395773cf8 100755 --- a/tests/Entities/FacebookBatchResponseTest.php +++ b/tests/Entities/FacebookBatchResponseTest.php @@ -24,12 +24,37 @@ namespace Facebook\Tests\Entities; use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookResponse; +use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookBatchResponse; class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\Entities\FacebookApp + */ + protected $app; + + /** + * @var \Facebook\Entities\FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $this->app, + 'foo_token', + 'POST', + '/', + ['batch' => 'foo'], + 'foo_eTag', + 'v1337'); + } + public function testASuccessfulJsonBatchResponseWillBeDecoded() { $graphResponseJson = '['; @@ -46,9 +71,9 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() // After DELETE operation. $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"true"}'; $graphResponseJson .= ']'; - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $batchResponse = new FacebookBatchResponse($response); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, []); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); $decodedResponses = $batchResponse->getResponses(); @@ -84,9 +109,9 @@ public function testABatchResponseCanBeIteratedOver() $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; $graphResponseJson .= ']'; - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $batchResponse = new FacebookBatchResponse($response); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, []); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); $this->assertInstanceOf('IteratorAggregate', $batchResponse); @@ -95,4 +120,29 @@ public function testABatchResponseCanBeIteratedOver() } } + public function testTheOriginalRequestCanBeObtainedForEachRequest() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $requests = [ + new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), + new FacebookRequest($this->app, 'foo_token_two', 'POST', '/you'), + new FacebookRequest($this->app, 'foo_token_three', 'DELETE', '/123456'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $batchResponse[0]); + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $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/Entities/FacebookRequestTest.php b/tests/Entities/FacebookRequestTest.php index 9c089ddd9..25ac1388c 100755 --- a/tests/Entities/FacebookRequestTest.php +++ b/tests/Entities/FacebookRequestTest.php @@ -98,6 +98,25 @@ public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() ], $params); } + public function testAnAccessTokenCanBeSetFromTheParams() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'POST', '/me', ['access_token' => 'bar_token']); + + $accessToken = $request->getAccessToken(); + + $this->assertEquals('bar_token', $accessToken); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAccessTokenConflictsWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + new FacebookRequest($app, 'foo_token', 'POST', '/me', ['access_token' => 'bar_token']); + } + public function testAProperUrlWillBeGenerated() { $app = new FacebookApp('123', 'foo_secret'); @@ -117,7 +136,7 @@ public function testAProperUrlWillBeGenerated() $this->assertEquals($expectedUrl, $postUrl); } - public function testParamsAreNotOverwritten() + public function testAuthenticationParamsAreStrippedAndReapplied() { $app = new FacebookApp('123', 'foo_secret'); @@ -127,71 +146,26 @@ public function testParamsAreNotOverwritten() $method = 'GET', $endpoint = '/foo', $params = [ - 'access_token' => 'bar_access_token', + 'access_token' => 'foo_token', 'appsecret_proof' => 'bar_app_secret', + 'bar' => 'baz', ] ); $url = $request->getUrl(); - $expectedParams = 'access_token=bar_access_token&appsecret_proof=bar_app_secret'; + $expectedParams = 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; $this->assertEquals($expectedUrl, $url); $params = $request->getParams(); $expectedParams = [ - 'access_token' => 'bar_access_token', - 'appsecret_proof' => 'bar_app_secret', - ]; - $this->assertEquals($expectedParams, $params); - } - - public function testGracefullyHandlesUrlAppending() - { - $params = []; - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/', $processed_url); - - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); - - $params = [ - 'access_token' => 'foo', + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', 'bar' => 'baz', ]; - $url = 'https://www.foo.com/?foo=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); - - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/?foo=bar&access_token=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); - } - - public function testSlashesAreProperlyPrepended() - { - $slashTestOne = FacebookRequest::forceSlashPrefix('foo'); - $slashTestTwo = FacebookRequest::forceSlashPrefix('/foo'); - $slashTestThree = FacebookRequest::forceSlashPrefix('foo/bar'); - $slashTestFour = FacebookRequest::forceSlashPrefix('/foo/bar'); - $slashTestFive = FacebookRequest::forceSlashPrefix(null); - $slashTestSix = FacebookRequest::forceSlashPrefix(''); - - $this->assertEquals('/foo', $slashTestOne); - $this->assertEquals('/foo', $slashTestTwo); - $this->assertEquals('/foo/bar', $slashTestThree); - $this->assertEquals('/foo/bar', $slashTestFour); - $this->assertEquals(null, $slashTestFive); - $this->assertEquals('', $slashTestSix); + $this->assertEquals($expectedParams, $params); } } diff --git a/tests/Entities/FacebookResponseTest.php b/tests/Entities/FacebookResponseTest.php index 42ca4572b..5ebba834a 100755 --- a/tests/Entities/FacebookResponseTest.php +++ b/tests/Entities/FacebookResponseTest.php @@ -24,23 +24,33 @@ namespace Facebook\Tests\Entities; use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookResponse; class FacebookResponseTest extends \PHPUnit_Framework_TestCase { - public function testAnEmptyResponseEntityCanInstantiate() + /** + * @var \Facebook\Entities\FacebookRequest + */ + protected $request; + + public function setUp() { $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app); - - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); } public function testAnETagCanBeProperlyAccessed() { - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, ['ETag' => 'foo_tag']); + $response = new FacebookResponse($this->request, '', 200, ['ETag' => 'foo_tag']); $eTag = $response->getETag(); @@ -49,8 +59,7 @@ public function testAnETagCanBeProperlyAccessed() public function testAProperAppSecretProofCanBeGenerated() { - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], '', 'foo_token'); + $response = new FacebookResponse($this->request); $appSecretProof = $response->getAppSecretProof(); @@ -59,9 +68,8 @@ public function testAProperAppSecretProofCanBeGenerated() public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseJson = '{"id":"123","name":"Foo"}'; - $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); $decodedResponse = $response->getDecodedBody(); $graphObject = $response->getGraphObject(); @@ -76,9 +84,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; - $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); $graphObjectList = $response->getGraphList(); @@ -89,9 +96,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseKeyValuePairs = 'id=123&name=Foo'; - $response = new FacebookResponse($app, 200, [], $graphResponseKeyValuePairs); + $response = new FacebookResponse($this->request, $graphResponseKeyValuePairs, 200); $decodedResponse = $response->getDecodedBody(); @@ -104,9 +110,8 @@ public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; - $response = new FacebookResponse($app, 401, [], $graphResponse); + $response = new FacebookResponse($this->request, $graphResponse, 401); $exception = $response->getThrownException(); diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 8996d443f..4a4523189 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -102,7 +102,6 @@ public function testBetaModeCanBeDisabledOrEnabledViaMethod() public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() { - $facebookApp = new FacebookApp('123', 'foo_secret'); $facebookRequest = m::mock('Facebook\Entities\FacebookRequest'); $facebookRequest ->shouldReceive('getUrl') @@ -120,14 +119,6 @@ public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() ->shouldReceive('getHeaders') ->once() ->andReturn(['request_header' => 'foo']); - $facebookRequest - ->shouldReceive('getAccessToken') - ->once() - ->andReturn('foo_token'); - $facebookRequest - ->shouldReceive('getApp') - ->once() - ->andReturn($facebookApp); $this->httpClientMock ->shouldReceive('send') @@ -151,7 +142,6 @@ public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() { - $facebookApp = new FacebookApp('123', 'foo_secret'); $facebookBatchRequest = m::mock('Facebook\Entities\FacebookBatchRequest'); $facebookBatchRequest ->shouldReceive('prepareRequestsForBatch') @@ -173,14 +163,6 @@ public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGra ->shouldReceive('getHeaders') ->once() ->andReturn(['request_header' => 'foo']); - $facebookBatchRequest - ->shouldReceive('getAccessToken') - ->once() - ->andReturn('foo_token'); - $facebookBatchRequest - ->shouldReceive('getApp') - ->once() - ->andReturn($facebookApp); $this->httpClientMock ->shouldReceive('send') diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 85ec11751..ae8a9c2d4 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -23,18 +23,21 @@ */ namespace Facebook\Tests; -use Mockery as m; use Facebook\Facebook; use Facebook\FacebookClient; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; +use Facebook\Entities\FacebookRequest; +use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface { public function getResponseHeaders() { return ['X-foo-header' => 'bar']; } public function getResponseHttpStatusCode() { return 1337; } - public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { return 'foo_response'; } + public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { + return '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; + } } class FooPersistentDataInterface implements PersistentDataInterface @@ -195,4 +198,36 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $this->assertEquals('v1337', $request->getGraphVersion()); } + public function testPaginationReturnsProperResponse() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + ]); + $fb = new Facebook($config); + + $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); + $graphList = new GraphList( + $request, + [], + [ + 'paging' => [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ] + ], + '/1337/photos', + '\Facebook\GraphNodes\GraphUser'); + + $nextPage = $fb->next($graphList); + $this->assertInstanceOf('Facebook\GraphNodes\GraphList', $nextPage); + $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); + $this->assertEquals('Foo', $nextPage[0]['name']); + + $lastResponse = $fb->getLastResponse(); + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $lastResponse); + $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); + } + } diff --git a/tests/GraphNodes/GraphListTest.php b/tests/GraphNodes/GraphListTest.php new file mode 100644 index 000000000..1590a77db --- /dev/null +++ b/tests/GraphNodes/GraphListTest.php @@ -0,0 +1,117 @@ + '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', + ]; + protected $cursorPagination = [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ]; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonGetRequestsWillThrow() + { + $this->request->setMethod('POST'); + $graphList = new GraphList($this->request); + $graphList->validateForPagination(); + } + + public function testCanReturnGraphGeneratedPaginationEndpoints() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->basePagination]); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); + + $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); + $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); + } + + public function testCanGeneratePaginationEndpointsFromACursor() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes'); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); + + $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); + $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); + } + + public function testCanInstantiateNewPaginationRequest() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes'); + $nextPage = $graphList->getNextPageRequest(); + $prevPage = $graphList->getPreviousPageRequest(); + + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $nextPage); + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $prevPage); + $this->assertNotSame($this->request, $nextPage); + $this->assertNotSame($this->request, $prevPage); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); + } + +} diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index 7d583af68..6690d4adf 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -23,7 +23,9 @@ */ namespace Facebook\Tests\GraphNodes; -use Mockery as m; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\Entities\FacebookResponse; use Facebook\GraphNodes\GraphObjectFactory; use Facebook\GraphNodes\GraphObject; @@ -31,7 +33,7 @@ class MyFooSubClassGraphObject extends GraphObject {} class MyFooGraphObject extends GraphObject { protected static $graphObjectMap = [ - 'foo_object' => '\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', + 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', ]; } @@ -39,37 +41,29 @@ class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\Entities\FacebookRequest */ - protected $responseMock; + protected $request; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testADecodedResponseThatIsNotAnArrayWillThrow() - { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn('foo'); - - $factory = new GraphObjectFactory($this->responseMock); - $factory->validateResponseAsArray(); + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); } public function testAValidGraphObjectResponseWillNotThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphObject(); } @@ -78,33 +72,19 @@ public function testAValidGraphObjectResponseWillNotThrow() */ public function testANonGraphObjectResponseWillThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'data' => [ - ['id' => '123', 'name' => 'foo'], - ['id' => '1337', 'name' => 'bar'], - ] - ]); - - $factory = new GraphObjectFactory($this->responseMock); + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphObject(); } public function testAValidGraphListResponseWillNotThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'data' => [ - ['id' => '123', 'name' => 'foo'], - ['id' => '1337', 'name' => 'bar'], - ] - ]); - - $factory = new GraphObjectFactory($this->responseMock); + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -113,12 +93,10 @@ public function testAValidGraphListResponseWillNotThrow() */ public function testANonGraphListResponseWillThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -143,52 +121,38 @@ public function testInvalidSubClassesWillThrow() public function testValidSubClassesWillNotThrow() { - GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphObject'); - GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphAlbum'); - GraphObjectFactory::validateSubclass('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); + GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphObject'); } public function testCastingAsASubClassObjectWillInstantiateTheSubClass() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); } public function testASubClassMappingWillAutomaticallyInstantiateSubClass() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'id' => '123', - 'name' => 'Foo Name', - 'foo_object' => [ - 'id' => '1337', - 'name' => 'Should be sub classed!', - ], - ]); + $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); $fooObject = $mySubClassObject->getProperty('foo_object'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', $fooObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $fooObject); } public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ + $data = json_encode([ 'id' => '123', 'name' => 'Foo Name', 'unknown_object' => [ @@ -196,49 +160,45 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() 'name' => 'Should be generic!', ], ]); + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); $unknownObject = $mySubClassObject->getProperty('unknown_object'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $unknownObject); - $this->assertNotInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $unknownObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $unknownObject); } public function testAListFromGraphWillBeCastAsAGraphList() { - $dataFromGraph = [ - 'data' => [ - [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', + $data = json_encode([ + 'data' => [ + [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + [ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], ], - [ - 'id' => '1337', - 'name' => 'Bar McBaz', - 'link' => 'http://facebook/bar', + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', ], - ], - 'paging' => [ - 'next' => 'http://facebook/next', - 'previous' => 'http://facebook/prev', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); + ]); + $res = new FacebookResponse($this->request, $data); + $factory = new GraphObjectFactory($res); $graphList = $factory->makeGraphList(); $graphData = $graphList->asArray(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphList); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -253,23 +213,18 @@ public function testAListFromGraphWillBeCastAsAGraphList() public function testAGraphObjectWillBeCastAsAGraphObject() { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); + $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->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -279,25 +234,21 @@ public function testAGraphObjectWillBeCastAsAGraphObject() public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() { - $dataFromGraph = [ - 'data' => [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); + $data = json_encode([ + 'data' => [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ]); - $factory = new GraphObjectFactory($this->responseMock); + $res = new FacebookResponse($this->request, $data); + $factory = new GraphObjectFactory($res); $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -305,7 +256,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() ], $graphData); } - public function testACollectionWillBeCastRecursively() + public function testAGraphListWillBeCastRecursively() { $someUser = [ 'id' => '123', @@ -386,33 +337,99 @@ public function testACollectionWillBeCastRecursively() 'previous' => 'http://facebook/prev', ], ]; + $data = json_encode($dataFromGraph); + $res = new FacebookResponse($this->request, $data); - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); - + $factory = new GraphObjectFactory($res); $graphObject = $factory->makeGraphList(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); // Story $storyObject = $graphObject[0]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $storyObject['from']); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['likes']); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['comments']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $storyObject['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); // Story Comments $storyComments = $storyObject['comments']; $firstStoryComment = $storyComments[0]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $firstStoryComment['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $firstStoryComment['from']); // Message $messageObject = $graphObject[1]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $messageObject['to']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); $toUsers = $messageObject['to']; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $toUsers[0]); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $toUsers[0]); + } + + public function testAGraphListWillGenerateTheProperParentGraphEdges() + { + $likesList = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'like_after_cursor', + 'before' => 'like_before_cursor', + ], + ], + ]; + + $photosList = [ + 'data' => [ + [ + 'id' => '777', + 'name' => 'Foo Photo', + 'likes' => $likesList, + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'photo_after_cursor', + 'before' => 'photo_before_cursor', + ], + ], + ]; + + $data = json_encode([ + 'data' => [ + [ + 'id' => '111', + 'name' => 'Foo McBar', + 'likes' => $likesList, + 'photos' => $photosList, + ], + [ + 'id' => '222', + 'name' => 'Bar McBaz', + 'likes' => $likesList, + 'photos' => $photosList, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphList = $factory->makeGraphList(); + $topGraphEdge = $graphList->getParentGraphEdge(); + $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); + $childGraphEdgeTwo = $graphList[1]['likes']->getParentGraphEdge(); + $childGraphEdgeThree = $graphList[1]['photos']->getParentGraphEdge(); + $childGraphEdgeFour = $graphList[1]['photos'][0]['likes']->getParentGraphEdge(); + + $this->assertNull($topGraphEdge); + $this->assertEquals('/111/likes', $childGraphEdgeOne); + $this->assertEquals('/222/likes', $childGraphEdgeTwo); + $this->assertEquals('/222/photos', $childGraphEdgeThree); + $this->assertEquals('/777/likes', $childGraphEdgeFour); } } diff --git a/tests/Url/FacebookUrlManipulatorTest.php b/tests/Url/FacebookUrlManipulatorTest.php index b540d60b7..3729cb6a0 100644 --- a/tests/Url/FacebookUrlManipulatorTest.php +++ b/tests/Url/FacebookUrlManipulatorTest.php @@ -91,4 +91,129 @@ public function provideUris() ]; } + public function testGracefullyHandlesUrlAppending() + { + $params = []; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + + $params = [ + 'access_token' => 'foo', + 'bar' => 'baz', + ]; + $url = 'https://www.foo.com/?foo=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/?foo=bar&access_token=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + } + + public function testSlashesAreProperlyPrepended() + { + $slashTestOne = FacebookUrlManipulator::forceSlashPrefix('foo'); + $slashTestTwo = FacebookUrlManipulator::forceSlashPrefix('/foo'); + $slashTestThree = FacebookUrlManipulator::forceSlashPrefix('foo/bar'); + $slashTestFour = FacebookUrlManipulator::forceSlashPrefix('/foo/bar'); + $slashTestFive = FacebookUrlManipulator::forceSlashPrefix(null); + $slashTestSix = FacebookUrlManipulator::forceSlashPrefix(''); + + $this->assertEquals('/foo', $slashTestOne); + $this->assertEquals('/foo', $slashTestTwo); + $this->assertEquals('/foo/bar', $slashTestThree); + $this->assertEquals('/foo/bar', $slashTestFour); + $this->assertEquals(null, $slashTestFive); + $this->assertEquals('', $slashTestSix); + } + + public function testParamsCanBeReturnedAsArray() + { + $paramsOne = FacebookUrlManipulator::getParamsAsArray('/foo'); + $paramsTwo = FacebookUrlManipulator::getParamsAsArray('/foo?one=1&two=2'); + $paramsThree = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com'); + $paramsFour = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?'); + $paramsFive = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?foo=bar'); + + $this->assertEquals([], $paramsOne); + $this->assertEquals(['one' => '1', 'two' => '2'], $paramsTwo); + $this->assertEquals([], $paramsThree); + $this->assertEquals([], $paramsFour); + $this->assertEquals(['foo' => 'bar'], $paramsFive); + } + + /** + * @dataProvider provideMergableEndpoints + */ + public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) + { + $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); + + $this->assertEquals($result, $expected); + } + + public function provideMergableEndpoints() + { + return [ + [ + 'https://www.foo.com/?foo=ignore_foo&dance=fun', + '/me?foo=keep_foo', + '/me?dance=fun&foo=keep_foo', + ], + [ + 'https://www.bar.com?', + 'https://foo.com?foo=bar', + 'https://foo.com?foo=bar', + ], + [ + 'you', + 'me', + 'me', + ], + [ + '/1234?swing=fun', + '/1337?bar=baz&west=coast', + '/1337?bar=baz&swing=fun&west=coast', + ], + ]; + } + + public function testGraphUrlsCanBeTrimmed() + { + $fullGraphUrl = 'https://graph.facebook.com/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v1.0/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.beta.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://whatever-they-want.facebook.com/v2.1/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v5.301/1233?foo=bar'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/1233?foo=bar', $baseGraphUrl); + } + } From dc5229159c33bd98562ffdce8c5c66902c02b755 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 9 Nov 2014 01:52:49 -0600 Subject: [PATCH 066/407] Added file upload support for normal and batch requests --- composer.json | 2 +- docs/Facebook.fbmd | 53 + docs/sdk_reference.fbmd | 16 +- src/Facebook/Entities/AccessToken.php | 7 +- .../Entities/FacebookBatchRequest.php | 120 ++- .../Entities/FacebookBatchResponse.php | 83 +- src/Facebook/Entities/FacebookRequest.php | 258 ++++- src/Facebook/Entities/FacebookResponse.php | 44 +- src/Facebook/Facebook.php | 76 +- src/Facebook/FacebookClient.php | 73 +- src/Facebook/FileUpload/FacebookFile.php | 126 +++ src/Facebook/FileUpload/FacebookVideo.php | 33 + src/Facebook/FileUpload/Mimetypes.php | 990 ++++++++++++++++++ src/Facebook/GraphNodes/GraphList.php | 147 ++- .../GraphNodes/GraphObjectFactory.php | 61 +- src/Facebook/Http/GraphRawResponse.php | 138 +++ src/Facebook/Http/RequestBodyInterface.php | 40 + src/Facebook/Http/RequestBodyMultipart.php | 153 +++ src/Facebook/Http/RequestBodyUrlEncoded.php | 56 + .../HttpClients/FacebookCurlHttpClient.php | 127 +-- .../HttpClients/FacebookGuzzleHttpClient.php | 76 +- .../FacebookHttpClientInterface.php | 20 +- .../HttpClients/FacebookStreamHttpClient.php | 108 +- src/Facebook/Url/FacebookUrlManipulator.php | 101 +- tests/Entities/FacebookBatchRequestTest.php | 72 +- tests/Entities/FacebookBatchResponseTest.php | 62 +- tests/Entities/FacebookRequestTest.php | 96 +- tests/Entities/FacebookResponseTest.php | 37 +- tests/FacebookClientTest.php | 198 ++-- tests/FacebookTest.php | 45 +- tests/FileUpload/FacebookFileTest.php | 54 + tests/FileUpload/MimetypesTest.php | 52 + tests/GraphNodes/GraphListTest.php | 117 +++ tests/GraphNodes/GraphObjectFactoryTest.php | 319 +++--- tests/Http/GraphRawResponseTest.php | 81 ++ tests/Http/RequestBodyMultipartTest.php | 69 ++ tests/Http/RequestUrlEncodedTest.php | 42 + tests/HttpClients/AbstractTestHttpClient.php | 1 - .../FacebookCurlHttpClientTest.php | 191 +--- .../FacebookGuzzleHttpClientTest.php | 40 +- .../FacebookStreamHttpClientTest.php | 32 +- tests/Url/FacebookUrlManipulatorTest.php | 125 +++ tests/foo.txt | 1 + 43 files changed, 3593 insertions(+), 949 deletions(-) create mode 100755 src/Facebook/FileUpload/FacebookFile.php create mode 100755 src/Facebook/FileUpload/FacebookVideo.php create mode 100644 src/Facebook/FileUpload/Mimetypes.php create mode 100755 src/Facebook/Http/GraphRawResponse.php create mode 100755 src/Facebook/Http/RequestBodyInterface.php create mode 100644 src/Facebook/Http/RequestBodyMultipart.php create mode 100644 src/Facebook/Http/RequestBodyUrlEncoded.php create mode 100644 tests/FileUpload/FacebookFileTest.php create mode 100644 tests/FileUpload/MimetypesTest.php create mode 100644 tests/GraphNodes/GraphListTest.php create mode 100644 tests/Http/GraphRawResponseTest.php create mode 100644 tests/Http/RequestBodyMultipartTest.php create mode 100644 tests/Http/RequestUrlEncodedTest.php create mode 100644 tests/foo.txt diff --git a/composer.json b/composer.json index 81e4b338b..63de9a546 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require-dev": { "phpunit/phpunit": "~4.0", "mockery/mockery": "~0.8", - "guzzlehttp/guzzle": "~4.0" + "guzzlehttp/guzzle": "~5.0" }, "suggest": { "guzzlehttp/guzzle": "Allows for implementation of the Guzzle HTTP client" diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 9981b1320..3ed3a4ff0 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -150,6 +150,14 @@ public FacebookClient getClient() Returns the instance of `Facebook\FacebookClient` for the instantiated service. + +### getLastResponse() {#get-last-response} +~~~~ +public Facebook\Entities\FacebookResponse|Facebook\Entities\FacebookBatchResponse|null getLastResponse() +~~~~ +Returns the last response received from the Graph API in the form of a `Facebook\Entities\FacebookResponse` or `Facebook\Entities\FacebookBatchResponse`. + + ### getDefaultAccessToken() {#get-default-access-token} ~~~~ @@ -306,3 +314,48 @@ Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRed $helper = $fb->getRedirectLoginHelper(); ~~~~ + + +### next() {#next} +~~~~ +public Facebook\GraphNodes\GraphList|null next(Facebook\GraphNodes\GraphList $graphList) +~~~~ + +Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) object. If the next page returns no results, `null` will be returned. + +~~~~ +// Iterate over 5 pages max +$maxPages = 5; + +// Get a list of photo objects +$response = $fb->get('/me/photos?fields=id,source,likes&limit=5'); + +$photosList = $response->getGraphList(); + +if (count($photosList) > 0) { + $pageCount = 0; + do { + foreach ($photosList as $photo) { + var_dump($photo->asArray()); + + // Deep pagination is supported on child GraphList's + $likes = $photo['likes']; + do { + echo '

Likes:

' . "\n\n"; + var_dump($likes->asArray()); + } while ($likes = $fqb->next($likes)); + } + $pageCount++; + } while ($pageCount < $maxPages && $photosList = $fb->next($photosList)); +} +~~~~ +
+ + +### previous() {#previous} +~~~~ +public Facebook\GraphNodes\GraphList|null previous(Facebook\GraphNodes\GraphList $graphList) +~~~~ + +Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` object. Functions just like `next()` above, but in the opposite direction of pagination. + diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 13f27b7f8..0f6d74643 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -116,6 +116,14 @@ Graph nodes are collections that represent nodes returned by Graph. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ + [ + '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', + 'The base collection object that represents a generic node.', + ], + [ + '`[Facebook\GraphNodes\GraphList](/docs/php/GraphList)`', + 'A list of GraphObject's with special methods to help paginate over the list.', + ], [ '`[Facebook\GraphNodes\GraphAlbum](/docs/php/GraphAlbum)`', 'A collection that represents an album node.', @@ -124,10 +132,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\GraphNodes\GraphLocation](/docs/php/GraphLocation)`', 'A collection that represents a location node.', ], - [ - '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', - 'The base collection object that represents a generic node.', - ], [ '`[Facebook\GraphNodes\GraphPage](/docs/php/GraphPage)`', 'A collection that represents a page node.', @@ -140,10 +144,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\GraphNodes\GraphUser](/docs/php/GraphUser)`', 'A collection that represents a user node.', ], - [ - '`[Facebook\GraphNodes\GraphUserPage](/docs/php/GraphUserPage)`', - '*(Deprecated)* A collection that represents a user page node.', - ], ], }) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 2785ed38d..ea4eeb607 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -343,9 +343,12 @@ protected static function request($endpoint, array $params, FacebookApp $app, Fa $app, $app->getAccessToken(), 'GET', - $endpoint, - $params + $endpoint ); + // We know what we're doing here. + // We want to send the access token as a param. + $request->dangerouslySetParams($params); + return $client->sendRequest($request); } diff --git a/src/Facebook/Entities/FacebookBatchRequest.php b/src/Facebook/Entities/FacebookBatchRequest.php index fc2aee2a5..706e3b473 100755 --- a/src/Facebook/Entities/FacebookBatchRequest.php +++ b/src/Facebook/Entities/FacebookBatchRequest.php @@ -23,13 +23,16 @@ */ namespace Facebook\Entities; +use ArrayIterator; +use IteratorAggregate; +use ArrayAccess; use Facebook\Exceptions\FacebookSDKException; /** * Class BatchRequest * @package Facebook */ -class FacebookBatchRequest extends FacebookRequest +class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, ArrayAccess { /** @@ -37,18 +40,23 @@ class FacebookBatchRequest extends FacebookRequest */ protected $requests; + /** + * @var array An array of files to upload. + */ + protected $attachedFiles; + /** * Creates a new Request entity. * * @param FacebookApp|null $app - * @param AccessToken|string|null $accessToken * @param array $requests + * @param AccessToken|string|null $accessToken * @param string|null $graphVersion */ public function __construct( FacebookApp $app = null, - $accessToken = null, array $requests = [], + $accessToken = null, $graphVersion = null ) { @@ -65,7 +73,7 @@ public function __construct( * * @return FacebookBatchRequest * - * @throws FacebookSDKException + * @throws \InvalidArgumentException */ public function add($request, $name = null) { @@ -76,13 +84,21 @@ public function add($request, $name = null) return $this; } elseif ($request instanceof FacebookRequest) { $this->addFallbackDefaults($request); - $this->requests[] = [ + $requestToAdd = [ 'name' => $name, 'request' => $request, ]; + + // File uploads + $attachedFiles = $this->extractFileAttachments($request); + if ($attachedFiles) { + $requestToAdd['attached_files'] = $attachedFiles; + } + $this->requests[] = $requestToAdd; + return $this; } - throw new FacebookSDKException( + throw new \InvalidArgumentException( 'Argument for add() must be of type array or FacebookRequest.' ); } @@ -116,6 +132,34 @@ public function addFallbackDefaults(FacebookRequest $request) } } + /** + * Extracts the files from a request. + * + * @param FacebookRequest $request + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function extractFileAttachments(FacebookRequest $request) + { + if ( ! $request->containsFileUploads()) { + return null; + } + $files = $request->getFiles(); + $fileNames = []; + foreach ($files as $file) { + $fileName = uniqid(); + $this->addFile($fileName, $file); + $fileNames[] = $fileName; + } + + $request->resetFiles(); + + // @TODO Does Graph support multiple uploads on one endpoint? + return implode(',', $fileNames); + } + /** * Return the FacebookRequest entities. * @@ -151,7 +195,8 @@ public function convertRequestsToJson() { $requests = []; foreach ($this->requests as $request) { - $requests[] = static::requestEntityToBatchArray($request['request'], $request['name']); + $attachedFiles = isset($request['attached_files']) ? $request['attached_files'] : null; + $requests[] = $this->requestEntityToBatchArray($request['request'], $request['name'], $attachedFiles); } return json_encode($requests); @@ -182,10 +227,14 @@ public function validateBatchRequestCount() * * @param FacebookRequest $request The request entity to convert. * @param string|null $requestName The name of the request. + * @param string|null $attachedFiles Names of files associated with the request. * * @return array */ - public static function requestEntityToBatchArray(FacebookRequest $request, $requestName = null) + public function requestEntityToBatchArray( + FacebookRequest $request, + $requestName = null, + $attachedFiles = null) { $compiledHeaders = []; $headers = $request->getHeaders(); @@ -199,21 +248,68 @@ public static function requestEntityToBatchArray(FacebookRequest $request, $requ 'relative_url' => $request->getUrl(), ]; - $params = $request->getPostParams(); - if ($params) { - $batch['body'] = http_build_query($params, null, '&'); + // Since file uploads are moved to the root request of a batch request, + // the child requests will always be URL-encoded. + $body = $request->getUrlEncodedBody()->getBody(); + if ($body) { + $batch['body'] = $body; } if (isset($requestName)) { $batch['name'] = $requestName; } + if (isset($attachedFiles)) { + $batch['attached_files'] = $attachedFiles; + } + // @TODO Add support for "omit_response_on_success" // @TODO Add support for "depends_on" - // @TODO Add support for "attached_files" // @TODO Add support for JSONP with "callback" return $batch; } + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->requests); + } + + /** + * @return @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->add($value, $offset); + } + + /** + * @return @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->requests[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->requests[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->requests[$offset]['request']) ? $this->requests[$offset]['request'] : null; + } + } diff --git a/src/Facebook/Entities/FacebookBatchResponse.php b/src/Facebook/Entities/FacebookBatchResponse.php index e13d56749..d43c2eb2a 100755 --- a/src/Facebook/Entities/FacebookBatchResponse.php +++ b/src/Facebook/Entities/FacebookBatchResponse.php @@ -25,14 +25,20 @@ use ArrayIterator; use IteratorAggregate; +use ArrayAccess; /** * Class BatchResponse * @package Facebook */ -class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate +class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate, ArrayAccess { + /** + * @var FacebookBatchRequest The original entity that made the batch request. + */ + protected $batchRequest; + /** * @var array An array of FacebookResponse entities. */ @@ -41,18 +47,21 @@ class FacebookBatchResponse extends FacebookResponse implements IteratorAggregat /** * Creates a new Response entity. * + * @param FacebookBatchRequest $batchRequest * @param FacebookResponse $response */ public function __construct( + FacebookBatchRequest $batchRequest, FacebookResponse $response ) { - $app = $response->getApp(); + $this->batchRequest = $batchRequest; + + $request = $response->getRequest(); + $body = $response->getBody(); $httpStatusCode = $response->getHttpStatusCode(); $headers = $response->getHeaders(); - $body = $response->getBody(); - $accessToken = $response->getAccessToken(); - parent::__construct($app, $httpStatusCode, $headers, $body, $accessToken); + parent::__construct($request, $body, $httpStatusCode, $headers); $responses = $response->getDecodedBody(); $this->setResponses($responses); @@ -77,24 +86,70 @@ public function getResponses() public function setResponses(array $responses) { $this->responses = []; - foreach ($responses as $graphResponse) { - $httpResponseCode = isset($graphResponse['code']) ? $graphResponse['code'] : null; - $httpResponseHeaders = isset($graphResponse['headers']) ? $graphResponse['headers'] : []; - $httpResponseBody = isset($graphResponse['body']) ? $graphResponse['body'] : null; - // @TODO Figure out an elegant way to get the access token that was used with this response. - $accessToken = null; - $this->responses[] = new FacebookResponse($this->app, $httpResponseCode, $httpResponseHeaders, $httpResponseBody, $accessToken); + foreach ($responses as $k => $graphResponse) { + $this->addResponse($graphResponse, $k); } } /** - * Get an iterator for the items. + * Add a response to the list. * - * @return ArrayIterator + * @param array $response + * @param mixed|null $key + */ + public function addResponse(array $response, $key = null) + { + $originalRequest = isset($this->batchRequest[$key]) ? $this->batchRequest[$key] : $this->batchRequest; + + $httpResponseBody = isset($response['body']) ? $response['body'] : null; + $httpResponseCode = isset($response['code']) ? $response['code'] : null; + $httpResponseHeaders = isset($response['headers']) ? $response['headers'] : []; + + $this->responses[] = new FacebookResponse( + $originalRequest, + $httpResponseBody, + $httpResponseCode, + $httpResponseHeaders); + } + + /** + * @return @inheritdoc */ public function getIterator() { return new ArrayIterator($this->responses); } + /** + * @return @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->addResponse($value, $offset); + } + + /** + * @return @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->responses[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->responses[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->responses[$offset]) ? $this->responses[$offset] : null; + } + } diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 558502ea4..791f9ff5b 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -24,6 +24,11 @@ namespace Facebook\Entities; use Facebook\Facebook; +use Facebook\Url\FacebookUrlManipulator; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookVideo; +use Facebook\Http\RequestBodyMultipart; +use Facebook\Http\RequestBodyUrlEncoded; use Facebook\Exceptions\FacebookSDKException; /** @@ -53,11 +58,21 @@ class FacebookRequest */ protected $endpoint; + /** + * @var array The headers to send with this request. + */ + protected $headers = []; + /** * @var array The parameters to send with this request. */ protected $params = []; + /** + * @var array The files to send with this request. + */ + protected $files = []; + /** * @var string ETag to send with this request. */ @@ -113,6 +128,30 @@ public function setAccessToken($accessToken) return $this; } + /** + * Sets the access token with one harvested from a URL or POST params. + * + * @param string $accessToken The access token. + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setAccessTokenFromParams($accessToken) + { + $existingAccessToken = $this->getAccessToken(); + if ( ! $existingAccessToken) { + $this->setAccessToken($accessToken); + } elseif ($accessToken !== $existingAccessToken) { + throw new FacebookSDKException( + 'Access token mismatch. The access token provided in the FacebookRequest ' . + 'and the one provided in the URL or POST params do not match.' + ); + } + + return $this; + } + /** * Return the access token for this request. * @@ -143,6 +182,16 @@ public function getApp() return $this->app; } + /** + * Generate an app secret proof to sign this request. + * + * @return string + */ + public function getAppSecretProof() + { + return AppSecretProof::make($this->getAccessToken(), $this->app->getSecret()); + } + /** * Validate that an access token exists for this request. * @@ -210,10 +259,21 @@ public function validateMethod() * @param string * * @return FacebookRequest + * + * @throws FacebookSDKException */ public function setEndpoint($endpoint) { - $this->endpoint = $endpoint; + // Harvest the access token from the endpoint to keep things in sync + $params = FacebookUrlManipulator::getParamsAsArray($endpoint); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Clean the token & app secret proof from the endpoint. + $filterParams = ['access_token', 'appsecret_proof']; + $this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams); + return $this; } @@ -241,7 +301,17 @@ public function getHeaders() $headers['If-None-Match'] = $this->eTag; } - return $headers; + return array_merge($this->headers, $headers); + } + + /** + * Set the headers for this request. + * + * @param array $headers + */ + public function setHeaders(array $headers) + { + $this->headers = array_merge($this->headers, $headers); } /** @@ -260,15 +330,138 @@ public function setETag($eTag) * @param array $params * * @return FacebookRequest + * + * @throws FacebookSDKException */ public function setParams(array $params = []) { - if (is_array($params)) { - $this->params = array_merge($this->params, $params); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); } + + // Don't let these buggers slip in. + unset($params['access_token'], $params['appsecret_proof']); + + // @TODO Refactor code above with this + //$params = $this->sanitizeAuthenticationParams($params); + $params = $this->sanitizeFileParams($params); + $this->dangerouslySetParams($params); + + return $this; + } + + /** + * Set the params for this request without filtering them first. + * + * @param array $params + * + * @return FacebookRequest + */ + public function dangerouslySetParams(array $params = []) + { + $this->params = array_merge($this->params, $params); + return $this; } + /** + * Iterate over the params and pull out the file uploads. + * + * @param array $params + * + * @return array + */ + public function sanitizeFileParams(array $params) + { + foreach ($params as $key => $value) { + if ($value instanceOf FacebookFile) { + $this->addFile($key, $value); + unset($params[$key]); + } + } + + return $params; + } + + /** + * Add a file to be uploaded. + * + * @param string $key + * @param FacebookFile $file + */ + public function addFile($key, FacebookFile $file) + { + $this->files[$key] = $file; + } + + /** + * Removes all the files from the upload queue. + */ + public function resetFiles() + { + $this->files = []; + } + + /** + * Get the list of files to be uploaded. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * Let's us know if there is a file upload with this request. + * + * @return boolean + */ + public function containsFileUploads() + { + return ! empty($this->files); + } + + /** + * Let's us know if there is a video upload with this request. + * + * @return boolean + */ + public function containsAVideoUpload() + { + foreach ($this->files as $file) { + if ($file instanceOf FacebookVideo) { + return true; + } + } + + return false; + } + + /** + * Returns the body of the request as multipart/form-data. + * + * @return RequestBodyMultipart + */ + public function getMultipartBody() + { + $params = $this->getPostParams(); + + return new RequestBodyMultipart($params, $this->files); + } + + /** + * Returns the body of the request as URL-encoded. + * + * @return RequestBodyUrlEncoded + */ + public function getUrlEncodedBody() + { + $params = $this->getPostParams(); + + return new RequestBodyUrlEncoded($params); + } + /** * Generate and return the params for this request. * @@ -278,11 +471,10 @@ public function getParams() { $params = $this->params; - if (!isset($params['access_token']) && $this->getAccessToken()) { - $params['access_token'] = $this->getAccessToken(); - } - if (!isset($params['appsecret_proof']) && isset($params['access_token'])) { - $params['appsecret_proof'] = AppSecretProof::make($params['access_token'], $this->app->getSecret()); + $accessToken = $this->getAccessToken(); + if ($accessToken) { + $params['access_token'] = $accessToken; + $params['appsecret_proof'] = $this->getAppSecretProof(); } return $params; @@ -321,61 +513,19 @@ public function getUrl() { $this->validateMethod(); - $graphVersion = static::forceSlashPrefix($this->graphVersion); - $endpoint = static::forceSlashPrefix($this->getEndpoint()); + $graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion); + $endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint()); $url = $graphVersion.$endpoint; if ($this->getMethod() !== 'POST') { $params = $this->getParams(); - $url = static::appendParamsToUrl($url, $params); + $url = FacebookUrlManipulator::appendParamsToUrl($url, $params); } return $url; } - /** - * Gracefully appends params to the URL. - * - * @param string $url - * @param array $params - * - * @return string - */ - public static function appendParamsToUrl($url, $params = []) - { - if (!$params) { - return $url; - } - - if (strpos($url, '?') === false) { - return $url . '?' . http_build_query($params, null, '&'); - } - - list($path, $query_string) = explode('?', $url, 2); - parse_str($query_string, $query_array); - - // Favor params from the original URL over $params - $params = array_merge($params, $query_array); - - return $path . '?' . http_build_query($params, null, '&'); - } - - /** - * Check for a "/" prefix and prepend it if not exists. - * - * @param string|null $string - * - * @return string|null - */ - public static function forceSlashPrefix($string) - { - if (!$string) { - return $string; - } - return strpos($string, '/') === 0 ? $string : '/'.$string; - } - /** * Return the default headers that every request should use. * diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index cfae8aa35..55a1e9bab 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -28,7 +28,7 @@ use Facebook\Exceptions\FacebookSDKException; /** - * Class Response + * Class FacebookResponse * @package Facebook */ class FacebookResponse @@ -55,14 +55,9 @@ class FacebookResponse protected $decodedBody = []; /** - * @var string The access token that was used. + * @var FacebookRequest The original request that returned this response. */ - protected $accessToken; - - /** - * @var FacebookApp The facebook app entity. - */ - protected $app; + protected $request; /** * @var FacebookSDKException The exception thrown by this request. @@ -72,29 +67,36 @@ class FacebookResponse /** * Creates a new Response entity. * - * @param FacebookApp $app + * @param FacebookRequest $request + * @param string|null $body * @param int|null $httpStatusCode * @param array|null $headers - * @param string|null $body - * @param string|null $accessToken */ public function __construct( - FacebookApp $app, - $httpStatusCode = null, - array $headers = [], + FacebookRequest $request, $body = null, - $accessToken = null + $httpStatusCode = null, + array $headers = [] ) { - $this->app = $app; + $this->request = $request; + $this->body = $body; $this->httpStatusCode = $httpStatusCode; $this->headers = $headers; - $this->body = $body; - $this->accessToken = $accessToken; $this->decodeBody(); } + /** + * Return the original request that returned this response. + * + * @return FacebookRequest + */ + public function getRequest() + { + return $this->request; + } + /** * Return the FacebookApp entity used for this response. * @@ -102,7 +104,7 @@ public function __construct( */ public function getApp() { - return $this->app; + return $this->request->getApp(); } /** @@ -112,7 +114,7 @@ public function getApp() */ public function getAccessToken() { - return $this->accessToken; + return $this->request->getAccessToken(); } /** @@ -162,7 +164,7 @@ public function getDecodedBody() */ public function getAppSecretProof() { - return AppSecretProof::make($this->accessToken, $this->app->getSecret()); + return $this->request->getAppSecretProof(); } /** diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index e634956a8..c75dc80fd 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -29,6 +29,7 @@ use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookResponse; use Facebook\Entities\FacebookBatchResponse; +use Facebook\GraphNodes\GraphList; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\HttpClients\FacebookHttpClientInterface; @@ -102,6 +103,11 @@ class Facebook */ protected $persistentDataHandler; + /** + * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. + */ + protected $lastResponse; + /** * @TODO Add FacebookInputInterface * @TODO Add FacebookRandomGeneratorInterface @@ -221,6 +227,16 @@ public function getClient() return $this->client; } + /** + * Returns the last response returned from Graph. + * + * @return FacebookResponse|FacebookBatchResponse|null + */ + public function getLastResponse() + { + return $this->lastResponse; + } + /** * Returns the URL detection handler. * @@ -352,6 +368,60 @@ public function delete( $graphVersion); } + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function next(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'next'); + } + + /** + * Sends a request to Graph for the previous page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function previous(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'previous'); + } + + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * @param string $direction The direction of the pagination: next|previous. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function getPaginationResults(GraphList $graphList, $direction) + { + $paginationRequest = $graphList->getPaginationRequest($direction); + if ( ! $paginationRequest) { + return null; + } + + $this->lastResponse = $this->client->sendRequest($paginationRequest); + + // Keep the same GraphObject subclass + $subClassName = $graphList->getSubClassName(); + $graphList = $this->lastResponse->getGraphList($subClassName, false); + + return count($graphList) > 0 ? $graphList : null; + } + /** * Sends a request to Graph and returns the result. * @@ -377,7 +447,7 @@ public function sendRequest( $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); - return $this->client->sendRequest($request); + return $this->lastResponse = $this->client->sendRequest($request); } /** @@ -400,12 +470,12 @@ public function sendBatchRequest( $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $batchRequest = new FacebookBatchRequest( $this->app, - $accessToken, $requests, + $accessToken, $graphVersion ); - return $this->client->sendBatchRequest($batchRequest); + return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); } /** diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index f5ccdc793..dc5e2d90c 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -44,11 +44,21 @@ class FacebookClient */ const BASE_GRAPH_URL = 'https://graph.facebook.com'; + /** + * @const string Graph API URL for video uploads. + */ + const BASE_GRAPH_VIDEO_URL = 'https://graph-video.facebook.com'; + /** * @const string Beta Graph API URL. */ const BASE_GRAPH_URL_BETA = 'https://graph.beta.facebook.com'; + /** + * @const string Beta Graph API URL for video uploads. + */ + const BASE_GRAPH_VIDEO_URL_BETA = 'https://graph-video.beta.facebook.com'; + /** * @var bool Toggle to use Graph beta url. */ @@ -124,13 +134,51 @@ 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() + public function getBaseGraphUrl($postToVideoUrl = false) { + if ($postToVideoUrl) { + return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL; + } return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL; } + /** + * Prepares the request for sending to the client handler. + * + * @param FacebookRequest $request + * + * @return array + */ + public function prepareRequestMessage(FacebookRequest $request) + { + $postToVideoUrl = $request->containsAVideoUpload(); + $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl(); + + // If we're sending files they should be sent as multipart/form-data + if($request->containsFileUploads()) { + $requestBody = $request->getMultipartBody(); + $request->setHeaders( + ['Content-Type' => 'multipart/form-data; boundary=' . $requestBody->getBoundary()] + ); + } else { + $requestBody = $request->getUrlEncodedBody(); + $request->setHeaders( + ['Content-Type' => 'application/x-www-form-urlencoded'] + ); + } + + return [ + $url, + $request->getMethod(), + $request->getHeaders(), + $requestBody->getBody(), + ]; + } + /** * Makes the request to Graph and returns the result. * @@ -145,24 +193,21 @@ public function sendRequest(FacebookRequest $request) if (get_class($request) === 'FacebookRequest') { $request->validateAccessToken(); } - $url = $this->getBaseGraphUrl() . $request->getUrl(); - $method = $request->getMethod(); - $params = $request->getPostParams(); - $headers = $request->getHeaders(); + + list($url, $method, $headers, $body) = $this->prepareRequestMessage($request); // Should throw `FacebookSDKException` exception on HTTP client error. // Don't catch to allow it to bubble up. - $response = $this->httpClientHandler->send($url, $method, $params, $headers); + $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers); static::$requestCount++; - $httpResponseCode = $this->httpClientHandler->getResponseHttpStatusCode(); - $httpResponseHeaders = $this->httpClientHandler->getResponseHeaders(); - - $accessToken = $request->getAccessToken(); - $app = $request->getApp(); - - $returnResponse = new FacebookResponse($app, $httpResponseCode, $httpResponseHeaders, $response, $accessToken); + $returnResponse = new FacebookResponse( + $request, + $rawResponse->getBody(), + $rawResponse->getHttpResponseCode(), + $rawResponse->getHeaders() + ); if ($returnResponse->isError()) { throw $returnResponse->getThrownException(); @@ -185,7 +230,7 @@ public function sendBatchRequest(FacebookBatchRequest $request) $request->prepareRequestsForBatch(); $facebookResponse = $this->sendRequest($request); - return new FacebookBatchResponse($facebookResponse); + return new FacebookBatchResponse($request, $facebookResponse); } } diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php new file mode 100755 index 000000000..7895e9e74 --- /dev/null +++ b/src/Facebook/FileUpload/FacebookFile.php @@ -0,0 +1,126 @@ +path = $filePath; + $this->open(); + } + + /** + * Closes the stream when destructed. + */ + public function __destruct() + { + $this->close(); + } + + /** + * Opens a stream for the file. + * + * @throws FacebookSDKException + */ + public function open() + { + if ( ! is_readable($this->path)) { + throw new FacebookSDKException('Failed to create FacebookFile entity. ' + . 'The file "' . $this->path . '" does not exist or is not readable.'); + } + + $this->stream = fopen($this->path, 'r'); + + if ( ! $this->stream) { + throw new FacebookSDKException('Failed to create FacebookFile entity. ' + . 'Unable to open file: ' . $this->path . '.'); + } + } + + /** + * Stops the file stream. + */ + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + } + + /** + * Return the contents of the file. + * + * @return string + */ + public function getContents() + { + return stream_get_contents($this->stream); + } + + /** + * Return the name of the file. + * + * @return string + */ + public function getFileName() + { + return basename($this->path); + } + + /** + * Return the mimetype of the file. + * + * @return string + */ + public function getMimetype() + { + return Mimetypes::getInstance()->fromFilename($this->path) ?: 'text/plain'; + } + +} diff --git a/src/Facebook/FileUpload/FacebookVideo.php b/src/Facebook/FileUpload/FacebookVideo.php new file mode 100755 index 000000000..002578b4d --- /dev/null +++ b/src/Facebook/FileUpload/FacebookVideo.php @@ -0,0 +1,33 @@ + 'text/vnd.in3d.3dml', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gpp', + '7z' => 'application/x-7z-compressed', + 'aab' => 'application/x-authorware-bin', + 'aac' => 'audio/x-aac', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abw' => 'application/x-abiword', + 'ac' => 'application/pkix-attr-cert', + 'acc' => 'application/vnd.americandynamics.acc', + 'ace' => 'application/x-ace-compressed', + 'acu' => 'application/vnd.acucobol', + 'acutc' => 'application/vnd.acucorp', + 'adp' => 'audio/adpcm', + 'aep' => 'application/vnd.audiograph', + 'afm' => 'application/x-font-type1', + 'afp' => 'application/vnd.ibm.modcap', + 'ahead' => 'application/vnd.ahead.space', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'ait' => 'application/vnd.dvb.ait', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'application' => 'application/x-ms-application', + 'apr' => 'application/vnd.lotus-approach', + 'asa' => 'text/plain', + 'asax' => 'application/octet-stream', + 'asc' => 'application/pgp-signature', + 'ascx' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'ashx' => 'text/plain', + 'asm' => 'text/x-asm', + 'asmx' => 'text/plain', + 'aso' => 'application/vnd.accpac.simply.aso', + 'asp' => 'text/plain', + 'aspx' => 'text/plain', + 'asx' => 'video/x-ms-asf', + 'atc' => 'application/vnd.acucorp', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'atx' => 'application/vnd.antix.game-component', + 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', + 'aw' => 'application/applixware', + 'axd' => 'text/plain', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azw' => 'application/vnd.amazon.ebook', + 'bat' => 'application/x-msdownload', + 'bcpio' => 'application/x-bcpio', + 'bdf' => 'application/x-font-bdf', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'bed' => 'application/vnd.realvnc.bed', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'bin' => 'application/octet-stream', + 'bmi' => 'application/vnd.bmi', + 'bmp' => 'image/bmp', + 'book' => 'application/vnd.framemaker', + 'box' => 'application/vnd.previewsystems.box', + 'boz' => 'application/x-bzip2', + 'bpk' => 'application/octet-stream', + 'btif' => 'image/prs.btif', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'c4d' => 'application/vnd.clonk.c4group', + 'c4f' => 'application/vnd.clonk.c4group', + 'c4g' => 'application/vnd.clonk.c4group', + 'c4p' => 'application/vnd.clonk.c4group', + 'c4u' => 'application/vnd.clonk.c4group', + 'cab' => 'application/vnd.ms-cab-compressed', + 'car' => 'application/vnd.curl.car', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/x-c', + 'cct' => 'application/x-director', + 'ccxml' => 'application/ccxml+xml', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cdf' => 'application/x-netcdf', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cdx' => 'chemical/x-cdx', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'cdy' => 'application/vnd.cinderella', + 'cer' => 'application/pkix-cert', + 'cfc' => 'application/x-coldfusion', + 'cfm' => 'application/x-coldfusion', + 'cgm' => 'image/cgm', + 'chat' => 'application/x-chat', + 'chm' => 'application/vnd.ms-htmlhelp', + 'chrt' => 'application/vnd.kde.kchart', + 'cif' => 'chemical/x-cif', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'cil' => 'application/vnd.ms-artgalry', + 'cla' => 'application/vnd.claymore', + 'class' => 'application/java-vm', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'clkx' => 'application/vnd.crick.clicker', + 'clp' => 'application/x-msclip', + 'cmc' => 'application/vnd.cosmocaller', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'cmx' => 'image/x-cmx', + 'cod' => 'application/vnd.rim.cod', + 'com' => 'application/x-msdownload', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crd' => 'application/x-mscardfile', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'cryptonote' => 'application/vnd.rig.cryptonote', + 'cs' => 'text/plain', + 'csh' => 'application/x-csh', + 'csml' => 'chemical/x-csml', + 'csp' => 'application/vnd.commonspace', + 'css' => 'text/css', + 'cst' => 'application/x-director', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'curl' => 'text/vnd.curl', + 'cww' => 'application/prs.cww', + 'cxt' => 'application/x-director', + 'cxx' => 'text/x-c', + 'dae' => 'model/vnd.collada+xml', + 'daf' => 'application/vnd.mobius.daf', + 'dataless' => 'application/vnd.fdsn.seed', + 'davmount' => 'application/davmount+xml', + 'dcr' => 'application/x-director', + 'dcurl' => 'text/vnd.curl.dcurl', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'deb' => 'application/x-debian-package', + 'def' => 'text/plain', + 'deploy' => 'application/octet-stream', + 'der' => 'application/x-x509-ca-cert', + 'dfac' => 'application/vnd.dreamfactory', + 'dic' => 'text/x-c', + 'dir' => 'application/x-director', + 'dis' => 'application/vnd.mobius.dis', + 'dist' => 'application/octet-stream', + 'distz' => 'application/octet-stream', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/x-msdownload', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'dna' => 'application/vnd.dna', + 'doc' => 'application/msword', + 'docm' => 'application/vnd.ms-word.document.macroenabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dp' => 'application/vnd.osgi.dp', + 'dpg' => 'application/vnd.dpgraph', + 'dra' => 'audio/vnd.dra', + 'dsc' => 'text/prs.lines.tag', + 'dssc' => 'application/dssc+der', + 'dtb' => 'application/x-dtbook+xml', + 'dtd' => 'application/xml-dtd', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'dump' => 'application/octet-stream', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'dxp' => 'application/vnd.spotfire.dxp', + 'dxr' => 'application/x-director', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'ecma' => 'application/ecmascript', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'efif' => 'application/vnd.picsel', + 'ei6' => 'application/vnd.pg.osasli', + 'elc' => 'application/octet-stream', + 'eml' => 'message/rfc822', + 'emma' => 'application/emma+xml', + 'eol' => 'audio/vnd.digital-winds', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'es3' => 'application/vnd.eszigno3+xml', + 'esf' => 'application/vnd.epson.esf', + 'et3' => 'application/vnd.eszigno3+xml', + 'etx' => 'text/x-setext', + 'exe' => 'application/x-msdownload', + 'exi' => 'application/exi', + 'ext' => 'application/vnd.novadigm.ext', + 'ez' => 'application/andrew-inset', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'f' => 'text/x-fortran', + 'f4v' => 'video/x-f4v', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fbs' => 'image/vnd.fastbidsheet', + 'fcs' => 'application/vnd.isac.fcs', + 'fdf' => 'application/vnd.fdf', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'fgd' => 'application/x-director', + 'fh' => 'image/x-freehand', + 'fh4' => 'image/x-freehand', + 'fh5' => 'image/x-freehand', + 'fh7' => 'image/x-freehand', + 'fhc' => 'image/x-freehand', + 'fig' => 'application/x-xfig', + 'fli' => 'video/x-fli', + 'flo' => 'application/vnd.micrografx.flo', + 'flv' => 'video/x-flv', + 'flw' => 'application/vnd.kde.kivio', + 'flx' => 'text/vnd.fmi.flexstor', + 'fly' => 'text/vnd.fly', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frame' => 'application/vnd.framemaker', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'fst' => 'image/vnd.fst', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'fvt' => 'video/vnd.fvt', + 'fxp' => 'application/vnd.adobe.fxp', + 'fxpl' => 'application/vnd.adobe.fxp', + 'fzs' => 'application/vnd.fuzzysheet', + 'g2w' => 'application/vnd.geoplan', + 'g3' => 'image/g3fax', + 'g3w' => 'application/vnd.geospace', + 'gac' => 'application/vnd.groove-account', + 'gdl' => 'model/vnd.gdl', + 'geo' => 'application/vnd.dynageo', + 'gex' => 'application/vnd.geometry-explorer', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'ghf' => 'application/vnd.groove-help', + 'gif' => 'image/gif', + 'gim' => 'application/vnd.groove-identity-message', + 'gmx' => 'application/vnd.gmx', + 'gnumeric' => 'application/x-gnumeric', + 'gph' => 'application/vnd.flographit', + 'gqf' => 'application/vnd.grafeq', + 'gqs' => 'application/vnd.grafeq', + 'gram' => 'application/srgs', + 'gre' => 'application/vnd.geometry-explorer', + 'grv' => 'application/vnd.groove-injector', + 'grxml' => 'application/srgs+xml', + 'gsf' => 'application/x-font-ghostscript', + 'gtar' => 'application/x-gtar', + 'gtm' => 'application/vnd.groove-tool-message', + 'gtw' => 'model/vnd.gtw', + 'gv' => 'text/vnd.graphviz', + 'gxt' => 'application/vnd.geonext', + 'h' => 'text/x-c', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'hal' => 'application/vnd.hal+xml', + 'hbci' => 'application/vnd.hbci', + 'hdf' => 'application/x-hdf', + 'hh' => 'text/x-c', + 'hlp' => 'application/winhlp', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'hqx' => 'application/mac-binhex40', + 'hta' => 'application/octet-stream', + 'htc' => 'text/html', + 'htke' => 'application/vnd.kenameaapp', + 'htm' => 'text/html', + 'html' => 'text/html', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'i2g' => 'application/vnd.intergeo', + 'icc' => 'application/vnd.iccprofile', + 'ice' => 'x-conference/x-cooltalk', + 'icm' => 'application/vnd.iccprofile', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ief' => 'image/ief', + 'ifb' => 'text/calendar', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'iges' => 'model/iges', + 'igl' => 'application/vnd.igloader', + 'igm' => 'application/vnd.insors.igm', + 'igs' => 'model/iges', + 'igx' => 'application/vnd.micrografx.igx', + 'iif' => 'application/vnd.shana.informed.interchange', + 'imp' => 'application/vnd.accpac.simply.imp', + 'ims' => 'application/vnd.ms-ims', + 'in' => 'text/plain', + 'ini' => 'text/plain', + 'ipfix' => 'application/ipfix', + 'ipk' => 'application/vnd.shana.informed.package', + 'irm' => 'application/vnd.ibm.rights-management', + 'irp' => 'application/vnd.irepository.package+xml', + 'iso' => 'application/octet-stream', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'jam' => 'application/vnd.jam', + 'jar' => 'application/java-archive', + 'java' => 'text/x-java-source', + 'jisp' => 'application/vnd.jisp', + 'jlt' => 'application/vnd.hp-jlyt', + 'jnlp' => 'application/x-java-jnlp-file', + 'joda' => 'application/vnd.joost.joda-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpgm' => 'video/jpm', + 'jpgv' => 'video/jpeg', + 'jpm' => 'video/jpm', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'kar' => 'audio/midi', + 'karbon' => 'application/vnd.kde.karbon', + 'kfo' => 'application/vnd.kde.kformula', + 'kia' => 'application/vnd.kidspiration', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kne' => 'application/vnd.kinar', + 'knp' => 'application/vnd.kinar', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'kpt' => 'application/vnd.kde.kpresenter', + 'ksp' => 'application/vnd.kde.kspread', + 'ktr' => 'application/vnd.kahootz', + 'ktx' => 'image/ktx', + 'ktz' => 'application/vnd.kahootz', + 'kwd' => 'application/vnd.kde.kword', + 'kwt' => 'application/vnd.kde.kword', + 'lasxml' => 'application/vnd.las.las+xml', + 'latex' => 'application/x-latex', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + 'les' => 'application/vnd.hhe.lesson-player', + 'lha' => 'application/octet-stream', + 'link66' => 'application/vnd.route66.link66+xml', + 'list' => 'text/plain', + 'list3820' => 'application/vnd.ibm.modcap', + 'listafp' => 'application/vnd.ibm.modcap', + 'log' => 'text/plain', + 'lostxml' => 'application/lost+xml', + 'lrf' => 'application/octet-stream', + 'lrm' => 'application/vnd.ms-lrm', + 'ltf' => 'application/vnd.frogans.ltf', + 'lvp' => 'audio/vnd.lucent.voice', + 'lwp' => 'application/vnd.lotus-wordpro', + 'lzh' => 'application/octet-stream', + 'm13' => 'application/x-msmediaview', + 'm14' => 'application/x-msmediaview', + 'm1v' => 'video/mpeg', + 'm21' => 'application/mp21', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3a' => 'audio/mpeg', + 'm3u' => 'audio/x-mpegurl', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'm4a' => 'audio/mp4', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/mp4', + 'ma' => 'application/mathematica', + 'mads' => 'application/mads+xml', + 'mag' => 'application/vnd.ecowin.chart', + 'maker' => 'application/vnd.framemaker', + 'man' => 'text/troff', + 'mathml' => 'application/mathml+xml', + 'mb' => 'application/mathematica', + 'mbk' => 'application/vnd.mobius.mbk', + 'mbox' => 'application/mbox', + 'mc1' => 'application/vnd.medcalcdata', + 'mcd' => 'application/vnd.mcd', + 'mcurl' => 'text/vnd.curl.mcurl', + 'mdb' => 'application/x-msaccess', + 'mdi' => 'image/vnd.ms-modi', + 'me' => 'text/troff', + 'mesh' => 'model/mesh', + 'meta4' => 'application/metalink4+xml', + 'mets' => 'application/mets+xml', + 'mfm' => 'application/vnd.mfmp', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'mgz' => 'application/vnd.proteus.magazine', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', + 'mime' => 'message/rfc822', + 'mj2' => 'video/mj2', + 'mjp2' => 'video/mj2', + 'mlp' => 'application/vnd.dolby.mlp', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'mmf' => 'application/vnd.smaf', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'mny' => 'application/x-msmoney', + 'mobi' => 'application/x-mobipocket-ebook', + 'mods' => 'application/mods+xml', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp21' => 'application/mp21', + 'mp2a' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4s' => 'application/mp4', + 'mp4v' => 'video/mp4', + 'mpc' => 'application/vnd.mophun.certificate', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'mpga' => 'audio/mpeg', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'mpm' => 'application/vnd.blueice.multipass', + 'mpn' => 'application/vnd.mophun.application', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/vnd.ms-project', + 'mpy' => 'application/vnd.ibm.minipay', + 'mqy' => 'application/vnd.mobius.mqy', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ms' => 'text/troff', + 'mscml' => 'application/mediaservercontrol+xml', + 'mseed' => 'application/vnd.fdsn.mseed', + 'mseq' => 'application/vnd.mseq', + 'msf' => 'application/vnd.epson.msf', + 'msh' => 'model/mesh', + 'msi' => 'application/x-msdownload', + 'msl' => 'application/vnd.mobius.msl', + 'msty' => 'application/vnd.muvee.style', + 'mts' => 'model/vnd.mts', + 'mus' => 'application/vnd.musician', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'mvb' => 'application/x-msmediaview', + 'mwf' => 'application/vnd.mfer', + 'mxf' => 'application/mxf', + 'mxl' => 'application/vnd.recordare.musicxml', + 'mxml' => 'application/xv+xml', + 'mxs' => 'application/vnd.triscape.mxs', + 'mxu' => 'video/vnd.mpegurl', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'n3' => 'text/n3', + 'nb' => 'application/mathematica', + 'nbp' => 'application/vnd.wolfram.player', + 'nc' => 'application/x-netcdf', + 'ncx' => 'application/x-dtbncx+xml', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'nml' => 'application/vnd.enliven', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'npx' => 'image/vnd.net-fpx', + 'nsf' => 'application/vnd.lotus-notes', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'oas' => 'application/vnd.fujitsu.oasys', + 'obd' => 'application/x-msbinder', + 'oda' => 'application/oda', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'onepkg' => 'application/onenote', + 'onetmp' => 'application/onenote', + 'onetoc' => 'application/onenote', + 'onetoc2' => 'application/onenote', + 'opf' => 'application/oebps-package+xml', + 'oprc' => 'application/vnd.palm', + 'org' => 'application/vnd.lotus-organizer', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'application/x-font-otf', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'p' => 'text/x-pascal', + 'p10' => 'application/pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'pas' => 'text/x-pascal', + 'paw' => 'application/vnd.pawaafile', + 'pbd' => 'application/vnd.powerbuilder6', + 'pbm' => 'image/x-portable-bitmap', + 'pcf' => 'application/x-font-pcf', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'pct' => 'image/x-pict', + 'pcurl' => 'application/vnd.curl.pcurl', + 'pcx' => 'image/x-pcx', + 'pdb' => 'application/vnd.palm', + 'pdf' => 'application/pdf', + 'pfa' => 'application/x-font-type1', + 'pfb' => 'application/x-font-type1', + 'pfm' => 'application/x-font-type1', + 'pfr' => 'application/font-tdpfr', + 'pfx' => 'application/x-pkcs12', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'pgp' => 'application/pgp-encrypted', + 'php' => 'text/x-php', + 'phps' => 'application/x-httpd-phps', + 'pic' => 'image/x-pict', + 'pkg' => 'application/octet-stream', + 'pki' => 'application/pkixcmp', + 'pkipath' => 'application/pkix-pkipath', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'plc' => 'application/vnd.mobius.plc', + 'plf' => 'application/vnd.pocketlearn', + 'pls' => 'application/pls+xml', + 'pml' => 'application/vnd.ctc-posml', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'portpkg' => 'application/vnd.macports.portpkg', + 'pot' => 'application/vnd.ms-powerpoint', + 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', + 'ppd' => 'application/vnd.cups-ppd', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pqa' => 'application/vnd.palm', + 'prc' => 'application/x-mobipocket-ebook', + 'pre' => 'application/vnd.lotus-freelance', + 'prf' => 'application/pics-rules', + 'ps' => 'application/postscript', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'psd' => 'image/vnd.adobe.photoshop', + 'psf' => 'application/x-font-linux-psf', + 'pskcxml' => 'application/pskc+xml', + 'ptid' => 'application/vnd.pvi.ptid1', + 'pub' => 'application/x-mspublisher', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'qam' => 'application/vnd.epson.quickanime', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'qps' => 'application/vnd.publishare-delta-tree', + 'qt' => 'video/quicktime', + 'qwd' => 'application/vnd.quark.quarkxpress', + 'qwt' => 'application/vnd.quark.quarkxpress', + 'qxb' => 'application/vnd.quark.quarkxpress', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'qxl' => 'application/vnd.quark.quarkxpress', + 'qxt' => 'application/vnd.quark.quarkxpress', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rb' => 'text/plain', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'rdf' => 'application/rdf+xml', + 'rdz' => 'application/vnd.data-vision.rdz', + 'rep' => 'application/vnd.businessobjects', + 'res' => 'application/x-dtbresource+xml', + 'resx' => 'text/xml', + 'rgb' => 'image/x-rgb', + 'rif' => 'application/reginfo+xml', + 'rip' => 'audio/vnd.rip', + 'rl' => 'application/resource-lists+xml', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'rld' => 'application/resource-lists-diff+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'rmi' => 'audio/midi', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'rnc' => 'application/relax-ng-compact-syntax', + 'roff' => 'text/troff', + 'rp9' => 'application/vnd.cloanto.rp9', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rq' => 'application/sparql-query', + 'rs' => 'application/rls-services+xml', + 'rsd' => 'application/rsd+xml', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'rtx' => 'text/richtext', + 's' => 'text/x-asm', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'sbml' => 'application/sbml+xml', + 'sc' => 'application/vnd.ibm.secure-container', + 'scd' => 'application/x-msschedule', + 'scm' => 'application/vnd.lotus-screencam', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'scurl' => 'text/vnd.curl.scurl', + 'sda' => 'application/vnd.stardivision.draw', + 'sdc' => 'application/vnd.stardivision.calc', + 'sdd' => 'application/vnd.stardivision.impress', + 'sdkd' => 'application/vnd.solent.sdkm+xml', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'sdp' => 'application/sdp', + 'sdw' => 'application/vnd.stardivision.writer', + 'see' => 'application/vnd.seemail', + 'seed' => 'application/vnd.fdsn.seed', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'ser' => 'application/java-serialized-object', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'shf' => 'application/shf+xml', + 'sig' => 'application/pgp-signature', + 'silo' => 'model/mesh', + 'sis' => 'application/vnd.symbian.install', + 'sisx' => 'application/vnd.symbian.install', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'skd' => 'application/vnd.koan', + 'skm' => 'application/vnd.koan', + 'skp' => 'application/vnd.koan', + 'skt' => 'application/vnd.koan', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'slt' => 'application/vnd.epson.salt', + 'sm' => 'application/vnd.stepmania.stepchart', + 'smf' => 'application/vnd.stardivision.math', + 'smi' => 'application/smil+xml', + 'smil' => 'application/smil+xml', + 'snd' => 'audio/basic', + 'snf' => 'application/x-font-snf', + 'so' => 'application/octet-stream', + 'spc' => 'application/x-pkcs7-certificates', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'spl' => 'application/x-futuresplash', + 'spot' => 'text/vnd.in3d.spot', + 'spp' => 'application/scvp-vp-response', + 'spq' => 'application/scvp-vp-request', + 'spx' => 'audio/ogg', + 'src' => 'application/x-wais-source', + 'sru' => 'application/sru+xml', + 'srx' => 'application/sparql-results+xml', + 'sse' => 'application/vnd.kodak-descriptor', + 'ssf' => 'application/vnd.epson.ssf', + 'ssml' => 'application/ssml+xml', + 'st' => 'application/vnd.sailingtracker.track', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'std' => 'application/vnd.sun.xml.draw.template', + 'stf' => 'application/vnd.wt.stf', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'stk' => 'application/hyperstudio', + 'stl' => 'application/vnd.ms-pki.stl', + 'str' => 'application/vnd.pg.format', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sub' => 'image/vnd.dvb.subtitle', + 'sus' => 'application/vnd.sus-calendar', + 'susp' => 'application/vnd.sus-calendar', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svc' => 'application/vnd.dvb.service', + 'svd' => 'application/vnd.svd', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swa' => 'application/x-director', + 'swf' => 'application/x-shockwave-flash', + 'swi' => 'application/vnd.aristanetworks.swi', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxd' => 'application/vnd.sun.xml.draw', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 't' => 'text/troff', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'tar' => 'application/x-tar', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'tcl' => 'application/x-tcl', + 'teacher' => 'application/vnd.smart.teacher', + 'tei' => 'application/tei+xml', + 'teicorpus' => 'application/tei+xml', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tfi' => 'application/thraud+xml', + 'tfm' => 'application/x-tex-tfm', + 'thmx' => 'application/vnd.ms-officetheme', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tmo' => 'application/vnd.tmobile-livetv', + 'torrent' => 'application/x-bittorrent', + 'tpl' => 'application/vnd.groove-tool-template', + 'tpt' => 'application/vnd.trid.tpt', + 'tr' => 'text/troff', + 'tra' => 'application/vnd.trueapp', + 'trm' => 'application/x-msterminal', + 'tsd' => 'application/timestamped-data', + 'tsv' => 'text/tab-separated-values', + 'ttc' => 'application/x-font-ttf', + 'ttf' => 'application/x-font-ttf', + 'ttl' => 'text/turtle', + 'twd' => 'application/vnd.simtech-mindmapper', + 'twds' => 'application/vnd.simtech-mindmapper', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'txf' => 'application/vnd.mobius.txf', + 'txt' => 'text/plain', + 'u32' => 'application/x-authorware-bin', + 'udeb' => 'application/x-debian-package', + 'ufd' => 'application/vnd.ufdl', + 'ufdl' => 'application/vnd.ufdl', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'urls' => 'text/uri-list', + 'ustar' => 'application/x-ustar', + 'utz' => 'application/vnd.uiq.theme', + 'uu' => 'text/x-uuencode', + 'uva' => 'audio/vnd.dece.audio', + 'uvd' => 'application/vnd.dece.data', + 'uvf' => 'application/vnd.dece.data', + 'uvg' => 'image/vnd.dece.graphic', + 'uvh' => 'video/vnd.dece.hd', + 'uvi' => 'image/vnd.dece.graphic', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvu' => 'video/vnd.uvvu.mp4', + 'uvv' => 'video/vnd.dece.video', + 'uvva' => 'audio/vnd.dece.audio', + 'uvvd' => 'application/vnd.dece.data', + 'uvvf' => 'application/vnd.dece.data', + 'uvvg' => 'image/vnd.dece.graphic', + 'uvvh' => 'video/vnd.dece.hd', + 'uvvi' => 'image/vnd.dece.graphic', + 'uvvm' => 'video/vnd.dece.mobile', + 'uvvp' => 'video/vnd.dece.pd', + 'uvvs' => 'video/vnd.dece.sd', + 'uvvt' => 'application/vnd.dece.ttml+xml', + 'uvvu' => 'video/vnd.uvvu.mp4', + 'uvvv' => 'video/vnd.dece.video', + 'uvvx' => 'application/vnd.dece.unspecified', + 'uvx' => 'application/vnd.dece.unspecified', + 'vcd' => 'application/x-cdlink', + 'vcf' => 'text/x-vcard', + 'vcg' => 'application/vnd.groove-vcard', + 'vcs' => 'text/x-vcalendar', + 'vcx' => 'application/vnd.vcx', + 'vis' => 'application/vnd.visionary', + 'viv' => 'video/vnd.vivo', + 'vor' => 'application/vnd.stardivision.writer', + 'vox' => 'application/x-authorware-bin', + 'vrml' => 'model/vrml', + 'vsd' => 'application/vnd.visio', + 'vsf' => 'application/vnd.vsf', + 'vss' => 'application/vnd.visio', + 'vst' => 'application/vnd.visio', + 'vsw' => 'application/vnd.visio', + 'vtu' => 'model/vnd.vtu', + 'vxml' => 'application/voicexml+xml', + 'w3d' => 'application/x-director', + 'wad' => 'application/x-doom', + 'wav' => 'audio/x-wav', + 'wax' => 'audio/x-ms-wax', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wcm' => 'application/vnd.ms-works', + 'wdb' => 'application/vnd.ms-works', + 'weba' => 'audio/webm', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wg' => 'application/vnd.pmi.widget', + 'wgt' => 'application/widget', + 'wks' => 'application/vnd.ms-works', + 'wm' => 'video/x-ms-wm', + 'wma' => 'audio/x-ms-wma', + 'wmd' => 'application/x-ms-wmd', + 'wmf' => 'application/x-msmetafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wmz' => 'application/x-ms-wmz', + 'woff' => 'application/x-font-woff', + 'wpd' => 'application/vnd.wordperfect', + 'wpl' => 'application/vnd.ms-wpl', + 'wps' => 'application/vnd.ms-works', + 'wqd' => 'application/vnd.wqd', + 'wri' => 'application/x-mswrite', + 'wrl' => 'model/vrml', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + 'wtb' => 'application/vnd.webturbo', + 'wvx' => 'video/x-ms-wvx', + 'x32' => 'application/x-authorware-bin', + 'x3d' => 'application/vnd.hzn-3d-crossword', + 'xap' => 'application/x-silverlight-app', + 'xar' => 'application/vnd.xara', + 'xbap' => 'application/x-ms-xbap', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'xbm' => 'image/x-xbitmap', + 'xdf' => 'application/xcap-diff+xml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xdssc' => 'application/dssc+xml', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xenc' => 'application/xenc+xml', + 'xer' => 'application/patch-ops-error+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdl' => 'application/vnd.xfdl', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xhvml' => 'application/xv+xml', + 'xif' => 'image/vnd.xiff', + 'xla' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', + 'xlc' => 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => 'application/vnd.ms-excel', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xlt' => 'application/vnd.ms-excel', + 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlw' => 'application/vnd.ms-excel', + 'xml' => 'application/xml', + 'xo' => 'application/vnd.olpc-sugar', + 'xop' => 'application/xop+xml', + 'xpi' => 'application/x-xpinstall', + 'xpm' => 'image/x-xpixmap', + 'xpr' => 'application/vnd.is-xpr', + 'xps' => 'application/vnd.ms-xpsdocument', + 'xpw' => 'application/vnd.intercon.formnet', + 'xpx' => 'application/vnd.intercon.formnet', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xsm' => 'application/vnd.syncml+xml', + 'xspf' => 'application/xspf+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xvm' => 'application/xv+xml', + 'xvml' => 'application/xv+xml', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-xyz', + 'yaml' => 'text/yaml', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'yml' => 'text/yaml', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'zip' => 'application/zip', + 'zir' => 'application/vnd.zul', + 'zirz' => 'application/vnd.zul', + 'zmm' => 'application/vnd.handheld-entertainment+xml' + ); + + /** + * Get a singleton instance of the class + * + * @return self + * @codeCoverageIgnore + */ + public static function getInstance() + { + if (!self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Get a mimetype value from a file extension + * + * @param string $extension File extension + * + * @return string|null + * + */ + public function fromExtension($extension) + { + $extension = strtolower($extension); + + return isset($this->mimetypes[$extension]) + ? $this->mimetypes[$extension] + : null; + } + + /** + * Get a mimetype from a filename + * + * @param string $filename Filename to generate a mimetype from + * + * @return string|null + */ + public function fromFilename($filename) + { + return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); + } +} diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 743138e4f..142b1c80f 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -23,6 +23,10 @@ */ namespace Facebook\GraphNodes; +use Facebook\Entities\FacebookRequest; +use Facebook\Url\FacebookUrlManipulator; +use Facebook\Exceptions\FacebookSDKException; + /** * Class GraphList * @package Facebook @@ -31,39 +35,166 @@ class GraphList extends Collection { /** - * @var array $metaData An array of Graph meta data like pagination, etc. + * @var FacebookRequest The original request that generated this data. + */ + protected $request; + + /** + * @var array An array of Graph meta data like pagination, etc. */ protected $metaData = []; + /** + * @var string|null The parent Graph edge endpoint that generated the list. + */ + protected $parentEdgeEndpoint; + + /** + * @var string|null The subclass of the child GraphObject's. + */ + protected $subclassName; + /** * Init this collection of GraphObject's. * + * @param FacebookRequest $request The original request that generated this data. * @param array $data An array of GraphObject's. * @param array $metaData An array of Graph meta data like pagination, etc. + * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. + * @param string|null $subclassName The subclass of the child GraphObject's. */ - public function __construct(array $data = [], array $metaData = []) + public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) { + $this->request = $request; $this->metaData = $metaData; + $this->parentEdgeEndpoint = $parentEdgeEndpoint; + $this->subclassName = $subclassName; parent::__construct($data); } /** - * Get the next page of results of this list of Graph objects. + * Gets the parent Graph edge endpoint that generated the list. + * + * @return string|null + */ + public function getParentGraphEdge() + { + return $this->parentEdgeEndpoint; + } + + /** + * Gets the subclass name that the child GraphObject's are cast as. + * + * @return string|null + */ + public function getSubClassName() + { + return $this->subclassName; + } + + /** + * Generates a pagination URL based on a cursor. + * + * @param string $direction The direction of the page: next|previous + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function getPaginationUrl($direction) + { + $this->validateForPagination(); + + // Do we have a paging URL? + if (isset($this->metaData['paging'][$direction])) { + // Graph returns the full URL with all the original params. + // We just want the endpoint though. + $pageUrl = $this->metaData['paging'][$direction]; + return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); + } + + // Do we have a cursor to work with? + $cursorDirection = $direction === 'next' ? 'after' : 'before'; + if ( ! isset($this->metaData['paging']['cursors'][$cursorDirection])) { + return null; + } + + // If we don't know the ID of the parent node, this ain't gonna work. + if ( ! $this->parentEdgeEndpoint) { + return null; + } + + // We have the parent node ID, paging cursor & original request. + // These were the ingredients chosen to create the perfect little URL. + $cursor = $this->metaData['paging']['cursors'][$cursorDirection]; + + $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); + + // Pull in the original params + $originalUrl = $this->request->getUrl(); + $pageUrl = FacebookUrlManipulator::mergeUrlParams($originalUrl, $pageUrl); + + return FacebookUrlManipulator::forceSlashPrefix($pageUrl); + } + + /** + * Validates whether or not we can paginate on this request. * - * @TODO + * @throws FacebookSDKException */ - public function next() + public function validateForPagination() { + if ($this->request->getMethod() !== 'GET') { + throw new FacebookSDKException( + 'You can only paginate on a GET request.', 720 + ); + } } /** - * Get the previous page of results of this list of Graph objects. + * Gets the request object needed to make a next|previous page request. + * + * @param string $direction The direction of the page: next|previous + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPaginationRequest($direction) + { + $pageUrl = $this->getPaginationUrl($direction); + if ( ! $pageUrl) { + return null; + } + + $newRequest = clone $this->request; + $newRequest->setEndpoint($pageUrl); + return $newRequest; + } + + /** + * Gets the request object needed to make a "next" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getNextPageRequest() + { + return $this->getPaginationRequest('next'); + } + + /** + * Gets the request object needed to make a "previous" page request. + * + * @return FacebookRequest|null * - * @TODO + * @throws FacebookSDKException */ - public function previous() + public function getPreviousPageRequest() { + return $this->getPaginationRequest('previous'); } } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 0d580ab0b..98d11be2f 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -46,12 +46,17 @@ class GraphObjectFactory /** * @const string The base graph object class. */ - const BASE_GRAPH_OBJECT_CLASS = '\\Facebook\\GraphNodes\\GraphObject'; + const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; /** * @const string The graph object prefix. */ - const BASE_GRAPH_OBJECT_PREFIX = '\\Facebook\\GraphNodes\\'; + const BASE_GRAPH_OBJECT_PREFIX = '\Facebook\GraphNodes\\'; + + /** + * @var FacebookResponse The response entity from Graph. + */ + protected $response; /** * @var array The decoded body of the FacebookResponse entity from Graph. @@ -65,6 +70,7 @@ class GraphObjectFactory */ public function __construct(FacebookResponse $response) { + $this->response = $response; $this->decodedBody = $response->getDecodedBody(); } @@ -82,12 +88,7 @@ public function makeGraphObject($subclassName = null) $this->validateResponseAsArray(); $this->validateResponseCastableAsGraphObject(); - // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key - if (isset($this->decodedBody['data'])) { - $this->decodedBody = $this->decodedBody['data']; - } - - return $this->safelyMakeGraphObject($this->decodedBody, $subclassName); + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } /** @@ -157,7 +158,7 @@ public function makeGraphList($subclassName = null, $auto_prefix = true) $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; } - return $this->safelyMakeGraphList($this->decodedBody, $subclassName); + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } /** @@ -223,6 +224,9 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; static::validateSubclass($subclassName); + // Remember the parent node ID + $parentNodeId = isset($data['id']) ? $data['id'] : null; + $items = []; foreach ($data as $k => $v) { @@ -237,7 +241,7 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) : null; // Could be a GraphList or GraphObject - $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass); + $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); } else { $items[$k] = $v; } @@ -251,17 +255,19 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) * * @param array $data The array of data to iterate over. * @param string|null $subclassName The subclass to cast this collection to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. * * @return GraphObject|GraphList * * @throws FacebookSDKException */ - public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) + public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (isset($data['data'])) { // Create GraphList if (static::isCastableAsGraphList($data['data'])) { - return $this->safelyMakeGraphList($data, $subclassName); + return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); } // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key $data = $data['data']; @@ -276,12 +282,14 @@ public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) * * @param array $data The array of data to iterate over. * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. * * @return GraphList * * @throws FacebookSDKException */ - public function safelyMakeGraphList(array $data, $subclassName = null) + public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if ( ! isset($data['data'])) { throw new FacebookSDKException( @@ -291,13 +299,32 @@ public function safelyMakeGraphList(array $data, $subclassName = null) $dataList = []; foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName); + $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName, $parentKey, $parentNodeId); } - // @TODO: Look for meta data here - $metaData = []; + $metaData = $this->getMetaData($data); + + // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) + $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; + + return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + } + + /** + * Get the meta data from a list in a Graph response. + * + * @param array $data The Graph response. + * + * @return array + */ + public function getMetaData(array $data) + { + $meta_data = []; + if (isset($data['paging'])) { + $meta_data['paging'] = $data['paging']; + } - return new GraphList($dataList, $metaData); + return $meta_data; } /** diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php new file mode 100755 index 000000000..2b69b40f3 --- /dev/null +++ b/src/Facebook/Http/GraphRawResponse.php @@ -0,0 +1,138 @@ +httpResponseCode = (int) $httpStatusCode; + } + + if (is_array($headers)) { + $this->headers = $headers; + } else { + $this->setHeadersFromString($headers); + } + + $this->body = $body; + } + + /** + * Return the response headers. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Return the body of the response. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Return the HTTP response code. + * + * @return int + */ + public function getHttpResponseCode() + { + return $this->httpResponseCode; + } + + /** + * Sets the HTTP response code from a raw header. + * + * @param string $rawResponseHeader + */ + public function setHttpResponseCodeFromHeader($rawResponseHeader) + { + preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $rawResponseHeader, $match); + $this->httpResponseCode = (int) $match[1]; + } + + /** + * Parse the raw headers and set as an array. + * + * @param string $rawHeaders The raw headers from the response. + */ + protected function setHeadersFromString($rawHeaders) + { + // Normalize line breaks + $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); + + // There will be multiple headers if a 301 was followed + // or a proxy was followed, etc + $headerCollection = explode("\n\n", trim($rawHeaders)); + // We just want the last response (at the end) + $rawHeader = array_pop($headerCollection); + + $headerComponents = explode("\n", $rawHeader); + foreach ($headerComponents as $line) { + if (strpos($line, ': ') === false) { + $this->setHttpResponseCodeFromHeader($line); + } else { + list ($key, $value) = explode(': ', $line); + $this->headers[$key] = $value; + } + } + } + +} diff --git a/src/Facebook/Http/RequestBodyInterface.php b/src/Facebook/Http/RequestBodyInterface.php new file mode 100755 index 000000000..f8ac89403 --- /dev/null +++ b/src/Facebook/Http/RequestBodyInterface.php @@ -0,0 +1,40 @@ +params = $params; + $this->files = $files; + $this->boundary = $boundary ?: uniqid(); + } + + /** + * @inheritdoc + */ + public function getBody() + { + $body = ''; + + // Compile normal params + foreach ($this->params as $k => $v) { + $body .= $this->getParamString($k, $v); + } + + // Compile files + foreach ($this->files as $k => $v) { + $body .= $this->getFileString($k, $v); + } + + // Peace out + $body .= "--{$this->boundary}--\r\n"; + + return $body; + } + + /** + * Get the boundary + * + * @return string + */ + public function getBoundary() + { + 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) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n", + $this->boundary, + $name, + $file->getFileName(), + $this->getFileHeaders($file), + $file->getContents() + ); + } + + /** + * Get the string needed to transfer a POST field. + * + * @param string $name + * @param string $value + * + * @return string + */ + private function getParamString($name, $value) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", + $this->boundary, + $name, + $value + ); + } + + /** + * Get the headers needed before transferring the content of a POST file. + * + * @param FacebookFile $file + * + * @return string + */ + protected function getFileHeaders(FacebookFile $file) + { + return "\r\nContent-Type: {$file->getMimetype()}"; + } + +} diff --git a/src/Facebook/Http/RequestBodyUrlEncoded.php b/src/Facebook/Http/RequestBodyUrlEncoded.php new file mode 100644 index 000000000..0476694e8 --- /dev/null +++ b/src/Facebook/Http/RequestBodyUrlEncoded.php @@ -0,0 +1,56 @@ +params = $params; + } + + /** + * @inheritdoc + */ + public function getBody() + { + return http_build_query($this->params, null, '&'); + } + +} diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 6d05fc524..2452503cb 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -23,6 +23,7 @@ */ namespace Facebook\HttpClients; +use Facebook\Http\GraphRawResponse; use Facebook\Exceptions\FacebookSDKException; /** @@ -32,16 +33,6 @@ class FacebookCurlHttpClient implements FacebookHttpClientInterface { - /** - * @var array The headers received from the response - */ - protected $responseHeaders = []; - - /** - * @var int The HTTP status code returned from the server - */ - protected $responseHttpStatusCode = 0; - /** * @var string The client error message */ @@ -60,7 +51,7 @@ class FacebookCurlHttpClient implements FacebookHttpClientInterface /** * @var FacebookCurl Procedural curl as object */ - protected static $facebookCurl; + protected $facebookCurl; /** * @const Curl Version which is unaffected by the proxy header length error. @@ -77,44 +68,15 @@ class FacebookCurlHttpClient implements FacebookHttpClientInterface */ public function __construct(FacebookCurl $facebookCurl = null) { - self::$facebookCurl = $facebookCurl ?: new FacebookCurl(); - } - - /** - * The headers returned in the response - * - * @return array - */ - public function getResponseHeaders() - { - return $this->responseHeaders; - } - - /** - * The HTTP status response code - * - * @return int - */ - public function getResponseHttpStatusCode() - { - return $this->responseHttpStatusCode; + $this->facebookCurl = $facebookCurl ?: new FacebookCurl(); } /** - * 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 array $parameters The key value pairs to be sent in the body. - * @param array $headers The request headers. - * - * @return string Raw response from the server. - * - * @throws \Facebook\Exceptions\FacebookSDKException + * @inheritdoc */ - public function send($url, $method = 'GET', array $parameters = [], array $headers = []) + public function send($url, $method, $body, array $headers) { - $this->openConnection($url, $method, $parameters, $headers); + $this->openConnection($url, $method, $body, $headers); $this->tryToSendRequest(); // Need to verify the peer @@ -130,11 +92,9 @@ public function send($url, $method = 'GET', array $parameters = [], array $heade // Separate the raw headers from the raw body list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody(); - $this->responseHeaders = self::headersToArray($rawHeaders); - $this->closeConnection(); - return $rawBody; + return new GraphRawResponse($rawHeaders, $rawBody); } /** @@ -142,12 +102,14 @@ public function send($url, $method = 'GET', array $parameters = [], array $heade * * @param string $url The endpoint to send the request to. * @param string $method The request method. - * @param array $parameters The key value pairs to be sent in the body. + * @param string $body The body of the request. * @param array $headers The request headers. */ - public function openConnection($url, $method = 'GET', array $parameters = [], array $headers = []) + public function openConnection($url, $method, $body, array $headers) { $options = [ + CURLOPT_CUSTOMREQUEST => $method, + CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers), CURLOPT_URL => $url, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, @@ -156,18 +118,11 @@ public function openConnection($url, $method = 'GET', array $parameters = [], ar ]; if ($method !== "GET") { - $options[CURLOPT_POSTFIELDS] = $parameters; - } - if ($method === 'DELETE' || $method === 'PUT') { - $options[CURLOPT_CUSTOMREQUEST] = $method; + $options[CURLOPT_POSTFIELDS] = $body; } - if (count($headers) > 0) { - $options[CURLOPT_HTTPHEADER] = $this->compileRequestHeaders($headers); - } - - self::$facebookCurl->init(); - self::$facebookCurl->setopt_array($options); + $this->facebookCurl->init(); + $this->facebookCurl->setopt_array($options); } /** @@ -175,7 +130,7 @@ public function openConnection($url, $method = 'GET', array $parameters = [], ar */ public function addBundledCert() { - self::$facebookCurl->setopt(CURLOPT_CAINFO, + $this->facebookCurl->setopt(CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt'); } @@ -184,7 +139,7 @@ public function addBundledCert() */ public function closeConnection() { - self::$facebookCurl->close(); + $this->facebookCurl->close(); } /** @@ -193,9 +148,8 @@ public function closeConnection() public function tryToSendRequest() { $this->sendRequest(); - $this->curlErrorMessage = self::$facebookCurl->error(); - $this->curlErrorCode = self::$facebookCurl->errno(); - $this->responseHttpStatusCode = self::$facebookCurl->getinfo(CURLINFO_HTTP_CODE); + $this->curlErrorMessage = $this->facebookCurl->error(); + $this->curlErrorCode = $this->facebookCurl->errno(); } /** @@ -203,7 +157,7 @@ public function tryToSendRequest() */ public function sendRequest() { - $this->rawResponse = self::$facebookCurl->exec(); + $this->rawResponse = $this->facebookCurl->exec(); } /** @@ -231,7 +185,7 @@ public function compileRequestHeaders(array $headers) */ public function extractResponseHeadersAndBody() { - $headerSize = self::getHeaderSize(); + $headerSize = $this->getHeaderSize(); $rawHeaders = mb_substr($this->rawResponse, 0, $headerSize); $rawBody = mb_substr($this->rawResponse, $headerSize); @@ -239,39 +193,6 @@ public function extractResponseHeadersAndBody() return array(trim($rawHeaders), trim($rawBody)); } - /** - * Converts raw header responses into an array - * - * @param string $rawHeaders - * - * @return array - */ - public static function headersToArray($rawHeaders) - { - $headers = []; - - // Normalize line breaks - $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); - - // There will be multiple headers if a 301 was followed - // or a proxy was followed, etc - $headerCollection = explode("\n\n", trim($rawHeaders)); - // We just want the last response (at the end) - $rawHeader = array_pop($headerCollection); - - $headerComponents = explode("\n", $rawHeader); - foreach ($headerComponents as $line) { - if (strpos($line, ': ') === false) { - $headers['http_code'] = $line; - } else { - list ($key, $value) = explode(': ', $line); - $headers[$key] = $value; - } - } - - return $headers; - } - /** * Return proper header size * @@ -279,10 +200,10 @@ public static function headersToArray($rawHeaders) */ private function getHeaderSize() { - $headerSize = self::$facebookCurl->getinfo(CURLINFO_HEADER_SIZE); + $headerSize = $this->facebookCurl->getinfo(CURLINFO_HEADER_SIZE); // This corrects a Curl bug where header size does not account // for additional Proxy headers. - if ( self::needsCurlProxyFix() ) { + if ( $this->needsCurlProxyFix() ) { // Additional way to calculate the request body size. if (preg_match('/Content-Length: (\d+)/', $this->rawResponse, $m)) { $headerSize = mb_strlen($this->rawResponse) - $m[1]; @@ -300,9 +221,9 @@ private function getHeaderSize() * * @return boolean */ - private static function needsCurlProxyFix() + private function needsCurlProxyFix() { - $ver = self::$facebookCurl->version(); + $ver = $this->facebookCurl->version(); $version = $ver['version_number']; return $version < self::CURL_PROXY_QUIRK_VER; diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index da7dd9e33..96b1b0ba7 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -23,96 +23,54 @@ */ namespace Facebook\HttpClients; +use Facebook\Http\GraphRawResponse; use Facebook\Exceptions\FacebookSDKException; use GuzzleHttp\Client; -use GuzzleHttp\Exception\AdapterException; +use GuzzleHttp\Ring\Exception\RingException; use GuzzleHttp\Exception\RequestException; class FacebookGuzzleHttpClient implements FacebookHttpClientInterface { - /** - * @var array The headers received from the response. - */ - protected $responseHeaders = []; - - /** - * @var int The HTTP status code returned from the server. - */ - protected $responseHttpStatusCode = 0; - /** * @var \GuzzleHttp\Client The Guzzle client. */ - protected static $guzzleClient; + protected $guzzleClient; /** * @param \GuzzleHttp\Client|null The Guzzle client. */ public function __construct(Client $guzzleClient = null) { - self::$guzzleClient = $guzzleClient ?: new Client(); - } - - /** - * The headers returned in the response. - * - * @return array - */ - public function getResponseHeaders() - { - return $this->responseHeaders; - } - - /** - * The HTTP status response code. - * - * @return int - */ - public function getResponseHttpStatusCode() - { - return $this->responseHttpStatusCode; + $this->guzzleClient = $guzzleClient ?: new Client(); } /** - * 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 array $parameters The key value pairs to be sent in the body. - * @param array $headers The request headers. - * - * @return string Raw response from the server. - * - * @throws \Facebook\Exceptions\FacebookSDKException + * @inheritdoc */ - public function send($url, $method = 'GET', array $parameters = [], array $headers = []) + public function send($url, $method, $body, array $headers) { - $options = []; - if ($parameters) { - $options = ['body' => $parameters]; - } - - $request = self::$guzzleClient->createRequest($method, $url, $options); - - foreach($headers as $k => $v) { - $request->setHeader($k, $v); - } + $options = [ + 'headers' => $headers, + 'body' => $body, + ]; + $request = $this->guzzleClient->createRequest($method, $url, $options); try { - $rawResponse = self::$guzzleClient->send($request); + $rawResponse = $this->guzzleClient->send($request); } catch (RequestException $e) { - if ($e->getPrevious() instanceof AdapterException) { + if ($e->getPrevious() instanceof RingException) { throw new FacebookSDKException($e->getMessage(), $e->getCode()); } $rawResponse = $e->getResponse(); } - $this->responseHttpStatusCode = $rawResponse->getStatusCode(); - $this->responseHeaders = $rawResponse->getHeaders(); + $headers = $rawResponse->getHeaders(); + $rawBody = $rawResponse->getBody(); + $httpStatusCode = $rawResponse->getStatusCode(); - return $rawResponse->getBody(); + return new GraphRawResponse($headers, $rawBody, $httpStatusCode); } } diff --git a/src/Facebook/HttpClients/FacebookHttpClientInterface.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php index f95b66603..88a974f34 100644 --- a/src/Facebook/HttpClients/FacebookHttpClientInterface.php +++ b/src/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -30,32 +30,18 @@ interface FacebookHttpClientInterface { - /** - * The headers returned in the response. - * - * @return array - */ - public function getResponseHeaders(); - - /** - * The HTTP status response code. - * - * @return int - */ - public function getResponseHttpStatusCode(); - /** * 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 array $parameters The key value pairs to be sent in the body. + * @param string $body The body of the request. * @param array $headers The request headers. * - * @return string Raw response from the server. + * @return \Facebook\Http\GraphRawResponse Raw response from the server. * * @throws \Facebook\Exceptions\FacebookSDKException */ - public function send($url, $method = 'GET', array $parameters = [], array $headers = []); + public function send($url, $method, $body, array $headers); } diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index f58f0260c..0898cc979 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -23,71 +23,35 @@ */ namespace Facebook\HttpClients; +use Facebook\Http\GraphRawResponse; use Facebook\Exceptions\FacebookSDKException; class FacebookStreamHttpClient implements FacebookHttpClientInterface { - /** - * @var array The headers received from the response. - */ - protected $responseHeaders = []; - - /** - * @var int The HTTP status code returned from the server. - */ - protected $responseHttpStatusCode = 0; - /** * @var FacebookStream Procedural stream wrapper as object. */ - protected static $facebookStream; + protected $facebookStream; /** * @param FacebookStream|null Procedural stream wrapper as object. */ public function __construct(FacebookStream $facebookStream = null) { - self::$facebookStream = $facebookStream ?: new FacebookStream(); + $this->facebookStream = $facebookStream ?: new FacebookStream(); } /** - * The headers returned in the response. - * - * @return array - */ - public function getResponseHeaders() - { - return $this->responseHeaders; - } - - /** - * The HTTP status response code. - * - * @return int - */ - public function getResponseHttpStatusCode() - { - return $this->responseHttpStatusCode; - } - - /** - * 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 array $parameters The key value pairs to be sent in the body. - * @param array $headers The request headers. - * - * @return string Raw response from the server. - * - * @throws \Facebook\Exceptions\FacebookSDKException + * @inheritdoc */ - public function send($url, $method = 'GET', array $parameters = [], array $headers = []) + public function send($url, $method, $body, array $headers) { $options = [ 'http' => [ 'method' => $method, + 'header' => $this->compileHeader($headers), + 'content' => $body, 'timeout' => 60, 'ignore_errors' => true ], @@ -97,26 +61,17 @@ public function send($url, $method = 'GET', array $parameters = [], array $heade ], ]; - if ($parameters) { - $options['http']['content'] = http_build_query($parameters, null, '&'); + $this->facebookStream->streamContextCreate($options); + $rawBody = $this->facebookStream->fileGetContents($url); + $rawHeaders = $this->facebookStream->getResponseHeaders(); - $headers['Content-type'] = 'application/x-www-form-urlencoded'; - } - - $options['http']['header'] = $this->compileHeader($headers); - - self::$facebookStream->streamContextCreate($options); - $rawResponse = self::$facebookStream->fileGetContents($url); - $rawHeaders = self::$facebookStream->getResponseHeaders(); - - if ($rawResponse === false || !$rawHeaders) { + if ($rawBody === false || !$rawHeaders) { throw new FacebookSDKException('Stream returned an empty response', 660); } - $this->responseHeaders = self::formatHeadersToArray($rawHeaders); - $this->responseHttpStatusCode = self::getStatusCodeFromHeader($this->responseHeaders['http_code']); + $rawHeaders = implode("\r\n", $rawHeaders); - return $rawResponse; + return new GraphRawResponse($rawHeaders, $rawBody); } /** @@ -136,41 +91,4 @@ public function compileHeader(array $headers) return implode("\r\n", $header); } - /** - * Converts array of headers returned from the wrapper into - * something standard - * - * @param array $rawHeaders - * - * @return array - */ - public static function formatHeadersToArray(array $rawHeaders) - { - $headers = []; - - foreach ($rawHeaders as $line) { - if (strpos($line, ':') === false) { - $headers['http_code'] = $line; - } else { - list ($key, $value) = explode(': ', $line); - $headers[$key] = $value; - } - } - - return $headers; - } - - /** - * Pulls out the HTTP status code from a response header - * - * @param string $header - * - * @return int - */ - public static function getStatusCodeFromHeader($header) - { - preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $header, $match); - return (int) $match[1]; - } - } diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index 2f79c49f3..f19eb3913 100755 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -57,11 +57,110 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) } } + $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; + $host = isset($parts['host']) ? $parts['host'] : ''; $port = isset($parts['port']) ? ':' . $parts['port'] : ''; $path = isset($parts['path']) ? $parts['path'] : ''; $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; - return $parts['scheme'] . '://' . $parts['host'] . $port . $path . $query . $fragment; + return $scheme . $host . $port . $path . $query . $fragment; + } + + /** + * Gracefully appends params to the URL. + * + * @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 = []) + { + if ( ! $newParams) { + return $url; + } + + if (strpos($url, '?') === false) { + return $url . '?' . http_build_query($newParams, null, '&'); + } + + list($path, $query) = explode('?', $url, 2); + $existingParams = []; + parse_str($query, $existingParams); + + // Favor params from the original URL over $newParams + $newParams = array_merge($newParams, $existingParams); + + // Sort for a predicable order + ksort($newParams); + + return $path . '?' . http_build_query($newParams, null, '&'); + } + + /** + * Returns the params from a URL in the form of an array. + * + * @param string $url The URL to parse the params from. + * + * @return array + */ + public static function getParamsAsArray($url) + { + $query = parse_url($url, PHP_URL_QUERY); + if ( ! $query) { + return []; + } + $params = []; + parse_str($query, $params); + + return $params; + } + + /** + * Adds the params of the first URL to the second URL. + * Any params that already exist in the second URL will go untouched. + * + * @param string $urlToStealFrom The URL harvest the params from. + * @param string $urlToAddTo The URL that will receive the new params. + * + * @return string The $urlToAddTo with any new params from $urlToStealFrom. + */ + public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) + { + $newParams = static::getParamsAsArray($urlToStealFrom); + // Nothing new to add, return as-is + if ( ! $newParams) { + return $urlToAddTo; + } + + return static::appendParamsToUrl($urlToAddTo, $newParams); + } + + /** + * Check for a "/" prefix and prepend it if not exists. + * + * @param string|null $string + * + * @return string|null + */ + public static function forceSlashPrefix($string) + { + if (!$string) { + return $string; + } + return strpos($string, '/') === 0 ? $string : '/' . $string; + } + + /** + * Trims off the hostname and Graph version from a URL. + * + * @param string $urlToTrim The URL the needs the surgery. + * + * @return string The $urlToTrim with the hostname and Graph version removed. + */ + public static function baseGraphUrlEndpoint($urlToTrim) + { + return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); } } diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/Entities/FacebookBatchRequestTest.php index f2659b1ac..cc0e946de 100755 --- a/tests/Entities/FacebookBatchRequestTest.php +++ b/tests/Entities/FacebookBatchRequestTest.php @@ -27,10 +27,14 @@ use Facebook\Entities\FacebookApp; use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookBatchRequest; +use Facebook\FileUpload\FacebookFile; class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ private $app; public function setUp() @@ -40,7 +44,7 @@ public function setUp() public function testABatchRequestWillInstantiateWithTheProperProperties() { - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', [], 'v0.1337'); + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token', 'v0.1337'); $this->assertSame($this->app, $batchRequest->getApp()); $this->assertEquals('foo_token', $batchRequest->getAccessToken()); @@ -98,7 +102,7 @@ public function testWillThrowWhenNoThereIsNoAccessTokenFallback() } /** - * @expectedException \Facebook\Exceptions\FacebookSDKException + * @expectedException \InvalidArgumentException */ public function testAnInvalidTypeGivenToAddWillThrow() { @@ -159,7 +163,7 @@ public function testRequestsCanBeInjectedIntoConstructor() new FacebookRequest(null, null, 'DELETE', '/baz'), ]; - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', $requests); + $batchRequest = new FacebookBatchRequest($this->app, $requests, 'foo_token'); $formattedRequests = $batchRequest->getRequests(); $this->assertRequestsMatch($requests, $formattedRequests); @@ -170,7 +174,7 @@ public function testRequestsCanBeInjectedIntoConstructor() */ public function testAZeroRequestCountWithThrow() { - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token'); + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token'); $batchRequest->validateBatchRequestCount(); } @@ -205,7 +209,7 @@ public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $batchRequest->add($request, 'foo_name'); $requests = $batchRequest->getRequests(); - $batchRequestArray = FacebookBatchRequest::requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); + $batchRequestArray = $batchRequest->requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); $this->assertEquals($expectedArray, $batchRequestArray); } @@ -246,6 +250,35 @@ public function requestsAndExpectedResponsesProvider() ]; } + public function testBatchRequestsWithFilesGetConvertedToAnArray() + { + $request = new FacebookRequest(null, null, 'POST', '/bar', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/../foo.txt'), + ]); + + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, 'foo_name'); + + $requests = $batchRequest->getRequests(); + + $attachedFiles = $requests[0]['attached_files']; + + $batchRequestArray = $batchRequest->requestEntityToBatchArray( + $requests[0]['request'], + $requests[0]['name'], + $attachedFiles); + + $this->assertEquals([ + 'headers' => $this->defaultHeaders(), + 'method' => 'POST', + 'relative_url' => '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar', + 'body' => 'message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + 'attached_files' => $attachedFiles, + ], $batchRequestArray); + } + public function testPreppingABatchRequestProperlySetsThePostParams() { $batchRequest = $this->createBatchRequest(); @@ -267,6 +300,33 @@ public function testPreppingABatchRequestProperlySetsThePostParams() $this->assertEquals($expectedBatchParams, $params); } + public function testPreppingABatchRequestProperlyMovesTheFiles() + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/me/photos', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/../foo.txt'), + ])); + $batchRequest->prepareRequestsForBatch(); + + $params = $batchRequest->getParams(); + $files = $batchRequest->getFiles(); + + $attachedFiles = implode(',', array_keys($files)); + + $expectedHeaders = json_encode($this->defaultHeaders()); + $version = Facebook::DEFAULT_GRAPH_VERSION; + $expectedBatchParams = [ + 'batch' => '[{"headers":'.$expectedHeaders.',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' + .'{"headers":'.$expectedHeaders.',"method":"POST","relative_url":"\\/' . $version . '\\/me\\/photos","body":"message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9","attached_files":"' . $attachedFiles . '"}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) { $app = $request->getApp(); @@ -294,7 +354,7 @@ private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $ private function createBatchRequest() { - return new FacebookBatchRequest($this->app, 'foo_token'); + return new FacebookBatchRequest($this->app, [], 'foo_token'); } private function createBatchRequestWithRequests(array $requests) diff --git a/tests/Entities/FacebookBatchResponseTest.php b/tests/Entities/FacebookBatchResponseTest.php index fd7ddb694..395773cf8 100755 --- a/tests/Entities/FacebookBatchResponseTest.php +++ b/tests/Entities/FacebookBatchResponseTest.php @@ -24,12 +24,37 @@ namespace Facebook\Tests\Entities; use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookResponse; +use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookBatchResponse; class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\Entities\FacebookApp + */ + protected $app; + + /** + * @var \Facebook\Entities\FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $this->app, + 'foo_token', + 'POST', + '/', + ['batch' => 'foo'], + 'foo_eTag', + 'v1337'); + } + public function testASuccessfulJsonBatchResponseWillBeDecoded() { $graphResponseJson = '['; @@ -46,9 +71,9 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() // After DELETE operation. $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"true"}'; $graphResponseJson .= ']'; - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $batchResponse = new FacebookBatchResponse($response); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, []); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); $decodedResponses = $batchResponse->getResponses(); @@ -84,9 +109,9 @@ public function testABatchResponseCanBeIteratedOver() $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; $graphResponseJson .= ']'; - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $batchResponse = new FacebookBatchResponse($response); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, []); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); $this->assertInstanceOf('IteratorAggregate', $batchResponse); @@ -95,4 +120,29 @@ public function testABatchResponseCanBeIteratedOver() } } + public function testTheOriginalRequestCanBeObtainedForEachRequest() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $requests = [ + new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), + new FacebookRequest($this->app, 'foo_token_two', 'POST', '/you'), + new FacebookRequest($this->app, 'foo_token_three', 'DELETE', '/123456'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $batchResponse[0]); + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $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/Entities/FacebookRequestTest.php b/tests/Entities/FacebookRequestTest.php index 9c089ddd9..5eb02c638 100755 --- a/tests/Entities/FacebookRequestTest.php +++ b/tests/Entities/FacebookRequestTest.php @@ -26,6 +26,8 @@ use Facebook\Facebook; use Facebook\Entities\FacebookApp; use Facebook\Entities\FacebookRequest; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookVideo; class FacebookRequestTest extends \PHPUnit_Framework_TestCase { @@ -98,6 +100,25 @@ public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() ], $params); } + public function testAnAccessTokenCanBeSetFromTheParams() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'POST', '/me', ['access_token' => 'bar_token']); + + $accessToken = $request->getAccessToken(); + + $this->assertEquals('bar_token', $accessToken); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAccessTokenConflictsWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + new FacebookRequest($app, 'foo_token', 'POST', '/me', ['access_token' => 'bar_token']); + } + public function testAProperUrlWillBeGenerated() { $app = new FacebookApp('123', 'foo_secret'); @@ -117,7 +138,7 @@ public function testAProperUrlWillBeGenerated() $this->assertEquals($expectedUrl, $postUrl); } - public function testParamsAreNotOverwritten() + public function testAuthenticationParamsAreStrippedAndReapplied() { $app = new FacebookApp('123', 'foo_secret'); @@ -127,71 +148,62 @@ public function testParamsAreNotOverwritten() $method = 'GET', $endpoint = '/foo', $params = [ - 'access_token' => 'bar_access_token', + 'access_token' => 'foo_token', 'appsecret_proof' => 'bar_app_secret', + 'bar' => 'baz', ] ); $url = $request->getUrl(); - $expectedParams = 'access_token=bar_access_token&appsecret_proof=bar_app_secret'; + $expectedParams = 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; $this->assertEquals($expectedUrl, $url); $params = $request->getParams(); $expectedParams = [ - 'access_token' => 'bar_access_token', - 'appsecret_proof' => 'bar_app_secret', + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'bar' => 'baz', ]; $this->assertEquals($expectedParams, $params); } - public function testGracefullyHandlesUrlAppending() + public function testAFileCanBeAddedToParams() { - $params = []; - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/', $processed_url); - + $myFile = new FacebookFile(__DIR__ . '/../foo.txt'); $params = [ - 'access_token' => 'foo', + 'name' => 'Foo Bar', + 'source' => $myFile, ]; - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/photos', $params); - $params = [ - 'access_token' => 'foo', - 'bar' => 'baz', - ]; - $url = 'https://www.foo.com/?foo=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + $actualParams = $request->getParams(); - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/?foo=bar&access_token=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + $this->assertTrue($request->containsFileUploads()); + $this->assertFalse($request->containsAVideoUpload()); + $this->assertTrue( ! isset($actualParams['source'])); + $this->assertEquals('Foo Bar', $actualParams['name']); } - public function testSlashesAreProperlyPrepended() + public function testAVideoCanBeAddedToParams() { - $slashTestOne = FacebookRequest::forceSlashPrefix('foo'); - $slashTestTwo = FacebookRequest::forceSlashPrefix('/foo'); - $slashTestThree = FacebookRequest::forceSlashPrefix('foo/bar'); - $slashTestFour = FacebookRequest::forceSlashPrefix('/foo/bar'); - $slashTestFive = FacebookRequest::forceSlashPrefix(null); - $slashTestSix = FacebookRequest::forceSlashPrefix(''); - - $this->assertEquals('/foo', $slashTestOne); - $this->assertEquals('/foo', $slashTestTwo); - $this->assertEquals('/foo/bar', $slashTestThree); - $this->assertEquals('/foo/bar', $slashTestFour); - $this->assertEquals(null, $slashTestFive); - $this->assertEquals('', $slashTestSix); + $myFile = new FacebookVideo(__DIR__ . '/../foo.txt'); + $params = [ + 'name' => 'Foo Bar', + 'source' => $myFile, + ]; + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/videos', $params); + + $actualParams = $request->getParams(); + + $this->assertTrue($request->containsFileUploads()); + $this->assertTrue($request->containsAVideoUpload()); + $this->assertTrue( ! isset($actualParams['source'])); + $this->assertEquals('Foo Bar', $actualParams['name']); } } diff --git a/tests/Entities/FacebookResponseTest.php b/tests/Entities/FacebookResponseTest.php index 42ca4572b..5ebba834a 100755 --- a/tests/Entities/FacebookResponseTest.php +++ b/tests/Entities/FacebookResponseTest.php @@ -24,23 +24,33 @@ namespace Facebook\Tests\Entities; use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookResponse; class FacebookResponseTest extends \PHPUnit_Framework_TestCase { - public function testAnEmptyResponseEntityCanInstantiate() + /** + * @var \Facebook\Entities\FacebookRequest + */ + protected $request; + + public function setUp() { $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app); - - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); } public function testAnETagCanBeProperlyAccessed() { - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, ['ETag' => 'foo_tag']); + $response = new FacebookResponse($this->request, '', 200, ['ETag' => 'foo_tag']); $eTag = $response->getETag(); @@ -49,8 +59,7 @@ public function testAnETagCanBeProperlyAccessed() public function testAProperAppSecretProofCanBeGenerated() { - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], '', 'foo_token'); + $response = new FacebookResponse($this->request); $appSecretProof = $response->getAppSecretProof(); @@ -59,9 +68,8 @@ public function testAProperAppSecretProofCanBeGenerated() public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseJson = '{"id":"123","name":"Foo"}'; - $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); $decodedResponse = $response->getDecodedBody(); $graphObject = $response->getGraphObject(); @@ -76,9 +84,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; - $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); $graphObjectList = $response->getGraphList(); @@ -89,9 +96,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseKeyValuePairs = 'id=123&name=Foo'; - $response = new FacebookResponse($app, 200, [], $graphResponseKeyValuePairs); + $response = new FacebookResponse($this->request, $graphResponseKeyValuePairs, 200); $decodedResponse = $response->getDecodedBody(); @@ -104,9 +110,8 @@ public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; - $response = new FacebookResponse($app, 401, [], $graphResponse); + $response = new FacebookResponse($this->request, $graphResponse, 401); $exception = $response->getThrownException(); diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 8996d443f..560a26549 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -25,17 +25,43 @@ use Facebook\Exceptions\FacebookSDKException; use Mockery as m; +use Facebook\Facebook; use Facebook\Entities\FacebookApp; use Facebook\Entities\FacebookRequest; +use Facebook\Entities\FacebookBatchRequest; use Facebook\FacebookClient; +use Facebook\Http\GraphRawResponse; +use Facebook\HttpClients\FacebookHttpClientInterface; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookVideo; // These are needed when you uncomment the HTTP clients below. use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookGuzzleHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; +class MyFooClientHandler implements FacebookHttpClientInterface +{ + public function send($url, $method, $body, array $headers) { + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' + ); + } +} + class FacebookClientTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ + public $fbApp; + + /** + * @var FacebookClient + */ + public $fbClient; + /** * @var FacebookApp */ @@ -53,16 +79,18 @@ class FacebookClientTest extends \PHPUnit_Framework_TestCase public function setUp() { + $this->fbApp = new FacebookApp('id', 'shhhh!'); + $this->fbClient = new FacebookClient(new MyFooClientHandler()); $this->httpClientMock = m::mock('Facebook\HttpClients\FacebookHttpClientInterface'); } public function testACustomHttpClientCanBeInjected() { - $client = new FacebookClient($this->httpClientMock); + $handler = new MyFooClientHandler(); + $client = new FacebookClient($handler); $httpHandler = $client->getHttpClientHandler(); - $this->assertInstanceOf('Mockery\MockInterface', $httpHandler); - $this->assertSame($this->httpClientMock, $httpHandler); + $this->assertInstanceOf('Facebook\Tests\MyFooClientHandler', $httpHandler); } public function testTheHttpClientWillFallbackToDefault() @@ -100,106 +128,90 @@ public function testBetaModeCanBeDisabledOrEnabledViaMethod() $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); } + public function testGraphVideoUrlCanBeSet() + { + $client = new FacebookClient(); + $client->enableBetaMode(false); + $url = $client->getBaseGraphUrl($postToVideoUrl = true); + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL, $url); + + $client->enableBetaMode(true); + $url = $client->getBaseGraphUrl($postToVideoUrl = true); + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL_BETA, $url); + } + public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() { - $facebookApp = new FacebookApp('123', 'foo_secret'); - $facebookRequest = m::mock('Facebook\Entities\FacebookRequest'); - $facebookRequest - ->shouldReceive('getUrl') - ->once() - ->andReturn('/foo'); - $facebookRequest - ->shouldReceive('getMethod') - ->once() - ->andReturn('GET'); - $facebookRequest - ->shouldReceive('getPostParams') - ->once() - ->andReturn([]); - $facebookRequest - ->shouldReceive('getHeaders') - ->once() - ->andReturn(['request_header' => 'foo']); - $facebookRequest - ->shouldReceive('getAccessToken') - ->once() - ->andReturn('foo_token'); - $facebookRequest - ->shouldReceive('getApp') - ->once() - ->andReturn($facebookApp); - - $this->httpClientMock - ->shouldReceive('send') - ->with(FacebookClient::BASE_GRAPH_URL . '/foo', 'GET', [], ['request_header' => 'foo']) - ->once() - ->andReturn('foo_response'); - $this->httpClientMock - ->shouldReceive('getResponseHttpStatusCode') - ->once() - ->andReturn(200); - $this->httpClientMock - ->shouldReceive('getResponseHeaders') - ->once() - ->andReturn(['response_header' => 'bar']); - - $client = new FacebookClient($this->httpClientMock); - $response = $client->sendRequest($facebookRequest); + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'); + $response = $this->fbClient->sendRequest($fbRequest); $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + $this->assertEquals(200, $response->getHttpStatusCode()); + $this->assertEquals('{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}', $response->getBody()); } public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() { - $facebookApp = new FacebookApp('123', 'foo_secret'); - $facebookBatchRequest = m::mock('Facebook\Entities\FacebookBatchRequest'); - $facebookBatchRequest - ->shouldReceive('prepareRequestsForBatch') - ->once() - ->andReturn(null); - $facebookBatchRequest - ->shouldReceive('getUrl') - ->once() - ->andReturn(''); - $facebookBatchRequest - ->shouldReceive('getMethod') - ->once() - ->andReturn('POST'); - $facebookBatchRequest - ->shouldReceive('getPostParams') - ->once() - ->andReturn([]); - $facebookBatchRequest - ->shouldReceive('getHeaders') - ->once() - ->andReturn(['request_header' => 'foo']); - $facebookBatchRequest - ->shouldReceive('getAccessToken') - ->once() - ->andReturn('foo_token'); - $facebookBatchRequest - ->shouldReceive('getApp') - ->once() - ->andReturn($facebookApp); - - $this->httpClientMock - ->shouldReceive('send') - ->with(FacebookClient::BASE_GRAPH_URL, 'POST', [], ['request_header' => 'foo']) - ->once() - ->andReturn('[]'); - $this->httpClientMock - ->shouldReceive('getResponseHttpStatusCode') - ->once() - ->andReturn(200); - $this->httpClientMock - ->shouldReceive('getResponseHeaders') - ->once() - ->andReturn(['response_header' => 'bar']); - - $client = new FacebookClient($this->httpClientMock); - $response = $client->sendBatchRequest($facebookBatchRequest); + $fbRequests = [ + new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'), + new FacebookRequest($this->fbApp, 'token', 'POST', '/bar'), + ]; + $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); + + $response = $this->fbClient->sendBatchRequest($fbBatchRequest); $this->assertInstanceOf('Facebook\Entities\FacebookBatchResponse', $response); + // @TODO I think this is a bug + //$this->assertEquals('GET', $response[0]->getRequest()->getMethod()); + //$this->assertEquals('POST', $response[1]->getRequest()->getMethod()); + } + + public function testAFacebookBatchRequestWillProperlyBatchFiles() + { + $fbRequests = [ + new FacebookRequest($this->fbApp, 'token', 'POST', '/photo', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + ]), + new FacebookRequest($this->fbApp, 'token', 'POST', '/video', [ + 'message' => 'foobar', + 'source' => new FacebookVideo(__DIR__ . '/foo.txt'), + ]), + ]; + $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); + $fbBatchRequest->prepareRequestsForBatch(); + + list($url, $method, $headers, $body) = $this->fbClient->prepareRequestMessage($fbBatchRequest); + + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL . '/' . Facebook::DEFAULT_GRAPH_VERSION, $url); + $this->assertEquals('POST', $method); + $this->assertContains('multipart/form-data; boundary=', $headers['Content-Type']); + $this->assertContains('Content-Disposition: form-data; name="batch"', $body); + $this->assertContains('Content-Disposition: form-data; name="include_headers"', $body); + $this->assertContains('"name":0,"attached_files":', $body); + $this->assertContains('"name":1,"attached_files":', $body); + $this->assertContains('"; filename="foo.txt"', $body); + } + + public function testARequestOfParamsWillBeUrlEncoded() + { + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['foo' => 'bar']); + $response = $this->fbClient->sendRequest($fbRequest); + + $headersSent = $response->getRequest()->getHeaders(); + + $this->assertEquals('application/x-www-form-urlencoded', $headersSent['Content-Type']); + } + + public function testARequestWithFilesWillBeMultipart() + { + $myFile = new FacebookFile(__DIR__ . '/foo.txt'); + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['file' => $myFile]); + $response = $this->fbClient->sendRequest($fbRequest); + + $headersSent = $response->getRequest()->getHeaders(); + + $this->assertContains('multipart/form-data; boundary=', $headersSent['Content-Type']); } /** diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 85ec11751..05e34f155 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -23,18 +23,23 @@ */ namespace Facebook\Tests; -use Mockery as m; use Facebook\Facebook; use Facebook\FacebookClient; +use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; +use Facebook\Entities\FacebookRequest; +use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface { - public function getResponseHeaders() { return ['X-foo-header' => 'bar']; } - public function getResponseHttpStatusCode() { return 1337; } - public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { return 'foo_response'; } + public function send($url, $method, $body, array $headers) { + return new GraphRawResponse( + "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' + ); + } } class FooPersistentDataInterface implements PersistentDataInterface @@ -195,4 +200,36 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $this->assertEquals('v1337', $request->getGraphVersion()); } + public function testPaginationReturnsProperResponse() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + ]); + $fb = new Facebook($config); + + $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); + $graphList = new GraphList( + $request, + [], + [ + 'paging' => [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ] + ], + '/1337/photos', + '\Facebook\GraphNodes\GraphUser'); + + $nextPage = $fb->next($graphList); + $this->assertInstanceOf('Facebook\GraphNodes\GraphList', $nextPage); + $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); + $this->assertEquals('Foo', $nextPage[0]['name']); + + $lastResponse = $fb->getLastResponse(); + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $lastResponse); + $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); + } + } diff --git a/tests/FileUpload/FacebookFileTest.php b/tests/FileUpload/FacebookFileTest.php new file mode 100644 index 000000000..885d0caae --- /dev/null +++ b/tests/FileUpload/FacebookFileTest.php @@ -0,0 +1,54 @@ +testFile = __DIR__ . '/../foo.txt'; + } + + 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); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testTryingToOpenAFileThatDoesntExistsThrows() + { + new FacebookFile('does_not_exist.file'); + } + +} diff --git a/tests/FileUpload/MimetypesTest.php b/tests/FileUpload/MimetypesTest.php new file mode 100644 index 000000000..26be32134 --- /dev/null +++ b/tests/FileUpload/MimetypesTest.php @@ -0,0 +1,52 @@ +assertEquals('text/x-php', Mimetypes::getInstance()->fromExtension('php')); + } + public function testGetsFromFilename() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(__FILE__)); + } + public function testGetsFromCaseInsensitiveFilename() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(strtoupper(__FILE__))); + } + public function testReturnsNullWhenNoMatchFound() + { + $this->assertNull(Mimetypes::getInstance()->fromExtension('foobar')); + } + +} diff --git a/tests/GraphNodes/GraphListTest.php b/tests/GraphNodes/GraphListTest.php new file mode 100644 index 000000000..1590a77db --- /dev/null +++ b/tests/GraphNodes/GraphListTest.php @@ -0,0 +1,117 @@ + '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', + ]; + protected $cursorPagination = [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ]; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonGetRequestsWillThrow() + { + $this->request->setMethod('POST'); + $graphList = new GraphList($this->request); + $graphList->validateForPagination(); + } + + public function testCanReturnGraphGeneratedPaginationEndpoints() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->basePagination]); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); + + $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); + $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); + } + + public function testCanGeneratePaginationEndpointsFromACursor() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes'); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); + + $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); + $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); + } + + public function testCanInstantiateNewPaginationRequest() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes'); + $nextPage = $graphList->getNextPageRequest(); + $prevPage = $graphList->getPreviousPageRequest(); + + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $nextPage); + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $prevPage); + $this->assertNotSame($this->request, $nextPage); + $this->assertNotSame($this->request, $prevPage); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); + } + +} diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index 7d583af68..6690d4adf 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -23,7 +23,9 @@ */ namespace Facebook\Tests\GraphNodes; -use Mockery as m; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\Entities\FacebookResponse; use Facebook\GraphNodes\GraphObjectFactory; use Facebook\GraphNodes\GraphObject; @@ -31,7 +33,7 @@ class MyFooSubClassGraphObject extends GraphObject {} class MyFooGraphObject extends GraphObject { protected static $graphObjectMap = [ - 'foo_object' => '\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', + 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', ]; } @@ -39,37 +41,29 @@ class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\Entities\FacebookRequest */ - protected $responseMock; + protected $request; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testADecodedResponseThatIsNotAnArrayWillThrow() - { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn('foo'); - - $factory = new GraphObjectFactory($this->responseMock); - $factory->validateResponseAsArray(); + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); } public function testAValidGraphObjectResponseWillNotThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphObject(); } @@ -78,33 +72,19 @@ public function testAValidGraphObjectResponseWillNotThrow() */ public function testANonGraphObjectResponseWillThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'data' => [ - ['id' => '123', 'name' => 'foo'], - ['id' => '1337', 'name' => 'bar'], - ] - ]); - - $factory = new GraphObjectFactory($this->responseMock); + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphObject(); } public function testAValidGraphListResponseWillNotThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'data' => [ - ['id' => '123', 'name' => 'foo'], - ['id' => '1337', 'name' => 'bar'], - ] - ]); - - $factory = new GraphObjectFactory($this->responseMock); + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -113,12 +93,10 @@ public function testAValidGraphListResponseWillNotThrow() */ public function testANonGraphListResponseWillThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -143,52 +121,38 @@ public function testInvalidSubClassesWillThrow() public function testValidSubClassesWillNotThrow() { - GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphObject'); - GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphAlbum'); - GraphObjectFactory::validateSubclass('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); + GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphObject'); } public function testCastingAsASubClassObjectWillInstantiateTheSubClass() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); } public function testASubClassMappingWillAutomaticallyInstantiateSubClass() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'id' => '123', - 'name' => 'Foo Name', - 'foo_object' => [ - 'id' => '1337', - 'name' => 'Should be sub classed!', - ], - ]); + $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); $fooObject = $mySubClassObject->getProperty('foo_object'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', $fooObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $fooObject); } public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ + $data = json_encode([ 'id' => '123', 'name' => 'Foo Name', 'unknown_object' => [ @@ -196,49 +160,45 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() 'name' => 'Should be generic!', ], ]); + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); $unknownObject = $mySubClassObject->getProperty('unknown_object'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $unknownObject); - $this->assertNotInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $unknownObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $unknownObject); } public function testAListFromGraphWillBeCastAsAGraphList() { - $dataFromGraph = [ - 'data' => [ - [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', + $data = json_encode([ + 'data' => [ + [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + [ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], ], - [ - 'id' => '1337', - 'name' => 'Bar McBaz', - 'link' => 'http://facebook/bar', + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', ], - ], - 'paging' => [ - 'next' => 'http://facebook/next', - 'previous' => 'http://facebook/prev', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); + ]); + $res = new FacebookResponse($this->request, $data); + $factory = new GraphObjectFactory($res); $graphList = $factory->makeGraphList(); $graphData = $graphList->asArray(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphList); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -253,23 +213,18 @@ public function testAListFromGraphWillBeCastAsAGraphList() public function testAGraphObjectWillBeCastAsAGraphObject() { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); + $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->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -279,25 +234,21 @@ public function testAGraphObjectWillBeCastAsAGraphObject() public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() { - $dataFromGraph = [ - 'data' => [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); + $data = json_encode([ + 'data' => [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ]); - $factory = new GraphObjectFactory($this->responseMock); + $res = new FacebookResponse($this->request, $data); + $factory = new GraphObjectFactory($res); $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -305,7 +256,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() ], $graphData); } - public function testACollectionWillBeCastRecursively() + public function testAGraphListWillBeCastRecursively() { $someUser = [ 'id' => '123', @@ -386,33 +337,99 @@ public function testACollectionWillBeCastRecursively() 'previous' => 'http://facebook/prev', ], ]; + $data = json_encode($dataFromGraph); + $res = new FacebookResponse($this->request, $data); - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); - + $factory = new GraphObjectFactory($res); $graphObject = $factory->makeGraphList(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); // Story $storyObject = $graphObject[0]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $storyObject['from']); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['likes']); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['comments']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $storyObject['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); // Story Comments $storyComments = $storyObject['comments']; $firstStoryComment = $storyComments[0]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $firstStoryComment['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $firstStoryComment['from']); // Message $messageObject = $graphObject[1]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $messageObject['to']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); $toUsers = $messageObject['to']; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $toUsers[0]); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $toUsers[0]); + } + + public function testAGraphListWillGenerateTheProperParentGraphEdges() + { + $likesList = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'like_after_cursor', + 'before' => 'like_before_cursor', + ], + ], + ]; + + $photosList = [ + 'data' => [ + [ + 'id' => '777', + 'name' => 'Foo Photo', + 'likes' => $likesList, + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'photo_after_cursor', + 'before' => 'photo_before_cursor', + ], + ], + ]; + + $data = json_encode([ + 'data' => [ + [ + 'id' => '111', + 'name' => 'Foo McBar', + 'likes' => $likesList, + 'photos' => $photosList, + ], + [ + 'id' => '222', + 'name' => 'Bar McBaz', + 'likes' => $likesList, + 'photos' => $photosList, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphList = $factory->makeGraphList(); + $topGraphEdge = $graphList->getParentGraphEdge(); + $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); + $childGraphEdgeTwo = $graphList[1]['likes']->getParentGraphEdge(); + $childGraphEdgeThree = $graphList[1]['photos']->getParentGraphEdge(); + $childGraphEdgeFour = $graphList[1]['photos'][0]['likes']->getParentGraphEdge(); + + $this->assertNull($topGraphEdge); + $this->assertEquals('/111/likes', $childGraphEdgeOne); + $this->assertEquals('/222/likes', $childGraphEdgeTwo); + $this->assertEquals('/222/photos', $childGraphEdgeThree); + $this->assertEquals('/777/likes', $childGraphEdgeFour); } } diff --git a/tests/Http/GraphRawResponseTest.php b/tests/Http/GraphRawResponseTest.php new file mode 100644 index 000000000..5be134ad5 --- /dev/null +++ b/tests/Http/GraphRawResponseTest.php @@ -0,0 +1,81 @@ + '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', + 'Content-Type' => 'text/javascript; charset=UTF-8', + 'X-FB-Rev' => '9244768', + 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', + 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', + 'Access-Control-Allow-Origin' => '*', + ]; + + public function testCanSetTheHeadersFromAnArray() + { + $myHeaders = [ + 'foo' => 'bar', + 'baz' => 'faz', + ]; + $response = new GraphRawResponse($myHeaders, ''); + $headers = $response->getHeaders(); + + $this->assertEquals($myHeaders, $headers); + } + + public function testCanSetTheHeadersFromAString() + { + $response = new GraphRawResponse($this->fakeRawHeader, ''); + $headers = $response->getHeaders(); + $httpResponseCode = $response->getHttpResponseCode(); + + $this->assertEquals($this->fakeHeadersAsArray, $headers); + $this->assertEquals(200, $httpResponseCode); + } + + public function testWillIgnoreProxyHeaders() + { + $response = new GraphRawResponse($this->fakeRawProxyHeader . $this->fakeRawHeader, ''); + $headers = $response->getHeaders(); + $httpResponseCode = $response->getHttpResponseCode(); + + $this->assertEquals($this->fakeHeadersAsArray, $headers); + $this->assertEquals(200, $httpResponseCode); + } + +} diff --git a/tests/Http/RequestBodyMultipartTest.php b/tests/Http/RequestBodyMultipartTest.php new file mode 100644 index 000000000..aca2d4473 --- /dev/null +++ b/tests/Http/RequestBodyMultipartTest.php @@ -0,0 +1,69 @@ + 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ], [], 'foo_boundary'); + $body = $message->getBody(); + + $expectedBody = "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"scawy_vawues\"\r\n\r\n@FooBar is a real twitter handle.\r\n"; + $expectedBody .= "--foo_boundary--\r\n"; + + $this->assertEquals($expectedBody, $body); + } + + public function testCanProperlyEncodeFilesAndParams() + { + $file = new FacebookFile(__DIR__ . '/../foo.txt'); + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + ], [ + 'foo_file' => $file, + ], 'foo_boundary'); + $body = $message->getBody(); + + $expectedBody = "--foo_boundary\r\n"; + $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 .= "--foo_boundary--\r\n"; + + $this->assertEquals($expectedBody, $body); + } + +} diff --git a/tests/Http/RequestUrlEncodedTest.php b/tests/Http/RequestUrlEncodedTest.php new file mode 100644 index 000000000..50f29bd0f --- /dev/null +++ b/tests/Http/RequestUrlEncodedTest.php @@ -0,0 +1,42 @@ + 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ]); + $body = $message->getBody(); + + $this->assertEquals('foo=bar&scawy_vawues=%40FooBar+is+a+real+twitter+handle.', $body); + } + +} diff --git a/tests/HttpClients/AbstractTestHttpClient.php b/tests/HttpClients/AbstractTestHttpClient.php index 98c6a7770..774a13e10 100644 --- a/tests/HttpClients/AbstractTestHttpClient.php +++ b/tests/HttpClients/AbstractTestHttpClient.php @@ -46,7 +46,6 @@ abstract class AbstractTestHttpClient extends \PHPUnit_Framework_TestCase Access-Control-Allow-Origin: *\r\n\r\n"; protected $fakeRawBody = "{\"id\":\"123\",\"name\":\"Foo Bar\"}"; protected $fakeHeadersAsArray = [ - 'http_code' => 'HTTP/1.1 200 OK', '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 4e725c9db..aa3c659cd 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -48,11 +48,6 @@ public function setUp() $this->curlClient = new FacebookCurlHttpClient($this->curlMock); } - public function tearDown() - { - (new FacebookCurlHttpClient()); // Resets the static dependency injection - } - public function testCanOpenGetCurlConnection() { $this->curlMock @@ -62,6 +57,8 @@ public function testCanOpenGetCurlConnection() $this->curlMock ->shouldReceive('setopt_array') ->with([ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_HTTPHEADER => ['X-Foo-Header: X-Bar'], CURLOPT_URL => 'http://foo.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, @@ -71,32 +68,10 @@ public function testCanOpenGetCurlConnection() ->once() ->andReturn(null); - $this->curlClient->openConnection('http://foo.com', 'GET', [], []); - } - - public function testCanOpenGetCurlConnectionWithHeaders() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->with([ - CURLOPT_URL => 'http://foo.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_HTTPHEADER => ['X-foo: bar'], - ]) - ->once() - ->andReturn(null); - - $this->curlClient->openConnection('http://foo.com', 'GET', [], ['X-foo' => 'bar']); + $this->curlClient->openConnection('http://foo.com', 'GET', 'foo_body', ['X-Foo-Header' => 'X-Bar']); } - public function testCanOpenPostCurlConnection() + public function testCanOpenCurlConnectionWithPostBody() { $this->curlMock ->shouldReceive('init') @@ -105,69 +80,19 @@ public function testCanOpenPostCurlConnection() $this->curlMock ->shouldReceive('setopt_array') ->with([ + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_HTTPHEADER => [], CURLOPT_URL => 'http://bar.com', CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, - CURLOPT_POSTFIELDS => [ - 'baz' => 'bar', - ], + CURLOPT_POSTFIELDS => 'baz=bar', ]) ->once() ->andReturn(null); - $this->curlClient->openConnection('http://bar.com', 'POST', ['baz' => 'bar'], []); - } - - public function testCanOpenPutCurlConnection() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->with([ - CURLOPT_URL => 'http://baz.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_CUSTOMREQUEST => 'PUT', - CURLOPT_POSTFIELDS => [ - 'baz' => 'bar', - ], - ]) - ->once() - ->andReturn(null); - - $this->curlClient->openConnection('http://baz.com', 'PUT', ['baz' => 'bar'], []); - } - - public function testCanOpenDeleteCurlConnection() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->with([ - CURLOPT_URL => 'http://faz.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_CUSTOMREQUEST => 'DELETE', - CURLOPT_POSTFIELDS => [ - 'baz' => 'bar', - ], - ]) - ->once() - ->andReturn(null); - - $this->curlClient->openConnection('http://faz.com', 'DELETE', ['baz' => 'bar'], []); + $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', []); } public function testCanAddBundledCert() @@ -205,26 +130,10 @@ public function testTrySendRequest() ->shouldReceive('error') ->once() ->andReturn(null); - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HTTP_CODE) - ->once() - ->andReturn(200); $this->curlClient->tryToSendRequest(); } - public function testProperlyCompilesRequestHeaders() - { - $headers = $this->curlClient->compileRequestHeaders([]); - $expectedHeaders = []; - $this->assertEquals($expectedHeaders, $headers); - - $headers = $this->curlClient->compileRequestHeaders(['X-foo' => 'bar']); - $expectedHeaders = ['X-foo: bar']; - $this->assertEquals($expectedHeaders, $headers); - } - public function testIsolatesTheHeaderAndBody() { $this->curlMock @@ -248,13 +157,6 @@ public function testIsolatesTheHeaderAndBody() $this->assertEquals($rawBody, $this->fakeRawBody); } - public function testConvertsRawHeadersToArray() - { - $headers = FacebookCurlHttpClient::headersToArray($this->fakeRawHeader); - - $this->assertEquals($headers, $this->fakeHeadersAsArray); - } - public function testProperlyHandlesProxyHeaders() { $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; @@ -277,10 +179,6 @@ public function testProperlyHandlesProxyHeaders() $this->assertEquals($rawHeaders, trim($rawHeader)); $this->assertEquals($rawBody, $this->fakeRawBody); - - $headers = FacebookCurlHttpClient::headersToArray($rawHeaders); - - $this->assertEquals($headers, $this->fakeHeadersAsArray); } public function testProperlyHandlesProxyHeadersWithCurlBug() @@ -305,38 +203,30 @@ public function testProperlyHandlesProxyHeadersWithCurlBug() $this->assertEquals($rawHeaders, trim($rawHeader)); $this->assertEquals($rawBody, $this->fakeRawBody); - - $headers = FacebookCurlHttpClient::headersToArray($rawHeaders); - - $this->assertEquals($headers, $this->fakeHeadersAsArray); } public function testProperlyHandlesProxyHeadersWithCurlBug2() { - $rawHeader = $this->fakeRawProxyHeader2 . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($rawHeader . $this->fakeRawBody); - - $this->curlClient->sendRequest(); - list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); - - $this->assertEquals($rawHeaders, trim($rawHeader)); - $this->assertEquals($rawBody, $this->fakeRawBody); - - $headers = FacebookCurlHttpClient::headersToArray($rawHeaders); - - $this->assertEquals($headers, $this->fakeHeadersAsArray); + $rawHeader = $this->fakeRawProxyHeader2 . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); } public function testProperlyHandlesRedirectHeaders() @@ -361,10 +251,6 @@ public function testProperlyHandlesRedirectHeaders() $this->assertEquals($rawHeaders, trim($rawHeader)); $this->assertEquals($rawBody, $this->fakeRawBody); - - $headers = FacebookCurlHttpClient::headersToArray($rawHeaders); - - $this->assertEquals($headers, $this->fakeHeadersAsArray); } public function testCanSendNormalRequest() @@ -389,11 +275,6 @@ public function testCanSendNormalRequest() ->shouldReceive('error') ->once() ->andReturn(null); - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HTTP_CODE) - ->once() - ->andReturn(200); $this->curlMock ->shouldReceive('getinfo') ->with(CURLINFO_HEADER_SIZE) @@ -408,11 +289,12 @@ public function testCanSendNormalRequest() ->once() ->andReturn(null); - $responseBody = $this->curlClient->send('http://foo.com/'); + $response = $this->curlClient->send('http://foo.com/', 'GET', '', []); - $this->assertEquals($responseBody, $this->fakeRawBody); - $this->assertEquals($this->curlClient->getResponseHeaders(), $this->fakeHeadersAsArray); - $this->assertEquals(200, $this->curlClient->getResponseHttpStatusCode()); + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); } /** @@ -440,13 +322,8 @@ public function testThrowsExceptionOnClientError() ->shouldReceive('error') ->once() ->andReturn('Foo error'); - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HTTP_CODE) - ->once() - ->andReturn(null); - $this->curlClient->send('http://foo.com/'); + $this->curlClient->send('http://foo.com/', 'GET', '', []); } } diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index 9ec3a6e8f..a614f043c 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -45,20 +45,8 @@ public function setUp() $this->guzzleClient = new FacebookGuzzleHttpClient($this->guzzleMock); } - public function tearDown() - { - (new FacebookGuzzleHttpClient()); // Resets the static dependency injection - } - public function testCanSendNormalRequest() { - $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); - $requestMock - ->shouldReceive('setHeader') - ->once() - ->with('X-foo', 'bar') - ->andReturn(null); - $responseMock = m::mock('GuzzleHttp\Message\ResponseInterface'); $responseMock ->shouldReceive('getStatusCode') @@ -73,10 +61,16 @@ public function testCanSendNormalRequest() ->once() ->andReturn($this->fakeRawBody); + $options = [ + 'headers' => ['X-foo' => 'bar'], + 'body' => 'foo_body', + ]; + + $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', []) + ->with('GET', 'http://foo.com/', $options) ->andReturn($requestMock); $this->guzzleMock ->shouldReceive('send') @@ -84,11 +78,12 @@ public function testCanSendNormalRequest() ->with($requestMock) ->andReturn($responseMock); - $responseBody = $this->guzzleClient->send('http://foo.com/', 'GET', [], ['X-foo' => 'bar']); + $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar']); - $this->assertEquals($responseBody, $this->fakeRawBody); - $this->assertEquals($this->guzzleClient->getResponseHeaders(), $this->fakeHeadersAsArray); - $this->assertEquals(200, $this->guzzleClient->getResponseHttpStatusCode()); + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); } /** @@ -103,13 +98,18 @@ public function testThrowsExceptionOnClientError() 'Foo Error', $requestMock, null, - m::mock('GuzzleHttp\Exception\AdapterException'), + m::mock('GuzzleHttp\Ring\Exception\RingException'), ]); + $options = [ + 'headers' => [], + 'body' => 'foo_body', + ]; + $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', []) + ->with('GET', 'http://foo.com/', $options) ->andReturn($requestMock); $this->guzzleMock ->shouldReceive('send') @@ -117,7 +117,7 @@ public function testThrowsExceptionOnClientError() ->with($requestMock) ->andThrow($exceptionMock); - $this->guzzleClient->send('http://foo.com/'); + $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', []); } } diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index 9b979e58b..e9b0ba969 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -45,11 +45,6 @@ public function setUp() $this->streamClient = new FacebookStreamHttpClient($this->streamMock); } - public function tearDown() - { - (new FacebookStreamHttpClient()); // Resets the static dependency injection - } - public function testCanCompileHeader() { $headers = [ @@ -60,19 +55,6 @@ public function testCanCompileHeader() $this->assertEquals("X-foo: bar\r\nX-bar: faz", $header); } - public function testCanFormatHeadersToArray() - { - $raw_header_array = explode("\n", trim($this->fakeRawHeader)); - $header_array = FacebookStreamHttpClient::formatHeadersToArray($raw_header_array); - $this->assertEquals($this->fakeHeadersAsArray, $header_array); - } - - public function testCanGetHttpStatusCodeFromResponseHeader() - { - $http_code = FacebookStreamHttpClient::getStatusCodeFromHeader('HTTP/1.1 123 Foo Response'); - $this->assertEquals('123', $http_code); - } - public function testCanSendNormalRequest() { $this->streamMock @@ -85,9 +67,10 @@ public function testCanSendNormalRequest() if ($arg['http'] !== [ 'method' => 'GET', + 'header' => 'X-foo: bar', + 'content' => 'foo_body', 'timeout' => 60, 'ignore_errors' => true, - 'header' => 'X-foo: bar', ]) { return false; } @@ -113,11 +96,12 @@ public function testCanSendNormalRequest() ->with('http://foo.com/') ->andReturn($this->fakeRawBody); - $responseBody = $this->streamClient->send('http://foo.com/', 'GET', [], ['X-foo' => 'bar']); + $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar']); - $this->assertEquals($responseBody, $this->fakeRawBody); - $this->assertEquals($this->streamClient->getResponseHeaders(), $this->fakeHeadersAsArray); - $this->assertEquals(200, $this->streamClient->getResponseHttpStatusCode()); + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); } /** @@ -139,7 +123,7 @@ public function testThrowsExceptionOnClientError() ->with('http://foo.com/') ->andReturn(false); - $this->streamClient->send('http://foo.com/'); + $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', []); } } diff --git a/tests/Url/FacebookUrlManipulatorTest.php b/tests/Url/FacebookUrlManipulatorTest.php index b540d60b7..3729cb6a0 100644 --- a/tests/Url/FacebookUrlManipulatorTest.php +++ b/tests/Url/FacebookUrlManipulatorTest.php @@ -91,4 +91,129 @@ public function provideUris() ]; } + public function testGracefullyHandlesUrlAppending() + { + $params = []; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + + $params = [ + 'access_token' => 'foo', + 'bar' => 'baz', + ]; + $url = 'https://www.foo.com/?foo=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/?foo=bar&access_token=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + } + + public function testSlashesAreProperlyPrepended() + { + $slashTestOne = FacebookUrlManipulator::forceSlashPrefix('foo'); + $slashTestTwo = FacebookUrlManipulator::forceSlashPrefix('/foo'); + $slashTestThree = FacebookUrlManipulator::forceSlashPrefix('foo/bar'); + $slashTestFour = FacebookUrlManipulator::forceSlashPrefix('/foo/bar'); + $slashTestFive = FacebookUrlManipulator::forceSlashPrefix(null); + $slashTestSix = FacebookUrlManipulator::forceSlashPrefix(''); + + $this->assertEquals('/foo', $slashTestOne); + $this->assertEquals('/foo', $slashTestTwo); + $this->assertEquals('/foo/bar', $slashTestThree); + $this->assertEquals('/foo/bar', $slashTestFour); + $this->assertEquals(null, $slashTestFive); + $this->assertEquals('', $slashTestSix); + } + + public function testParamsCanBeReturnedAsArray() + { + $paramsOne = FacebookUrlManipulator::getParamsAsArray('/foo'); + $paramsTwo = FacebookUrlManipulator::getParamsAsArray('/foo?one=1&two=2'); + $paramsThree = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com'); + $paramsFour = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?'); + $paramsFive = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?foo=bar'); + + $this->assertEquals([], $paramsOne); + $this->assertEquals(['one' => '1', 'two' => '2'], $paramsTwo); + $this->assertEquals([], $paramsThree); + $this->assertEquals([], $paramsFour); + $this->assertEquals(['foo' => 'bar'], $paramsFive); + } + + /** + * @dataProvider provideMergableEndpoints + */ + public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) + { + $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); + + $this->assertEquals($result, $expected); + } + + public function provideMergableEndpoints() + { + return [ + [ + 'https://www.foo.com/?foo=ignore_foo&dance=fun', + '/me?foo=keep_foo', + '/me?dance=fun&foo=keep_foo', + ], + [ + 'https://www.bar.com?', + 'https://foo.com?foo=bar', + 'https://foo.com?foo=bar', + ], + [ + 'you', + 'me', + 'me', + ], + [ + '/1234?swing=fun', + '/1337?bar=baz&west=coast', + '/1337?bar=baz&swing=fun&west=coast', + ], + ]; + } + + public function testGraphUrlsCanBeTrimmed() + { + $fullGraphUrl = 'https://graph.facebook.com/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v1.0/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.beta.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://whatever-they-want.facebook.com/v2.1/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v5.301/1233?foo=bar'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/1233?foo=bar', $baseGraphUrl); + } + } diff --git a/tests/foo.txt b/tests/foo.txt new file mode 100644 index 000000000..fa6541b27 --- /dev/null +++ b/tests/foo.txt @@ -0,0 +1 @@ +This is a text file used for testing. Let's dance. \ No newline at end of file From cd845f3c014c36517055c3f72a087594d7460aee Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 20 Nov 2014 13:01:59 -0600 Subject: [PATCH 067/407] Fixed bug with not filtering state from callback URL --- .../Helpers/FacebookRedirectLoginHelper.php | 111 +++++++++++++----- 1 file changed, 81 insertions(+), 30 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 5f0a0d8be..e6f1219ec 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -119,11 +119,12 @@ public function getLoginUrl($redirectUrl, { $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; $state = $this->generateState(); - $this->storeState($state); + $this->persistentDataHandler->set('state', $state); $params = [ 'client_id' => $this->app->getId(), 'redirect_uri' => $redirectUrl, 'state' => $state, + 'response_type' => 'code', 'sdk' => 'php-sdk-' . Facebook::VERSION, 'scope' => implode(',', $scope) ]; @@ -167,24 +168,40 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') */ public function getAccessToken(FacebookClient $client, $redirectUrl = null) { - if ($this->isValidRedirect()) { - $code = $this->getCode(); - $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); - - return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); + $this->validateCsrf(); + if ( ! $code = $this->getCode()) { + return null; } - return null; + + $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); + // At minimum we need to remove the state param + $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']); + + return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); } /** - * Check if a redirect has a valid state. + * Validate the request against a cross-site request forgery. * - * @return bool + * @throws FacebookSDKException */ - protected function isValidRedirect() + protected function validateCsrf() { - return $this->getCode() && isset($_GET['state']) - && $_GET['state'] == $this->loadState(); + $state = $this->getState(); + $savedState = $this->persistentDataHandler->get('state'); + + if ( ! $state || ! $savedState) { + throw new FacebookSDKException( + 'Cross-site request forgery validation failed. ' . + 'Required param "state" missing.' + ); + } + if ($state !== $savedState) { + throw new FacebookSDKException( + 'Cross-site request forgery validation failed. ' . + 'The "state" param from the URL and session do not match.' + ); + } } /** @@ -194,45 +211,79 @@ protected function isValidRedirect() */ protected function getCode() { - return isset($_GET['code']) ? $_GET['code'] : null; + return $this->getInput('code'); } /** - * Generate a state string for CSRF protection. + * Return the state. * - * @return string + * @return string|null */ - protected function generateState() + protected function getState() { - return $this->random(16); + return $this->getInput('state'); } /** - * Stores a state string in session storage for CSRF protection. - * Developers should subclass and override this method if they want to store - * this state in a different location. + * Return the error code. * - * @param string $state + * @return string|null + */ + public function getErrorCode() + { + return $this->getInput('error_code'); + } + + /** + * Returns the error. * - * @throws FacebookSDKException + * @return string|null */ - protected function storeState($state) + public function getError() { - $this->persistentDataHandler->set('state', $state); + return $this->getInput('error'); } /** - * Loads a state string from session storage for CSRF validation. May return - * null if no object exists. Developers should subclass and override this - * method if they want to load the state from a different location. + * Returns the error reason. * * @return string|null + */ + public function getErrorReason() + { + return $this->getInput('error_reason'); + } + + /** + * Returns the error description. * - * @throws FacebookSDKException + * @return string|null */ - protected function loadState() + public function getErrorDescription() { - return $this->persistentDataHandler->get('state'); + return $this->getInput('error_description'); + } + + /** + * Returns a value from a GET param. + * + * @param string $key + * + * @return string|null + */ + private function getInput($key) + { + return isset($_GET[$key]) ? $_GET[$key] : null; + } + + /** + * Generate a state string for CSRF protection. + * + * @return string + */ + protected function generateState() + { + return $this->random(16); } /** From 6e47dbde91079dd98fa070014b2e496ba772ab18 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 9 Nov 2014 01:52:49 -0600 Subject: [PATCH 068/407] Added pagination and deep pagination support --- docs/Facebook.fbmd | 53 +++ docs/GraphList.fbmd | 71 ++++ docs/GraphObject.fbmd | 75 ++-- docs/sdk_reference.fbmd | 16 +- src/Facebook/Entities/AccessToken.php | 7 +- .../Entities/FacebookBatchRequest.php | 51 ++- .../Entities/FacebookBatchResponse.php | 88 ++++- src/Facebook/Entities/FacebookRequest.php | 131 ++++--- src/Facebook/Entities/FacebookResponse.php | 44 +-- src/Facebook/Facebook.php | 76 ++++- src/Facebook/FacebookClient.php | 9 +- src/Facebook/GraphNodes/GraphList.php | 147 +++++++- .../GraphNodes/GraphObjectFactory.php | 61 +++- src/Facebook/Url/FacebookUrlManipulator.php | 101 +++++- tests/Entities/FacebookBatchRequestTest.php | 11 +- tests/Entities/FacebookBatchResponseTest.php | 92 +++-- tests/Entities/FacebookRequestTest.php | 78 ++--- tests/Entities/FacebookResponseTest.php | 37 +- tests/FacebookClientTest.php | 18 - tests/FacebookTest.php | 39 ++- tests/GraphNodes/GraphListTest.php | 117 +++++++ tests/GraphNodes/GraphObjectFactoryTest.php | 319 +++++++++--------- tests/Url/FacebookUrlManipulatorTest.php | 125 +++++++ 23 files changed, 1339 insertions(+), 427 deletions(-) create mode 100644 docs/GraphList.fbmd create mode 100644 tests/GraphNodes/GraphListTest.php diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 9981b1320..3ed3a4ff0 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -150,6 +150,14 @@ public FacebookClient getClient() Returns the instance of `Facebook\FacebookClient` for the instantiated service. + +### getLastResponse() {#get-last-response} +~~~~ +public Facebook\Entities\FacebookResponse|Facebook\Entities\FacebookBatchResponse|null getLastResponse() +~~~~ +Returns the last response received from the Graph API in the form of a `Facebook\Entities\FacebookResponse` or `Facebook\Entities\FacebookBatchResponse`. + + ### getDefaultAccessToken() {#get-default-access-token} ~~~~ @@ -306,3 +314,48 @@ Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRed $helper = $fb->getRedirectLoginHelper(); ~~~~ + + +### next() {#next} +~~~~ +public Facebook\GraphNodes\GraphList|null next(Facebook\GraphNodes\GraphList $graphList) +~~~~ + +Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) object. If the next page returns no results, `null` will be returned. + +~~~~ +// Iterate over 5 pages max +$maxPages = 5; + +// Get a list of photo objects +$response = $fb->get('/me/photos?fields=id,source,likes&limit=5'); + +$photosList = $response->getGraphList(); + +if (count($photosList) > 0) { + $pageCount = 0; + do { + foreach ($photosList as $photo) { + var_dump($photo->asArray()); + + // Deep pagination is supported on child GraphList's + $likes = $photo['likes']; + do { + echo '

Likes:

' . "\n\n"; + var_dump($likes->asArray()); + } while ($likes = $fqb->next($likes)); + } + $pageCount++; + } while ($pageCount < $maxPages && $photosList = $fb->next($photosList)); +} +~~~~ +
+ + +### previous() {#previous} +~~~~ +public Facebook\GraphNodes\GraphList|null previous(Facebook\GraphNodes\GraphList $graphList) +~~~~ + +Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` object. Functions just like `next()` above, but in the opposite direction of pagination. + diff --git a/docs/GraphList.fbmd b/docs/GraphList.fbmd new file mode 100644 index 000000000..7ad738df6 --- /dev/null +++ b/docs/GraphList.fbmd @@ -0,0 +1,71 @@ + +# GraphList for the Facebook SDK for PHP + +When a list of nodes is returned from a Graph request, it can be cast as a `GraphList` which provides convenient ways of interacting with the data which includes pagination. + + + +## Facebook\GraphNodes\GraphList {#overview} + +You can grab a `GraphList` from a response from Graph. + +~~~~ +$graphList = $request->getGraphList(); +~~~~ + +Usage: + +~~~~ +// Iterate over all the GraphObject in the list +foreach ($graphList as $graphObject) { + // . . . +} +~~~~ + + + +## Pagination {#pagination} + +With the help of the `Facebook\Facebook` super service class, the `GraphList` collection can grab the next and previous sets of data. + +~~~~ +$listOfAlbums = $response->getGraphList(); + +// Get the next page of results +$nextPageOfAlbums = $fb->next($listOfAlbums); +// 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 {#deep-pagination} + +Sometimes Graph will return a list of nodes within a node. Paginating on these sub lists can be non-trivial. Fortunately, the `GraphList` collection takes the guesswork out and allows you to paginate deeply within a `GraphList`. + +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. + +~~~~ +$listOfPages = $response->getGraphList(); +// Only grab 5 pages +$maxPages = 5; +$pageCount = 0; + +do { + echo '

Page #' . $page_count . ':

' . "\n\n"; + + foreach ($listOfPages 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 && $listOfPages = $fb->next($listOfPages)); +~~~~ +
diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd index 99517b895..2829d0ff9 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphObject.fbmd @@ -1,17 +1,19 @@ # GraphObject for the Facebook SDK for PHP -Represents an object returned by the Graph API. +A `GraphObject` is a collection that represents a node returned by the Graph API. ## Facebook\GraphObject {#overview} -This base class has several subclasses, some are provided by default: +This base class has several subclasses: -[__GraphUser__](#user-instance-methods) -[__GraphLocation__](#location-instance-methods) +[__GraphUser__](#user-instance-methods) +[__GraphPage__](#page-instance-methods) +[__GraphAlbum__](#album-instance-methods) +[__GraphLocation__](#location-instance-methods) [__GraphSessionInfo__](#sessioninfo-instance-methods) Usage: @@ -21,14 +23,10 @@ Usage: $object = $response->getGraphObject(); // Get the response typed as a GraphUser -$user = $response->getGraphObject(GraphUser::className()); -// or convert the base object previously accessed -// $user = $object->cast(GraphUser::className()); +$user = $response->getGraphUser()); -// Get the response typed as a GraphLocation -$loc = $response->getGraphObject(GraphLocation::className()); -// or convert the base object previously accessed -// $loc = $object->cast(GraphLocation::className()); +// Get the response typed as a GraphPage +$page = $response->getGraphPage(); // User example echo $object->getProperty('name'); @@ -40,7 +38,31 @@ echo $loc->getCountry(); // SessionInfo example $info = $session->getSessionInfo()); -echo $info->getxpiresAt(); +echo $info->getExpiresAt(); +~~~~ + + + + +## SPL Libraries {#spl} + +The `GraphObject` 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 `GraphObject`. + +~~~~ +$graphObject = $response->getGraphObject(); + +// Array access +$id = $graphObject['id']; + +// Iteration +foreach ($graphObject as $key => $value) { + // . . . +} + +// Counting +$total = count($graphObject); ~~~~ @@ -48,25 +70,32 @@ echo $info->getxpiresAt(); ## GraphObject Instance Methods {#instance-methods} -### cast {#cast} -`cast(string $type)` -Returns a new instance of a GraphObject subclass with this objects underlying data. -### asArray {#asarray} +### asArray {#as-array} `asArray()` Returns the raw representation (associative arrays, nested) of this objects underlying data. -### getProperty {#getproperty} -`getProperty(string $name, string $type = 'Facebook\GraphObject')` -Gets the value of a named key for this graph object. 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 GraphObject cast to the appropriate subclass type if provided. -### getPropertyAsArray {#getproparray} -`getPropertyAsArray()` -Gets the contents of a named array property on this graph object. If the values are scalar (strings, numbers, etc.) they will be returned as-is. If the values are associative arrays, they will be returned as GraphObjects cast to the appropriate subclass type if provided. +### asJson {#as-json} +`asJson()` +Returns the data as a JSON string. + + +### getProperty {#get-property} +`getProperty(string $name, string $default = 'foo')` +Gets the value of a named key for this graph object. 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 GraphObject. -### getPropertyNames +The second argument lets you define a default value to return if the property doesn't exist. + + +### getPropertyNames {#get-property-names} `getPropertyNames()` Returns an array with the names of all properties present on this graph object. + + +### map {#map} +`map(Closure $callback)` +Provides a way to map over the data within the collection just like `array_map()`. diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 13f27b7f8..0f6d74643 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -116,6 +116,14 @@ Graph nodes are collections that represent nodes returned by Graph. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ + [ + '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', + 'The base collection object that represents a generic node.', + ], + [ + '`[Facebook\GraphNodes\GraphList](/docs/php/GraphList)`', + 'A list of GraphObject's with special methods to help paginate over the list.', + ], [ '`[Facebook\GraphNodes\GraphAlbum](/docs/php/GraphAlbum)`', 'A collection that represents an album node.', @@ -124,10 +132,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\GraphNodes\GraphLocation](/docs/php/GraphLocation)`', 'A collection that represents a location node.', ], - [ - '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', - 'The base collection object that represents a generic node.', - ], [ '`[Facebook\GraphNodes\GraphPage](/docs/php/GraphPage)`', 'A collection that represents a page node.', @@ -140,10 +144,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\GraphNodes\GraphUser](/docs/php/GraphUser)`', 'A collection that represents a user node.', ], - [ - '`[Facebook\GraphNodes\GraphUserPage](/docs/php/GraphUserPage)`', - '*(Deprecated)* A collection that represents a user page node.', - ], ], }) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index 2785ed38d..ea4eeb607 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -343,9 +343,12 @@ protected static function request($endpoint, array $params, FacebookApp $app, Fa $app, $app->getAccessToken(), 'GET', - $endpoint, - $params + $endpoint ); + // We know what we're doing here. + // We want to send the access token as a param. + $request->dangerouslySetParams($params); + return $client->sendRequest($request); } diff --git a/src/Facebook/Entities/FacebookBatchRequest.php b/src/Facebook/Entities/FacebookBatchRequest.php index fc2aee2a5..92941a9e5 100755 --- a/src/Facebook/Entities/FacebookBatchRequest.php +++ b/src/Facebook/Entities/FacebookBatchRequest.php @@ -23,13 +23,16 @@ */ namespace Facebook\Entities; +use ArrayIterator; +use IteratorAggregate; +use ArrayAccess; use Facebook\Exceptions\FacebookSDKException; /** * Class BatchRequest * @package Facebook */ -class FacebookBatchRequest extends FacebookRequest +class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, ArrayAccess { /** @@ -41,14 +44,14 @@ class FacebookBatchRequest extends FacebookRequest * Creates a new Request entity. * * @param FacebookApp|null $app - * @param AccessToken|string|null $accessToken * @param array $requests + * @param AccessToken|string|null $accessToken * @param string|null $graphVersion */ public function __construct( FacebookApp $app = null, - $accessToken = null, array $requests = [], + $accessToken = null, $graphVersion = null ) { @@ -216,4 +219,46 @@ public static function requestEntityToBatchArray(FacebookRequest $request, $requ return $batch; } + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->requests); + } + + /** + * @return @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->add($value, $offset); + } + + /** + * @return @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->requests[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->requests[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->requests[$offset]) ? $this->requests[$offset] : null; + } + } diff --git a/src/Facebook/Entities/FacebookBatchResponse.php b/src/Facebook/Entities/FacebookBatchResponse.php index e13d56749..0db515970 100755 --- a/src/Facebook/Entities/FacebookBatchResponse.php +++ b/src/Facebook/Entities/FacebookBatchResponse.php @@ -25,14 +25,20 @@ use ArrayIterator; use IteratorAggregate; +use ArrayAccess; /** * Class BatchResponse * @package Facebook */ -class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate +class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate, ArrayAccess { + /** + * @var FacebookBatchRequest The original entity that made the batch request. + */ + protected $batchRequest; + /** * @var array An array of FacebookResponse entities. */ @@ -41,18 +47,21 @@ class FacebookBatchResponse extends FacebookResponse implements IteratorAggregat /** * Creates a new Response entity. * + * @param FacebookBatchRequest $batchRequest * @param FacebookResponse $response */ public function __construct( + FacebookBatchRequest $batchRequest, FacebookResponse $response ) { - $app = $response->getApp(); + $this->batchRequest = $batchRequest; + + $request = $response->getRequest(); + $body = $response->getBody(); $httpStatusCode = $response->getHttpStatusCode(); $headers = $response->getHeaders(); - $body = $response->getBody(); - $accessToken = $response->getAccessToken(); - parent::__construct($app, $httpStatusCode, $headers, $body, $accessToken); + parent::__construct($request, $body, $httpStatusCode, $headers); $responses = $response->getDecodedBody(); $this->setResponses($responses); @@ -77,24 +86,75 @@ public function getResponses() public function setResponses(array $responses) { $this->responses = []; - foreach ($responses as $graphResponse) { - $httpResponseCode = isset($graphResponse['code']) ? $graphResponse['code'] : null; - $httpResponseHeaders = isset($graphResponse['headers']) ? $graphResponse['headers'] : []; - $httpResponseBody = isset($graphResponse['body']) ? $graphResponse['body'] : null; - // @TODO Figure out an elegant way to get the access token that was used with this response. - $accessToken = null; - $this->responses[] = new FacebookResponse($this->app, $httpResponseCode, $httpResponseHeaders, $httpResponseBody, $accessToken); + foreach ($responses as $key => $graphResponse) { + $this->addResponse($key, $graphResponse); } } /** - * Get an iterator for the items. + * Add a response to the list. * - * @return ArrayIterator + * @param int $key + * @param array|null $response + */ + public function addResponse($key, $response) + { + $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; + $httpResponseHeaders = isset($response['headers']) ? $response['headers'] : []; + + $this->responses[$originalRequestName] = new FacebookResponse( + $originalRequest, + $httpResponseBody, + $httpResponseCode, + $httpResponseHeaders); + } + + /** + * @return @inheritdoc */ public function getIterator() { return new ArrayIterator($this->responses); } + /** + * @return @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->addResponse($offset, $value); + } + + /** + * @return @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->responses[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->responses[$offset]); + } + + /** + * @return @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->responses[$offset]) ? $this->responses[$offset] : null; + } + } diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 558502ea4..7cac7d9ae 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -24,6 +24,7 @@ namespace Facebook\Entities; use Facebook\Facebook; +use Facebook\Url\FacebookUrlManipulator; use Facebook\Exceptions\FacebookSDKException; /** @@ -113,6 +114,30 @@ public function setAccessToken($accessToken) return $this; } + /** + * Sets the access token with one harvested from a URL or POST params. + * + * @param string $accessToken The access token. + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setAccessTokenFromParams($accessToken) + { + $existingAccessToken = $this->getAccessToken(); + if ( ! $existingAccessToken) { + $this->setAccessToken($accessToken); + } elseif ($accessToken !== $existingAccessToken) { + throw new FacebookSDKException( + 'Access token mismatch. The access token provided in the FacebookRequest ' . + 'and the one provided in the URL or POST params do not match.' + ); + } + + return $this; + } + /** * Return the access token for this request. * @@ -143,6 +168,16 @@ public function getApp() return $this->app; } + /** + * Generate an app secret proof to sign this request. + * + * @return string + */ + public function getAppSecretProof() + { + return AppSecretProof::make($this->getAccessToken(), $this->app->getSecret()); + } + /** * Validate that an access token exists for this request. * @@ -210,10 +245,21 @@ public function validateMethod() * @param string * * @return FacebookRequest + * + * @throws FacebookSDKException */ public function setEndpoint($endpoint) { - $this->endpoint = $endpoint; + // Harvest the access token from the endpoint to keep things in sync + $params = FacebookUrlManipulator::getParamsAsArray($endpoint); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Clean the token & app secret proof from the endpoint. + $filterParams = ['access_token', 'appsecret_proof']; + $this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams); + return $this; } @@ -260,12 +306,34 @@ public function setETag($eTag) * @param array $params * * @return FacebookRequest + * + * @throws FacebookSDKException */ public function setParams(array $params = []) { - if (is_array($params)) { - $this->params = array_merge($this->params, $params); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); } + + // Don't let these buggers slip in. + unset($params['access_token'], $params['appsecret_proof']); + + $this->dangerouslySetParams($params); + + return $this; + } + + /** + * Set the params for this request without filtering them first. + * + * @param array $params + * + * @return FacebookRequest + */ + public function dangerouslySetParams(array $params = []) + { + $this->params = array_merge($this->params, $params); + return $this; } @@ -278,11 +346,10 @@ public function getParams() { $params = $this->params; - if (!isset($params['access_token']) && $this->getAccessToken()) { - $params['access_token'] = $this->getAccessToken(); - } - if (!isset($params['appsecret_proof']) && isset($params['access_token'])) { - $params['appsecret_proof'] = AppSecretProof::make($params['access_token'], $this->app->getSecret()); + $accessToken = $this->getAccessToken(); + if ($accessToken) { + $params['access_token'] = $accessToken; + $params['appsecret_proof'] = $this->getAppSecretProof(); } return $params; @@ -321,61 +388,19 @@ public function getUrl() { $this->validateMethod(); - $graphVersion = static::forceSlashPrefix($this->graphVersion); - $endpoint = static::forceSlashPrefix($this->getEndpoint()); + $graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion); + $endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint()); $url = $graphVersion.$endpoint; if ($this->getMethod() !== 'POST') { $params = $this->getParams(); - $url = static::appendParamsToUrl($url, $params); + $url = FacebookUrlManipulator::appendParamsToUrl($url, $params); } return $url; } - /** - * Gracefully appends params to the URL. - * - * @param string $url - * @param array $params - * - * @return string - */ - public static function appendParamsToUrl($url, $params = []) - { - if (!$params) { - return $url; - } - - if (strpos($url, '?') === false) { - return $url . '?' . http_build_query($params, null, '&'); - } - - list($path, $query_string) = explode('?', $url, 2); - parse_str($query_string, $query_array); - - // Favor params from the original URL over $params - $params = array_merge($params, $query_array); - - return $path . '?' . http_build_query($params, null, '&'); - } - - /** - * Check for a "/" prefix and prepend it if not exists. - * - * @param string|null $string - * - * @return string|null - */ - public static function forceSlashPrefix($string) - { - if (!$string) { - return $string; - } - return strpos($string, '/') === 0 ? $string : '/'.$string; - } - /** * Return the default headers that every request should use. * diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index cfae8aa35..55a1e9bab 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -28,7 +28,7 @@ use Facebook\Exceptions\FacebookSDKException; /** - * Class Response + * Class FacebookResponse * @package Facebook */ class FacebookResponse @@ -55,14 +55,9 @@ class FacebookResponse protected $decodedBody = []; /** - * @var string The access token that was used. + * @var FacebookRequest The original request that returned this response. */ - protected $accessToken; - - /** - * @var FacebookApp The facebook app entity. - */ - protected $app; + protected $request; /** * @var FacebookSDKException The exception thrown by this request. @@ -72,29 +67,36 @@ class FacebookResponse /** * Creates a new Response entity. * - * @param FacebookApp $app + * @param FacebookRequest $request + * @param string|null $body * @param int|null $httpStatusCode * @param array|null $headers - * @param string|null $body - * @param string|null $accessToken */ public function __construct( - FacebookApp $app, - $httpStatusCode = null, - array $headers = [], + FacebookRequest $request, $body = null, - $accessToken = null + $httpStatusCode = null, + array $headers = [] ) { - $this->app = $app; + $this->request = $request; + $this->body = $body; $this->httpStatusCode = $httpStatusCode; $this->headers = $headers; - $this->body = $body; - $this->accessToken = $accessToken; $this->decodeBody(); } + /** + * Return the original request that returned this response. + * + * @return FacebookRequest + */ + public function getRequest() + { + return $this->request; + } + /** * Return the FacebookApp entity used for this response. * @@ -102,7 +104,7 @@ public function __construct( */ public function getApp() { - return $this->app; + return $this->request->getApp(); } /** @@ -112,7 +114,7 @@ public function getApp() */ public function getAccessToken() { - return $this->accessToken; + return $this->request->getAccessToken(); } /** @@ -162,7 +164,7 @@ public function getDecodedBody() */ public function getAppSecretProof() { - return AppSecretProof::make($this->accessToken, $this->app->getSecret()); + return $this->request->getAppSecretProof(); } /** diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index e634956a8..c75dc80fd 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -29,6 +29,7 @@ use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookResponse; use Facebook\Entities\FacebookBatchResponse; +use Facebook\GraphNodes\GraphList; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\HttpClients\FacebookHttpClientInterface; @@ -102,6 +103,11 @@ class Facebook */ protected $persistentDataHandler; + /** + * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. + */ + protected $lastResponse; + /** * @TODO Add FacebookInputInterface * @TODO Add FacebookRandomGeneratorInterface @@ -221,6 +227,16 @@ public function getClient() return $this->client; } + /** + * Returns the last response returned from Graph. + * + * @return FacebookResponse|FacebookBatchResponse|null + */ + public function getLastResponse() + { + return $this->lastResponse; + } + /** * Returns the URL detection handler. * @@ -352,6 +368,60 @@ public function delete( $graphVersion); } + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function next(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'next'); + } + + /** + * Sends a request to Graph for the previous page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function previous(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'previous'); + } + + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * @param string $direction The direction of the pagination: next|previous. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function getPaginationResults(GraphList $graphList, $direction) + { + $paginationRequest = $graphList->getPaginationRequest($direction); + if ( ! $paginationRequest) { + return null; + } + + $this->lastResponse = $this->client->sendRequest($paginationRequest); + + // Keep the same GraphObject subclass + $subClassName = $graphList->getSubClassName(); + $graphList = $this->lastResponse->getGraphList($subClassName, false); + + return count($graphList) > 0 ? $graphList : null; + } + /** * Sends a request to Graph and returns the result. * @@ -377,7 +447,7 @@ public function sendRequest( $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); - return $this->client->sendRequest($request); + return $this->lastResponse = $this->client->sendRequest($request); } /** @@ -400,12 +470,12 @@ public function sendBatchRequest( $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $batchRequest = new FacebookBatchRequest( $this->app, - $accessToken, $requests, + $accessToken, $graphVersion ); - return $this->client->sendBatchRequest($batchRequest); + return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); } /** diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index f5ccdc793..c90ac5a88 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -152,17 +152,14 @@ public function sendRequest(FacebookRequest $request) // Should throw `FacebookSDKException` exception on HTTP client error. // Don't catch to allow it to bubble up. - $response = $this->httpClientHandler->send($url, $method, $params, $headers); + $responseBody = $this->httpClientHandler->send($url, $method, $params, $headers); static::$requestCount++; $httpResponseCode = $this->httpClientHandler->getResponseHttpStatusCode(); $httpResponseHeaders = $this->httpClientHandler->getResponseHeaders(); - $accessToken = $request->getAccessToken(); - $app = $request->getApp(); - - $returnResponse = new FacebookResponse($app, $httpResponseCode, $httpResponseHeaders, $response, $accessToken); + $returnResponse = new FacebookResponse($request, $responseBody, $httpResponseCode, $httpResponseHeaders); if ($returnResponse->isError()) { throw $returnResponse->getThrownException(); @@ -185,7 +182,7 @@ public function sendBatchRequest(FacebookBatchRequest $request) $request->prepareRequestsForBatch(); $facebookResponse = $this->sendRequest($request); - return new FacebookBatchResponse($facebookResponse); + return new FacebookBatchResponse($request, $facebookResponse); } } diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 743138e4f..142b1c80f 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -23,6 +23,10 @@ */ namespace Facebook\GraphNodes; +use Facebook\Entities\FacebookRequest; +use Facebook\Url\FacebookUrlManipulator; +use Facebook\Exceptions\FacebookSDKException; + /** * Class GraphList * @package Facebook @@ -31,39 +35,166 @@ class GraphList extends Collection { /** - * @var array $metaData An array of Graph meta data like pagination, etc. + * @var FacebookRequest The original request that generated this data. + */ + protected $request; + + /** + * @var array An array of Graph meta data like pagination, etc. */ protected $metaData = []; + /** + * @var string|null The parent Graph edge endpoint that generated the list. + */ + protected $parentEdgeEndpoint; + + /** + * @var string|null The subclass of the child GraphObject's. + */ + protected $subclassName; + /** * Init this collection of GraphObject's. * + * @param FacebookRequest $request The original request that generated this data. * @param array $data An array of GraphObject's. * @param array $metaData An array of Graph meta data like pagination, etc. + * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. + * @param string|null $subclassName The subclass of the child GraphObject's. */ - public function __construct(array $data = [], array $metaData = []) + public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) { + $this->request = $request; $this->metaData = $metaData; + $this->parentEdgeEndpoint = $parentEdgeEndpoint; + $this->subclassName = $subclassName; parent::__construct($data); } /** - * Get the next page of results of this list of Graph objects. + * Gets the parent Graph edge endpoint that generated the list. + * + * @return string|null + */ + public function getParentGraphEdge() + { + return $this->parentEdgeEndpoint; + } + + /** + * Gets the subclass name that the child GraphObject's are cast as. + * + * @return string|null + */ + public function getSubClassName() + { + return $this->subclassName; + } + + /** + * Generates a pagination URL based on a cursor. + * + * @param string $direction The direction of the page: next|previous + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function getPaginationUrl($direction) + { + $this->validateForPagination(); + + // Do we have a paging URL? + if (isset($this->metaData['paging'][$direction])) { + // Graph returns the full URL with all the original params. + // We just want the endpoint though. + $pageUrl = $this->metaData['paging'][$direction]; + return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); + } + + // Do we have a cursor to work with? + $cursorDirection = $direction === 'next' ? 'after' : 'before'; + if ( ! isset($this->metaData['paging']['cursors'][$cursorDirection])) { + return null; + } + + // If we don't know the ID of the parent node, this ain't gonna work. + if ( ! $this->parentEdgeEndpoint) { + return null; + } + + // We have the parent node ID, paging cursor & original request. + // These were the ingredients chosen to create the perfect little URL. + $cursor = $this->metaData['paging']['cursors'][$cursorDirection]; + + $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); + + // Pull in the original params + $originalUrl = $this->request->getUrl(); + $pageUrl = FacebookUrlManipulator::mergeUrlParams($originalUrl, $pageUrl); + + return FacebookUrlManipulator::forceSlashPrefix($pageUrl); + } + + /** + * Validates whether or not we can paginate on this request. * - * @TODO + * @throws FacebookSDKException */ - public function next() + public function validateForPagination() { + if ($this->request->getMethod() !== 'GET') { + throw new FacebookSDKException( + 'You can only paginate on a GET request.', 720 + ); + } } /** - * Get the previous page of results of this list of Graph objects. + * Gets the request object needed to make a next|previous page request. + * + * @param string $direction The direction of the page: next|previous + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPaginationRequest($direction) + { + $pageUrl = $this->getPaginationUrl($direction); + if ( ! $pageUrl) { + return null; + } + + $newRequest = clone $this->request; + $newRequest->setEndpoint($pageUrl); + return $newRequest; + } + + /** + * Gets the request object needed to make a "next" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getNextPageRequest() + { + return $this->getPaginationRequest('next'); + } + + /** + * Gets the request object needed to make a "previous" page request. + * + * @return FacebookRequest|null * - * @TODO + * @throws FacebookSDKException */ - public function previous() + public function getPreviousPageRequest() { + return $this->getPaginationRequest('previous'); } } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 0d580ab0b..98d11be2f 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -46,12 +46,17 @@ class GraphObjectFactory /** * @const string The base graph object class. */ - const BASE_GRAPH_OBJECT_CLASS = '\\Facebook\\GraphNodes\\GraphObject'; + const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; /** * @const string The graph object prefix. */ - const BASE_GRAPH_OBJECT_PREFIX = '\\Facebook\\GraphNodes\\'; + const BASE_GRAPH_OBJECT_PREFIX = '\Facebook\GraphNodes\\'; + + /** + * @var FacebookResponse The response entity from Graph. + */ + protected $response; /** * @var array The decoded body of the FacebookResponse entity from Graph. @@ -65,6 +70,7 @@ class GraphObjectFactory */ public function __construct(FacebookResponse $response) { + $this->response = $response; $this->decodedBody = $response->getDecodedBody(); } @@ -82,12 +88,7 @@ public function makeGraphObject($subclassName = null) $this->validateResponseAsArray(); $this->validateResponseCastableAsGraphObject(); - // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key - if (isset($this->decodedBody['data'])) { - $this->decodedBody = $this->decodedBody['data']; - } - - return $this->safelyMakeGraphObject($this->decodedBody, $subclassName); + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } /** @@ -157,7 +158,7 @@ public function makeGraphList($subclassName = null, $auto_prefix = true) $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; } - return $this->safelyMakeGraphList($this->decodedBody, $subclassName); + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } /** @@ -223,6 +224,9 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; static::validateSubclass($subclassName); + // Remember the parent node ID + $parentNodeId = isset($data['id']) ? $data['id'] : null; + $items = []; foreach ($data as $k => $v) { @@ -237,7 +241,7 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) : null; // Could be a GraphList or GraphObject - $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass); + $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); } else { $items[$k] = $v; } @@ -251,17 +255,19 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) * * @param array $data The array of data to iterate over. * @param string|null $subclassName The subclass to cast this collection to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. * * @return GraphObject|GraphList * * @throws FacebookSDKException */ - public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) + public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (isset($data['data'])) { // Create GraphList if (static::isCastableAsGraphList($data['data'])) { - return $this->safelyMakeGraphList($data, $subclassName); + return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); } // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key $data = $data['data']; @@ -276,12 +282,14 @@ public function castAsGraphObjectOrGraphList(array $data, $subclassName = null) * * @param array $data The array of data to iterate over. * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. * * @return GraphList * * @throws FacebookSDKException */ - public function safelyMakeGraphList(array $data, $subclassName = null) + public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if ( ! isset($data['data'])) { throw new FacebookSDKException( @@ -291,13 +299,32 @@ public function safelyMakeGraphList(array $data, $subclassName = null) $dataList = []; foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName); + $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName, $parentKey, $parentNodeId); } - // @TODO: Look for meta data here - $metaData = []; + $metaData = $this->getMetaData($data); + + // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) + $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; + + return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + } + + /** + * Get the meta data from a list in a Graph response. + * + * @param array $data The Graph response. + * + * @return array + */ + public function getMetaData(array $data) + { + $meta_data = []; + if (isset($data['paging'])) { + $meta_data['paging'] = $data['paging']; + } - return new GraphList($dataList, $metaData); + return $meta_data; } /** diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index 2f79c49f3..f19eb3913 100755 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -57,11 +57,110 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) } } + $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; + $host = isset($parts['host']) ? $parts['host'] : ''; $port = isset($parts['port']) ? ':' . $parts['port'] : ''; $path = isset($parts['path']) ? $parts['path'] : ''; $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; - return $parts['scheme'] . '://' . $parts['host'] . $port . $path . $query . $fragment; + return $scheme . $host . $port . $path . $query . $fragment; + } + + /** + * Gracefully appends params to the URL. + * + * @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 = []) + { + if ( ! $newParams) { + return $url; + } + + if (strpos($url, '?') === false) { + return $url . '?' . http_build_query($newParams, null, '&'); + } + + list($path, $query) = explode('?', $url, 2); + $existingParams = []; + parse_str($query, $existingParams); + + // Favor params from the original URL over $newParams + $newParams = array_merge($newParams, $existingParams); + + // Sort for a predicable order + ksort($newParams); + + return $path . '?' . http_build_query($newParams, null, '&'); + } + + /** + * Returns the params from a URL in the form of an array. + * + * @param string $url The URL to parse the params from. + * + * @return array + */ + public static function getParamsAsArray($url) + { + $query = parse_url($url, PHP_URL_QUERY); + if ( ! $query) { + return []; + } + $params = []; + parse_str($query, $params); + + return $params; + } + + /** + * Adds the params of the first URL to the second URL. + * Any params that already exist in the second URL will go untouched. + * + * @param string $urlToStealFrom The URL harvest the params from. + * @param string $urlToAddTo The URL that will receive the new params. + * + * @return string The $urlToAddTo with any new params from $urlToStealFrom. + */ + public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) + { + $newParams = static::getParamsAsArray($urlToStealFrom); + // Nothing new to add, return as-is + if ( ! $newParams) { + return $urlToAddTo; + } + + return static::appendParamsToUrl($urlToAddTo, $newParams); + } + + /** + * Check for a "/" prefix and prepend it if not exists. + * + * @param string|null $string + * + * @return string|null + */ + public static function forceSlashPrefix($string) + { + if (!$string) { + return $string; + } + return strpos($string, '/') === 0 ? $string : '/' . $string; + } + + /** + * Trims off the hostname and Graph version from a URL. + * + * @param string $urlToTrim The URL the needs the surgery. + * + * @return string The $urlToTrim with the hostname and Graph version removed. + */ + public static function baseGraphUrlEndpoint($urlToTrim) + { + return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); } } diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/Entities/FacebookBatchRequestTest.php index f2659b1ac..b888ceadb 100755 --- a/tests/Entities/FacebookBatchRequestTest.php +++ b/tests/Entities/FacebookBatchRequestTest.php @@ -31,6 +31,9 @@ class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ private $app; public function setUp() @@ -40,7 +43,7 @@ public function setUp() public function testABatchRequestWillInstantiateWithTheProperProperties() { - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', [], 'v0.1337'); + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token', 'v0.1337'); $this->assertSame($this->app, $batchRequest->getApp()); $this->assertEquals('foo_token', $batchRequest->getAccessToken()); @@ -159,7 +162,7 @@ public function testRequestsCanBeInjectedIntoConstructor() new FacebookRequest(null, null, 'DELETE', '/baz'), ]; - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token', $requests); + $batchRequest = new FacebookBatchRequest($this->app, $requests, 'foo_token'); $formattedRequests = $batchRequest->getRequests(); $this->assertRequestsMatch($requests, $formattedRequests); @@ -170,7 +173,7 @@ public function testRequestsCanBeInjectedIntoConstructor() */ public function testAZeroRequestCountWithThrow() { - $batchRequest = new FacebookBatchRequest($this->app, 'foo_token'); + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token'); $batchRequest->validateBatchRequestCount(); } @@ -294,7 +297,7 @@ private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $ private function createBatchRequest() { - return new FacebookBatchRequest($this->app, 'foo_token'); + return new FacebookBatchRequest($this->app, [], 'foo_token'); } private function createBatchRequestWithRequests(array $requests) diff --git a/tests/Entities/FacebookBatchResponseTest.php b/tests/Entities/FacebookBatchResponseTest.php index fd7ddb694..3f5c466e9 100755 --- a/tests/Entities/FacebookBatchResponseTest.php +++ b/tests/Entities/FacebookBatchResponseTest.php @@ -24,12 +24,37 @@ namespace Facebook\Tests\Entities; use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookResponse; +use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookBatchResponse; class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\Entities\FacebookApp + */ + protected $app; + + /** + * @var \Facebook\Entities\FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $this->app, + 'foo_token', + 'POST', + '/', + ['batch' => 'foo'], + 'foo_eTag', + 'v1337'); + } + public function testASuccessfulJsonBatchResponseWillBeDecoded() { $graphResponseJson = '['; @@ -37,18 +62,19 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() $graphResponseJson .= '{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Last-Modified","value":"2013-12-24T00:34:20+0000"},{"name":"Facebook-API-Version","value":"v2.0"},{"name":"ETag","value":"\"fooTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"id\":\"123\",\"name\":\"Foo McBar\",\"updated_time\":\"2013-12-24T00:34:20+0000\",\"verified\":true}"}'; // Paginated list of Graph objects. $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Facebook-API-Version","value":"v1.0"},{"name":"ETag","value":"\"barTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"data\":[{\"id\":\"1337\",\"story\":\"Foo story.\"},{\"id\":\"1338\",\"story\":\"Bar story.\"}],\"paging\":{\"previous\":\"previous_url\",\"next\":\"next_url\"}}"}'; - // Endpoint not found. - //$graphResponseJson .= ',{"code":404,"headers":[{"name":"Connection","value":"close"},{"name":"WWW-Authenticate","value":"OAuth \"Facebook Platform\" \"not_found\" \"(#803) Cannot query users by their username (foo)\""},{"name":"Facebook-API-Version","value":"v2.0"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"no-store"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"error\":{\"message\":\"(#803) Cannot query users by their username (foo)\",\"type\":\"OAuthException\",\"code\":803}}"}'; - // Invalid access token. - //$graphResponseJson .= ',{"code":400,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"no-store"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"WWW-Authenticate","value":"OAuth \"Facebook Platform\" \"invalid_token\" \"Invalid OAuth access token.\""}],"body":"{\"error\":{\"message\":\"Invalid OAuth access token.\",\"type\":\"OAuthException\",\"code\":190}}"}'; // After POST operation. $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"{\"id\":\"123_1337\"}"}'; // After DELETE operation. $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"true"}'; $graphResponseJson .= ']'; - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $batchResponse = new FacebookBatchResponse($response); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, [ + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + ]); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); $decodedResponses = $batchResponse->getResponses(); @@ -60,20 +86,6 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() $graphList = $decodedResponses[1]->getGraphList(); $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[0]); $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[1]); - /* - // Endpoint not found. - $this->assertTrue($decodedResponses[2]->isError(), 'Expected Response to return an error for endpoint not found.'); - $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $decodedResponses[2]->getThrownException()); - // Invalid access token. - $this->assertTrue($decodedResponses[3]->isError(), 'Expected Response to return an error for invalid access token.'); - $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $decodedResponses[3]->getThrownException()); - // After POST operation. - $this->assertFalse($decodedResponses[4]->isError(), 'Did not expect Response to return an error for POST operation.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[4]->getGraphObject()); - // After DELETE operation. - $this->assertFalse($decodedResponses[5]->isError(), 'Did not expect Response to return an error for DELETE operation.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[5]->getGraphObject()); - */ } @@ -84,15 +96,45 @@ public function testABatchResponseCanBeIteratedOver() $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; $graphResponseJson .= ']'; - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], $graphResponseJson); - $batchResponse = new FacebookBatchResponse($response); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, [ + 'req_one' => new FacebookRequest($this->app, 'token'), + 'req_two' => new FacebookRequest($this->app, 'token'), + 'req_three' => new FacebookRequest($this->app, 'token'), + ]); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); $this->assertInstanceOf('IteratorAggregate', $batchResponse); - foreach ($batchResponse as $responseEntity) { + foreach ($batchResponse as $key => $responseEntity) { + $this->assertTrue(in_array($key, ['req_one', 'req_two', 'req_three'])); $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $responseEntity); } } + public function testTheOriginalRequestCanBeObtainedForEachRequest() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $requests = [ + new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), + new FacebookRequest($this->app, 'foo_token_two', 'POST', '/you'), + new FacebookRequest($this->app, 'foo_token_three', 'DELETE', '/123456'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $batchResponse[0]); + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $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/Entities/FacebookRequestTest.php b/tests/Entities/FacebookRequestTest.php index 9c089ddd9..25ac1388c 100755 --- a/tests/Entities/FacebookRequestTest.php +++ b/tests/Entities/FacebookRequestTest.php @@ -98,6 +98,25 @@ public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() ], $params); } + public function testAnAccessTokenCanBeSetFromTheParams() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'POST', '/me', ['access_token' => 'bar_token']); + + $accessToken = $request->getAccessToken(); + + $this->assertEquals('bar_token', $accessToken); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAccessTokenConflictsWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + new FacebookRequest($app, 'foo_token', 'POST', '/me', ['access_token' => 'bar_token']); + } + public function testAProperUrlWillBeGenerated() { $app = new FacebookApp('123', 'foo_secret'); @@ -117,7 +136,7 @@ public function testAProperUrlWillBeGenerated() $this->assertEquals($expectedUrl, $postUrl); } - public function testParamsAreNotOverwritten() + public function testAuthenticationParamsAreStrippedAndReapplied() { $app = new FacebookApp('123', 'foo_secret'); @@ -127,71 +146,26 @@ public function testParamsAreNotOverwritten() $method = 'GET', $endpoint = '/foo', $params = [ - 'access_token' => 'bar_access_token', + 'access_token' => 'foo_token', 'appsecret_proof' => 'bar_app_secret', + 'bar' => 'baz', ] ); $url = $request->getUrl(); - $expectedParams = 'access_token=bar_access_token&appsecret_proof=bar_app_secret'; + $expectedParams = 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; $this->assertEquals($expectedUrl, $url); $params = $request->getParams(); $expectedParams = [ - 'access_token' => 'bar_access_token', - 'appsecret_proof' => 'bar_app_secret', - ]; - $this->assertEquals($expectedParams, $params); - } - - public function testGracefullyHandlesUrlAppending() - { - $params = []; - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/', $processed_url); - - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); - - $params = [ - 'access_token' => 'foo', + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', 'bar' => 'baz', ]; - $url = 'https://www.foo.com/?foo=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); - - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/?foo=bar&access_token=bar'; - $processed_url = FacebookRequest::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); - } - - public function testSlashesAreProperlyPrepended() - { - $slashTestOne = FacebookRequest::forceSlashPrefix('foo'); - $slashTestTwo = FacebookRequest::forceSlashPrefix('/foo'); - $slashTestThree = FacebookRequest::forceSlashPrefix('foo/bar'); - $slashTestFour = FacebookRequest::forceSlashPrefix('/foo/bar'); - $slashTestFive = FacebookRequest::forceSlashPrefix(null); - $slashTestSix = FacebookRequest::forceSlashPrefix(''); - - $this->assertEquals('/foo', $slashTestOne); - $this->assertEquals('/foo', $slashTestTwo); - $this->assertEquals('/foo/bar', $slashTestThree); - $this->assertEquals('/foo/bar', $slashTestFour); - $this->assertEquals(null, $slashTestFive); - $this->assertEquals('', $slashTestSix); + $this->assertEquals($expectedParams, $params); } } diff --git a/tests/Entities/FacebookResponseTest.php b/tests/Entities/FacebookResponseTest.php index 42ca4572b..5ebba834a 100755 --- a/tests/Entities/FacebookResponseTest.php +++ b/tests/Entities/FacebookResponseTest.php @@ -24,23 +24,33 @@ namespace Facebook\Tests\Entities; use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; use Facebook\Entities\FacebookResponse; class FacebookResponseTest extends \PHPUnit_Framework_TestCase { - public function testAnEmptyResponseEntityCanInstantiate() + /** + * @var \Facebook\Entities\FacebookRequest + */ + protected $request; + + public function setUp() { $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app); - - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); } public function testAnETagCanBeProperlyAccessed() { - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, ['ETag' => 'foo_tag']); + $response = new FacebookResponse($this->request, '', 200, ['ETag' => 'foo_tag']); $eTag = $response->getETag(); @@ -49,8 +59,7 @@ public function testAnETagCanBeProperlyAccessed() public function testAProperAppSecretProofCanBeGenerated() { - $app = new FacebookApp('123', 'foo_secret'); - $response = new FacebookResponse($app, 200, [], '', 'foo_token'); + $response = new FacebookResponse($this->request); $appSecretProof = $response->getAppSecretProof(); @@ -59,9 +68,8 @@ public function testAProperAppSecretProofCanBeGenerated() public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseJson = '{"id":"123","name":"Foo"}'; - $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); $decodedResponse = $response->getDecodedBody(); $graphObject = $response->getGraphObject(); @@ -76,9 +84,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; - $response = new FacebookResponse($app, 200, [], $graphResponseJson); + $response = new FacebookResponse($this->request, $graphResponseJson, 200); $graphObjectList = $response->getGraphList(); @@ -89,9 +96,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponseKeyValuePairs = 'id=123&name=Foo'; - $response = new FacebookResponse($app, 200, [], $graphResponseKeyValuePairs); + $response = new FacebookResponse($this->request, $graphResponseKeyValuePairs, 200); $decodedResponse = $response->getDecodedBody(); @@ -104,9 +110,8 @@ public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() { - $app = new FacebookApp('123', 'foo_secret'); $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; - $response = new FacebookResponse($app, 401, [], $graphResponse); + $response = new FacebookResponse($this->request, $graphResponse, 401); $exception = $response->getThrownException(); diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 8996d443f..4a4523189 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -102,7 +102,6 @@ public function testBetaModeCanBeDisabledOrEnabledViaMethod() public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() { - $facebookApp = new FacebookApp('123', 'foo_secret'); $facebookRequest = m::mock('Facebook\Entities\FacebookRequest'); $facebookRequest ->shouldReceive('getUrl') @@ -120,14 +119,6 @@ public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() ->shouldReceive('getHeaders') ->once() ->andReturn(['request_header' => 'foo']); - $facebookRequest - ->shouldReceive('getAccessToken') - ->once() - ->andReturn('foo_token'); - $facebookRequest - ->shouldReceive('getApp') - ->once() - ->andReturn($facebookApp); $this->httpClientMock ->shouldReceive('send') @@ -151,7 +142,6 @@ public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() { - $facebookApp = new FacebookApp('123', 'foo_secret'); $facebookBatchRequest = m::mock('Facebook\Entities\FacebookBatchRequest'); $facebookBatchRequest ->shouldReceive('prepareRequestsForBatch') @@ -173,14 +163,6 @@ public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGra ->shouldReceive('getHeaders') ->once() ->andReturn(['request_header' => 'foo']); - $facebookBatchRequest - ->shouldReceive('getAccessToken') - ->once() - ->andReturn('foo_token'); - $facebookBatchRequest - ->shouldReceive('getApp') - ->once() - ->andReturn($facebookApp); $this->httpClientMock ->shouldReceive('send') diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 85ec11751..ae8a9c2d4 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -23,18 +23,21 @@ */ namespace Facebook\Tests; -use Mockery as m; use Facebook\Facebook; use Facebook\FacebookClient; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; +use Facebook\Entities\FacebookRequest; +use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface { public function getResponseHeaders() { return ['X-foo-header' => 'bar']; } public function getResponseHttpStatusCode() { return 1337; } - public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { return 'foo_response'; } + public function send($url, $method = 'GET', array $parameters = [], array $headers = []) { + return '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; + } } class FooPersistentDataInterface implements PersistentDataInterface @@ -195,4 +198,36 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() $this->assertEquals('v1337', $request->getGraphVersion()); } + public function testPaginationReturnsProperResponse() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + ]); + $fb = new Facebook($config); + + $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); + $graphList = new GraphList( + $request, + [], + [ + 'paging' => [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ] + ], + '/1337/photos', + '\Facebook\GraphNodes\GraphUser'); + + $nextPage = $fb->next($graphList); + $this->assertInstanceOf('Facebook\GraphNodes\GraphList', $nextPage); + $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); + $this->assertEquals('Foo', $nextPage[0]['name']); + + $lastResponse = $fb->getLastResponse(); + $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $lastResponse); + $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); + } + } diff --git a/tests/GraphNodes/GraphListTest.php b/tests/GraphNodes/GraphListTest.php new file mode 100644 index 000000000..1590a77db --- /dev/null +++ b/tests/GraphNodes/GraphListTest.php @@ -0,0 +1,117 @@ + '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', + ]; + protected $cursorPagination = [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ]; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonGetRequestsWillThrow() + { + $this->request->setMethod('POST'); + $graphList = new GraphList($this->request); + $graphList->validateForPagination(); + } + + public function testCanReturnGraphGeneratedPaginationEndpoints() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->basePagination]); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); + + $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); + $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); + } + + public function testCanGeneratePaginationEndpointsFromACursor() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes'); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); + + $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); + $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); + } + + public function testCanInstantiateNewPaginationRequest() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes'); + $nextPage = $graphList->getNextPageRequest(); + $prevPage = $graphList->getPreviousPageRequest(); + + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $nextPage); + $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $prevPage); + $this->assertNotSame($this->request, $nextPage); + $this->assertNotSame($this->request, $prevPage); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); + } + +} diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index 7d583af68..6690d4adf 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -23,7 +23,9 @@ */ namespace Facebook\Tests\GraphNodes; -use Mockery as m; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\Entities\FacebookResponse; use Facebook\GraphNodes\GraphObjectFactory; use Facebook\GraphNodes\GraphObject; @@ -31,7 +33,7 @@ class MyFooSubClassGraphObject extends GraphObject {} class MyFooGraphObject extends GraphObject { protected static $graphObjectMap = [ - 'foo_object' => '\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', + 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', ]; } @@ -39,37 +41,29 @@ class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\Entities\FacebookRequest */ - protected $responseMock; + protected $request; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testADecodedResponseThatIsNotAnArrayWillThrow() - { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn('foo'); - - $factory = new GraphObjectFactory($this->responseMock); - $factory->validateResponseAsArray(); + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337'); } public function testAValidGraphObjectResponseWillNotThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphObject(); } @@ -78,33 +72,19 @@ public function testAValidGraphObjectResponseWillNotThrow() */ public function testANonGraphObjectResponseWillThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'data' => [ - ['id' => '123', 'name' => 'foo'], - ['id' => '1337', 'name' => 'bar'], - ] - ]); - - $factory = new GraphObjectFactory($this->responseMock); + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphObject(); } public function testAValidGraphListResponseWillNotThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'data' => [ - ['id' => '123', 'name' => 'foo'], - ['id' => '1337', 'name' => 'bar'], - ] - ]); - - $factory = new GraphObjectFactory($this->responseMock); + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -113,12 +93,10 @@ public function testAValidGraphListResponseWillNotThrow() */ public function testANonGraphListResponseWillThrow() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -143,52 +121,38 @@ public function testInvalidSubClassesWillThrow() public function testValidSubClassesWillNotThrow() { - GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphObject'); - GraphObjectFactory::validateSubclass('\\Facebook\\GraphNodes\\GraphAlbum'); - GraphObjectFactory::validateSubclass('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); + GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphObject'); } public function testCastingAsASubClassObjectWillInstantiateTheSubClass() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn(['id' => '123', 'name' => 'foo']); + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); } public function testASubClassMappingWillAutomaticallyInstantiateSubClass() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'id' => '123', - 'name' => 'Foo Name', - 'foo_object' => [ - 'id' => '1337', - 'name' => 'Should be sub classed!', - ], - ]); + $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); $fooObject = $mySubClassObject->getProperty('foo_object'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooSubClassGraphObject', $fooObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $fooObject); } public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ + $data = json_encode([ 'id' => '123', 'name' => 'Foo Name', 'unknown_object' => [ @@ -196,49 +160,45 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() 'name' => 'Should be generic!', ], ]); + $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject'); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); $unknownObject = $mySubClassObject->getProperty('unknown_object'); - $this->assertInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $unknownObject); - $this->assertNotInstanceOf('\\Facebook\\Tests\\GraphNodes\\MyFooGraphObject', $unknownObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $unknownObject); } public function testAListFromGraphWillBeCastAsAGraphList() { - $dataFromGraph = [ - 'data' => [ - [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', + $data = json_encode([ + 'data' => [ + [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + [ + 'id' => '1337', + 'name' => 'Bar McBaz', + 'link' => 'http://facebook/bar', + ], ], - [ - 'id' => '1337', - 'name' => 'Bar McBaz', - 'link' => 'http://facebook/bar', + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', ], - ], - 'paging' => [ - 'next' => 'http://facebook/next', - 'previous' => 'http://facebook/prev', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); + ]); + $res = new FacebookResponse($this->request, $data); + $factory = new GraphObjectFactory($res); $graphList = $factory->makeGraphList(); $graphData = $graphList->asArray(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphList); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -253,23 +213,18 @@ public function testAListFromGraphWillBeCastAsAGraphList() public function testAGraphObjectWillBeCastAsAGraphObject() { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); + $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->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -279,25 +234,21 @@ public function testAGraphObjectWillBeCastAsAGraphObject() public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() { - $dataFromGraph = [ - 'data' => [ - 'id' => '123', - 'name' => 'Foo McBar', - 'link' => 'http://facebook/foo', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); + $data = json_encode([ + 'data' => [ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ]); - $factory = new GraphObjectFactory($this->responseMock); + $res = new FacebookResponse($this->request, $data); + $factory = new GraphObjectFactory($res); $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -305,7 +256,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() ], $graphData); } - public function testACollectionWillBeCastRecursively() + public function testAGraphListWillBeCastRecursively() { $someUser = [ 'id' => '123', @@ -386,33 +337,99 @@ public function testACollectionWillBeCastRecursively() 'previous' => 'http://facebook/prev', ], ]; + $data = json_encode($dataFromGraph); + $res = new FacebookResponse($this->request, $data); - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - - $factory = new GraphObjectFactory($this->responseMock); - + $factory = new GraphObjectFactory($res); $graphObject = $factory->makeGraphList(); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); // Story $storyObject = $graphObject[0]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $storyObject['from']); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['likes']); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $storyObject['comments']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $storyObject['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); // Story Comments $storyComments = $storyObject['comments']; $firstStoryComment = $storyComments[0]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $firstStoryComment['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $firstStoryComment['from']); // Message $messageObject = $graphObject[1]; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphList', $messageObject['to']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); $toUsers = $messageObject['to']; - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphObject', $toUsers[0]); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $toUsers[0]); + } + + public function testAGraphListWillGenerateTheProperParentGraphEdges() + { + $likesList = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'like_after_cursor', + 'before' => 'like_before_cursor', + ], + ], + ]; + + $photosList = [ + 'data' => [ + [ + 'id' => '777', + 'name' => 'Foo Photo', + 'likes' => $likesList, + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'photo_after_cursor', + 'before' => 'photo_before_cursor', + ], + ], + ]; + + $data = json_encode([ + 'data' => [ + [ + 'id' => '111', + 'name' => 'Foo McBar', + 'likes' => $likesList, + 'photos' => $photosList, + ], + [ + 'id' => '222', + 'name' => 'Bar McBaz', + 'likes' => $likesList, + 'photos' => $photosList, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphList = $factory->makeGraphList(); + $topGraphEdge = $graphList->getParentGraphEdge(); + $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); + $childGraphEdgeTwo = $graphList[1]['likes']->getParentGraphEdge(); + $childGraphEdgeThree = $graphList[1]['photos']->getParentGraphEdge(); + $childGraphEdgeFour = $graphList[1]['photos'][0]['likes']->getParentGraphEdge(); + + $this->assertNull($topGraphEdge); + $this->assertEquals('/111/likes', $childGraphEdgeOne); + $this->assertEquals('/222/likes', $childGraphEdgeTwo); + $this->assertEquals('/222/photos', $childGraphEdgeThree); + $this->assertEquals('/777/likes', $childGraphEdgeFour); } } diff --git a/tests/Url/FacebookUrlManipulatorTest.php b/tests/Url/FacebookUrlManipulatorTest.php index b540d60b7..3729cb6a0 100644 --- a/tests/Url/FacebookUrlManipulatorTest.php +++ b/tests/Url/FacebookUrlManipulatorTest.php @@ -91,4 +91,129 @@ public function provideUris() ]; } + public function testGracefullyHandlesUrlAppending() + { + $params = []; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + + $params = [ + 'access_token' => 'foo', + 'bar' => 'baz', + ]; + $url = 'https://www.foo.com/?foo=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/?foo=bar&access_token=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + } + + public function testSlashesAreProperlyPrepended() + { + $slashTestOne = FacebookUrlManipulator::forceSlashPrefix('foo'); + $slashTestTwo = FacebookUrlManipulator::forceSlashPrefix('/foo'); + $slashTestThree = FacebookUrlManipulator::forceSlashPrefix('foo/bar'); + $slashTestFour = FacebookUrlManipulator::forceSlashPrefix('/foo/bar'); + $slashTestFive = FacebookUrlManipulator::forceSlashPrefix(null); + $slashTestSix = FacebookUrlManipulator::forceSlashPrefix(''); + + $this->assertEquals('/foo', $slashTestOne); + $this->assertEquals('/foo', $slashTestTwo); + $this->assertEquals('/foo/bar', $slashTestThree); + $this->assertEquals('/foo/bar', $slashTestFour); + $this->assertEquals(null, $slashTestFive); + $this->assertEquals('', $slashTestSix); + } + + public function testParamsCanBeReturnedAsArray() + { + $paramsOne = FacebookUrlManipulator::getParamsAsArray('/foo'); + $paramsTwo = FacebookUrlManipulator::getParamsAsArray('/foo?one=1&two=2'); + $paramsThree = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com'); + $paramsFour = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?'); + $paramsFive = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?foo=bar'); + + $this->assertEquals([], $paramsOne); + $this->assertEquals(['one' => '1', 'two' => '2'], $paramsTwo); + $this->assertEquals([], $paramsThree); + $this->assertEquals([], $paramsFour); + $this->assertEquals(['foo' => 'bar'], $paramsFive); + } + + /** + * @dataProvider provideMergableEndpoints + */ + public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) + { + $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); + + $this->assertEquals($result, $expected); + } + + public function provideMergableEndpoints() + { + return [ + [ + 'https://www.foo.com/?foo=ignore_foo&dance=fun', + '/me?foo=keep_foo', + '/me?dance=fun&foo=keep_foo', + ], + [ + 'https://www.bar.com?', + 'https://foo.com?foo=bar', + 'https://foo.com?foo=bar', + ], + [ + 'you', + 'me', + 'me', + ], + [ + '/1234?swing=fun', + '/1337?bar=baz&west=coast', + '/1337?bar=baz&swing=fun&west=coast', + ], + ]; + } + + public function testGraphUrlsCanBeTrimmed() + { + $fullGraphUrl = 'https://graph.facebook.com/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v1.0/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.beta.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://whatever-they-want.facebook.com/v2.1/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v5.301/1233?foo=bar'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/1233?foo=bar', $baseGraphUrl); + } + } From 9e37d5a6b0c53fa32fdfd5210ebc519994671cab Mon Sep 17 00:00:00 2001 From: SammyK Date: Mon, 24 Nov 2014 15:48:06 -0500 Subject: [PATCH 069/407] Finished added upload support --- docs/Facebook.fbmd | 57 ++++++++++++++++ docs/FacebookFile.fbmd | 66 +++++++++++++++++++ docs/FacebookVideo.fbmd | 53 +++++++++++++++ docs/sdk_reference.fbmd | 20 ++++++ src/Facebook/Entities/FacebookRequest.php | 2 +- src/Facebook/Facebook.php | 30 +++++++++ src/Facebook/FacebookClient.php | 27 +++++++- src/Facebook/FileUpload/FacebookFile.php | 20 ++++-- .../HttpClients/FacebookCurlHttpClient.php | 9 +-- .../HttpClients/FacebookGuzzleHttpClient.php | 4 +- .../FacebookHttpClientInterface.php | 3 +- .../HttpClients/FacebookStreamHttpClient.php | 4 +- tests/Entities/FacebookRequestTest.php | 4 +- tests/FacebookClientTest.php | 2 +- tests/FacebookTest.php | 2 +- .../FacebookCurlHttpClientTest.php | 10 +-- .../FacebookGuzzleHttpClientTest.php | 8 ++- .../FacebookStreamHttpClientTest.php | 6 +- 18 files changed, 298 insertions(+), 29 deletions(-) create mode 100644 docs/FacebookFile.fbmd create mode 100644 docs/FacebookVideo.fbmd diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 3ed3a4ff0..a2e7a2be5 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -359,3 +359,60 @@ public Facebook\GraphNodes\GraphList|null previous(Facebook\GraphNodes\GraphList Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` object. Functions just like `next()` above, but in the opposite direction of pagination. + + +### fileToUpload() {#file-to-upload} +~~~~ +public Facebook\FileUpload\FacebookFile fileToUpload(string $pathToFile) +~~~~ + +When a valid path to a local or remote file is provided, `fileToUpload()` will returns a `FacebookFile` that can be used in the params in a POST request to Graph. + +~~~~ +// 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; +} + +$graphObject = $response->getGraphObject(); + +echo 'Photo ID: ' . $graphObject['id']; +~~~~ + + + +### videoToUpload() {#video-to-upload} +~~~~ +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 PHP SDK will automatically point the request to the `graph-video.facebook.com` host name for you. + +~~~~ +// 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; +} + +$graphObject = $response->getGraphObject(); + +echo 'Video ID: ' . $graphObject['id']; +~~~~ + diff --git a/docs/FacebookFile.fbmd b/docs/FacebookFile.fbmd new file mode 100644 index 000000000..ade8f09cb --- /dev/null +++ b/docs/FacebookFile.fbmd @@ -0,0 +1,66 @@ + +# File Uploading with the Facebook SDK for PHP + +Uploading files to the Graph API is made a breeze with the PHP SDK. + + + +## Facebook\FileUpload\FacebookFile(string $pathToFile) {#overview} + +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: + +~~~~ +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. + +~~~~ +$fb = new Facebook\Facebook(/* . . . */); + +$myFileToUpload = $fb->fileToUpload('/path/to/file.jpg'), +~~~~ + + + +## Usage {#usage} + +The following example uploads a photo for a user. + +~~~~ +$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; +} + +$graphObject = $response->getGraphObject(); + +echo 'Photo ID: ' . $graphObject['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. + +~~~~ +// 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/FacebookVideo.fbmd b/docs/FacebookVideo.fbmd new file mode 100644 index 000000000..85616f070 --- /dev/null +++ b/docs/FacebookVideo.fbmd @@ -0,0 +1,53 @@ + +# Video Uploading with the Facebook SDK for PHP + +Uploading video files to the Graph API is made a breeze with the PHP SDK. + + + +## Facebook\FileUpload\FacebookVideo(string $pathToVideoFile) {#overview} + +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: + +~~~~ +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. + +~~~~ +$fb = new Facebook\Facebook(/* . . . */); + +$myVideoFileToUpload = $fb->videoToUpload('/path/to/video-file.mp4'), +~~~~ + + + +## Usage {#usage} + +The following example uploads a video for a user. + +~~~~ +// 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; +} + +$graphObject = $response->getGraphObject(); + +echo 'Video ID: ' . $graphObject['id']; +~~~~ + diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 0f6d74643..2244c1bd6 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -176,6 +176,26 @@ FB(devsite:markdown-wiki:table { }) + +# File Uploads {#file-uploads} + +Special objects that represent files to be uploaded with a Graph request. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`[Facebook\FileUpload\FacebookFile](/docs/php/FacebookFile)`', + 'Represents a generic file to be uploaded to the Graph API.', + ], + [ + '`[Facebook\FileUpload\FacebookVideo](/docs/php/FacebookVideo)`', + 'Represents a video file to be uploaded to the Graph API.', + ], + ], +}) + + # HTTP clients {#http-clients} diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 791f9ff5b..04a559f45 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -427,7 +427,7 @@ public function containsFileUploads() * * @return boolean */ - public function containsAVideoUpload() + public function containsVideoUploads() { foreach ($this->files as $file) { if ($file instanceOf FacebookVideo) { diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index c75dc80fd..a43fba284 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -29,6 +29,8 @@ use Facebook\Entities\FacebookBatchRequest; use Facebook\Entities\FacebookResponse; use Facebook\Entities\FacebookBatchResponse; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookVideo; use Facebook\GraphNodes\GraphList; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; @@ -513,4 +515,32 @@ public function request( ); } + /** + * Factory to create FacebookFile's. + * + * @param string $pathToFile + * + * @return FacebookFile + * + * @throws FacebookSDKException + */ + public function fileToUpload($pathToFile) + { + return new FacebookFile($pathToFile); + } + + /** + * Factory to create FacebookVideo's. + * + * @param string $pathToFile + * + * @return FacebookVideo + * + * @throws FacebookSDKException + */ + public function videoToUpload($pathToFile) + { + return new FacebookVideo($pathToFile); + } + } diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index dc5e2d90c..706822d5a 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -59,6 +59,21 @@ class FacebookClient */ const BASE_GRAPH_VIDEO_URL_BETA = 'https://graph-video.beta.facebook.com'; + /** + * @const int The timeout in seconds for a normal request. + */ + const DEFAULT_REQUEST_TIMEOUT = 60; + + /** + * @const int The timeout in seconds for a request that contains file uploads. + */ + const DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT = 3600; + + /** + * @const int The timeout in seconds for a request that contains video uploads. + */ + const DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT = 7200; + /** * @var bool Toggle to use Graph beta url. */ @@ -155,7 +170,7 @@ public function getBaseGraphUrl($postToVideoUrl = false) */ public function prepareRequestMessage(FacebookRequest $request) { - $postToVideoUrl = $request->containsAVideoUpload(); + $postToVideoUrl = $request->containsVideoUploads(); $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl(); // If we're sending files they should be sent as multipart/form-data @@ -196,9 +211,17 @@ public function sendRequest(FacebookRequest $request) list($url, $method, $headers, $body) = $this->prepareRequestMessage($request); + // Since file uploads can take a while, we need to give more time for uploads + $timeOut = static::DEFAULT_REQUEST_TIMEOUT; + if ($request->containsFileUploads()) { + $timeOut = static::DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT; + } elseif ($request->containsVideoUploads()) { + $timeOut = static::DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT; + } + // Should throw `FacebookSDKException` exception on HTTP client error. // Don't catch to allow it to bubble up. - $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers); + $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers, $timeOut); static::$requestCount++; diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php index 7895e9e74..783cc9ea0 100755 --- a/src/Facebook/FileUpload/FacebookFile.php +++ b/src/Facebook/FileUpload/FacebookFile.php @@ -70,16 +70,16 @@ public function __destruct() */ public function open() { - if ( ! is_readable($this->path)) { + if ( ! $this->isRemoteFile($this->path) + && ! is_readable($this->path) ) { throw new FacebookSDKException('Failed to create FacebookFile entity. ' - . 'The file "' . $this->path . '" does not exist or is not readable.'); + . 'Unable to read resource: ' . $this->path . '.'); } - $this->stream = fopen($this->path, 'r'); if ( ! $this->stream) { throw new FacebookSDKException('Failed to create FacebookFile entity. ' - . 'Unable to open file: ' . $this->path . '.'); + . 'Unable to open resource: ' . $this->path . '.'); } } @@ -123,4 +123,16 @@ public function getMimetype() 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) + { + return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1; + } + } diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 2452503cb..b7cd5a8de 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -74,9 +74,9 @@ public function __construct(FacebookCurl $facebookCurl = null) /** * @inheritdoc */ - public function send($url, $method, $body, array $headers) + public function send($url, $method, $body, array $headers, $timeOut) { - $this->openConnection($url, $method, $body, $headers); + $this->openConnection($url, $method, $body, $headers, $timeOut); $this->tryToSendRequest(); // Need to verify the peer @@ -104,15 +104,16 @@ public function send($url, $method, $body, array $headers) * @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. */ - public function openConnection($url, $method, $body, array $headers) + public function openConnection($url, $method, $body, array $headers, $timeOut) { $options = [ CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers), CURLOPT_URL => $url, CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, + CURLOPT_TIMEOUT => $timeOut, CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects CURLOPT_HEADER => true, // Enable header processing ]; diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index 96b1b0ba7..960476d3d 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -49,11 +49,13 @@ public function __construct(Client $guzzleClient = null) /** * @inheritdoc */ - public function send($url, $method, $body, array $headers) + public function send($url, $method, $body, array $headers, $timeOut) { $options = [ 'headers' => $headers, 'body' => $body, + 'timeout' => $timeOut, + 'connect_timeout' => 10, ]; $request = $this->guzzleClient->createRequest($method, $url, $options); diff --git a/src/Facebook/HttpClients/FacebookHttpClientInterface.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php index 88a974f34..389b0cc8c 100644 --- a/src/Facebook/HttpClients/FacebookHttpClientInterface.php +++ b/src/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -37,11 +37,12 @@ interface FacebookHttpClientInterface * @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. * * @return \Facebook\Http\GraphRawResponse Raw response from the server. * * @throws \Facebook\Exceptions\FacebookSDKException */ - public function send($url, $method, $body, array $headers); + public function send($url, $method, $body, array $headers, $timeOut); } diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index 0898cc979..de5e6701e 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -45,14 +45,14 @@ public function __construct(FacebookStream $facebookStream = null) /** * @inheritdoc */ - public function send($url, $method, $body, array $headers) + public function send($url, $method, $body, array $headers, $timeOut) { $options = [ 'http' => [ 'method' => $method, 'header' => $this->compileHeader($headers), 'content' => $body, - 'timeout' => 60, + 'timeout' => $timeOut, 'ignore_errors' => true ], 'ssl' => [ diff --git a/tests/Entities/FacebookRequestTest.php b/tests/Entities/FacebookRequestTest.php index 5eb02c638..5ba2b1da2 100755 --- a/tests/Entities/FacebookRequestTest.php +++ b/tests/Entities/FacebookRequestTest.php @@ -183,7 +183,7 @@ public function testAFileCanBeAddedToParams() $actualParams = $request->getParams(); $this->assertTrue($request->containsFileUploads()); - $this->assertFalse($request->containsAVideoUpload()); + $this->assertFalse($request->containsVideoUploads()); $this->assertTrue( ! isset($actualParams['source'])); $this->assertEquals('Foo Bar', $actualParams['name']); } @@ -201,7 +201,7 @@ public function testAVideoCanBeAddedToParams() $actualParams = $request->getParams(); $this->assertTrue($request->containsFileUploads()); - $this->assertTrue($request->containsAVideoUpload()); + $this->assertTrue($request->containsVideoUploads()); $this->assertTrue( ! isset($actualParams['source'])); $this->assertEquals('Foo Bar', $actualParams['name']); } diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 560a26549..155f628bd 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -41,7 +41,7 @@ class MyFooClientHandler implements FacebookHttpClientInterface { - public function send($url, $method, $body, array $headers) { + public function send($url, $method, $body, array $headers, $timeOut) { return new GraphRawResponse( "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 05e34f155..48c9b2de4 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -34,7 +34,7 @@ class FooClientInterface implements FacebookHttpClientInterface { - public function send($url, $method, $body, array $headers) { + public function send($url, $method, $body, array $headers, $timeOut) { return new GraphRawResponse( "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index aa3c659cd..f7e1b2482 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -61,14 +61,14 @@ public function testCanOpenGetCurlConnection() CURLOPT_HTTPHEADER => ['X-Foo-Header: X-Bar'], CURLOPT_URL => 'http://foo.com', CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, + CURLOPT_TIMEOUT => 123, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, ]) ->once() ->andReturn(null); - $this->curlClient->openConnection('http://foo.com', 'GET', 'foo_body', ['X-Foo-Header' => 'X-Bar']); + $this->curlClient->openConnection('http://foo.com', 'GET', 'foo_body', ['X-Foo-Header' => 'X-Bar'], 123); } public function testCanOpenCurlConnectionWithPostBody() @@ -92,7 +92,7 @@ public function testCanOpenCurlConnectionWithPostBody() ->once() ->andReturn(null); - $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', []); + $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', [], 60); } public function testCanAddBundledCert() @@ -289,7 +289,7 @@ public function testCanSendNormalRequest() ->once() ->andReturn(null); - $response = $this->curlClient->send('http://foo.com/', 'GET', '', []); + $response = $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); $this->assertEquals($this->fakeRawBody, $response->getBody()); @@ -323,7 +323,7 @@ public function testThrowsExceptionOnClientError() ->once() ->andReturn('Foo error'); - $this->curlClient->send('http://foo.com/', 'GET', '', []); + $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); } } diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index a614f043c..b5bb678fa 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -64,6 +64,8 @@ public function testCanSendNormalRequest() $options = [ 'headers' => ['X-foo' => 'bar'], 'body' => 'foo_body', + 'timeout' => 123, + 'connect_timeout' => 10, ]; $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); @@ -78,7 +80,7 @@ public function testCanSendNormalRequest() ->with($requestMock) ->andReturn($responseMock); - $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar']); + $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); $this->assertEquals($this->fakeRawBody, $response->getBody()); @@ -104,6 +106,8 @@ public function testThrowsExceptionOnClientError() $options = [ 'headers' => [], 'body' => 'foo_body', + 'timeout' => 60, + 'connect_timeout' => 10, ]; $this->guzzleMock @@ -117,7 +121,7 @@ public function testThrowsExceptionOnClientError() ->with($requestMock) ->andThrow($exceptionMock); - $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', []); + $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); } } diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index e9b0ba969..fc1e99114 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -69,7 +69,7 @@ public function testCanSendNormalRequest() 'method' => 'GET', 'header' => 'X-foo: bar', 'content' => 'foo_body', - 'timeout' => 60, + 'timeout' => 123, 'ignore_errors' => true, ]) { return false; @@ -96,7 +96,7 @@ public function testCanSendNormalRequest() ->with('http://foo.com/') ->andReturn($this->fakeRawBody); - $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar']); + $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); $this->assertEquals($this->fakeRawBody, $response->getBody()); @@ -123,7 +123,7 @@ public function testThrowsExceptionOnClientError() ->with('http://foo.com/') ->andReturn(false); - $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', []); + $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); } } From 94bfb38152a9859007502cb12483dae40b5cb127 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 5 Dec 2014 15:22:27 -0600 Subject: [PATCH 070/407] Added helpers to super service. Added setter for default access token. --- README.md | 28 ++++++++-------- docs/Facebook.fbmd | 64 ++++++++++++++++++++++++++++++++++-- src/Facebook/Facebook.php | 69 +++++++++++++++++++++++++++++++++------ tests/FacebookTest.php | 21 ++++++++++++ 4 files changed, 156 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 0a79f4537..502943bf0 100644 --- a/README.md +++ b/README.md @@ -16,34 +16,34 @@ Usage Simple GET example of a user's profile. ```php -use Facebook\Facebook; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; - -$fb = new Facebook([ +$fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', //'default_access_token' => '{access-token}', // optional ]); // Use one of the helper classes to get a Facebook\Entities\AccessToken entity. -// Facebook\Helpers\FacebookRedirectLoginHelper -// Facebook\Helpers\FacebookJavaScriptLoginHelper -// Facebook\Helpers\FacebookCanvasLoginHelper -// Facebook\Helpers\FacebookPageTabHelper +// $helper = $fb->getRedirectLoginHelper(); +// $helper = $fb->getJavaScriptHelper(); +// $helper = $fb->getCanvasHelper(); +// $helper = $fb->getPageTabHelper(); try { - // Get the Facebook\GraphNodes\GraphUser object for the current user: + // 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}'); - $me = $response->getGraphUser(); - echo 'Logged in as ' . $me->getName(); -} catch(FacebookResponseException $e) { +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { + exit; +} catch(Facebook\Exceptions\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 at: diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index a2e7a2be5..188b323a9 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -161,9 +161,30 @@ Returns the last response received from the Graph API in the form of a `Facebook ### getDefaultAccessToken() {#get-default-access-token} ~~~~ -public AccessToken|null getDefaultAccessToken() +public Facebook\Entities\AccessToken|null getDefaultAccessToken() ~~~~ -Returns the default `Facebook\Entities\AccessToken` entity if the configuration option `default_access_token` was set. + +Returns the default fallback `Facebook\Entities\AccessToken` 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() {#set-default-access-token} +~~~~ +public setDefaultAccessToken(string|Facebook\Entities\AccessToken $accessToken) +~~~~ + +Sets the default access token to be use with all requests sent to Graph. The access token can be in string or `Facebook\Entities\AccessToken` format. + +~~~~ +$fb->setDefaultAccessToken('{my-access-token}'); + +// . . . OR . . . + +$accessToken = new Facebook\Entities\AccessToken('{my-access-token}'); +$fb->setDefaultAccessToken($accessToken); +~~~~ + +This setting will overwrite the value from `default_access_token` if it was passed to the `Facebook\Facebook` constructor. @@ -315,6 +336,45 @@ $helper = $fb->getRedirectLoginHelper(); ~~~~ + +### getJavaScriptHelper() {#get-javascript-helper} +~~~~ +public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) which is used to access the signed request stored in the cookie set by the JavaScript SDK. + +~~~~ +$helper = $fb->getJavaScriptHelper(); +~~~~ + + + +### getCanvasHelper() {#get-canvas-helper} +~~~~ +public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) which is used to access the signed request that is `POST`ed to canvas apps. + +~~~~ +$helper = $fb->getCanvasHelper(); +~~~~ + + + +### getPageTabHelper() {#get-page-tab-helper} +~~~~ +public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper) 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. + +~~~~ +$helper = $fb->getPageTabHelper(); +~~~~ + + ### next() {#next} ~~~~ diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index a43fba284..32ef867a5 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -41,14 +41,15 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\Helpers\FacebookCanvasHelper; +use Facebook\Helpers\FacebookJavaScriptHelper; +use Facebook\Helpers\FacebookPageTabHelper; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\Exceptions\FacebookSDKException; /** * Class Facebook * @package Facebook - * - * @TODO Add helpers to superclass */ class Facebook { @@ -194,14 +195,7 @@ public function __construct(array $config = []) } if (isset($config['default_access_token'])) { - if (is_string($config['default_access_token'])) { - $this->defaultAccessToken = new AccessToken($config['default_access_token']); - } elseif ( ! $config['default_access_token'] instanceof AccessToken) { - throw new \InvalidArgumentException( - 'The "default_access_token" provided must be of type "string"' - . ' or Facebook\Entities\AccessToken' - ); - } + $this->setDefaultAccessToken($config['default_access_token']); } $this->defaultGraphVersion = isset($config['default_graph_version']) @@ -263,6 +257,31 @@ public function getDefaultAccessToken() return $this->defaultAccessToken; } + /** + * Sets the default access token to use with requests. + * + * @param AccessToken|string $accessToken The access token to save. + * + * @throws \InvalidArgumentException + */ + public function setDefaultAccessToken($accessToken) + { + if (is_string($accessToken)) { + $this->defaultAccessToken = new AccessToken($accessToken); + return; + } + + if ($accessToken instanceof AccessToken) { + $this->defaultAccessToken = $accessToken; + return; + } + + throw new \InvalidArgumentException( + 'The default access token must be of type "string"' + . ' or Facebook\Entities\AccessToken' + ); + } + /** * Returns the default Graph version. * @@ -287,6 +306,36 @@ public function getRedirectLoginHelper() ); } + /** + * Returns the JavaScript helper. + * + * @return FacebookJavaScriptHelper + */ + public function getJavaScriptHelper() + { + return new FacebookJavaScriptHelper($this->app); + } + + /** + * Returns the canvas helper. + * + * @return FacebookCanvasHelper + */ + public function getCanvasHelper() + { + return new FacebookCanvasHelper($this->app); + } + + /** + * Returns the page tab helper. + * + * @return FacebookPageTabHelper + */ + public function getPageTabHelper() + { + return new FacebookPageTabHelper($this->app); + } + /** * Sends a GET request to Graph and returns the result. * diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 48c9b2de4..b60ca9436 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -30,6 +30,7 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; use Facebook\Entities\FacebookRequest; +use Facebook\Entities\AccessToken; use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface @@ -162,6 +163,26 @@ public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); } + public function testAnAccessTokenCanBeSetAsAString() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken('foo_token'); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('foo_token', (string) $accessToken); + } + + public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken(new AccessToken('bar_token')); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('bar_token', (string) $accessToken); + } + /** * @expectedException \InvalidArgumentException */ From b2b0454e37c423647980467b00f2b79f67d2ed63 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 5 Dec 2014 16:07:11 -0600 Subject: [PATCH 071/407] Added access to GraphList meta data --- docs/GraphList.fbmd | 53 ++++++++++++++++ src/Facebook/GraphNodes/GraphList.php | 62 ++++++++++++++++++- .../GraphNodes/GraphObjectFactory.php | 7 +-- 3 files changed, 114 insertions(+), 8 deletions(-) diff --git a/docs/GraphList.fbmd b/docs/GraphList.fbmd index 7ad738df6..3283c586e 100644 --- a/docs/GraphList.fbmd +++ b/docs/GraphList.fbmd @@ -69,3 +69,56 @@ do { } while ($pageCount < $maxPages && $listOfPages = $fb->next($listOfPages)); ~~~~ + + +## Method Reference {#method-reference} + +### getMetaData() {#get-meta-data} +~~~~ +public array getMetaData() +~~~~ + +Sometimes Graph will return additional data associated with a list of Graph nodes. You can access this raw data as an array with `getMetaData()`. + +~~~~ +$metaData = $graphList->getMetaData(); +~~~~ + +### getNextCursor() {#get-next-cursor} +~~~~ +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 a list of Graph nodes, it is sometimes handy to store the last cursor used so that you can revisit the exact position at a later time. + +~~~~ +$nextCursor = $graphList->getNextCursor(); +// Returns: MMAyDDM5NjA0OTEyMDc0OTM= +~~~~ + +### getPreviousCursor() {#get-previous-cursor} +~~~~ +public string|null getPreviousCursor() +~~~~ + +Returns the `$.paging.cursors.before` value if it exists or `null` if it does not exist. + +~~~~ +$previousCursor = $graphList->getPreviousCursor(); +// Returns: ODOxMTUzMjQzNTg5zzU5 +~~~~ + +### getTotalCount() {#get-total-count} +~~~~ +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. + +~~~~ +$response = $fb->get('/{post-id}/likes?summary=true'); +$listOfLikes = $response->getGraphList(); +$totalCount = $listOfLikes->getTotalCount(); +// Returns: 10 +~~~~ + diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 142b1c80f..94bc93b27 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -93,6 +93,50 @@ public function getSubClassName() return $this->subclassName; } + /** + * Returns the raw meta data associated with this GraphList. + * + * @return array + */ + public function getMetaData() + { + return $this->metaData; + } + + /** + * Returns the next cursor if it exists. + * + * @return string|null + */ + public function getNextCursor() + { + return $this->getCursor('after'); + } + + /** + * Returns the previous cursor if it exists. + * + * @return string|null + */ + public function getPreviousCursor() + { + return $this->getCursor('before'); + } + + /** + * Returns the cursor for a specific direction if it exists. + * + * @param string $direction The direction of the page: after|before + * + * @return string|null + */ + public function getCursor($direction) + { + return isset($this->metaData['paging']['cursors'][$direction]) + ? $this->metaData['paging']['cursors'][$direction] + : null; + } + /** * Generates a pagination URL based on a cursor. * @@ -116,7 +160,8 @@ public function getPaginationUrl($direction) // Do we have a cursor to work with? $cursorDirection = $direction === 'next' ? 'after' : 'before'; - if ( ! isset($this->metaData['paging']['cursors'][$cursorDirection])) { + $cursor = $this->getCursor($cursorDirection); + if ( ! $cursor) { return null; } @@ -127,8 +172,6 @@ public function getPaginationUrl($direction) // We have the parent node ID, paging cursor & original request. // These were the ingredients chosen to create the perfect little URL. - $cursor = $this->metaData['paging']['cursors'][$cursorDirection]; - $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); // Pull in the original params @@ -197,4 +240,17 @@ public function getPreviousPageRequest() return $this->getPaginationRequest('previous'); } + /** + * 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() + { + return isset($this->metaData['summary']['total_count']) + ? $this->metaData['summary']['total_count'] + : null; + } + } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 98d11be2f..67dbe934e 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -319,12 +319,9 @@ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKe */ public function getMetaData(array $data) { - $meta_data = []; - if (isset($data['paging'])) { - $meta_data['paging'] = $data['paging']; - } + unset($data['data']); - return $meta_data; + return $data; } /** From aeb924a96d7e9cae709d529701e2ebc7db1573a6 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 5 Dec 2014 17:35:57 -0600 Subject: [PATCH 072/407] Improved exception handling --- src/Facebook/Entities/FacebookResponse.php | 5 +- .../FacebookAuthorizationException.php | 2 +- .../Exceptions/FacebookClientException.php | 2 +- .../Exceptions/FacebookOtherException.php | 2 +- .../FacebookPermissionException.php | 2 +- .../Exceptions/FacebookResponseException.php | 91 +++++----- .../Exceptions/FacebookServerException.php | 2 +- .../Exceptions/FacebookThrottleException.php | 2 +- .../FacebookResponseExceptionTest.php | 161 +++++++++--------- 9 files changed, 134 insertions(+), 135 deletions(-) diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index 55a1e9bab..e7f63ae7d 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -212,10 +212,7 @@ public function throwException() */ public function makeException() { - $this->thrownException = FacebookResponseException::create( - $this->body, - $this->decodedBody, - $this->httpStatusCode); + $this->thrownException = FacebookResponseException::create($this); } /** diff --git a/src/Facebook/Exceptions/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php index 0a373eb3e..a633ecbc2 100644 --- a/src/Facebook/Exceptions/FacebookAuthorizationException.php +++ b/src/Facebook/Exceptions/FacebookAuthorizationException.php @@ -27,7 +27,7 @@ * Class FacebookAuthorizationException * @package Facebook */ -class FacebookAuthorizationException extends FacebookResponseException +class FacebookAuthorizationException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php index e22219efd..650381022 100644 --- a/src/Facebook/Exceptions/FacebookClientException.php +++ b/src/Facebook/Exceptions/FacebookClientException.php @@ -27,7 +27,7 @@ * Class FacebookClientException * @package Facebook */ -class FacebookClientException extends FacebookResponseException +class FacebookClientException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php index 9a0e77842..34c6be5b2 100644 --- a/src/Facebook/Exceptions/FacebookOtherException.php +++ b/src/Facebook/Exceptions/FacebookOtherException.php @@ -27,7 +27,7 @@ * Class FacebookOtherException * @package Facebook */ -class FacebookOtherException extends FacebookResponseException +class FacebookOtherException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookPermissionException.php b/src/Facebook/Exceptions/FacebookPermissionException.php index d37d30920..3d9c175a3 100644 --- a/src/Facebook/Exceptions/FacebookPermissionException.php +++ b/src/Facebook/Exceptions/FacebookPermissionException.php @@ -27,7 +27,7 @@ * Class FacebookPermissionException * @package Facebook */ -class FacebookPermissionException extends FacebookResponseException +class FacebookPermissionException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 59b7760e9..bb4b083cc 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -23,6 +23,8 @@ */ namespace Facebook\Exceptions; +use Facebook\Entities\FacebookResponse; + /** * Class FacebookResponseException * @package Facebook @@ -33,54 +35,50 @@ class FacebookResponseException extends FacebookSDKException { /** - * @var int Status code for the response causing the exception - */ - private $statusCode; - - /** - * @var string Raw response + * @var FacebookResponse The response that threw the exception. */ - private $rawResponse; + protected $response; /** - * @var array Decoded response + * @var array Decoded response. */ - private $responseData; + protected $responseData; /** * Creates a FacebookResponseException. * - * @param string $rawResponse The raw response from the Graph API - * @param array $responseData The decoded response from the Graph API - * @param int $statusCode + * @param FacebookResponse $response The response that threw the exception. + * @param FacebookSDKException $previousException The more detailed exception. */ - public function __construct($rawResponse, $responseData, $statusCode) + public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) { - $this->rawResponse = $rawResponse; - $this->statusCode = $statusCode; - $this->responseData = self::convertToArray($responseData); - parent::__construct( - $this->get('message', 'Unknown Exception'), $this->get('code', -1), null - ); + $this->response = $response; + $this->responseData = $response->getDecodedBody(); + + $errorMessage = $this->get('message', 'Unknown error from Graph.'); + $errorCode = $this->get('code', -1); + + parent::__construct($errorMessage, $errorCode, $previousException); } /** - * Process an error payload from the Graph API and return the appropriate - * exception subclass. + * A factory for creating the appropriate exception based on the response from Graph. * - * @param string $raw the raw response from the Graph API - * @param array $data the decoded response from the Graph API - * @param int $statusCode the HTTP response code + * @param FacebookResponse $response The response that threw the exception. * * @return FacebookResponseException */ - public static function create($raw, $data, $statusCode) + public static function create(FacebookResponse $response) { - $data = self::convertToArray($data); - if (!isset($data['error']['code']) && isset($data['code'])) { + $data = $response->getDecodedBody(); + + if ( ! isset($data['error']['code']) && isset($data['code'])) { $data = ['error' => $data]; } - $code = (isset($data['error']['code']) ? $data['error']['code'] : null); + $code = isset($data['error']['code']) ? $data['error']['code'] : null; + $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; + + $previousException = null; if (isset($data['error']['error_subcode'])) { switch ($data['error']['error_subcode']) { @@ -91,7 +89,7 @@ public static function create($raw, $data, $statusCode) case 463: case 464: case 467: - return new FacebookAuthorizationException($raw, $data, $statusCode); + return new static($response, new FacebookAuthorizationException($message, $code)); break; } } @@ -101,41 +99,41 @@ public static function create($raw, $data, $statusCode) case 100: case 102: case 190: - return new FacebookAuthorizationException($raw, $data, $statusCode); + return new static($response, new FacebookAuthorizationException($message, $code)); break; // Server issue, possible downtime case 1: case 2: - return new FacebookServerException($raw, $data, $statusCode); + return new static($response, new FacebookServerException($message, $code)); break; // API Throttling case 4: case 17: case 341: - return new FacebookThrottleException($raw, $data, $statusCode); + return new static($response, new FacebookThrottleException($message, $code)); break; // Duplicate Post case 506: - return new FacebookClientException($raw, $data, $statusCode); + return new static($response, new FacebookClientException($message, $code)); break; } // Missing Permissions if ($code == 10 || ($code >= 200 && $code <= 299)) { - return new FacebookPermissionException($raw, $data, $statusCode); + return new static($response, new FacebookPermissionException($message, $code)); } // OAuth authentication error if (isset($data['error']['type']) and $data['error']['type'] === 'OAuthException') { - return new FacebookAuthorizationException($raw, $data, $statusCode); + return new static($response, new FacebookAuthorizationException($message, $code)); } // All others - return new FacebookOtherException($raw, $data, $statusCode); + return new static($response, new FacebookOtherException($message, $code)); } /** @@ -161,7 +159,7 @@ private function get($key, $default = null) */ public function getHttpStatusCode() { - return $this->statusCode; + return $this->response->getHttpStatusCode(); } /** @@ -191,7 +189,7 @@ public function getErrorType() */ public function getRawResponse() { - return $this->rawResponse; + return $this->response->getBody(); } /** @@ -199,24 +197,19 @@ public function getRawResponse() * * @return array */ - public function getResponse() + public function getResponseData() { return $this->responseData; } /** - * Converts a stdClass object to an array - * - * @param mixed $object + * Returns the response entity used to create the exception. * - * @return array + * @return FacebookResponse */ - private static function convertToArray($object) + public function getResponse() { - if ($object instanceof \stdClass) { - return get_object_vars($object); - } - return $object; + return $this->response; } -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php index 06d7f756c..962615876 100644 --- a/src/Facebook/Exceptions/FacebookServerException.php +++ b/src/Facebook/Exceptions/FacebookServerException.php @@ -27,7 +27,7 @@ * Class FacebookServerException * @package Facebook */ -class FacebookServerException extends FacebookResponseException +class FacebookServerException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php index be5bee8c3..662d3bad1 100644 --- a/src/Facebook/Exceptions/FacebookThrottleException.php +++ b/src/Facebook/Exceptions/FacebookThrottleException.php @@ -27,7 +27,7 @@ * Class FacebookThrottleException * @package Facebook */ -class FacebookThrottleException extends FacebookResponseException +class FacebookThrottleException extends FacebookSDKException { } \ No newline at end of file diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 91e35e9ca..506d359cf 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -23,17 +23,24 @@ */ namespace Facebook\Tests\Exceptions; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\Entities\FacebookResponse; use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookAuthorizationException; -use Facebook\Exceptions\FacebookOtherException; -use Facebook\Exceptions\FacebookServerException; -use Facebook\Exceptions\FacebookPermissionException; -use Facebook\Exceptions\FacebookClientException; -use Facebook\Exceptions\FacebookThrottleException; class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); + } + public function testAuthorizationExceptions() { $params = [ @@ -44,58 +51,59 @@ public function testAuthorizationExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(100, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['code'] = 102; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(102, $exception->getCode()); $params['error']['code'] = 190; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(190, $exception->getCode()); $params['error']['type'] = 'OAuthException'; $params['error']['code'] = 0; $params['error']['error_subcode'] = 458; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(458, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 460; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(460, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 463; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(463, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 467; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(467, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 0; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(0, $exception->getSubErrorCode()); } @@ -109,20 +117,21 @@ public function testServerExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 500); - $this->assertTrue($exception instanceof FacebookServerException); + + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); $this->assertEquals(1, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(500, $exception->getHttpStatusCode()); $params['error']['code'] = 2; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookServerException); + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); $this->assertEquals(2, $exception->getCode()); } @@ -136,26 +145,26 @@ public function testThrottleExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookThrottleException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); $this->assertEquals(4, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['code'] = 17; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookThrottleException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); $this->assertEquals(17, $exception->getCode()); $params['error']['code'] = 341; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookThrottleException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); $this->assertEquals(341, $exception->getCode()); } @@ -169,20 +178,20 @@ public function testUserIssueExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(230, $exception->getCode()); $this->assertEquals(459, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['error_subcode'] = 464; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(464, $exception->getSubErrorCode()); } @@ -196,32 +205,32 @@ public function testPermissionExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(10, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['code'] = 200; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(200, $exception->getCode()); $params['error']['code'] = 250; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(250, $exception->getCode()); $params['error']['code'] = 299; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(299, $exception->getCode()); } @@ -235,14 +244,14 @@ public function testClientExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookClientException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookClientException', $exception->getPrevious()); $this->assertEquals(506, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); } @@ -256,14 +265,14 @@ public function testOtherException() 'type' => 'feature' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 200); - $this->assertTrue($exception instanceof FacebookOtherException); + $response = new FacebookResponse($this->request, json_encode($params), 200); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookOtherException', $exception->getPrevious()); $this->assertEquals(42, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('feature', $exception->getErrorType()); $this->assertEquals('ship love', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(200, $exception->getHttpStatusCode()); } From e10ea41410aa950dcf0369b7be736d026761fe59 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 5 Dec 2014 12:55:54 -0600 Subject: [PATCH 073/407] Added more secure peer verification --- .../HttpClients/FacebookCurlHttpClient.php | 35 +- .../HttpClients/FacebookGuzzleHttpClient.php | 32 +- .../HttpClients/FacebookStreamHttpClient.php | 4 +- .../certs/DigiCertHighAssuranceEVRootCA.pem | 23 + .../HttpClients/fb_ca_chain_bundle.crt | 3920 ----------------- .../FacebookCurlHttpClientTest.php | 101 +- .../FacebookGuzzleHttpClientTest.php | 94 +- .../FacebookStreamHttpClientTest.php | 14 +- 8 files changed, 170 insertions(+), 4053 deletions(-) create mode 100644 src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem delete mode 100644 src/Facebook/HttpClients/fb_ca_chain_bundle.crt diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index b7cd5a8de..56e66c9ed 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -77,16 +77,11 @@ public function __construct(FacebookCurl $facebookCurl = null) public function send($url, $method, $body, array $headers, $timeOut) { $this->openConnection($url, $method, $body, $headers, $timeOut); - $this->tryToSendRequest(); - - // Need to verify the peer - if ($this->curlErrorCode == 60 || $this->curlErrorCode == 77) { - $this->addBundledCert(); - $this->tryToSendRequest(); - } + $this->sendRequest(); - if ($this->curlErrorCode) { - throw new FacebookSDKException($this->curlErrorMessage, $this->curlErrorCode); + if ($curlErrorCode = $this->facebookCurl->errno()) { + $curlErrorMessage = $this->facebookCurl->error(); + throw new FacebookSDKException($curlErrorMessage, $curlErrorCode); } // Separate the raw headers from the raw body @@ -116,6 +111,9 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) CURLOPT_TIMEOUT => $timeOut, CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects CURLOPT_HEADER => true, // Enable header processing + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ]; if ($method !== "GET") { @@ -126,15 +124,6 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) $this->facebookCurl->setopt_array($options); } - /** - * Add a bundled cert to the connection - */ - public function addBundledCert() - { - $this->facebookCurl->setopt(CURLOPT_CAINFO, - dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt'); - } - /** * Closes an existing curl connection */ @@ -143,16 +132,6 @@ public function closeConnection() $this->facebookCurl->close(); } - /** - * Try to send the request - */ - public function tryToSendRequest() - { - $this->sendRequest(); - $this->curlErrorMessage = $this->facebookCurl->error(); - $this->curlErrorCode = $this->facebookCurl->errno(); - } - /** * Send the request and get the raw response from curl */ diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index 960476d3d..6f1c822a3 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -27,6 +27,7 @@ use Facebook\Exceptions\FacebookSDKException; use GuzzleHttp\Client; +use GuzzleHttp\Message\ResponseInterface; use GuzzleHttp\Ring\Exception\RingException; use GuzzleHttp\Exception\RequestException; @@ -56,23 +57,46 @@ public function send($url, $method, $body, array $headers, $timeOut) 'body' => $body, 'timeout' => $timeOut, 'connect_timeout' => 10, + 'verify' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ]; $request = $this->guzzleClient->createRequest($method, $url, $options); try { $rawResponse = $this->guzzleClient->send($request); } catch (RequestException $e) { - if ($e->getPrevious() instanceof RingException) { + $rawResponse = $e->getResponse(); + + if ( + $e->getPrevious() instanceof RingException + || ! $rawResponse instanceof ResponseInterface + ) { throw new FacebookSDKException($e->getMessage(), $e->getCode()); } - $rawResponse = $e->getResponse(); } - $headers = $rawResponse->getHeaders(); + $rawHeaders = $this->getHeadersAsString($rawResponse); $rawBody = $rawResponse->getBody(); $httpStatusCode = $rawResponse->getStatusCode(); - return new GraphRawResponse($headers, $rawBody, $httpStatusCode); + return new GraphRawResponse($rawHeaders, $rawBody, $httpStatusCode); + } + + /** + * Returns the Guzzle array of headers as a string. + * + * @param ResponseInterface $response The Guzzle response. + * + * @return string + */ + public function getHeadersAsString(ResponseInterface $response) + { + $headers = $response->getHeaders(); + $rawHeaders = []; + foreach ($headers as $name => $values) { + $rawHeaders[] = $name . ": " . implode(", ", $values); + } + + return implode("\r\n", $rawHeaders); } } diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index de5e6701e..4f450b9b3 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -57,7 +57,9 @@ public function send($url, $method, $body, array $headers, $timeOut) ], 'ssl' => [ 'verify_peer' => true, - 'cafile' => dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt', + 'verify_peer_name' => true, + 'allow_self_signed' => true, // All root certificates are self-signed + 'cafile' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ], ]; diff --git a/src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem b/src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem new file mode 100644 index 000000000..9e6810ab7 --- /dev/null +++ b/src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- diff --git a/src/Facebook/HttpClients/fb_ca_chain_bundle.crt b/src/Facebook/HttpClients/fb_ca_chain_bundle.crt deleted file mode 100644 index 969239ff6..000000000 --- a/src/Facebook/HttpClients/fb_ca_chain_bundle.crt +++ /dev/null @@ -1,3920 +0,0 @@ -## -## ca-bundle.crt -- Bundle of CA Root Certificates -## -## Certificate data from Mozilla as of: Thu Oct 18 19:05:59 2012 -## -## This is a bundle of X.509 certificates of public Certificate Authorities -## (CA). These were automatically extracted from Mozilla's root certificates -## file (certdata.txt). This file can be found in the mozilla source tree: -## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 -## -## It contains the certificates in PEM format and therefore -## can be directly used with curl / libcurl / php_curl, or with -## an Apache+mod_ssl webserver for SSL client authentication. -## Just configure this file as the SSLCACertificateFile. -## - -# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.86 $ $Date: 2012/10/18 16:26:52 $ - -GTE CyberTrust Global Root -========================== ------BEGIN CERTIFICATE----- -MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg -Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG -A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz -MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL -Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 -IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u -sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql -HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID -AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW -M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF -NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ ------END CERTIFICATE----- - -Thawte Server CA -================ ------BEGIN CERTIFICATE----- -MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE -AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j -b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV -BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u -c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG -A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 -ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl -/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 -1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J -GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ -GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= ------END CERTIFICATE----- - -Thawte Premium Server CA -======================== ------BEGIN CERTIFICATE----- -MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE -AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl -ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT -AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU -VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 -aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ -cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 -aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh -Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ -qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm -SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf -8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t -UCemDaYj+bvLpgcUQg== ------END CERTIFICATE----- - -Equifax Secure CA -================= ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE -ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT -B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR -fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW -8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG -A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE -CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG -A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS -spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB -Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 -zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB -BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 -70+sB3c4 ------END CERTIFICATE----- - -Digital Signature Trust Co. Global CA 1 -======================================= ------BEGIN CERTIFICATE----- -MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE -ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy -MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs -IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE -NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i -o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo -BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 -dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw -IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY -MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM -BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB -ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq -kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4 -RbyhkwS7hp86W0N6w4pl ------END CERTIFICATE----- - -Digital Signature Trust Co. Global CA 3 -======================================= ------BEGIN CERTIFICATE----- -MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE -ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy -MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs -IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD -VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS -xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo -BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 -dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw -IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY -MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM -BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB -AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi -up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1 -mPnHfxsb1gYgAlihw6ID ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA -TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah -WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf -Tqj/ZA1k ------END CERTIFICATE----- - -Verisign Class 1 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd -k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq -WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB -MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM -XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC -lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ ------END CERTIFICATE----- - -Verisign Class 2 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h -cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp -Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 -c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h -cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp -Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 -c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx -nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC -wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA -ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK -1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk -LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg== ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO -FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 -lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB -MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT -1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD -Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 ------END CERTIFICATE----- - -GlobalSign Root CA -================== ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx -GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds -b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD -VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa -DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc -THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb -Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP -c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX -gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF -AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj -Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG -j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH -hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC -X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -GlobalSign Root CA - R2 -======================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 -ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp -s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN -S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL -TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C -ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i -YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN -BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp -9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu -01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 -9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -ValiCert Class 1 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy -MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi -GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm -DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG -lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX -icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP -Orf1LXLI ------END CERTIFICATE----- - -ValiCert Class 2 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC -CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf -ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ -SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV -UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 -W9ViH0Pd ------END CERTIFICATE----- - -RSA Root Certificate 1 -====================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td -3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H -BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs -3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF -V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r -on+jjBXu ------END CERTIFICATE----- - -Verisign Class 1 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E -bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ -rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+ -Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB -FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N -y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 -ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h -a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc -D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== ------END CERTIFICATE----- - -Verisign Class 2 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y -azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug -b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 -c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y -aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6 -tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7 -C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS -0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs -Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0 -JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf -0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU -sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx -JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j -GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 -EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc -cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw -EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj -055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f -j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 -xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa -t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - -Verisign Class 4 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS -tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM -8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW -Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX -Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt -mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd -RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG -UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - -Entrust.net Secure Server CA -============================ ------BEGIN CERTIFICATE----- -MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg -cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl -ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG -A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi -eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p -dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ -aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 -gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw -ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw -CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l -dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF -bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu -dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw -NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow -HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA -BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN -Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 -n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= ------END CERTIFICATE----- - -Entrust.net Premium 2048 Secure Server CA -========================================= ------BEGIN CERTIFICATE----- -MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u -ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp -bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV -BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx -NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 -d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl -MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u -ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL -Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr -hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW -nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi -VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC -AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER -gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B -AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo -oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS -o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z -2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX -OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ== ------END CERTIFICATE----- - -Baltimore CyberTrust Root -========================= ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE -ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li -ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC -SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs -dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME -uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB -UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C -G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 -XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr -l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI -VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB -BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh -cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 -hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa -Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H -RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -Equifax Secure Global eBusiness CA -================================== ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp -bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx -HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds -b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV -PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN -qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn -hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs -MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN -I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY -NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 1 -============================= ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB -LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE -ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz -IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ -1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a -IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk -MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW -Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF -AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 -lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ -KpYrtWKmpj29f5JZzVoqgrI3eQ== ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 2 -============================= ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE -ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y -MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT -DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn -2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 -BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG -A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx -JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG -A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e -uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB -Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 -jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia -78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm -V+GRMOrN ------END CERTIFICATE----- - -AddTrust Low-Value Services Root -================================ ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU -cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw -CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO -ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 -54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr -oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 -Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui -GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w -HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT -RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw -HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt -ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph -iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr -mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj -ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- - -AddTrust External Root -====================== ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD -VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw -NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU -cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg -Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 -+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw -Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo -aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy -2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 -7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL -VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk -VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl -j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 -e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u -G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - -AddTrust Public Services Root -============================= ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU -cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ -BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l -dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu -nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i -d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG -Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw -HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G -A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G -A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 -JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL -+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao -GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 -Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H -EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= ------END CERTIFICATE----- - -AddTrust Qualified Certificates Root -==================================== ------BEGIN CERTIFICATE----- -MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU -cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx -CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ -IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx -64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 -KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o -L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR -wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU -MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE -BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y -azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG -GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X -dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze -RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB -iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= ------END CERTIFICATE----- - -Entrust Root Certification Authority -==================================== ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw -b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG -A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 -MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu -MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu -Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v -dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz -A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww -Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 -j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN -rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 -MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH -hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM -Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa -v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS -W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 -tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -RSA Security 2048 v3 -==================== ------BEGIN CERTIFICATE----- -MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK -ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy -MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb -BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 -Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb -WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH -KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP -+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E -FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY -v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj -0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj -VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 -nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA -pKnXwiJPZ9d37CAFYd4= ------END CERTIFICATE----- - -GeoTrust Global CA -================== ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw -MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo -BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet -8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc -T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU -vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q -zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 -d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 -mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p -XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm -Mw== ------END CERTIFICATE----- - -GeoTrust Global CA 2 -==================== ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw -MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ -NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k -LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA -Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b -HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH -K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 -srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh -ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL -OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC -x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF -H4z1Ir+rzoPz4iIprn2DQKi6bA== ------END CERTIFICATE----- - -GeoTrust Universal CA -===================== ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 -MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu -Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t -JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e -RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs -7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d -8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V -qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga -Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB -Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu -KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 -ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 -XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB -hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 -qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL -oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK -xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF -KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 -DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK -xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU -p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI -P/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -GeoTrust Universal CA 2 -======================= ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 -MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg -SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 -DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 -j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q -JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a -QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 -WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP -20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn -ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC -SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG -8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 -+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E -BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ -4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ -mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq -A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg -Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP -pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d -FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp -gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm -X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - -UTN-USER First-Network Applications -=================================== ------BEGIN CERTIFICATE----- -MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp -BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5 -WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T -YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB -cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug -mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj -DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu -Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi -P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE -j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w -HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j -cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G -CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y -IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK -RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp -xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq -DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE ------END CERTIFICATE----- - -America Online Root Certification Authority 1 -============================================= ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG -v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z -DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh -sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP -8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z -o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf -GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF -VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft -3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g -Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds -sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 ------END CERTIFICATE----- - -America Online Root Certification Authority 2 -============================================= ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en -fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 -f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO -qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN -RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 -gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn -6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid -FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 -Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj -B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op -aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY -T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p -+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg -JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy -zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO -ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh -1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf -GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff -Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP -cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= ------END CERTIFICATE----- - -Visa eCommerce Root -=================== ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG -EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug -QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 -WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm -VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL -F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b -RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 -TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI -/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs -GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG -MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc -CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW -YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz -zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu -YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- - -Certum Root CA -============== ------BEGIN CERTIFICATE----- -MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK -ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla -Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u -by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x -wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL -kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ -89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K -Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P -NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ -GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg -GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ -0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS -qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== ------END CERTIFICATE----- - -Comodo AAA Services root -======================== ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw -MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl -c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV -BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG -C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs -i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW -Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH -Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK -Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f -BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl -cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz -LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm -7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z -8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C -12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -Comodo Secure Services root -=========================== ------BEGIN CERTIFICATE----- -MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw -MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu -Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi -BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP -9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc -rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC -oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V -p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E -FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w -gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj -YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm -aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm -4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj -Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL -DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw -pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H -RR3B7Hzs/Sk= ------END CERTIFICATE----- - -Comodo Trusted Services root -============================ ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw -MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h -bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw -IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 -3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y -/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 -juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS -ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud -DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp -ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl -cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw -uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 -pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA -BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l -R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O -9y5Xt5hwXsjEeLBi ------END CERTIFICATE----- - -QuoVadis Root CA -================ ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE -ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz -MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp -cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD -EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk -J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL -F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL -YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen -AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w -PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y -ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 -MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj -YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs -ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW -Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu -BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw -FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 -tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo -fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul -LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x -gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi -5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi -5nrQNiOKSnQ2+Q== ------END CERTIFICATE----- - -QuoVadis Root CA 2 -================== ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT -EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx -ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 -XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk -lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB -lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy -lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt -66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn -wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh -D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy -BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie -J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud -DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU -a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv -Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 -UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm -VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK -+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW -IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 -WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X -f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II -4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 -VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- - -QuoVadis Root CA 3 -================== ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT -EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx -OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg -DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij -KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K -DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv -BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp -p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 -nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX -MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM -Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz -uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT -BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj -YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB -BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD -VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 -ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE -AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV -qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s -hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z -POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 -Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp -8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC -bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu -g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p -vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr -qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- - -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - -Sonera Class 1 Root CA -====================== ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG -U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw -NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh -IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88 -7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9 -EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl -0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645 -2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa -HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT -iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9 -28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV -yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR -vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P -qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z -IRlXvVWa ------END CERTIFICATE----- - -Sonera Class 2 Root CA -====================== ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG -U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw -NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh -IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 -/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT -dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG -f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P -tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH -nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT -XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt -0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI -cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph -Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx -EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH -llpwrN9M ------END CERTIFICATE----- - -Staat der Nederlanden Root CA -============================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE -ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w -HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh -bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt -vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P -jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca -C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth -vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 -22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV -HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v -dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN -BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR -EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw -MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y -nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- - -TDC Internet Root CA -==================== ------BEGIN CERTIFICATE----- -MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE -ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx -NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu -ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j -xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL -znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc -5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 -otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI -AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM -VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM -MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC -AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe -UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G -CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m -gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ -2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb -O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU -Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l ------END CERTIFICATE----- - -TDC OCES Root CA -================ ------BEGIN CERTIFICATE----- -MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE -ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5 -MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH -nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0 -zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV -iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde -dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO -3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB -5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k -ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm -cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp -Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x -LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM -MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm -aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy -MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647 -+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6 -NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4 -A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc -A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9 -AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1 -AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw== ------END CERTIFICATE----- - -UTN DATACorp SGC Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ -BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa -MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w -HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy -dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys -raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo -wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA -9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv -33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud -DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 -BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD -LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 -DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 -I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx -EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP -DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- - -UTN USERFirst Email Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0 -BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05 -OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx -FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx -ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz -dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx -B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8 -om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG -TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl -yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE -AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV -HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll -bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH -AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne -xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+ -5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV -NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ -w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= ------END CERTIFICATE----- - -UTN USERFirst Hardware Root CA -============================== ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd -BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx -OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 -eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz -ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI -wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd -tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 -i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf -Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw -gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF -lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF -UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF -BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW -XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 -lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn -iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 -nfhmqA== ------END CERTIFICATE----- - -UTN USERFirst Object Root CA -============================ ------BEGIN CERTIFICATE----- -MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb -BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz -NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx -HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy -dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR -loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ -w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu -lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7 -RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL -BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8 -ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly -c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw -DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw -NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO -PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE -qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG -hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= ------END CERTIFICATE----- - -Camerfirma Chambers of Commerce Root -==================================== ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe -QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i -ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx -NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp -cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn -MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC -AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU -xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH -NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW -DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV -d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud -EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v -cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P -AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh -bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD -VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz -aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi -fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD -L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN -UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n -ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 -erfutGWaIZDgqtCYvDi1czyL+Nw= ------END CERTIFICATE----- - -Camerfirma Global Chambersign Root -================================== ------BEGIN CERTIFICATE----- -MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe -QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i -ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx -NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt -YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg -MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw -ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J -1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O -by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl -6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c -8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ -BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j -aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B -Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj -aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y -ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh -bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA -PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y -gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ -PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 -IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes -t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== ------END CERTIFICATE----- - -NetLock Qualified (Class QA) Root -================================= ------BEGIN CERTIFICATE----- -MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn -eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0 -bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER -MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0 -LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0 -dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP -aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV -CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e -8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb -m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ -0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM -0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV -HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2 -YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh -biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p -a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz -YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg -YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg -ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov -L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr -Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0 -aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg -YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0 -IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3 -DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN -wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg -W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc -R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR -5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko ------END CERTIFICATE----- - -NetLock Notary (Class A) Root -============================= ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI -EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j -ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX -DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH -EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD -VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz -cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM -D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ -z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC -/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 -tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 -4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG -A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC -Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv -bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn -LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 -ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz -IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh -IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu -b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh -bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg -Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp -bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 -ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP -ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB -CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr -KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM -8CgHrTwXZoi1/baI ------END CERTIFICATE----- - -NetLock Business (Class B) Root -=============================== ------BEGIN CERTIFICATE----- -MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg -VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD -VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv -bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg -VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S -o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr -1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV -HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ -RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh -dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 -ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv -c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg -YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh -c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz -Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA -bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl -IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 -YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj -cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM -43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR -stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI ------END CERTIFICATE----- - -NetLock Express (Class C) Root -============================== ------BEGIN CERTIFICATE----- -MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ -BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j -ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB -jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z -W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 -euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw -DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN -RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn -YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB -IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i -aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 -ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs -ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo -dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y -emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k -IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ -UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg -YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 -xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW -gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== ------END CERTIFICATE----- - -XRamp Global CA Root -==================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE -BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj -dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx -HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg -U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu -IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx -foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE -zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs -AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry -xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap -oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC -AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc -/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n -nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz -8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -Go Daddy Class 2 CA -=================== ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY -VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG -A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g -RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD -ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv -2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 -qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j -YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY -vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O -BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o -atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu -MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG -A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim -PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt -I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI -Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b -vZ8= ------END CERTIFICATE----- - -Starfield Class 2 CA -==================== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc -U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo -MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG -A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG -SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY -bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ -JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm -epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN -F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF -MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f -hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo -bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g -QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs -afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM -PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD -KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 -QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -StartCom Certification Authority -================================ ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu -ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 -NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk -LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg -U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y -o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ -Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d -eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt -2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z -6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ -osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ -untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc -UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT -37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj -YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH -AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw -Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg -U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 -LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh -cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT -dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC -AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh -3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm -vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk -fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 -fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ -EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl -1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ -lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro -g14= ------END CERTIFICATE----- - -Taiwan GRCA -=========== ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG -EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X -DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv -dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN -w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 -BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O -1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO -htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov -J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 -Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t -B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB -O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 -lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV -HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 -09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj -Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 -Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU -D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz -DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk -Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk -7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ -CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy -+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS ------END CERTIFICATE----- - -Firmaprofesional Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT -GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp -Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA -ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL -MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT -OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2 -ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V -j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH -lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf -3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8 -NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww -KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG -AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD -ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq -u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf -wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm -7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG -VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA= ------END CERTIFICATE----- - -Wells Fargo Root CA -=================== ------BEGIN CERTIFICATE----- -MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl -bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv -MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX -x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3 -E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5 -OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j -sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj -YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF -BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD -ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv -m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R -OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx -x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023 -tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= ------END CERTIFICATE----- - -Swisscom Root CA 1 -================== ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG -EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy -dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 -MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln -aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC -IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM -MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF -NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe -AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC -b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn -7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN -cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp -WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 -haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY -MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw -HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j -BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 -MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn -jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ -MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H -VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl -vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl -OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 -1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq -nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy -x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW -NY6E0F/6MBr1mmz0DlP5OlvRHA== ------END CERTIFICATE----- - -DigiCert Assured ID Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx -MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO -9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy -UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW -/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy -oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf -GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF -66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq -hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc -EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn -SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i -8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -DigiCert Global Root CA -======================= ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -DigiCert High Assurance EV Root CA -================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw -KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw -MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ -MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu -Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t -Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS -OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 -MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ -NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe -h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY -JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ -V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp -myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK -mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K ------END CERTIFICATE----- - -Certplus Class 2 Primary CA -=========================== ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE -BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN -OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy -dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR -5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ -Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO -YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e -e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME -CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ -YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t -L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD -P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R -TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ -7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW -//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - -DST Root CA X3 -============== ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK -ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X -DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 -cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT -rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 -UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy -xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d -utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ -MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug -dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE -GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw -RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS -fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - -DST ACES CA X6 -============== ------BEGIN CERTIFICATE----- -MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT -MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha -MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE -CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI -DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa -pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow -GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy -MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu -Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy -dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU -CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 -5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t -Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq -nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs -vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 -oKfN5XozNmr6mis= ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 1 -============================================== ------BEGIN CERTIFICATE----- -MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP -MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 -acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx -MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB -TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC -aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX -yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i -Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ -8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 -W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME -BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 -sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE -q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy -B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY -nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 2 -============================================== ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP -MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg -QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN -MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr -dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G -A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls -acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe -LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI -x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g -QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr -5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB -AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt -Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 -Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ -hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P -9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 -UrbnBEI= ------END CERTIFICATE----- - -SwissSign Platinum CA - G2 -========================== ------BEGIN CERTIFICATE----- -MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCQ0gxFTAT -BgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIw -HhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAwWjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMM -U3dpc3NTaWduIEFHMSMwIQYDVQQDExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu -669yIIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2HtnIuJpX+UF -eNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+6ixuEFGSzH7VozPY1kne -WCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5objM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIo -j5+saCB9bzuohTEJfwvH6GXp43gOCWcwizSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/6 -8++QHkwFix7qepF6w9fl+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34T -aNhxKFrYzt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaPpZjy -domyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtFKwH3HBqi7Ri6Cr2D -+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuWae5ogObnmLo2t/5u7Su9IPhlGdpV -CX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMBAAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCv -zAeHFUdvOMW0ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW -IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUAA4ICAQAIhab1 -Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0uMoI3LQwnkAHFmtllXcBrqS3 -NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4 -U99REJNi54Av4tHgvI42Rncz7Lj7jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8 -KV2LwUvJ4ooTHbG/u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl -9x8DYSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1puEa+S1B -aYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXaicYwu+uPyyIIoK6q8QNs -OktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbGDI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSY -Mdp08YSTcU1f+2BY0fvEwW2JorsgH51xkcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAci -IfNAChs0B0QTwoRqjt8ZWr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== ------END CERTIFICATE----- - -SwissSign Gold CA - G2 -====================== ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw -EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN -MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp -c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq -t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C -jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg -vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF -ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR -AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend -jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO -peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR -7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi -GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 -OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm -5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr -44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf -Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m -Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp -mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk -vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf -KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br -NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj -viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- - -SwissSign Silver CA - G2 -======================== ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT -BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X -DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 -aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG -9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 -N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm -+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH -6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu -MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h -qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 -FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs -ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc -celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X -CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB -tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P -4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F -kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L -3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx -/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa -DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP -e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu -WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ -DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub -DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority -======================================== ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx -CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ -cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN -b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 -nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge -RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt -tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI -hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K -Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN -NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa -Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG -1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -thawte Primary Root CA -====================== ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 -MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg -SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv -KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT -FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs -oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ -1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc -q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K -aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p -afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF -AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE -uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 -jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH -z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G5 -============================================================ ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln -biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh -dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz -j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD -Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r -fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ -BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv -Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG -SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ -X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE -KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC -Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE -ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - -SecureTrust CA -============== ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy -dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe -BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX -OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t -DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH -GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b -01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH -ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj -aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu -SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf -mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ -nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -Secure Global CA -================ ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH -bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg -MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg -Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx -YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ -bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g -8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV -HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi -0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn -oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA -MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ -OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn -CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 -3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -COMODO Certification Authority -============================== ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE -BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG -A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb -MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD -T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH -+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww -xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV -4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA -1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI -rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k -b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC -AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP -OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc -IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN -+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== ------END CERTIFICATE----- - -Network Solutions Certificate Authority -======================================= ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG -EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr -IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx -MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx -jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT -aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT -crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc -/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB -AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv -bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA -A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q -4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ -GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD -ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - -WellsSecure Public Root Certificate Authority -============================================= ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM -F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw -NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl -bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD -VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 -iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 -i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 -bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB -K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB -AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu -cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm -lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB -i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww -GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI -K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 -bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj -qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es -E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ -tylv2G0xffX8oRAHh84vWdw+WNs= ------END CERTIFICATE----- - -COMODO ECC Certification Authority -================================== ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC -R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE -ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix -GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X -4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni -wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG -FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA -U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -IGC/A -===== ------BEGIN CERTIFICATE----- -MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD -VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE -Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy -MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI -EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT -STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 -TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW -So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy -HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd -frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ -tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB -egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC -iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK -q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q -MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg -Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI -lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF -0mBWWg== ------END CERTIFICATE----- - -Security Communication EV RootCA1 -================================= ------BEGIN CERTIFICATE----- -MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE -BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl -Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO -/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX -WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z -ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 -bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK -9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm -iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG -Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW -mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW -T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 ------END CERTIFICATE----- - -OISTE WISeKey Global Root GA CA -=============================== ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE -BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG -A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH -bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD -VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw -IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 -IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 -Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg -Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD -d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ -/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R -LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm -MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 -+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY -okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= ------END CERTIFICATE----- - -S-TRUST Authentication and Encryption Root CA 2005 PN -===================================================== ------BEGIN CERTIFICATE----- -MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE -BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh -cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT -LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w -NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk -ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj -aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp -b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob -4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL -g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf -eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3 -KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB -/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv -bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU -D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD -pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08 -P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA -nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit -F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b -Hz2eBIPdltkdOpQ= ------END CERTIFICATE----- - -Microsec e-Szigno Root CA -========================= ------BEGIN CERTIFICATE----- -MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE -BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL -EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 -MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz -dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT -GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG -d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N -oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc -QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ -PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb -MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG -IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD -VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 -LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A -dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn -AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA -4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg -AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA -egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 -Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO -PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv -c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h -cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw -IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT -WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV -MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER -MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp -Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal -HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT -nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE -aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a -86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK -yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB -S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= ------END CERTIFICATE----- - -Certigna -======== ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw -EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 -MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI -Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q -XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH -GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p -ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg -DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf -Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ -tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ -BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J -SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA -hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ -ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu -PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY -1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. -====================================== ------BEGIN CERTIFICATE----- -MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT -AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg -LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w -HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ -U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh -IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN -yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU -2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 -4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP -2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm -8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf -HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa -Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK -5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b -czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g -ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF -BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug -cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf -AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX -EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v -/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 -MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 -3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk -eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f -/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h -RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU -Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== ------END CERTIFICATE----- - -TC TrustCenter Class 2 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw -MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw -IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 -xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ -Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u -SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G -dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ -KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj -TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP -JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk -vQ== ------END CERTIFICATE----- - -TC TrustCenter Class 3 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw -MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W -yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo -6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ -uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk -2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE -O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 -yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 -IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal -092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc -5A== ------END CERTIFICATE----- - -TC TrustCenter Universal CA I -============================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN -MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg -VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw -JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC -qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv -xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw -ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O -gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j -BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG -1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy -vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 -ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a -7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- - -Deutsche Telekom Root CA 2 -========================== ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT -RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG -A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 -MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G -A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS -b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 -bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI -KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY -AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK -Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV -jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV -HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr -E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy -zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 -rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G -dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - -ComSign CA -========== ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD -EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy -MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp -Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q -ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy -P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN -GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk -YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM -rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy -oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P -AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+ -VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2 -QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI -mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb -/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG -zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U -AGegcQCCSA== ------END CERTIFICATE----- - -ComSign Secured CA -================== ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE -AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w -NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD -QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs -49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH -7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB -kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 -9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw -AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t -U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA -j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC -AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a -BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp -FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP -51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- - -Cybertrust Global Root -====================== ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li -ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 -MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD -ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW -0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL -AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin -89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT -8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 -MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G -A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO -lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi -5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 -hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T -X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - -ePKI Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx -MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq -MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs -IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi -lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv -qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX -12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O -WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ -ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao -lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ -vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi -Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi -MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 -1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq -KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV -xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP -NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r -GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE -xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx -gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy -sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD -BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 -============================================================================================================================= ------BEGIN CERTIFICATE----- -MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH -DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q -aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry -b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV -BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg -S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 -MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl -IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF -n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl -IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft -dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl -cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO -Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 -xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR -6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL -hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd -BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 -N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT -y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh -LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M -dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= ------END CERTIFICATE----- - -Buypass Class 2 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 -MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M -cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 -0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 -0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R -uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV -1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt -7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 -fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w -wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho ------END CERTIFICATE----- - -Buypass Class 3 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 -MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx -ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 -n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia -AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c -1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 -pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA -EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 -htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj -el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------END CERTIFICATE----- - -EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 -========================================================================== ------BEGIN CERTIFICATE----- -MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg -QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe -Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p -ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt -IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by -X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b -gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr -eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ -TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy -Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn -uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI -qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm -ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 -Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB -/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW -Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t -FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm -zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k -XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT -bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU -RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK -1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt -2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ -Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 -AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT ------END CERTIFICATE----- - -certSIGN ROOT CA -================ ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD -VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa -Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE -CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I -JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH -rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 -ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD -0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 -AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B -Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB -AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 -SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 -x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt -vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz -TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -CNNIC ROOT -========== ------BEGIN CERTIFICATE----- -MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE -ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw -OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD -o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz -VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT -VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or -czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK -y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC -wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S -lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 -Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM -O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 -BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 -G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m -mxE= ------END CERTIFICATE----- - -ApplicationCA - Japanese Government -=================================== ------BEGIN CERTIFICATE----- -MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT -SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw -MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl -cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 -fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN -wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE -jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu -nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU -WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV -BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD -vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs -o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g -/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD -io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW -dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL -rosot4LKGAfmt1t06SAZf7IbiVQ= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G3 -============================================= ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 -IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz -NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo -YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT -LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j -K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE -c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C -IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu -dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr -2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 -cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE -Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s -t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -thawte Primary Root CA - G2 -=========================== ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC -VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu -IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg -Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV -MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG -b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt -IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS -LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 -8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU -mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN -G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K -rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -thawte Primary Root CA - G3 -=========================== ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w -ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD -VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG -A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At -P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC -+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY -7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW -vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ -KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK -A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC -8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm -er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G2 -============================================= ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu -Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 -OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl -b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG -BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc -KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ -EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m -ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 -npaqBA+K ------END CERTIFICATE----- - -VeriSign Universal Root Certification Authority -=============================================== ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj -1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP -MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 -9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I -AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR -tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G -CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O -a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 -Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx -Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx -P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P -wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 -mJO37M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G4 -============================================================ ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC -VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 -b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz -ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU -cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo -b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 -Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz -rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw -HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u -Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD -A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx -AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - -NetLock Arany (Class Gold) Főtanúsítvány -============================================ ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G -A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 -dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB -cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx -MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO -ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 -c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu -0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw -/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk -H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw -fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 -neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW -qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta -YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna -NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu -dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -Staat der Nederlanden Root CA - G2 -================================== ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE -CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC -TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l -ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ -5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn -vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj -CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil -e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR -OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI -CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 -48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi -trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 -qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB -AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC -ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA -A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz -+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj -f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN -kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk -CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF -URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb -CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h -oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV -IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm -66+KAQ== ------END CERTIFICATE----- - -CA Disig -======== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK -QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw -MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz -bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm -GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD -Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo -hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt -ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w -gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P -AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz -aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff -ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa -BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t -WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 -mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K -ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA -4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- - -Juur-SK -======= ------BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA -c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw -DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG -SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy -aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf -TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC -+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw -UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa -Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF -MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD -HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh -AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA -cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr -AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw -cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE -FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G -A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo -ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL -abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 -IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh -Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 -yyqcjg== ------END CERTIFICATE----- - -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - -SecureSign RootCA11 -=================== ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi -SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS -b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw -KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 -cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL -TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO -wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq -g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP -O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA -bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX -t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh -OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r -bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ -Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 -y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 -lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - -ACEDICOM Root -============= ------BEGIN CERTIFICATE----- -MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD -T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 -MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG -A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk -WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD -YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew -MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb -m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk -HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT -xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 -3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 -2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq -TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz -4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU -9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv -bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg -aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP -eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk -zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 -ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI -KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq -nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE -I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp -MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o -tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== ------END CERTIFICATE----- - -Verisign Class 1 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ -VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2 -yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa -XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n -0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ -RjXZ+Hxb ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky -CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX -bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ -D/xwzoiQ ------END CERTIFICATE----- - -Microsec e-Szigno Root CA 2009 -============================== ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER -MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv -c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE -BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt -U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA -fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG -0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA -pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm -1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC -AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf -QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE -FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o -lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX -I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 -yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi -LXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi -=================================================== ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz -ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 -MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 -cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u -aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY -8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y -jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI -JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk -9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG -SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d -F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq -D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 -Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- - -GlobalSign Root CA - R3 -======================= ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt -iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ -0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 -rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl -OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 -xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 -lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 -EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E -bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 -YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r -kpeDMdmztcpHWD9f ------END CERTIFICATE----- - -TC TrustCenter Universal CA III -=============================== ------BEGIN CERTIFICATE----- -MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe -Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU -QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex -KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt -QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO -juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut -CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1 -M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G -A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA -g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+ -KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK -BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV -CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq -woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== ------END CERTIFICATE----- - -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - -Izenpe.com -========== ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG -EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz -MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu -QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ -03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK -ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU -+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC -PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT -OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK -F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK -0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ -0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB -leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID -AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ -SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG -NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O -BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l -Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga -kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q -hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs -g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 -aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 -nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC -ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo -Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z -WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- - -Chambers of Commerce Root - 2008 -================================ ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy -Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl -ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF -EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl -cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA -XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj -h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ -ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk -NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g -D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 -lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ -0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 -EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI -G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ -BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh -bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh -bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC -CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH -AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 -wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH -3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU -RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 -M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 -YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF -9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK -zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG -nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ ------END CERTIFICATE----- - -Global Chambersign Root - 2008 -============================== ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx -NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg -Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ -QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf -VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf -XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 -ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB -/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA -TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M -H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe -Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF -HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB -AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT -BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE -BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm -aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm -aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp -1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 -dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG -/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 -ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s -dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg -9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH -foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du -qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr -P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq -c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- - -Go Daddy Root Certificate Authority - G2 -======================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu -MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G -A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq -9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD -+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd -fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl -NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 -BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac -vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r -5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV -N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 ------END CERTIFICATE----- - -Starfield Root Certificate Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw -DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg -VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB -dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv -W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs -bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk -N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf -ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU -JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol -TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx -4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw -F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ -c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -Starfield Services Root Certificate Authority - G2 -================================================== ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl -IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT -dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 -h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa -hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP -LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB -rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG -SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP -E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy -xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza -YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 ------END CERTIFICATE----- - -AffirmTrust Commercial -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw -MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb -DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV -C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 -BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww -MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV -HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG -hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi -qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv -0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh -sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -AffirmTrust Networking -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw -MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE -Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI -dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 -/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb -h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV -HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu -UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 -12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 -WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 -/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -AffirmTrust Premium -=================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy -OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy -dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn -BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV -5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs -+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd -GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R -p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI -S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 -6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 -/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo -+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv -MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC -6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S -L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK -+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV -BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg -IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 -g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb -zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== ------END CERTIFICATE----- - -AffirmTrust Premium ECC -======================= ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV -BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx -MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U -cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ -N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW -BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK -BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X -57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM -eQ== ------END CERTIFICATE----- - -Certum Trusted Network CA -========================= ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK -ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy -MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU -ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC -l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J -J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 -fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 -cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB -Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw -DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj -jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 -mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj -Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -Certinomis - Autorité Racine -============================= ------BEGIN CERTIFICATE----- -MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK -Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg -LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG -A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw -JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa -wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly -Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw -2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N -jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q -c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC -lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb -xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g -530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna -4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ -KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x -WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva -R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 -nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B -CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv -JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE -qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b -WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE -wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ -vgt2Fl43N+bYdJeimUV5 ------END CERTIFICATE----- - -Root CA Generalitat Valenciana -============================== ------BEGIN CERTIFICATE----- -MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE -ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 -IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 -WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE -CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 -F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B -ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ -D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte -JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB -AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n -dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB -ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl -AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA -YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy -AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA -aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt -AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA -YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu -AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA -OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 -dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV -BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G -A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S -b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh -TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz -Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 -NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH -iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt -+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= ------END CERTIFICATE----- - -A-Trust-nQual-03 -================ ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE -Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy -a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R -dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw -RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 -ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 -c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA -zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n -yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE -SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 -iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V -cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV -eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 -ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr -sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd -JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS -mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 -ahq97BvIxYSazQ== ------END CERTIFICATE----- - -TWCA Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ -VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG -EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB -IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx -QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC -oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP -4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r -y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG -9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC -mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW -QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY -T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny -Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -Security Communication RootCA2 -============================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC -SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy -aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ -+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R -3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV -spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K -EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 -QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj -u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk -3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q -tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 -mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -EC-ACC -====== ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE -BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w -ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD -VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE -CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT -BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 -MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt -SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl -Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh -cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK -w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT -ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 -HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a -E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw -0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD -VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 -Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l -dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ -lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa -Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe -l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 -E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D -5EI= ------END CERTIFICATE----- - -Hellenic Academic and Research Institutions RootCA 2011 -======================================================= ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT -O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y -aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT -AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo -IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI -1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa -71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u -8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH -3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ -MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 -MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu -b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt -XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD -/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N -7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- - -Actalis Authentication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM -BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE -AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky -MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz -IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ -wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa -by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 -zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f -YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 -oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l -EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 -hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 -EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 -jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY -iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI -WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 -JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx -K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ -Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC -4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo -2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz -lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem -OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 -vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -Trustis FPS Root CA -=================== ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG -EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 -IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV -BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ -RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk -H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa -cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt -o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA -AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd -BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c -GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC -yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P -8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV -l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl -iB6XzCGcKQENZetX2fNXlrtIzYE= ------END CERTIFICATE----- - -StartCom Certification Authority -================================ ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu -ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 -NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk -LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg -U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y -o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ -Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d -eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt -2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z -6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ -osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ -untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc -UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT -37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ -Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 -dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu -c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv -bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 -aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t -L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG -cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 -fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm -N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN -Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T -tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX -e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA -2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs -HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib -D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= ------END CERTIFICATE----- - -StartCom Certification Authority G2 -=================================== ------BEGIN CERTIFICATE----- -MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE -ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O -o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG -4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi -Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul -Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs -O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H -vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L -nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS -FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa -z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ -KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K -2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk -J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ -JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG -/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc -nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld -blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc -l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm -7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm -obp573PYtlNXLfbQ4ddI ------END CERTIFICATE----- - -Buypass Class 2 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X -DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 -g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn -9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b -/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU -CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff -awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI -zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn -Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX -Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs -M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI -osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S -aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd -DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD -LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 -oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC -wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS -CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN -rJgWVqA= ------END CERTIFICATE----- - -Buypass Class 3 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X -DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH -sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR -5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh -7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ -ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH -2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV -/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ -RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA -Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq -j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G -uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG -Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 -ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 -KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz -6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug -UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe -eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi -Cp/HuZc= ------END CERTIFICATE----- - -TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı -====================================================== ------BEGIN CERTIFICATE----- -MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP -MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg -QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X -DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl -a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN -BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp -bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N -YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv -KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya -KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT -rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC -AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s -Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I -aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO -Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb -BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK -poRq0Tl9 ------END CERTIFICATE----- - -T-TeleSec GlobalRoot Class 3 -============================ ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM -IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU -cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx -MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz -dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD -ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK -9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU -NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF -iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W -0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr -AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb -fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT -ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h -P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== ------END CERTIFICATE----- - -EE Certification Centre Root CA -=============================== ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy -dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw -MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB -UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy -ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM -TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 -rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw -93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN -P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ -MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF -BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj -xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM -lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU -3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM -dcGWxZ0= ------END CERTIFICATE----- diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index f7e1b2482..0b72bf31e 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -56,15 +56,30 @@ public function testCanOpenGetCurlConnection() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with([ - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_HTTPHEADER => ['X-Foo-Header: X-Bar'], - CURLOPT_URL => 'http://foo.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 123, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - ]) + ->with(m::on(function($arg) { + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_HTTPHEADER => ['X-Foo-Header: X-Bar'], + CURLOPT_URL => 'http://foo.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 123, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) ->once() ->andReturn(null); @@ -79,33 +94,37 @@ public function testCanOpenCurlConnectionWithPostBody() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with([ - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_HTTPHEADER => [], - CURLOPT_URL => 'http://bar.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POSTFIELDS => 'baz=bar', - ]) + ->with(m::on(function($arg) { + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_HTTPHEADER => [], + CURLOPT_URL => 'http://bar.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 60, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_POSTFIELDS => 'baz=bar', + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) ->once() ->andReturn(null); $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', [], 60); } - public function testCanAddBundledCert() - { - $this->curlMock - ->shouldReceive('setopt') - ->with(CURLOPT_CAINFO, '/.fb_ca_chain_bundle\.crt$/') - ->once() - ->andReturn(null); - - $this->curlClient->addBundledCert(); - } - public function testCanCloseConnection() { $this->curlMock @@ -116,24 +135,6 @@ public function testCanCloseConnection() $this->curlClient->closeConnection(); } - public function testTrySendRequest() - { - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn('foo response'); - $this->curlMock - ->shouldReceive('errno') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('error') - ->once() - ->andReturn(null); - - $this->curlClient->tryToSendRequest(); - } - public function testIsolatesTheHeaderAndBody() { $this->curlMock @@ -271,10 +272,6 @@ public function testCanSendNormalRequest() ->shouldReceive('errno') ->once() ->andReturn(null); - $this->curlMock - ->shouldReceive('error') - ->once() - ->andReturn(null); $this->curlMock ->shouldReceive('getinfo') ->with(CURLINFO_HEADER_SIZE) diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index b5bb678fa..4e3b2057e 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -25,6 +25,10 @@ use Mockery as m; use Facebook\HttpClients\FacebookGuzzleHttpClient; +use GuzzleHttp\Message\Request; +use GuzzleHttp\Message\Response; +use GuzzleHttp\Stream\Stream; +use GuzzleHttp\Exception\RequestException; class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient { @@ -47,38 +51,38 @@ public function setUp() public function testCanSendNormalRequest() { - $responseMock = m::mock('GuzzleHttp\Message\ResponseInterface'); - $responseMock - ->shouldReceive('getStatusCode') - ->once() - ->andReturn(200); - $responseMock - ->shouldReceive('getHeaders') - ->once() - ->andReturn($this->fakeHeadersAsArray); - $responseMock - ->shouldReceive('getBody') - ->once() - ->andReturn($this->fakeRawBody); + $request = new Request('GET', 'http://foo.com'); - $options = [ - 'headers' => ['X-foo' => 'bar'], - 'body' => 'foo_body', - 'timeout' => 123, - 'connect_timeout' => 10, - ]; + $body = Stream::factory($this->fakeRawBody); + $response = new Response(200, $this->fakeHeadersAsArray, $body); - $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', $options) - ->andReturn($requestMock); + ->with('GET', 'http://foo.com/', m::on(function($arg) { + $caInfo = array_diff_assoc($arg, [ + 'headers' => ['X-foo' => 'bar'], + 'body' => 'foo_body', + 'timeout' => 123, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); $this->guzzleMock ->shouldReceive('send') ->once() - ->with($requestMock) - ->andReturn($responseMock); + ->with($request) + ->andReturn($response); $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); @@ -93,33 +97,35 @@ public function testCanSendNormalRequest() */ public function testThrowsExceptionOnClientError() { - $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); - $exceptionMock = m::mock( - 'GuzzleHttp\Exception\RequestException', - [ - 'Foo Error', - $requestMock, - null, - m::mock('GuzzleHttp\Ring\Exception\RingException'), - ]); - - $options = [ - 'headers' => [], - 'body' => 'foo_body', - 'timeout' => 60, - 'connect_timeout' => 10, - ]; + $request = new Request('GET', 'http://foo.com'); $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', $options) - ->andReturn($requestMock); + ->with('GET', 'http://foo.com/', m::on(function($arg) { + $caInfo = array_diff_assoc($arg, [ + 'headers' => [], + 'body' => 'foo_body', + 'timeout' => 60, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); $this->guzzleMock ->shouldReceive('send') ->once() - ->with($requestMock) - ->andThrow($exceptionMock); + ->with($request) + ->andThrow(new RequestException('Foo', $request)); $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); } diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index fc1e99114..9f9247c5f 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -60,8 +60,8 @@ public function testCanSendNormalRequest() $this->streamMock ->shouldReceive('streamContextCreate') ->once() - ->with(\Mockery::on(function($arg) { - if (!isset($arg['http']) || !isset($arg['ssl'])) { + ->with(m::on(function($arg) { + if ( ! isset($arg['http']) || ! isset($arg['ssl'])) { return false; } @@ -75,11 +75,17 @@ public function testCanSendNormalRequest() return false; } - if ($arg['ssl']['verify_peer'] !== true) { + $caInfo = array_diff_assoc($arg['ssl'], [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, + ]); + + if (count($caInfo) !== 1) { return false; } - if (false === preg_match('/.fb_ca_chain_bundle\.crt$/', $arg['ssl']['cafile'])) { + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['cafile'])) { return false; } From 9ae638c90805772199aa18fcc686924d24599203 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 3 Dec 2014 19:31:53 -0600 Subject: [PATCH 074/407] Added injectable CSPRSG --- docs/Facebook.fbmd | 24 ++++ .../PseudoRandomStringGeneratorInterface.fbmd | 65 ++++++++++ docs/sdk_reference.fbmd | 6 +- src/Facebook/Facebook.php | 36 ++++-- .../Helpers/FacebookRedirectLoginHelper.php | 122 +++++++++--------- .../McryptPseudoRandomStringGenerator.php | 70 ++++++++++ .../OpenSslPseudoRandomStringGenerator.php | 79 ++++++++++++ .../PseudoRandomStringGeneratorInterface.php | 46 +++++++ .../PseudoRandomStringGeneratorTrait.php | 64 +++++++++ .../UrandomPseudoRandomStringGenerator.php | 86 ++++++++++++ tests/FacebookTest.php | 105 +++++++++++++-- .../FacebookRedirectLoginHelperTest.php | 37 ++++-- .../McryptPseudoRandomStringGeneratorTest.php | 46 +++++++ ...OpenSslPseudoRandomStringGeneratorTest.php | 46 +++++++ .../PseudoRandomStringGeneratorTraitTest.php | 54 ++++++++ ...UrandomPseudoRandomStringGeneratorTest.php | 52 ++++++++ 16 files changed, 846 insertions(+), 92 deletions(-) create mode 100644 docs/PseudoRandomStringGeneratorInterface.fbmd create mode 100644 src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php create mode 100644 src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php create mode 100755 src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php create mode 100644 src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php create mode 100644 src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php create mode 100644 tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php create mode 100644 tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php create mode 100644 tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php create mode 100644 tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index a2e7a2be5..1faf1b99e 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -56,6 +56,7 @@ $fb = new Facebook\Facebook([ 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), + 'pseudo_random_string_generator' => new MyPseudoRandomStringGenerator(), ]); ~~~~ @@ -117,6 +118,29 @@ $fb = new Facebook([ ]); ~~~~ +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`. + +~~~~ +$fb = new Facebook([ + 'pseudo_random_string_generator' => 'openssl', +]); +~~~~ + +You can write your own CSPRSG that implements the `[Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface](/docs/php/PseudoRandomStringGeneratorInterface)` and set the value of `pseudo_random_string_generator` to an instance of your custom generator. + +~~~~ +$fb = new Facebook([ + 'pseudo_random_string_generator' => new MyPseudoRandomStringGenerator(), +]); +~~~~ + If any other value is provided an `InvalidArgumentException` will be thrown. diff --git a/docs/PseudoRandomStringGeneratorInterface.fbmd b/docs/PseudoRandomStringGeneratorInterface.fbmd new file mode 100644 index 000000000..e0aa5d819 --- /dev/null +++ b/docs/PseudoRandomStringGeneratorInterface.fbmd @@ -0,0 +1,65 @@ + +# 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 {#overview} + +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: + +~~~~ +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. + +~~~~ +$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. + +~~~~ +use Facebook\Helpers\FacebookRedirectLoginHelper; + +$myPseudoRandomStringGenerator = new MyCustomPseudoRandomStringGenerator(); +$helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStringGenerator); +~~~~ + + + +## Method Reference {#method-reference} + +### getPseudoRandomString() {#get-pseudo-random-string} +~~~~ +public string getPseudoRandomString(int $length) +~~~~ +Returns a cryptographically secure pseudo-random string that is `$length` characters long. + diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 2244c1bd6..c53f9f4a2 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -223,7 +223,7 @@ FB(devsite:markdown-wiki:table { # Interfaces {#interfaces} -Interfaces you can code to. +You can overwrite certain functionality of the SDK by coding to an interface. FB(devsite:markdown-wiki:table { columns: ['Interface name','Description',], @@ -240,6 +240,10 @@ FB(devsite:markdown-wiki:table { '`[Facebook\Url\UrlDetectionInterface](/docs/php/UrlDetectionInterface)`', 'Interface to code your own URL detection logic.', ], + [ + '`[Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface](/docs/php/PseudoRandomStringGeneratorInterface)`', + 'Interface to code your own cryptographically secure pseudo-random string generator.', + ], ], }) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index a43fba284..f1af7e40f 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -34,6 +34,10 @@ use Facebook\GraphNodes\GraphList; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; +use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; @@ -90,6 +94,12 @@ class Facebook */ protected $urlDetectionHandler; + /** + * @var PseudoRandomStringGeneratorInterface|null The cryptographically secure + * pseudo-random string generator. + */ + protected $pseudoRandomStringGenerator; + /** * @var AccessToken|null The default access token to use with requests. */ @@ -110,13 +120,6 @@ class Facebook */ protected $lastResponse; - /** - * @TODO Add FacebookInputInterface - * @TODO Add FacebookRandomGeneratorInterface - * @TODO Add FacebookRequestInterface - * @TODO Add FacebookResponseInterface - */ - /** * Instantiates a new Facebook super-class object. * @@ -178,6 +181,22 @@ public function __construct(array $config = []) } } + if (isset($config['pseudo_random_string_generator'])) { + if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) { + $this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator']; + } elseif ($config['pseudo_random_string_generator'] === 'mcrypt') { + $this->pseudoRandomStringGenerator = new McryptPseudoRandomStringGenerator(); + } elseif ($config['pseudo_random_string_generator'] === 'openssl') { + $this->pseudoRandomStringGenerator = new OpenSslPseudoRandomStringGenerator(); + } elseif ($config['pseudo_random_string_generator'] === 'urandom') { + $this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator(); + } else { + throw new \InvalidArgumentException( + 'The pseudo_random_string_generator must be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface' + ); + } + } + if (isset($config['persistent_data_handler'])) { if ( $config['persistent_data_handler'] instanceof PersistentDataInterface) { $this->persistentDataHandler = $config['persistent_data_handler']; @@ -283,7 +302,8 @@ public function getRedirectLoginHelper() return new FacebookRedirectLoginHelper( $this->app, $this->persistentDataHandler, - $this->urlDetectionHandler + $this->urlDetectionHandler, + $this->pseudoRandomStringGenerator ); } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index e6f1219ec..97209967c 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -31,6 +31,10 @@ use Facebook\Url\FacebookUrlManipulator; use Facebook\PersistentData\PersistentDataInterface; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; +use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; +use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookClient; @@ -43,6 +47,11 @@ class FacebookRedirectLoginHelper { + /** + * @const int The length of CSRF string to validate the login link. + */ + const CSRF_LENGTH = 32; + /** * @var FacebookApp The FacebookApp entity. */ @@ -58,20 +67,30 @@ class FacebookRedirectLoginHelper */ protected $persistentDataHandler; + /** + * @var PseudoRandomStringGeneratorInterface The cryptographically secure + * pseudo-random string generator. + */ + protected $pseudoRandomStringGenerator; + /** * Constructs a RedirectLoginHelper for a given appId. * * @param FacebookApp $app The FacebookApp entity. * @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(FacebookApp $app, PersistentDataInterface $persistentDataHandler = null, - UrlDetectionInterface $urlHandler = null) + UrlDetectionInterface $urlHandler = null, + PseudoRandomStringGeneratorInterface $prsg = null) { $this->app = $app; $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); + $this->pseudoRandomStringGenerator = $prsg ?: $this->detectPseudoRandomStringGenerator(); } /** @@ -94,6 +113,42 @@ public function getUrlDetectionHandler() return $this->urlDetectionHandler; } + /** + * Returns the cryptographically secure pseudo-random string generator. + * + * @return PseudoRandomStringGeneratorInterface + */ + public function getPseudoRandomStringGenerator() + { + return $this->pseudoRandomStringGenerator; + } + + /** + * Detects which pseudo-random string generator to use. + * + * @return PseudoRandomStringGeneratorInterface + * + * @throws FacebookSDKException + */ + public function detectPseudoRandomStringGenerator() + { + // Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically + // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() first. + if(function_exists('mcrypt_create_iv')) { + return new McryptPseudoRandomStringGenerator(); + } + if(function_exists('openssl_random_pseudo_bytes')) { + return new OpenSslPseudoRandomStringGenerator(); + } + if( ! ini_get('open_basedir') && is_readable('/dev/urandom')) { + return new UrandomPseudoRandomStringGenerator(); + } + + throw new FacebookSDKException( + 'Unable to detect a cryptographically secure pseudo-random string generator.' + ); + } + /** * Stores CSRF state and returns a URL to which the user should be sent to * in order to continue the login process with Facebook. The @@ -118,8 +173,10 @@ public function getLoginUrl($redirectUrl, $separator = '&') { $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; - $state = $this->generateState(); + + $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state); + $params = [ 'client_id' => $this->app->getId(), 'redirect_uri' => $redirectUrl, @@ -276,65 +333,4 @@ private function getInput($key) return isset($_GET[$key]) ? $_GET[$key] : null; } - /** - * Generate a state string for CSRF protection. - * - * @return string - */ - protected function generateState() - { - return $this->random(16); - } - - /** - * Generate a cryptographically secure pseudrandom number. - * - * @param int $bytes Number of bytes to return. - * - * @return string - * - * @throws FacebookSDKException - * - * @TODO Add support for Windows platforms. - */ - private function random($bytes) - { - if (!is_numeric($bytes)) { - throw new FacebookSDKException( - "random() expects an integer" - ); - } - if ($bytes < 1) { - throw new FacebookSDKException( - "random() expects an integer greater than zero" - ); - } - $buf = ''; - // http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ - if (!ini_get('open_basedir') - && is_readable('/dev/urandom')) { - $fp = fopen('/dev/urandom', 'rb'); - if ($fp !== FALSE) { - $buf = fread($fp, $bytes); - fclose($fp); - if($buf !== FALSE) { - return bin2hex($buf); - } - } - } - - if (function_exists('mcrypt_create_iv')) { - $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); - if ($buf !== FALSE) { - return bin2hex($buf); - } - } - - while (strlen($buf) < $bytes) { - $buf .= md5(uniqid(mt_rand(), true), true); - // We are appending raw binary - } - return bin2hex(substr($buf, 0, $bytes)); - } - } diff --git a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php new file mode 100644 index 000000000..51c7fa3d0 --- /dev/null +++ b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php @@ -0,0 +1,70 @@ +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 new file mode 100644 index 000000000..68a1c8895 --- /dev/null +++ b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php @@ -0,0 +1,79 @@ +validateLength($length); + + $wasCryptographicallyStrong = false; + $binaryString = openssl_random_pseudo_bytes($length, $wasCryptographicallyStrong); + + if ($binaryString === false) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'openssl_random_pseudo_bytes() returned an unknown error.' + ); + } + + if ($wasCryptographicallyStrong !== true) { + 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.' + ); + } + + return $this->binToHex($binaryString, $length); + } + +} diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php new file mode 100755 index 000000000..95aa1cdcf --- /dev/null +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php @@ -0,0 +1,46 @@ +validateLength($length); + + $stream = fopen('/dev/urandom', 'rb'); + if ( ! is_resource($stream)) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Unable to open stream to /dev/urandom.' + ); + } + + $binaryString = fread($stream, $length); + fclose($stream); + + if( ! $binaryString) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Stream to /dev/urandom returned no data.' + ); + } + + return $this->binToHex($binaryString, $length); + } + +} diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 48c9b2de4..6c74e1638 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -29,6 +29,7 @@ use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; use Facebook\Entities\FacebookRequest; use Facebook\GraphNodes\GraphList; @@ -53,6 +54,13 @@ class FooUrlDetectionInterface implements UrlDetectionInterface public function getCurrentUrl() { return 'https://foo.bar'; } } +class FooBarPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface +{ + public function getPseudoRandomString($length) { + return 'csprs123'; + } +} + class FacebookTest extends \PHPUnit_Framework_TestCase { @@ -162,6 +170,74 @@ public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); } + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidPseudoRandomStringGeneratorThrows() + { + $config = array_merge($this->config, [ + 'pseudo_random_string_generator' => 'foo_generator', + ]); + new Facebook($config); + } + + public function testMcryptCsprgCanBeForced() + { + if ( ! function_exists('mcrypt_create_iv')) { + $this->markTestSkipped( + 'Mcrypt must be installed to test mcrypt_create_iv().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'mcrypt' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); + } + + public function testOpenSslCsprgCanBeForced() + { + if ( ! function_exists('openssl_random_pseudo_bytes')) { + $this->markTestSkipped( + 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'openssl' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); + } + + public function testUrandomCsprgCanBeForced() + { + if (ini_get('open_basedir')) { + $this->markTestSkipped( + 'Cannot test /dev/urandom generator due to open_basedir constraint.' + ); + } + + if ( ! is_readable('/dev/urandom')) { + $this->markTestSkipped( + '/dev/urandom not found or is not readable.' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'urandom' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); + } + /** * @expectedException \InvalidArgumentException */ @@ -177,27 +253,38 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() { $config = array_merge($this->config, [ 'default_access_token' => 'foo_token', - 'http_client_handler' => new FooClientInterface(), - 'persistent_data_handler' => new FooPersistentDataInterface(), - 'url_detection_handler' => new FooUrlDetectionInterface(), 'enable_beta_mode' => true, 'default_graph_version' => 'v1337', ]); $fb = new Facebook($config); $request = $fb->request('FOO_VERB', '/foo'); + $this->assertEquals('1337', $request->getApp()->getId()); + $this->assertEquals('foo_secret', $request->getApp()->getSecret()); + $this->assertEquals('foo_token', (string) $request->getAccessToken()); + $this->assertEquals('v1337', $request->getGraphVersion()); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, + $fb->getClient()->getBaseGraphUrl()); + } + + public function testCanInjectCustomHandlers() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + 'persistent_data_handler' => new FooPersistentDataInterface(), + 'url_detection_handler' => new FooUrlDetectionInterface(), + 'pseudo_random_string_generator' => new FooBarPseudoRandomStringGenerator(), + ]); + $fb = new Facebook($config); + $this->assertInstanceOf('Facebook\Tests\FooClientInterface', $fb->getClient()->getHttpClientHandler()); $this->assertInstanceOf('Facebook\Tests\FooPersistentDataInterface', $fb->getRedirectLoginHelper()->getPersistentDataHandler()); $this->assertInstanceOf('Facebook\Tests\FooUrlDetectionInterface', $fb->getRedirectLoginHelper()->getUrlDetectionHandler()); - $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, - $fb->getClient()->getBaseGraphUrl()); - $this->assertEquals('1337', $request->getApp()->getId()); - $this->assertEquals('foo_secret', $request->getApp()->getSecret()); - $this->assertEquals('foo_token', (string) $request->getAccessToken()); - $this->assertEquals('v1337', $request->getGraphVersion()); + $this->assertInstanceOf('Facebook\Tests\FooBarPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); } public function testPaginationReturnsProperResponse() diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index a61e6e8ed..c58cae610 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -28,6 +28,14 @@ use Facebook\Entities\FacebookApp; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; + +class FooPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface +{ + public function getPseudoRandomString($length) { + return 'csprs123'; + } +} class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase { @@ -58,14 +66,12 @@ public function testLoginURL() $params = [ 'client_id' => '123', 'redirect_uri' => self::REDIRECT_URL, - 'state' => $_SESSION['FBRLH_state'], + 'state' => $this->persistentDataHandler->get('state'), 'sdk' => 'php-sdk-' . Facebook::VERSION, 'scope' => implode(',', $scope), ]; foreach ($params as $key => $value) { - $this->assertTrue( - strpos($loginUrl, $key . '=' . urlencode($value)) !== false - ); + $this->assertContains($key . '=' . urlencode($value), $loginUrl); } } @@ -119,16 +125,25 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $this->assertEquals('access_token_from_code', (string) $accessToken); } - public function testCSPRNG() + public function testACustomCsprsgCanBeInjected() { $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); - - $class = new \ReflectionClass('Facebook\\Helpers\\FacebookRedirectLoginHelper'); - $method = $class->getMethod('random'); - $method->setAccessible(true); + $fooPrsg = new FooPseudoRandomStringGenerator(); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler, null, $fooPrsg); - $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $method->invoke($helper, 32))); + $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); + + $this->assertContains('state=csprs123', $loginUrl); + } + + public function testThePseudoRandomStringGeneratorWillAutoDetectCsprsg() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface', + $helper->getPseudoRandomStringGenerator() + ); } } diff --git a/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php new file mode 100644 index 000000000..66ec9c4c3 --- /dev/null +++ b/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php @@ -0,0 +1,46 @@ +markTestSkipped( + 'Mcrypt must be installed to test mcrypt_create_iv().' + ); + } + + $prsg = new McryptPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } + +} diff --git a/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php new file mode 100644 index 000000000..0284aca81 --- /dev/null +++ b/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php @@ -0,0 +1,46 @@ +markTestSkipped( + 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' + ); + } + + $prsg = new OpenSslPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } + +} diff --git a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php new file mode 100644 index 000000000..313d965ed --- /dev/null +++ b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php @@ -0,0 +1,54 @@ +validateLength('foo_len'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testALengthThatIsNotAtLeastOneCharacterWillThrow() + { + $prsg = new MyFooBarPseudoRandomStringGenerator(); + $prsg->validateLength(0); + } + +} diff --git a/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php new file mode 100644 index 000000000..b95a6b8ee --- /dev/null +++ b/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php @@ -0,0 +1,52 @@ +markTestSkipped( + 'Cannot test /dev/urandom generator due to open_basedir constraint.' + ); + } + + if ( ! is_readable('/dev/urandom')) { + $this->markTestSkipped( + '/dev/urandom not found or is not readable.' + ); + } + + $prsg = new UrandomPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } + +} From e7925f72f5eccfaaaf8db40bacf230f2f6f27a07 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sat, 6 Dec 2014 12:31:11 -0600 Subject: [PATCH 075/407] Refactored signed request handling --- src/Facebook/Entities/SignedRequest.php | 151 ++++++++---------- .../FacebookSignedRequestFromInputHelper.php | 6 +- tests/Entities/SignedRequestTest.php | 130 ++++++--------- 3 files changed, 125 insertions(+), 162 deletions(-) diff --git a/src/Facebook/Entities/SignedRequest.php b/src/Facebook/Entities/SignedRequest.php index eaa636686..f6bc89e55 100644 --- a/src/Facebook/Entities/SignedRequest.php +++ b/src/Facebook/Entities/SignedRequest.php @@ -33,30 +33,44 @@ class SignedRequest { /** - * @var string + * @var FacebookApp The FacebookApp entity. */ - public $rawSignedRequest; + protected $app; /** - * @var array + * @var string The raw encrypted signed request. */ - public $payload; + protected $rawSignedRequest; + + /** + * @var string|null Pseudo-random string to prevent CSRF. + */ + protected $state; + + /** + * @var array The payload from the decrypted signed request. + */ + protected $payload; /** * Instantiate a new SignedRequest entity. * + * @param FacebookApp $facebookApp The FacebookApp entity. * @param string|null $rawSignedRequest The raw signed request. - * @param string|null $state random string to prevent CSRF. - * @param string|null $appSecret + * @param string|null $state Pseudo-random string to prevent CSRF. */ - public function __construct($rawSignedRequest = null, $state = null, $appSecret = null) + public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null, $state = null) { - if (!$rawSignedRequest) { + $this->app = $facebookApp; + + if ( ! $rawSignedRequest) { return; } $this->rawSignedRequest = $rawSignedRequest; - $this->payload = static::parse($rawSignedRequest, $state, $appSecret); + $this->state = $state; + + $this->parse(); } /** @@ -112,88 +126,64 @@ public function getUserId() */ public function hasOAuthData() { - return isset($this->payload['oauth_token']) || isset($this->payload['code']); + return $this->get('oauth_token') || $this->get('code'); } /** * Creates a signed request from an array of data. * * @param array $payload - * @param string|null $appSecret * * @return string */ - public static function make(array $payload, $appSecret = null) + public function make(array $payload) { - $payload['algorithm'] = 'HMAC-SHA256'; - $payload['issued_at'] = time(); - $encodedPayload = static::base64UrlEncode(json_encode($payload)); + $payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-SHA256'; + $payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time(); + $encodedPayload = $this->base64UrlEncode(json_encode($payload)); - $hashedSig = static::hashSignature($encodedPayload, $appSecret); - $encodedSig = static::base64UrlEncode($hashedSig); + $hashedSig = $this->hashSignature($encodedPayload); + $encodedSig = $this->base64UrlEncode($hashedSig); - return $encodedSig.'.'.$encodedPayload; + return $encodedSig . '.' . $encodedPayload; } /** - * Validates and decodes a signed request and returns - * the payload as an array. - * - * @param string $signedRequest - * @param string|null $state - * @param string|null $appSecret - * - * @return array + * Validates and decodes a signed request and saves + * the payload to an array. */ - public static function parse($signedRequest, $state = null, $appSecret = null) + protected function parse() { - list($encodedSig, $encodedPayload) = static::split($signedRequest); + list($encodedSig, $encodedPayload) = $this->split(); // Signature validation - $sig = static::decodeSignature($encodedSig); - $hashedSig = static::hashSignature($encodedPayload, $appSecret); - static::validateSignature($hashedSig, $sig); + $sig = $this->decodeSignature($encodedSig); + $hashedSig = $this->hashSignature($encodedPayload); + $this->validateSignature($hashedSig, $sig); - // Payload validation - $data = static::decodePayload($encodedPayload); - static::validateAlgorithm($data); - if ($state) { - static::validateCsrf($data, $state); - } + $this->payload = $this->decodePayload($encodedPayload); - return $data; + // Payload validation + $this->validateAlgorithm(); + $this->validateCsrf(); } /** - * Validates the format of a signed request. + * Splits a raw signed request into signature and payload. * - * @param string $signedRequest + * @returns array * * @throws FacebookSDKException */ - public static function validateFormat($signedRequest) + protected function split() { - if (strpos($signedRequest, '.') !== false) { - return; + if (strpos($this->rawSignedRequest, '.') === false) { + throw new FacebookSDKException( + 'Malformed signed request.', 606 + ); } - throw new FacebookSDKException( - 'Malformed signed request.', 606 - ); - } - - /** - * Decodes a raw valid signed request. - * - * @param string $signedRequest - * - * @returns array - */ - public static function split($signedRequest) - { - static::validateFormat($signedRequest); - - return explode('.', $signedRequest, 2); + return explode('.', $this->rawSignedRequest, 2); } /** @@ -205,9 +195,9 @@ public static function split($signedRequest) * * @throws FacebookSDKException */ - public static function decodeSignature($encodedSig) + protected function decodeSignature($encodedSig) { - $sig = static::base64UrlDecode($encodedSig); + $sig = $this->base64UrlDecode($encodedSig); if ($sig) { return $sig; @@ -227,9 +217,9 @@ public static function decodeSignature($encodedSig) * * @throws FacebookSDKException */ - public static function decodePayload($encodedPayload) + protected function decodePayload($encodedPayload) { - $payload = static::base64UrlDecode($encodedPayload); + $payload = $this->base64UrlDecode($encodedPayload); if ($payload) { $payload = json_decode($payload, true); @@ -247,13 +237,11 @@ public static function decodePayload($encodedPayload) /** * Validates the algorithm used in a signed request. * - * @param array $data - * * @throws FacebookSDKException */ - public static function validateAlgorithm(array $data) + protected function validateAlgorithm() { - if (isset($data['algorithm']) && $data['algorithm'] === 'HMAC-SHA256') { + if ($this->get('algorithm') === 'HMAC-SHA256') { return; } @@ -266,16 +254,15 @@ public static function validateAlgorithm(array $data) * Hashes the signature used in a signed request. * * @param string $encodedData - * @param string $appSecret * * @return string * * @throws FacebookSDKException */ - public static function hashSignature($encodedData, $appSecret) + protected function hashSignature($encodedData) { $hashedSig = hash_hmac( - 'sha256', $encodedData, $appSecret, $raw_output = true + 'sha256', $encodedData, $this->app->getSecret(), $raw_output = true ); if ($hashedSig) { @@ -295,7 +282,7 @@ public static function hashSignature($encodedData, $appSecret) * * @throws FacebookSDKException */ - public static function validateSignature($hashedSig, $sig) + protected function validateSignature($hashedSig, $sig) { if (mb_strlen($hashedSig) === mb_strlen($sig)) { $validate = 0; @@ -315,14 +302,15 @@ public static function validateSignature($hashedSig, $sig) /** * Validates a signed request against CSRF. * - * @param array $data - * @param string $state - * * @throws FacebookSDKException */ - public static function validateCsrf(array $data, $state) + protected function validateCsrf() { - if (isset($data['state']) && $data['state'] === $state) { + if ( ! $this->state) { + return; + } + + if ($this->get('state') === $this->state) { return; } @@ -341,10 +329,11 @@ public static function validateCsrf(array $data, $state) * * @return string decoded string */ - public static function base64UrlDecode($input) + public function base64UrlDecode($input) { $urlDecodedBase64 = strtr($input, '-_', '+/'); - static::validateBase64($urlDecodedBase64); + $this->validateBase64($urlDecodedBase64); + return base64_decode($urlDecodedBase64); } @@ -358,7 +347,7 @@ public static function base64UrlDecode($input) * * @return string base64 url encoded input */ - public static function base64UrlEncode($input) + public function base64UrlEncode($input) { return strtr(base64_encode($input), '+/', '-_'); } @@ -370,7 +359,7 @@ public static function base64UrlEncode($input) * * @throws FacebookSDKException */ - public static function validateBase64($input) + protected function validateBase64($input) { $pattern = '/^[a-zA-Z0-9\/\r\n+]*={0,2}$/'; if (preg_match($pattern, $input)) { diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index 072685e35..5f45d5b34 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -71,11 +71,11 @@ public function instantiateSignedRequest($rawSignedRequest = null) { $rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); - if (!$rawSignedRequest) { + if ( ! $rawSignedRequest) { return; } - $this->signedRequest = new SignedRequest($rawSignedRequest, $this->state, $this->app->getSecret()); + $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest, $this->state); } /** @@ -100,6 +100,7 @@ public function getAccessToken(FacebookClient $client) $expiresAt = $this->signedRequest->get('expires', 0); return new AccessToken($accessToken, $expiresAt); } + return null; } @@ -168,6 +169,7 @@ public function getRawSignedRequestFromCookie() if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { return $_COOKIE['fbsr_' . $this->app->getId()]; } + return null; } diff --git a/tests/Entities/SignedRequestTest.php b/tests/Entities/SignedRequestTest.php index 67096fdcf..0218fda05 100644 --- a/tests/Entities/SignedRequestTest.php +++ b/tests/Entities/SignedRequestTest.php @@ -23,16 +23,21 @@ */ namespace Facebook\Tests\Entities; +use Facebook\Entities\FacebookApp; use Facebook\Entities\SignedRequest; class SignedRequestTest extends \PHPUnit_Framework_TestCase { - public $appSecret = 'foo_app_secret'; + /** + * @var FacebookApp + */ + protected $app; - public $rawSignedRequest = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; + protected $rawSignature = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8='; + protected $rawPayload = 'eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; - public $payloadData = [ + protected $payloadData = [ 'oauth_token' => 'foo_token', 'algorithm' => 'HMAC-SHA256', 'issued_at' => 321, @@ -42,10 +47,22 @@ class SignedRequestTest extends \PHPUnit_Framework_TestCase 'foo' => 'bar', ]; - public function testValidSignedRequestsWillPassFormattingValidation() + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_app_secret'); + } + + public function testAValidSignedRequestCanBeCreated() { - $sr = SignedRequest::make($this->payloadData, $this->appSecret); - SignedRequest::validateFormat($sr); + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($this->payloadData); + + $srTwo = new SignedRequest($this->app, $rawSignedRequest); + $payload = $srTwo->getPayload(); + + $expectedRawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $this->assertEquals($expectedRawSignedRequest, $rawSignedRequest); + $this->assertEquals($this->payloadData, $payload); } /** @@ -53,51 +70,31 @@ public function testValidSignedRequestsWillPassFormattingValidation() */ public function testInvalidSignedRequestsWillFailFormattingValidation() { - SignedRequest::validateFormat('invalid_signed_request'); - } - - public function testSignatureAndPayloadCanBeSeparatedInSignedRequests() - { - list($sig, $payload) = SignedRequest::split('sig.payload'); - - $this->assertEquals('sig', $sig); - $this->assertEquals('payload', $payload); + new SignedRequest($this->app, 'invalid_signed_request'); } public function testBase64EncodingIsUrlSafe() { - $encodedData = SignedRequest::base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); + $sr = new SignedRequest($this->app); + $encodedData = $sr->base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); $this->assertEquals('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4_Lnx-', $encodedData); } public function testAUrlSafeBase64EncodedStringCanBeDecoded() { - $decodedData = SignedRequest::base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); + $sr = new SignedRequest($this->app); + $decodedData = $sr->base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); $this->assertEquals('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~', $decodedData); } - public function testAValidEncodedSignatureCanBeDecoded() - { - $decodedSig = SignedRequest::decodeSignature('c2ln'); - - $this->assertEquals('sig', $decodedSig); - } - /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testAnImproperlyEncodedSignatureWillThrowAnException() { - SignedRequest::decodeSignature('foo!'); - } - - public function testAValidEncodedPayloadCanBeDecoded() - { - $decodedPayload = SignedRequest::decodePayload('WyJwYXlsb2FkIl0='); - - $this->assertEquals(['payload'], $decodedPayload); + new SignedRequest($this->app, 'foo_sig.' . $this->rawPayload); } /** @@ -105,12 +102,7 @@ public function testAValidEncodedPayloadCanBeDecoded() */ public function testAnImproperlyEncodedPayloadWillThrowAnException() { - SignedRequest::decodePayload('foo!'); - } - - public function testSignedRequestDataMustContainTheHmacSha256Algorithm() - { - SignedRequest::validateAlgorithm($this->payloadData); + new SignedRequest($this->app, $this->rawSignature . '.foo_payload'); } /** @@ -120,36 +112,19 @@ public function testNonApprovedAlgorithmsWillThrowAnException() { $signedRequestData = $this->payloadData; $signedRequestData['algorithm'] = 'FOO-ALGORITHM'; - SignedRequest::validateAlgorithm($signedRequestData); - } - - public function testASignatureHashCanBeGeneratedFromBase64EncodedData() - { - $hashedSig = SignedRequest::hashSignature('WyJwYXlsb2FkIl0=', $this->appSecret); - $expectedSig = base64_decode('bFofyO2sERX73y8uvuX26SLodv0mZ+Zk18d8b3zhD+s='); - $this->assertEquals($expectedSig, $hashedSig); - } + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($signedRequestData); - public function testTwoBinaryStringsCanBeComparedForSignatureValidation() - { - $hashedSig = base64_decode('bFofyO2sERX73y8uvuX26SLodv0mZ+Zk18d8b3zhD+s='); - SignedRequest::validateSignature($hashedSig, $hashedSig); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testNonSameBinaryStringsWillThrowAnExceptionForSignatureValidation() - { - $hashedSig1 = base64_decode('bFofyO2sERX73y8uvuX26SLodv0mZ+Zk18d8b3zhD+s='); - $hashedSig2 = base64_decode('GJy4HzkRtCeZA0cJjdZJtGfovcdxgl/AERI20S4MY7c='); - SignedRequest::validateSignature($hashedSig1, $hashedSig2); + new SignedRequest($this->app, $rawSignedRequest); } public function testASignedRequestWillPassCsrfValidation() { - SignedRequest::validateCsrf($this->payloadData, 'foo_state'); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest, 'foo_state'); + + $this->assertEquals($this->payloadData, $sr->getPayload()); } /** @@ -157,30 +132,27 @@ public function testASignedRequestWillPassCsrfValidation() */ public function testASignedRequestWithIncorrectCsrfDataWillThrowAnException() { - SignedRequest::validateCsrf($this->payloadData, 'invalid_foo_state'); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + new SignedRequest($this->app, $rawSignedRequest, 'invalid_foo_state'); } - public function testARawSignedRequestCanBeValidatedAndDecoded() + public function testAsRawSignedRequestCanBeValidatedAndDecoded() { - $payload = SignedRequest::parse($this->rawSignedRequest, 'foo_state', $this->appSecret); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); - $this->assertEquals($this->payloadData, $payload); + $this->assertEquals($this->payloadData, $sr->getPayload()); } - public function testARawSignedRequestCanBeInjectedIntoTheConstructorToInstantiateANewEntity() + public function testARawSignedRequestCanBeValidatedAndDecoded() { - $signedRequest = new SignedRequest($this->rawSignedRequest, 'foo_state', $this->appSecret); - - $rawSignedRequest = $signedRequest->getRawSignedRequest(); - $payloadData = $signedRequest->getPayload(); - $userId = $signedRequest->getUserId(); - $hasOAuthData = $signedRequest->hasOAuthData(); - - $this->assertInstanceOf('\Facebook\Entities\SignedRequest', $signedRequest); - $this->assertEquals($this->rawSignedRequest, $rawSignedRequest); - $this->assertEquals($this->payloadData, $payloadData); - $this->assertEquals(123, $userId); - $this->assertTrue($hasOAuthData); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); + + $this->assertEquals($sr->getPayload(), $this->payloadData); + $this->assertEquals($sr->getRawSignedRequest(), $rawSignedRequest); + $this->assertEquals(123, $sr->getUserId()); + $this->assertTrue($sr->hasOAuthData()); } } From 8536119ddeb8417f332a83792adb466094477b9a Mon Sep 17 00:00:00 2001 From: SammyK Date: Sat, 6 Dec 2014 10:57:32 -0600 Subject: [PATCH 076/407] Rebased app secret proof --- README.md | 28 +- docs/Facebook.fbmd | 64 +- docs/GraphList.fbmd | 53 + src/Facebook/Entities/AppSecretProof.php | 87 - src/Facebook/Entities/FacebookApp.php | 21 +- src/Facebook/Entities/FacebookRequest.php | 14 +- src/Facebook/Entities/FacebookResponse.php | 9 +- src/Facebook/Entities/SignedRequest.php | 151 +- .../FacebookAuthorizationException.php | 2 +- .../Exceptions/FacebookClientException.php | 2 +- .../Exceptions/FacebookOtherException.php | 2 +- .../FacebookPermissionException.php | 2 +- .../Exceptions/FacebookResponseException.php | 91 +- .../Exceptions/FacebookServerException.php | 2 +- .../Exceptions/FacebookThrottleException.php | 2 +- src/Facebook/Facebook.php | 69 +- src/Facebook/GraphNodes/GraphList.php | 62 +- .../GraphNodes/GraphObjectFactory.php | 7 +- .../FacebookSignedRequestFromInputHelper.php | 6 +- .../HttpClients/FacebookCurlHttpClient.php | 35 +- .../HttpClients/FacebookGuzzleHttpClient.php | 32 +- .../HttpClients/FacebookStreamHttpClient.php | 4 +- .../certs/DigiCertHighAssuranceEVRootCA.pem | 23 + .../HttpClients/fb_ca_chain_bundle.crt | 3920 ----------------- tests/Entities/AppSecretProofTest.php | 45 - tests/Entities/FacebookAppTest.php | 7 +- tests/Entities/SignedRequestTest.php | 130 +- .../FacebookResponseExceptionTest.php | 161 +- tests/FacebookTest.php | 21 + .../FacebookCurlHttpClientTest.php | 111 +- .../FacebookGuzzleHttpClientTest.php | 106 +- .../FacebookStreamHttpClientTest.php | 14 +- 32 files changed, 757 insertions(+), 4526 deletions(-) delete mode 100755 src/Facebook/Entities/AppSecretProof.php create mode 100644 src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem delete mode 100644 src/Facebook/HttpClients/fb_ca_chain_bundle.crt delete mode 100755 tests/Entities/AppSecretProofTest.php diff --git a/README.md b/README.md index 0a79f4537..502943bf0 100644 --- a/README.md +++ b/README.md @@ -16,34 +16,34 @@ Usage Simple GET example of a user's profile. ```php -use Facebook\Facebook; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; - -$fb = new Facebook([ +$fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', //'default_access_token' => '{access-token}', // optional ]); // Use one of the helper classes to get a Facebook\Entities\AccessToken entity. -// Facebook\Helpers\FacebookRedirectLoginHelper -// Facebook\Helpers\FacebookJavaScriptLoginHelper -// Facebook\Helpers\FacebookCanvasLoginHelper -// Facebook\Helpers\FacebookPageTabHelper +// $helper = $fb->getRedirectLoginHelper(); +// $helper = $fb->getJavaScriptHelper(); +// $helper = $fb->getCanvasHelper(); +// $helper = $fb->getPageTabHelper(); try { - // Get the Facebook\GraphNodes\GraphUser object for the current user: + // 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}'); - $me = $response->getGraphUser(); - echo 'Logged in as ' . $me->getName(); -} catch(FacebookResponseException $e) { +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { + exit; +} catch(Facebook\Exceptions\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 at: diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index a2e7a2be5..188b323a9 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -161,9 +161,30 @@ Returns the last response received from the Graph API in the form of a `Facebook ### getDefaultAccessToken() {#get-default-access-token} ~~~~ -public AccessToken|null getDefaultAccessToken() +public Facebook\Entities\AccessToken|null getDefaultAccessToken() ~~~~ -Returns the default `Facebook\Entities\AccessToken` entity if the configuration option `default_access_token` was set. + +Returns the default fallback `Facebook\Entities\AccessToken` 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() {#set-default-access-token} +~~~~ +public setDefaultAccessToken(string|Facebook\Entities\AccessToken $accessToken) +~~~~ + +Sets the default access token to be use with all requests sent to Graph. The access token can be in string or `Facebook\Entities\AccessToken` format. + +~~~~ +$fb->setDefaultAccessToken('{my-access-token}'); + +// . . . OR . . . + +$accessToken = new Facebook\Entities\AccessToken('{my-access-token}'); +$fb->setDefaultAccessToken($accessToken); +~~~~ + +This setting will overwrite the value from `default_access_token` if it was passed to the `Facebook\Facebook` constructor. @@ -315,6 +336,45 @@ $helper = $fb->getRedirectLoginHelper(); ~~~~ + +### getJavaScriptHelper() {#get-javascript-helper} +~~~~ +public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) which is used to access the signed request stored in the cookie set by the JavaScript SDK. + +~~~~ +$helper = $fb->getJavaScriptHelper(); +~~~~ + + + +### getCanvasHelper() {#get-canvas-helper} +~~~~ +public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) which is used to access the signed request that is `POST`ed to canvas apps. + +~~~~ +$helper = $fb->getCanvasHelper(); +~~~~ + + + +### getPageTabHelper() {#get-page-tab-helper} +~~~~ +public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() +~~~~ + +Returns a [`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper) 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. + +~~~~ +$helper = $fb->getPageTabHelper(); +~~~~ + + ### next() {#next} ~~~~ diff --git a/docs/GraphList.fbmd b/docs/GraphList.fbmd index 7ad738df6..3283c586e 100644 --- a/docs/GraphList.fbmd +++ b/docs/GraphList.fbmd @@ -69,3 +69,56 @@ do { } while ($pageCount < $maxPages && $listOfPages = $fb->next($listOfPages)); ~~~~ + + +## Method Reference {#method-reference} + +### getMetaData() {#get-meta-data} +~~~~ +public array getMetaData() +~~~~ + +Sometimes Graph will return additional data associated with a list of Graph nodes. You can access this raw data as an array with `getMetaData()`. + +~~~~ +$metaData = $graphList->getMetaData(); +~~~~ + +### getNextCursor() {#get-next-cursor} +~~~~ +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 a list of Graph nodes, it is sometimes handy to store the last cursor used so that you can revisit the exact position at a later time. + +~~~~ +$nextCursor = $graphList->getNextCursor(); +// Returns: MMAyDDM5NjA0OTEyMDc0OTM= +~~~~ + +### getPreviousCursor() {#get-previous-cursor} +~~~~ +public string|null getPreviousCursor() +~~~~ + +Returns the `$.paging.cursors.before` value if it exists or `null` if it does not exist. + +~~~~ +$previousCursor = $graphList->getPreviousCursor(); +// Returns: ODOxMTUzMjQzNTg5zzU5 +~~~~ + +### getTotalCount() {#get-total-count} +~~~~ +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. + +~~~~ +$response = $fb->get('/{post-id}/likes?summary=true'); +$listOfLikes = $response->getGraphList(); +$totalCount = $listOfLikes->getTotalCount(); +// Returns: 10 +~~~~ + diff --git a/src/Facebook/Entities/AppSecretProof.php b/src/Facebook/Entities/AppSecretProof.php deleted file mode 100755 index bbf31d352..000000000 --- a/src/Facebook/Entities/AppSecretProof.php +++ /dev/null @@ -1,87 +0,0 @@ -accessToken = $accessToken; - $this->appSecret = $appSecret; - } - - /** - * Generate and return the app secret proof value for an access token. - * - * @param string $accessToken The access token as a string. - * @param string $appSecret The app secret. - * - * @return string The app secret proof. - */ - public static function make($accessToken, $appSecret) - { - return hash_hmac('sha256', $accessToken, $appSecret); - } - - /** - * Convert the entity to a string by creating an app secret proof. - * - * @return string The app secret proof. - */ - public function __toString() - { - if ($this->appSecretProof) { - return $this->appSecretProof; - } - - return $this->appSecretProof = static::make($this->accessToken, $this->appSecret); - } - -} diff --git a/src/Facebook/Entities/FacebookApp.php b/src/Facebook/Entities/FacebookApp.php index ff5e0c8c1..f426cfa13 100644 --- a/src/Facebook/Entities/FacebookApp.php +++ b/src/Facebook/Entities/FacebookApp.php @@ -25,13 +25,14 @@ class FacebookApp implements \Serializable { + /** - * @var string + * @var string The app ID. */ protected $id; /** - * @var string + * @var string The app secret. */ protected $secret; @@ -46,6 +47,8 @@ public function __construct($id, $secret) } /** + * Returns the app ID. + * * @return string */ public function getId() @@ -54,6 +57,8 @@ public function getId() } /** + * Returns the app secret. + * * @return string */ public function getSecret() @@ -62,6 +67,8 @@ public function getSecret() } /** + * Returns an app access token. + * * @return AccessToken */ public function getAccessToken() @@ -69,11 +76,21 @@ public function getAccessToken() return new AccessToken($this->id . '|' . $this->secret); } + /** + * Serializes the FacebookApp entity as a string. + * + * @return string + */ public function serialize() { return serialize([$this->id, $this->secret]); } + /** + * Unserializes a string as a FacebookApp entity. + * + * @param string $serialized + */ public function unserialize($serialized) { list($id, $secret) = unserialize($serialized); diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index 04a559f45..f8c1efcdc 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -44,7 +44,7 @@ class FacebookRequest protected $app; /** - * @var string The access token to use for this request. + * @var string|null The access token to use for this request. */ protected $accessToken; @@ -155,11 +155,11 @@ public function setAccessTokenFromParams($accessToken) /** * Return the access token for this request. * - * @return string + * @return string|null */ public function getAccessToken() { - return (string) $this->accessToken; + return $this->accessToken; } /** @@ -185,11 +185,15 @@ public function getApp() /** * Generate an app secret proof to sign this request. * - * @return string + * @return string|null */ public function getAppSecretProof() { - return AppSecretProof::make($this->getAccessToken(), $this->app->getSecret()); + if ( ! $accessToken = $this->getAccessToken()) { + return null; + } + + return hash_hmac('sha256', $accessToken, $this->app->getSecret()); } /** diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/Entities/FacebookResponse.php index 55a1e9bab..34f4069b0 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/Entities/FacebookResponse.php @@ -110,7 +110,7 @@ public function getApp() /** * Return the access token that was used for this response. * - * @return string + * @return string|null */ public function getAccessToken() { @@ -160,7 +160,7 @@ public function getDecodedBody() /** * Get the app secret proof that was used for this response. * - * @return string + * @return string|null */ public function getAppSecretProof() { @@ -212,10 +212,7 @@ public function throwException() */ public function makeException() { - $this->thrownException = FacebookResponseException::create( - $this->body, - $this->decodedBody, - $this->httpStatusCode); + $this->thrownException = FacebookResponseException::create($this); } /** diff --git a/src/Facebook/Entities/SignedRequest.php b/src/Facebook/Entities/SignedRequest.php index eaa636686..f6bc89e55 100644 --- a/src/Facebook/Entities/SignedRequest.php +++ b/src/Facebook/Entities/SignedRequest.php @@ -33,30 +33,44 @@ class SignedRequest { /** - * @var string + * @var FacebookApp The FacebookApp entity. */ - public $rawSignedRequest; + protected $app; /** - * @var array + * @var string The raw encrypted signed request. */ - public $payload; + protected $rawSignedRequest; + + /** + * @var string|null Pseudo-random string to prevent CSRF. + */ + protected $state; + + /** + * @var array The payload from the decrypted signed request. + */ + protected $payload; /** * Instantiate a new SignedRequest entity. * + * @param FacebookApp $facebookApp The FacebookApp entity. * @param string|null $rawSignedRequest The raw signed request. - * @param string|null $state random string to prevent CSRF. - * @param string|null $appSecret + * @param string|null $state Pseudo-random string to prevent CSRF. */ - public function __construct($rawSignedRequest = null, $state = null, $appSecret = null) + public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null, $state = null) { - if (!$rawSignedRequest) { + $this->app = $facebookApp; + + if ( ! $rawSignedRequest) { return; } $this->rawSignedRequest = $rawSignedRequest; - $this->payload = static::parse($rawSignedRequest, $state, $appSecret); + $this->state = $state; + + $this->parse(); } /** @@ -112,88 +126,64 @@ public function getUserId() */ public function hasOAuthData() { - return isset($this->payload['oauth_token']) || isset($this->payload['code']); + return $this->get('oauth_token') || $this->get('code'); } /** * Creates a signed request from an array of data. * * @param array $payload - * @param string|null $appSecret * * @return string */ - public static function make(array $payload, $appSecret = null) + public function make(array $payload) { - $payload['algorithm'] = 'HMAC-SHA256'; - $payload['issued_at'] = time(); - $encodedPayload = static::base64UrlEncode(json_encode($payload)); + $payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-SHA256'; + $payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time(); + $encodedPayload = $this->base64UrlEncode(json_encode($payload)); - $hashedSig = static::hashSignature($encodedPayload, $appSecret); - $encodedSig = static::base64UrlEncode($hashedSig); + $hashedSig = $this->hashSignature($encodedPayload); + $encodedSig = $this->base64UrlEncode($hashedSig); - return $encodedSig.'.'.$encodedPayload; + return $encodedSig . '.' . $encodedPayload; } /** - * Validates and decodes a signed request and returns - * the payload as an array. - * - * @param string $signedRequest - * @param string|null $state - * @param string|null $appSecret - * - * @return array + * Validates and decodes a signed request and saves + * the payload to an array. */ - public static function parse($signedRequest, $state = null, $appSecret = null) + protected function parse() { - list($encodedSig, $encodedPayload) = static::split($signedRequest); + list($encodedSig, $encodedPayload) = $this->split(); // Signature validation - $sig = static::decodeSignature($encodedSig); - $hashedSig = static::hashSignature($encodedPayload, $appSecret); - static::validateSignature($hashedSig, $sig); + $sig = $this->decodeSignature($encodedSig); + $hashedSig = $this->hashSignature($encodedPayload); + $this->validateSignature($hashedSig, $sig); - // Payload validation - $data = static::decodePayload($encodedPayload); - static::validateAlgorithm($data); - if ($state) { - static::validateCsrf($data, $state); - } + $this->payload = $this->decodePayload($encodedPayload); - return $data; + // Payload validation + $this->validateAlgorithm(); + $this->validateCsrf(); } /** - * Validates the format of a signed request. + * Splits a raw signed request into signature and payload. * - * @param string $signedRequest + * @returns array * * @throws FacebookSDKException */ - public static function validateFormat($signedRequest) + protected function split() { - if (strpos($signedRequest, '.') !== false) { - return; + if (strpos($this->rawSignedRequest, '.') === false) { + throw new FacebookSDKException( + 'Malformed signed request.', 606 + ); } - throw new FacebookSDKException( - 'Malformed signed request.', 606 - ); - } - - /** - * Decodes a raw valid signed request. - * - * @param string $signedRequest - * - * @returns array - */ - public static function split($signedRequest) - { - static::validateFormat($signedRequest); - - return explode('.', $signedRequest, 2); + return explode('.', $this->rawSignedRequest, 2); } /** @@ -205,9 +195,9 @@ public static function split($signedRequest) * * @throws FacebookSDKException */ - public static function decodeSignature($encodedSig) + protected function decodeSignature($encodedSig) { - $sig = static::base64UrlDecode($encodedSig); + $sig = $this->base64UrlDecode($encodedSig); if ($sig) { return $sig; @@ -227,9 +217,9 @@ public static function decodeSignature($encodedSig) * * @throws FacebookSDKException */ - public static function decodePayload($encodedPayload) + protected function decodePayload($encodedPayload) { - $payload = static::base64UrlDecode($encodedPayload); + $payload = $this->base64UrlDecode($encodedPayload); if ($payload) { $payload = json_decode($payload, true); @@ -247,13 +237,11 @@ public static function decodePayload($encodedPayload) /** * Validates the algorithm used in a signed request. * - * @param array $data - * * @throws FacebookSDKException */ - public static function validateAlgorithm(array $data) + protected function validateAlgorithm() { - if (isset($data['algorithm']) && $data['algorithm'] === 'HMAC-SHA256') { + if ($this->get('algorithm') === 'HMAC-SHA256') { return; } @@ -266,16 +254,15 @@ public static function validateAlgorithm(array $data) * Hashes the signature used in a signed request. * * @param string $encodedData - * @param string $appSecret * * @return string * * @throws FacebookSDKException */ - public static function hashSignature($encodedData, $appSecret) + protected function hashSignature($encodedData) { $hashedSig = hash_hmac( - 'sha256', $encodedData, $appSecret, $raw_output = true + 'sha256', $encodedData, $this->app->getSecret(), $raw_output = true ); if ($hashedSig) { @@ -295,7 +282,7 @@ public static function hashSignature($encodedData, $appSecret) * * @throws FacebookSDKException */ - public static function validateSignature($hashedSig, $sig) + protected function validateSignature($hashedSig, $sig) { if (mb_strlen($hashedSig) === mb_strlen($sig)) { $validate = 0; @@ -315,14 +302,15 @@ public static function validateSignature($hashedSig, $sig) /** * Validates a signed request against CSRF. * - * @param array $data - * @param string $state - * * @throws FacebookSDKException */ - public static function validateCsrf(array $data, $state) + protected function validateCsrf() { - if (isset($data['state']) && $data['state'] === $state) { + if ( ! $this->state) { + return; + } + + if ($this->get('state') === $this->state) { return; } @@ -341,10 +329,11 @@ public static function validateCsrf(array $data, $state) * * @return string decoded string */ - public static function base64UrlDecode($input) + public function base64UrlDecode($input) { $urlDecodedBase64 = strtr($input, '-_', '+/'); - static::validateBase64($urlDecodedBase64); + $this->validateBase64($urlDecodedBase64); + return base64_decode($urlDecodedBase64); } @@ -358,7 +347,7 @@ public static function base64UrlDecode($input) * * @return string base64 url encoded input */ - public static function base64UrlEncode($input) + public function base64UrlEncode($input) { return strtr(base64_encode($input), '+/', '-_'); } @@ -370,7 +359,7 @@ public static function base64UrlEncode($input) * * @throws FacebookSDKException */ - public static function validateBase64($input) + protected function validateBase64($input) { $pattern = '/^[a-zA-Z0-9\/\r\n+]*={0,2}$/'; if (preg_match($pattern, $input)) { diff --git a/src/Facebook/Exceptions/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php index 0a373eb3e..a633ecbc2 100644 --- a/src/Facebook/Exceptions/FacebookAuthorizationException.php +++ b/src/Facebook/Exceptions/FacebookAuthorizationException.php @@ -27,7 +27,7 @@ * Class FacebookAuthorizationException * @package Facebook */ -class FacebookAuthorizationException extends FacebookResponseException +class FacebookAuthorizationException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php index e22219efd..650381022 100644 --- a/src/Facebook/Exceptions/FacebookClientException.php +++ b/src/Facebook/Exceptions/FacebookClientException.php @@ -27,7 +27,7 @@ * Class FacebookClientException * @package Facebook */ -class FacebookClientException extends FacebookResponseException +class FacebookClientException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php index 9a0e77842..34c6be5b2 100644 --- a/src/Facebook/Exceptions/FacebookOtherException.php +++ b/src/Facebook/Exceptions/FacebookOtherException.php @@ -27,7 +27,7 @@ * Class FacebookOtherException * @package Facebook */ -class FacebookOtherException extends FacebookResponseException +class FacebookOtherException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookPermissionException.php b/src/Facebook/Exceptions/FacebookPermissionException.php index d37d30920..3d9c175a3 100644 --- a/src/Facebook/Exceptions/FacebookPermissionException.php +++ b/src/Facebook/Exceptions/FacebookPermissionException.php @@ -27,7 +27,7 @@ * Class FacebookPermissionException * @package Facebook */ -class FacebookPermissionException extends FacebookResponseException +class FacebookPermissionException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 59b7760e9..bb4b083cc 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -23,6 +23,8 @@ */ namespace Facebook\Exceptions; +use Facebook\Entities\FacebookResponse; + /** * Class FacebookResponseException * @package Facebook @@ -33,54 +35,50 @@ class FacebookResponseException extends FacebookSDKException { /** - * @var int Status code for the response causing the exception - */ - private $statusCode; - - /** - * @var string Raw response + * @var FacebookResponse The response that threw the exception. */ - private $rawResponse; + protected $response; /** - * @var array Decoded response + * @var array Decoded response. */ - private $responseData; + protected $responseData; /** * Creates a FacebookResponseException. * - * @param string $rawResponse The raw response from the Graph API - * @param array $responseData The decoded response from the Graph API - * @param int $statusCode + * @param FacebookResponse $response The response that threw the exception. + * @param FacebookSDKException $previousException The more detailed exception. */ - public function __construct($rawResponse, $responseData, $statusCode) + public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) { - $this->rawResponse = $rawResponse; - $this->statusCode = $statusCode; - $this->responseData = self::convertToArray($responseData); - parent::__construct( - $this->get('message', 'Unknown Exception'), $this->get('code', -1), null - ); + $this->response = $response; + $this->responseData = $response->getDecodedBody(); + + $errorMessage = $this->get('message', 'Unknown error from Graph.'); + $errorCode = $this->get('code', -1); + + parent::__construct($errorMessage, $errorCode, $previousException); } /** - * Process an error payload from the Graph API and return the appropriate - * exception subclass. + * A factory for creating the appropriate exception based on the response from Graph. * - * @param string $raw the raw response from the Graph API - * @param array $data the decoded response from the Graph API - * @param int $statusCode the HTTP response code + * @param FacebookResponse $response The response that threw the exception. * * @return FacebookResponseException */ - public static function create($raw, $data, $statusCode) + public static function create(FacebookResponse $response) { - $data = self::convertToArray($data); - if (!isset($data['error']['code']) && isset($data['code'])) { + $data = $response->getDecodedBody(); + + if ( ! isset($data['error']['code']) && isset($data['code'])) { $data = ['error' => $data]; } - $code = (isset($data['error']['code']) ? $data['error']['code'] : null); + $code = isset($data['error']['code']) ? $data['error']['code'] : null; + $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; + + $previousException = null; if (isset($data['error']['error_subcode'])) { switch ($data['error']['error_subcode']) { @@ -91,7 +89,7 @@ public static function create($raw, $data, $statusCode) case 463: case 464: case 467: - return new FacebookAuthorizationException($raw, $data, $statusCode); + return new static($response, new FacebookAuthorizationException($message, $code)); break; } } @@ -101,41 +99,41 @@ public static function create($raw, $data, $statusCode) case 100: case 102: case 190: - return new FacebookAuthorizationException($raw, $data, $statusCode); + return new static($response, new FacebookAuthorizationException($message, $code)); break; // Server issue, possible downtime case 1: case 2: - return new FacebookServerException($raw, $data, $statusCode); + return new static($response, new FacebookServerException($message, $code)); break; // API Throttling case 4: case 17: case 341: - return new FacebookThrottleException($raw, $data, $statusCode); + return new static($response, new FacebookThrottleException($message, $code)); break; // Duplicate Post case 506: - return new FacebookClientException($raw, $data, $statusCode); + return new static($response, new FacebookClientException($message, $code)); break; } // Missing Permissions if ($code == 10 || ($code >= 200 && $code <= 299)) { - return new FacebookPermissionException($raw, $data, $statusCode); + return new static($response, new FacebookPermissionException($message, $code)); } // OAuth authentication error if (isset($data['error']['type']) and $data['error']['type'] === 'OAuthException') { - return new FacebookAuthorizationException($raw, $data, $statusCode); + return new static($response, new FacebookAuthorizationException($message, $code)); } // All others - return new FacebookOtherException($raw, $data, $statusCode); + return new static($response, new FacebookOtherException($message, $code)); } /** @@ -161,7 +159,7 @@ private function get($key, $default = null) */ public function getHttpStatusCode() { - return $this->statusCode; + return $this->response->getHttpStatusCode(); } /** @@ -191,7 +189,7 @@ public function getErrorType() */ public function getRawResponse() { - return $this->rawResponse; + return $this->response->getBody(); } /** @@ -199,24 +197,19 @@ public function getRawResponse() * * @return array */ - public function getResponse() + public function getResponseData() { return $this->responseData; } /** - * Converts a stdClass object to an array - * - * @param mixed $object + * Returns the response entity used to create the exception. * - * @return array + * @return FacebookResponse */ - private static function convertToArray($object) + public function getResponse() { - if ($object instanceof \stdClass) { - return get_object_vars($object); - } - return $object; + return $this->response; } -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php index 06d7f756c..962615876 100644 --- a/src/Facebook/Exceptions/FacebookServerException.php +++ b/src/Facebook/Exceptions/FacebookServerException.php @@ -27,7 +27,7 @@ * Class FacebookServerException * @package Facebook */ -class FacebookServerException extends FacebookResponseException +class FacebookServerException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php index be5bee8c3..662d3bad1 100644 --- a/src/Facebook/Exceptions/FacebookThrottleException.php +++ b/src/Facebook/Exceptions/FacebookThrottleException.php @@ -27,7 +27,7 @@ * Class FacebookThrottleException * @package Facebook */ -class FacebookThrottleException extends FacebookResponseException +class FacebookThrottleException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index a43fba284..32ef867a5 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -41,14 +41,15 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\Helpers\FacebookCanvasHelper; +use Facebook\Helpers\FacebookJavaScriptHelper; +use Facebook\Helpers\FacebookPageTabHelper; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\Exceptions\FacebookSDKException; /** * Class Facebook * @package Facebook - * - * @TODO Add helpers to superclass */ class Facebook { @@ -194,14 +195,7 @@ public function __construct(array $config = []) } if (isset($config['default_access_token'])) { - if (is_string($config['default_access_token'])) { - $this->defaultAccessToken = new AccessToken($config['default_access_token']); - } elseif ( ! $config['default_access_token'] instanceof AccessToken) { - throw new \InvalidArgumentException( - 'The "default_access_token" provided must be of type "string"' - . ' or Facebook\Entities\AccessToken' - ); - } + $this->setDefaultAccessToken($config['default_access_token']); } $this->defaultGraphVersion = isset($config['default_graph_version']) @@ -263,6 +257,31 @@ public function getDefaultAccessToken() return $this->defaultAccessToken; } + /** + * Sets the default access token to use with requests. + * + * @param AccessToken|string $accessToken The access token to save. + * + * @throws \InvalidArgumentException + */ + public function setDefaultAccessToken($accessToken) + { + if (is_string($accessToken)) { + $this->defaultAccessToken = new AccessToken($accessToken); + return; + } + + if ($accessToken instanceof AccessToken) { + $this->defaultAccessToken = $accessToken; + return; + } + + throw new \InvalidArgumentException( + 'The default access token must be of type "string"' + . ' or Facebook\Entities\AccessToken' + ); + } + /** * Returns the default Graph version. * @@ -287,6 +306,36 @@ public function getRedirectLoginHelper() ); } + /** + * Returns the JavaScript helper. + * + * @return FacebookJavaScriptHelper + */ + public function getJavaScriptHelper() + { + return new FacebookJavaScriptHelper($this->app); + } + + /** + * Returns the canvas helper. + * + * @return FacebookCanvasHelper + */ + public function getCanvasHelper() + { + return new FacebookCanvasHelper($this->app); + } + + /** + * Returns the page tab helper. + * + * @return FacebookPageTabHelper + */ + public function getPageTabHelper() + { + return new FacebookPageTabHelper($this->app); + } + /** * Sends a GET request to Graph and returns the result. * diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 142b1c80f..94bc93b27 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -93,6 +93,50 @@ public function getSubClassName() return $this->subclassName; } + /** + * Returns the raw meta data associated with this GraphList. + * + * @return array + */ + public function getMetaData() + { + return $this->metaData; + } + + /** + * Returns the next cursor if it exists. + * + * @return string|null + */ + public function getNextCursor() + { + return $this->getCursor('after'); + } + + /** + * Returns the previous cursor if it exists. + * + * @return string|null + */ + public function getPreviousCursor() + { + return $this->getCursor('before'); + } + + /** + * Returns the cursor for a specific direction if it exists. + * + * @param string $direction The direction of the page: after|before + * + * @return string|null + */ + public function getCursor($direction) + { + return isset($this->metaData['paging']['cursors'][$direction]) + ? $this->metaData['paging']['cursors'][$direction] + : null; + } + /** * Generates a pagination URL based on a cursor. * @@ -116,7 +160,8 @@ public function getPaginationUrl($direction) // Do we have a cursor to work with? $cursorDirection = $direction === 'next' ? 'after' : 'before'; - if ( ! isset($this->metaData['paging']['cursors'][$cursorDirection])) { + $cursor = $this->getCursor($cursorDirection); + if ( ! $cursor) { return null; } @@ -127,8 +172,6 @@ public function getPaginationUrl($direction) // We have the parent node ID, paging cursor & original request. // These were the ingredients chosen to create the perfect little URL. - $cursor = $this->metaData['paging']['cursors'][$cursorDirection]; - $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); // Pull in the original params @@ -197,4 +240,17 @@ public function getPreviousPageRequest() return $this->getPaginationRequest('previous'); } + /** + * 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() + { + return isset($this->metaData['summary']['total_count']) + ? $this->metaData['summary']['total_count'] + : null; + } + } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 98d11be2f..67dbe934e 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -319,12 +319,9 @@ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKe */ public function getMetaData(array $data) { - $meta_data = []; - if (isset($data['paging'])) { - $meta_data['paging'] = $data['paging']; - } + unset($data['data']); - return $meta_data; + return $data; } /** diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index 072685e35..5f45d5b34 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -71,11 +71,11 @@ public function instantiateSignedRequest($rawSignedRequest = null) { $rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); - if (!$rawSignedRequest) { + if ( ! $rawSignedRequest) { return; } - $this->signedRequest = new SignedRequest($rawSignedRequest, $this->state, $this->app->getSecret()); + $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest, $this->state); } /** @@ -100,6 +100,7 @@ public function getAccessToken(FacebookClient $client) $expiresAt = $this->signedRequest->get('expires', 0); return new AccessToken($accessToken, $expiresAt); } + return null; } @@ -168,6 +169,7 @@ public function getRawSignedRequestFromCookie() if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { return $_COOKIE['fbsr_' . $this->app->getId()]; } + return null; } diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index b7cd5a8de..56e66c9ed 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -77,16 +77,11 @@ public function __construct(FacebookCurl $facebookCurl = null) public function send($url, $method, $body, array $headers, $timeOut) { $this->openConnection($url, $method, $body, $headers, $timeOut); - $this->tryToSendRequest(); - - // Need to verify the peer - if ($this->curlErrorCode == 60 || $this->curlErrorCode == 77) { - $this->addBundledCert(); - $this->tryToSendRequest(); - } + $this->sendRequest(); - if ($this->curlErrorCode) { - throw new FacebookSDKException($this->curlErrorMessage, $this->curlErrorCode); + if ($curlErrorCode = $this->facebookCurl->errno()) { + $curlErrorMessage = $this->facebookCurl->error(); + throw new FacebookSDKException($curlErrorMessage, $curlErrorCode); } // Separate the raw headers from the raw body @@ -116,6 +111,9 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) CURLOPT_TIMEOUT => $timeOut, CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects CURLOPT_HEADER => true, // Enable header processing + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ]; if ($method !== "GET") { @@ -126,15 +124,6 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) $this->facebookCurl->setopt_array($options); } - /** - * Add a bundled cert to the connection - */ - public function addBundledCert() - { - $this->facebookCurl->setopt(CURLOPT_CAINFO, - dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt'); - } - /** * Closes an existing curl connection */ @@ -143,16 +132,6 @@ public function closeConnection() $this->facebookCurl->close(); } - /** - * Try to send the request - */ - public function tryToSendRequest() - { - $this->sendRequest(); - $this->curlErrorMessage = $this->facebookCurl->error(); - $this->curlErrorCode = $this->facebookCurl->errno(); - } - /** * Send the request and get the raw response from curl */ diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index 960476d3d..6f1c822a3 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -27,6 +27,7 @@ use Facebook\Exceptions\FacebookSDKException; use GuzzleHttp\Client; +use GuzzleHttp\Message\ResponseInterface; use GuzzleHttp\Ring\Exception\RingException; use GuzzleHttp\Exception\RequestException; @@ -56,23 +57,46 @@ public function send($url, $method, $body, array $headers, $timeOut) 'body' => $body, 'timeout' => $timeOut, 'connect_timeout' => 10, + 'verify' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ]; $request = $this->guzzleClient->createRequest($method, $url, $options); try { $rawResponse = $this->guzzleClient->send($request); } catch (RequestException $e) { - if ($e->getPrevious() instanceof RingException) { + $rawResponse = $e->getResponse(); + + if ( + $e->getPrevious() instanceof RingException + || ! $rawResponse instanceof ResponseInterface + ) { throw new FacebookSDKException($e->getMessage(), $e->getCode()); } - $rawResponse = $e->getResponse(); } - $headers = $rawResponse->getHeaders(); + $rawHeaders = $this->getHeadersAsString($rawResponse); $rawBody = $rawResponse->getBody(); $httpStatusCode = $rawResponse->getStatusCode(); - return new GraphRawResponse($headers, $rawBody, $httpStatusCode); + return new GraphRawResponse($rawHeaders, $rawBody, $httpStatusCode); + } + + /** + * Returns the Guzzle array of headers as a string. + * + * @param ResponseInterface $response The Guzzle response. + * + * @return string + */ + public function getHeadersAsString(ResponseInterface $response) + { + $headers = $response->getHeaders(); + $rawHeaders = []; + foreach ($headers as $name => $values) { + $rawHeaders[] = $name . ": " . implode(", ", $values); + } + + return implode("\r\n", $rawHeaders); } } diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index de5e6701e..4f450b9b3 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -57,7 +57,9 @@ public function send($url, $method, $body, array $headers, $timeOut) ], 'ssl' => [ 'verify_peer' => true, - 'cafile' => dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt', + 'verify_peer_name' => true, + 'allow_self_signed' => true, // All root certificates are self-signed + 'cafile' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', ], ]; diff --git a/src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem b/src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem new file mode 100644 index 000000000..9e6810ab7 --- /dev/null +++ b/src/Facebook/HttpClients/certs/DigiCertHighAssuranceEVRootCA.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- diff --git a/src/Facebook/HttpClients/fb_ca_chain_bundle.crt b/src/Facebook/HttpClients/fb_ca_chain_bundle.crt deleted file mode 100644 index 969239ff6..000000000 --- a/src/Facebook/HttpClients/fb_ca_chain_bundle.crt +++ /dev/null @@ -1,3920 +0,0 @@ -## -## ca-bundle.crt -- Bundle of CA Root Certificates -## -## Certificate data from Mozilla as of: Thu Oct 18 19:05:59 2012 -## -## This is a bundle of X.509 certificates of public Certificate Authorities -## (CA). These were automatically extracted from Mozilla's root certificates -## file (certdata.txt). This file can be found in the mozilla source tree: -## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 -## -## It contains the certificates in PEM format and therefore -## can be directly used with curl / libcurl / php_curl, or with -## an Apache+mod_ssl webserver for SSL client authentication. -## Just configure this file as the SSLCACertificateFile. -## - -# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.86 $ $Date: 2012/10/18 16:26:52 $ - -GTE CyberTrust Global Root -========================== ------BEGIN CERTIFICATE----- -MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg -Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG -A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz -MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL -Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 -IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u -sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql -HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID -AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW -M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF -NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ ------END CERTIFICATE----- - -Thawte Server CA -================ ------BEGIN CERTIFICATE----- -MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE -AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j -b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV -BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u -c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG -A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 -ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl -/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 -1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J -GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ -GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= ------END CERTIFICATE----- - -Thawte Premium Server CA -======================== ------BEGIN CERTIFICATE----- -MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT -DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs -dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE -AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl -ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT -AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU -VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 -aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ -cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 -aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh -Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ -qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm -SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf -8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t -UCemDaYj+bvLpgcUQg== ------END CERTIFICATE----- - -Equifax Secure CA -================= ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE -ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT -B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR -fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW -8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG -A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE -CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG -A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS -spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB -Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 -zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB -BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 -70+sB3c4 ------END CERTIFICATE----- - -Digital Signature Trust Co. Global CA 1 -======================================= ------BEGIN CERTIFICATE----- -MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE -ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy -MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs -IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE -NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i -o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo -BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 -dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw -IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY -MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM -BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB -ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq -kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4 -RbyhkwS7hp86W0N6w4pl ------END CERTIFICATE----- - -Digital Signature Trust Co. Global CA 3 -======================================= ------BEGIN CERTIFICATE----- -MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE -ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy -MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs -IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA -A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD -VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS -xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo -BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 -dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw -IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY -MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM -BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB -AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi -up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1 -mPnHfxsb1gYgAlihw6ID ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA -TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah -WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf -Tqj/ZA1k ------END CERTIFICATE----- - -Verisign Class 1 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd -k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq -WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB -MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM -XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC -lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ ------END CERTIFICATE----- - -Verisign Class 2 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h -cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp -Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 -c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h -cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp -Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 -c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx -nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC -wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA -ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK -1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk -LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg== ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G2 -============================================================ ------BEGIN CERTIFICATE----- -MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln -biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO -FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 -lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB -MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT -1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD -Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 ------END CERTIFICATE----- - -GlobalSign Root CA -================== ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx -GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds -b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD -VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa -DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc -THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb -Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP -c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX -gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF -AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj -Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG -j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH -hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC -X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -GlobalSign Root CA - R2 -======================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 -ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp -s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN -S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL -TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C -ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i -YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN -BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp -9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu -01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 -9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 -TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== ------END CERTIFICATE----- - -ValiCert Class 1 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy -MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi -GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm -DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG -lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX -icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP -Orf1LXLI ------END CERTIFICATE----- - -ValiCert Class 2 VA -=================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC -CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf -ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ -SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV -UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 -W9ViH0Pd ------END CERTIFICATE----- - -RSA Root Certificate 1 -====================== ------BEGIN CERTIFICATE----- -MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp -b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs -YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh -bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw -MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 -d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg -UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 -LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td -3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H -BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs -3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF -V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r -on+jjBXu ------END CERTIFICATE----- - -Verisign Class 1 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E -bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ -rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+ -Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB -FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N -y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 -ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h -a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc -D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== ------END CERTIFICATE----- - -Verisign Class 2 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y -azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug -b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ -BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 -c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y -aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6 -tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7 -C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS -0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs -Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0 -JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf -0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU -sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx -JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j -GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 -EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc -cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw -EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj -055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f -j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 -xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa -t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - -Verisign Class 4 Public Primary Certification Authority - G3 -============================================================ ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy -dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS -tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM -8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW -Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX -Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA -j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt -mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd -RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG -UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - -Entrust.net Secure Server CA -============================ ------BEGIN CERTIFICATE----- -MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg -cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl -ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG -A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi -eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p -dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ -aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 -gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw -ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw -CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l -dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF -bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu -dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw -NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow -HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA -BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN -Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 -n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= ------END CERTIFICATE----- - -Entrust.net Premium 2048 Secure Server CA -========================================= ------BEGIN CERTIFICATE----- -MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u -ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp -bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV -BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx -NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 -d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl -MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u -ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL -Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr -hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW -nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi -VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC -AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER -gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B -AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo -oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS -o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z -2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX -OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ== ------END CERTIFICATE----- - -Baltimore CyberTrust Root -========================= ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE -ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li -ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC -SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs -dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME -uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB -UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C -G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 -XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr -l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI -VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB -BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh -cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 -hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa -Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H -RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -Equifax Secure Global eBusiness CA -================================== ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp -bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx -HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds -b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV -PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN -qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn -hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs -MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN -I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY -NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 1 -============================= ------BEGIN CERTIFICATE----- -MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB -LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE -ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz -IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ -1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a -IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk -MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW -Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF -AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 -lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ -KpYrtWKmpj29f5JZzVoqgrI3eQ== ------END CERTIFICATE----- - -Equifax Secure eBusiness CA 2 -============================= ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE -ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y -MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT -DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn -2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 -BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG -A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx -JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG -A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e -uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB -Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 -jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia -78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm -V+GRMOrN ------END CERTIFICATE----- - -AddTrust Low-Value Services Root -================================ ------BEGIN CERTIFICATE----- -MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU -cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw -CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO -ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 -54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr -oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 -Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui -GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w -HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT -RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw -HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt -ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph -iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY -eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr -mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj -ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= ------END CERTIFICATE----- - -AddTrust External Root -====================== ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD -VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw -NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU -cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg -Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 -+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw -Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo -aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy -2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 -7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL -VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk -VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl -j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 -e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u -G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - -AddTrust Public Services Root -============================= ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU -cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ -BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l -dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu -nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i -d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG -Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw -HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G -A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G -A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 -JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL -+YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao -GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 -Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H -EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= ------END CERTIFICATE----- - -AddTrust Qualified Certificates Root -==================================== ------BEGIN CERTIFICATE----- -MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU -cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx -CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ -IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx -64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 -KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o -L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR -wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU -MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE -BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y -azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG -GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X -dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze -RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB -iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= ------END CERTIFICATE----- - -Entrust Root Certification Authority -==================================== ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw -b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG -A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 -MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu -MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu -Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v -dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz -A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww -Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 -j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN -rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 -MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH -hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM -Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa -v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS -W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 -tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -RSA Security 2048 v3 -==================== ------BEGIN CERTIFICATE----- -MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK -ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy -MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb -BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 -Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb -WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH -KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP -+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E -FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY -v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj -0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj -VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 -nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA -pKnXwiJPZ9d37CAFYd4= ------END CERTIFICATE----- - -GeoTrust Global CA -================== ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw -MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo -BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet -8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc -T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU -vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q -zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 -d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 -mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p -XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm -Mw== ------END CERTIFICATE----- - -GeoTrust Global CA 2 -==================== ------BEGIN CERTIFICATE----- -MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw -MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j -LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ -NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k -LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA -Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b -HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH -K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 -srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh -ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL -OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC -x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF -H4z1Ir+rzoPz4iIprn2DQKi6bA== ------END CERTIFICATE----- - -GeoTrust Universal CA -===================== ------BEGIN CERTIFICATE----- -MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 -MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu -Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t -JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e -RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs -7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d -8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V -qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga -Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB -Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu -KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 -ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 -XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB -hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc -aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 -qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL -oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK -xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF -KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 -DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK -xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU -p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI -P/rmMuGNG2+k5o7Y+SlIis5z/iw= ------END CERTIFICATE----- - -GeoTrust Universal CA 2 -======================= ------BEGIN CERTIFICATE----- -MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN -R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 -MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg -SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 -DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 -j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q -JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a -QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 -WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP -20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn -ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC -SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG -8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 -+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E -BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z -dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ -4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ -mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq -A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg -Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP -pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d -FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp -gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm -X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS ------END CERTIFICATE----- - -UTN-USER First-Network Applications -=================================== ------BEGIN CERTIFICATE----- -MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp -BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5 -WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T -YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB -cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug -mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj -DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu -Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi -P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE -j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w -HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j -cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G -CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y -IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK -RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp -xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq -DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE ------END CERTIFICATE----- - -America Online Root Certification Authority 1 -============================================= ------BEGIN CERTIFICATE----- -MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG -v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z -DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh -sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP -8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z -o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf -GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF -VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft -3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g -Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds -sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 ------END CERTIFICATE----- - -America Online Root Certification Authority 2 -============================================= ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT -QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG -A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg -T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en -fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 -f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO -qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN -RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 -gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn -6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid -FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 -Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj -B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op -aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY -T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p -+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg -JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy -zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO -ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh -1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf -GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff -Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP -cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= ------END CERTIFICATE----- - -Visa eCommerce Root -=================== ------BEGIN CERTIFICATE----- -MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG -EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug -QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 -WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm -VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv -bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL -F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b -RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 -TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI -/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs -GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG -MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc -CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW -YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz -zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu -YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt -398znM/jra6O1I7mT1GvFpLgXPYHDw== ------END CERTIFICATE----- - -Certum Root CA -============== ------BEGIN CERTIFICATE----- -MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK -ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla -Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u -by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x -wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL -kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ -89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K -Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P -NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ -GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg -GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ -0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS -qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== ------END CERTIFICATE----- - -Comodo AAA Services root -======================== ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw -MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl -c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV -BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG -C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs -i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW -Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH -Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK -Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f -BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl -cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz -LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm -7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z -8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C -12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -Comodo Secure Services root -=========================== ------BEGIN CERTIFICATE----- -MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw -MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu -Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi -BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP -9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc -rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC -oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V -p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E -FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w -gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj -YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm -aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm -4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj -Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL -DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw -pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H -RR3B7Hzs/Sk= ------END CERTIFICATE----- - -Comodo Trusted Services root -============================ ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw -MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h -bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw -IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 -3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y -/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 -juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS -ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud -DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp -ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl -cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw -uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 -pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA -BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l -R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O -9y5Xt5hwXsjEeLBi ------END CERTIFICATE----- - -QuoVadis Root CA -================ ------BEGIN CERTIFICATE----- -MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE -ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 -eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz -MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp -cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD -EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk -J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL -F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL -YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen -AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w -PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y -ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 -MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj -YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs -ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh -Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW -Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu -BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw -FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 -tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo -fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul -LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x -gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi -5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi -5nrQNiOKSnQ2+Q== ------END CERTIFICATE----- - -QuoVadis Root CA 2 -================== ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT -EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx -ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 -XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk -lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB -lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy -lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt -66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn -wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh -D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy -BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie -J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud -DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU -a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv -Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 -UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm -VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK -+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW -IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 -WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X -f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II -4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 -VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- - -QuoVadis Root CA 3 -================== ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT -EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx -OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg -DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij -KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K -DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv -BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp -p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 -nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX -MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM -Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz -uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT -BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj -YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB -BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD -VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 -ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE -AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV -qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s -hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z -POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 -Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp -8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC -bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu -g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p -vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr -qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- - -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - -Sonera Class 1 Root CA -====================== ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG -U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw -NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh -IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88 -7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9 -EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl -0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645 -2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa -HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT -iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9 -28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV -yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR -vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P -qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z -IRlXvVWa ------END CERTIFICATE----- - -Sonera Class 2 Root CA -====================== ------BEGIN CERTIFICATE----- -MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG -U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw -NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh -IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 -/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT -dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG -f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P -tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH -nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT -XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt -0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI -cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph -Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx -EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH -llpwrN9M ------END CERTIFICATE----- - -Staat der Nederlanden Root CA -============================= ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE -ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w -HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh -bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt -vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P -jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca -C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth -vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 -22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV -HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v -dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN -BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR -EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw -MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y -nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- - -TDC Internet Root CA -==================== ------BEGIN CERTIFICATE----- -MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE -ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx -NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu -ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j -xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL -znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc -5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 -otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI -AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM -VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM -MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC -AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe -UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G -CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m -gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ -2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb -O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU -Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l ------END CERTIFICATE----- - -TDC OCES Root CA -================ ------BEGIN CERTIFICATE----- -MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE -ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5 -MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH -nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0 -zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV -iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde -dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO -3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB -5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k -ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm -cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp -Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x -LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM -MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm -aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy -MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647 -+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6 -NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4 -A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc -A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9 -AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1 -AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw== ------END CERTIFICATE----- - -UTN DATACorp SGC Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ -BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa -MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w -HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy -dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys -raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo -wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA -9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv -33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud -DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 -BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD -LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 -DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 -I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx -EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP -DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- - -UTN USERFirst Email Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0 -BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05 -OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx -FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx -ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz -dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx -B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8 -om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG -TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl -yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE -AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV -HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll -bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH -AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne -xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+ -5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV -NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ -w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= ------END CERTIFICATE----- - -UTN USERFirst Hardware Root CA -============================== ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd -BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx -OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 -eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz -ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI -wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd -tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 -i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf -Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw -gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF -lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF -UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF -BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW -XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 -lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn -iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 -nfhmqA== ------END CERTIFICATE----- - -UTN USERFirst Object Root CA -============================ ------BEGIN CERTIFICATE----- -MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb -BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz -NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx -HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy -dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR -loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ -w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu -lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7 -RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL -BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8 -ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly -c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw -DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw -NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO -PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE -qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG -hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= ------END CERTIFICATE----- - -Camerfirma Chambers of Commerce Root -==================================== ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe -QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i -ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx -NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp -cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn -MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC -AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU -xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH -NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW -DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV -d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud -EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v -cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P -AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh -bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD -VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz -aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi -fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD -L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN -UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n -ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 -erfutGWaIZDgqtCYvDi1czyL+Nw= ------END CERTIFICATE----- - -Camerfirma Global Chambersign Root -================================== ------BEGIN CERTIFICATE----- -MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe -QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i -ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx -NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt -YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg -MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw -ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J -1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O -by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl -6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c -8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ -BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j -aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B -Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj -aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y -ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh -bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA -PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y -gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ -PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 -IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes -t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== ------END CERTIFICATE----- - -NetLock Qualified (Class QA) Root -================================= ------BEGIN CERTIFICATE----- -MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn -eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0 -bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER -MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0 -LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0 -dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP -aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV -CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e -8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb -m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ -0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM -0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV -HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2 -YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh -biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p -a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz -YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg -YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg -ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov -L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr -Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0 -aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg -YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0 -IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3 -DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN -wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg -W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc -R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR -5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko ------END CERTIFICATE----- - -NetLock Notary (Class A) Root -============================= ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI -EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j -ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX -DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH -EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD -VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz -cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM -D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ -z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC -/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 -tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 -4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG -A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC -Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv -bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn -LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 -ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz -IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh -IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu -b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh -bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg -Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp -bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 -ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP -ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB -CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr -KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM -8CgHrTwXZoi1/baI ------END CERTIFICATE----- - -NetLock Business (Class B) Root -=============================== ------BEGIN CERTIFICATE----- -MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg -VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD -VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv -bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg -VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S -o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr -1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV -HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ -RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh -dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 -ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv -c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg -YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh -c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz -Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA -bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl -IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 -YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj -cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM -43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR -stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI ------END CERTIFICATE----- - -NetLock Express (Class C) Root -============================== ------BEGIN CERTIFICATE----- -MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT -CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV -BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ -BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 -dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j -ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB -jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z -W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 -euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw -DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN -RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn -YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB -IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i -aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 -ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs -ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo -dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y -emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k -IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ -UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg -YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 -xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW -gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== ------END CERTIFICATE----- - -XRamp Global CA Root -==================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE -BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj -dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx -HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg -U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu -IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx -foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE -zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs -AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry -xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap -oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC -AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc -/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n -nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz -8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -Go Daddy Class 2 CA -=================== ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY -VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG -A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g -RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD -ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv -2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 -qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j -YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY -vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O -BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o -atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu -MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG -A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim -PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt -I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI -Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b -vZ8= ------END CERTIFICATE----- - -Starfield Class 2 CA -==================== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc -U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo -MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG -A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG -SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY -bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ -JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm -epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN -F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF -MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f -hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo -bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g -QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs -afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM -PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD -KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 -QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -StartCom Certification Authority -================================ ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu -ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 -NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk -LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg -U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y -o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ -Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d -eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt -2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z -6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ -osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ -untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc -UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT -37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj -YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH -AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw -Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg -U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 -LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh -cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT -dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC -AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh -3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm -vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk -fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 -fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ -EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl -1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ -lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro -g14= ------END CERTIFICATE----- - -Taiwan GRCA -=========== ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG -EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X -DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv -dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN -w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 -BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O -1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO -htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov -J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 -Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t -B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB -O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 -lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV -HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 -09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ -TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj -Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 -Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU -D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz -DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk -Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk -7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ -CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy -+fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS ------END CERTIFICATE----- - -Firmaprofesional Root CA -======================== ------BEGIN CERTIFICATE----- -MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT -GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp -Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA -ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL -MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT -OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2 -ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V -j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH -lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf -3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8 -NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww -KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG -AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD -ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq -u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf -wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm -7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG -VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA= ------END CERTIFICATE----- - -Wells Fargo Root CA -=================== ------BEGIN CERTIFICATE----- -MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV -BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl -bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv -MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX -x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3 -E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5 -OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j -sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj -YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF -BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD -ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv -m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R -OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx -x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023 -tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= ------END CERTIFICATE----- - -Swisscom Root CA 1 -================== ------BEGIN CERTIFICATE----- -MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG -EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy -dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 -MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln -aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC -IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM -MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF -NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe -AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC -b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn -7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN -cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp -WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 -haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY -MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw -HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j -BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 -MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn -jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ -MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H -VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl -vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl -OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 -1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq -nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy -x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW -NY6E0F/6MBr1mmz0DlP5OlvRHA== ------END CERTIFICATE----- - -DigiCert Assured ID Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx -MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO -9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy -UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW -/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy -oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf -GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF -66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq -hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc -EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn -SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i -8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -DigiCert Global Root CA -======================= ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -DigiCert High Assurance EV Root CA -================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw -KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw -MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ -MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu -Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t -Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS -OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 -MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ -NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe -h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY -JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ -V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp -myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK -mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K ------END CERTIFICATE----- - -Certplus Class 2 Primary CA -=========================== ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE -BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN -OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy -dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR -5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ -Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO -YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e -e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME -CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ -YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t -L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD -P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R -TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ -7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW -//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - -DST Root CA X3 -============== ------BEGIN CERTIFICATE----- -MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK -ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X -DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 -cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT -rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 -UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy -xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d -utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ -MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug -dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE -GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw -RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS -fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE----- - -DST ACES CA X6 -============== ------BEGIN CERTIFICATE----- -MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT -MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha -MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE -CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI -DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa -pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow -GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy -MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu -Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy -dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU -CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 -5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t -Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq -nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs -vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 -oKfN5XozNmr6mis= ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 1 -============================================== ------BEGIN CERTIFICATE----- -MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP -MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 -acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx -MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB -TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC -aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX -yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i -Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ -8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 -W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME -BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 -sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE -q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy -B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY -nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H ------END CERTIFICATE----- - -TURKTRUST Certificate Services Provider Root 2 -============================================== ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP -MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg -QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN -MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr -dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G -A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls -acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe -LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI -x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g -QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr -5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB -AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt -Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 -Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ -hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P -9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 -UrbnBEI= ------END CERTIFICATE----- - -SwissSign Platinum CA - G2 -========================== ------BEGIN CERTIFICATE----- -MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCQ0gxFTAT -BgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIw -HhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAwWjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMM -U3dpc3NTaWduIEFHMSMwIQYDVQQDExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu -669yIIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2HtnIuJpX+UF -eNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+6ixuEFGSzH7VozPY1kne -WCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5objM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIo -j5+saCB9bzuohTEJfwvH6GXp43gOCWcwizSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/6 -8++QHkwFix7qepF6w9fl+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34T -aNhxKFrYzt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaPpZjy -domyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtFKwH3HBqi7Ri6Cr2D -+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuWae5ogObnmLo2t/5u7Su9IPhlGdpV -CX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMBAAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCv -zAeHFUdvOMW0ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW -IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUAA4ICAQAIhab1 -Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0uMoI3LQwnkAHFmtllXcBrqS3 -NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4 -U99REJNi54Av4tHgvI42Rncz7Lj7jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8 -KV2LwUvJ4ooTHbG/u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl -9x8DYSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1puEa+S1B -aYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXaicYwu+uPyyIIoK6q8QNs -OktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbGDI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSY -Mdp08YSTcU1f+2BY0fvEwW2JorsgH51xkcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAci -IfNAChs0B0QTwoRqjt8ZWr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== ------END CERTIFICATE----- - -SwissSign Gold CA - G2 -====================== ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw -EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN -MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp -c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq -t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C -jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg -vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF -ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR -AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend -jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO -peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR -7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi -GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 -OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm -5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr -44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf -Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m -Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp -mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk -vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf -KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br -NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj -viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- - -SwissSign Silver CA - G2 -======================== ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT -BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X -DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 -aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG -9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 -N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm -+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH -6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu -MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h -qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 -FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs -ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc -celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X -CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB -tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P -4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F -kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L -3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx -/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa -DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP -e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu -WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ -DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub -DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority -======================================== ------BEGIN CERTIFICATE----- -MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx -CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ -cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN -b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 -nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge -RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt -tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI -hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K -Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN -NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa -Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG -1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= ------END CERTIFICATE----- - -thawte Primary Root CA -====================== ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 -MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg -SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv -KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT -FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs -oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ -1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc -q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K -aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p -afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF -AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE -uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX -xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 -jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH -z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G5 -============================================================ ------BEGIN CERTIFICATE----- -MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln -biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh -dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt -YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz -j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD -Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r -fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ -BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv -Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy -aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG -SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ -X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE -KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC -Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE -ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq ------END CERTIFICATE----- - -SecureTrust CA -============== ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy -dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe -BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX -OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t -DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH -GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b -01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH -ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj -aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu -SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf -mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ -nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -Secure Global CA -================ ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH -bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg -MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg -Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx -YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ -bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g -8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV -HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi -0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn -oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA -MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ -OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn -CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 -3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -COMODO Certification Authority -============================== ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE -BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG -A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb -MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD -T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH -+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww -xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV -4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA -1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI -rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k -b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC -AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP -OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc -IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN -+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== ------END CERTIFICATE----- - -Network Solutions Certificate Authority -======================================= ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG -EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr -IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx -MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx -jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT -aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT -crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc -/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB -AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv -bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA -A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q -4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ -GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD -ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - -WellsSecure Public Root Certificate Authority -============================================= ------BEGIN CERTIFICATE----- -MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM -F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw -NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN -MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl -bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD -VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 -iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 -i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 -bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB -K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB -AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu -cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm -lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB -i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww -GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI -K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 -bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj -qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es -E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ -tylv2G0xffX8oRAHh84vWdw+WNs= ------END CERTIFICATE----- - -COMODO ECC Certification Authority -================================== ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC -R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE -ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix -GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X -4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni -wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG -FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA -U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -IGC/A -===== ------BEGIN CERTIFICATE----- -MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD -VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE -Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy -MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI -EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT -STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 -TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW -So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy -HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd -frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ -tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB -egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC -iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK -q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q -MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg -Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI -lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF -0mBWWg== ------END CERTIFICATE----- - -Security Communication EV RootCA1 -================================= ------BEGIN CERTIFICATE----- -MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE -BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl -Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO -/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX -WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z -ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 -bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK -9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm -iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG -Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW -mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW -T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 ------END CERTIFICATE----- - -OISTE WISeKey Global Root GA CA -=============================== ------BEGIN CERTIFICATE----- -MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE -BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG -A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH -bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD -VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw -IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 -IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 -Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg -Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD -d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ -/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R -LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm -MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 -+vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa -hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY -okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= ------END CERTIFICATE----- - -S-TRUST Authentication and Encryption Root CA 2005 PN -===================================================== ------BEGIN CERTIFICATE----- -MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE -BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh -cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT -LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w -NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk -ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj -aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp -b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob -4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL -g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf -eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3 -KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB -/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv -bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU -D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD -pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08 -P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA -nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit -F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b -Hz2eBIPdltkdOpQ= ------END CERTIFICATE----- - -Microsec e-Szigno Root CA -========================= ------BEGIN CERTIFICATE----- -MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE -BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL -EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 -MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz -dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT -GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG -d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N -oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc -QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ -PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb -MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG -IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD -VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 -LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A -dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn -AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA -4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg -AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA -egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 -Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO -PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv -c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h -cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw -IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT -WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV -MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER -MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp -Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal -HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT -nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE -aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a -86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK -yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB -S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= ------END CERTIFICATE----- - -Certigna -======== ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw -EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 -MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI -Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q -XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH -GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p -ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg -DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf -Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ -tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ -BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J -SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA -hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ -ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu -PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY -1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. -====================================== ------BEGIN CERTIFICATE----- -MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT -AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg -LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w -HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ -U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh -IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN -yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU -2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 -4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP -2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm -8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf -HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa -Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK -5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b -czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g -ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF -BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug -cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf -AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX -EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v -/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 -MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 -3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk -eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f -/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h -RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU -Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== ------END CERTIFICATE----- - -TC TrustCenter Class 2 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw -MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw -IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 -xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ -Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u -SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G -dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ -KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj -TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP -JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk -vQ== ------END CERTIFICATE----- - -TC TrustCenter Class 3 CA II -============================ ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy -IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw -MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 -c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE -AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W -yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo -6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ -uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk -2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB -7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 -Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU -cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i -SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE -O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 -yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 -IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal -092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc -5A== ------END CERTIFICATE----- - -TC TrustCenter Universal CA I -============================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN -MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg -VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw -JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC -qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv -xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw -ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O -gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j -BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG -1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy -vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 -ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a -7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- - -Deutsche Telekom Root CA 2 -========================== ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT -RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG -A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 -MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G -A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS -b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 -bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI -KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY -AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK -Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV -jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV -HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr -E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy -zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 -rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G -dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - -ComSign CA -========== ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD -EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy -MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp -Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q -ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy -P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN -GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk -YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM -rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy -oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P -AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+ -VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2 -QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI -mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb -/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG -zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U -AGegcQCCSA== ------END CERTIFICATE----- - -ComSign Secured CA -================== ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE -AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w -NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD -QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs -49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH -7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB -kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 -9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw -AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t -U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA -j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC -AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a -BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp -FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP -51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- - -Cybertrust Global Root -====================== ------BEGIN CERTIFICATE----- -MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li -ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 -MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD -ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -+Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW -0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL -AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin -89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT -8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 -MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G -A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO -lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi -5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 -hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T -X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW -WL1WMRJOEcgh4LMRkWXbtKaIOM5V ------END CERTIFICATE----- - -ePKI Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx -MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq -MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs -IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi -lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv -qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX -12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O -WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ -ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao -lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ -vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi -Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi -MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 -1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq -KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV -xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP -NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r -GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE -xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx -gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy -sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD -BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 -============================================================================================================================= ------BEGIN CERTIFICATE----- -MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH -DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q -aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry -b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV -BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg -S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 -MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl -IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF -n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl -IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft -dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl -cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO -Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 -xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR -6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL -hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd -BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 -N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT -y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh -LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M -dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= ------END CERTIFICATE----- - -Buypass Class 2 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 -MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M -cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 -0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 -0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R -uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV -1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt -7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 -fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w -wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho ------END CERTIFICATE----- - -Buypass Class 3 CA 1 -==================== ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 -MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh -c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx -ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 -n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia -AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c -1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P -AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 -pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA -EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 -htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj -el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------END CERTIFICATE----- - -EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 -========================================================================== ------BEGIN CERTIFICATE----- -MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg -QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe -Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p -ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt -IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by -X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b -gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr -eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ -TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy -Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn -uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI -qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm -ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 -Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB -/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW -Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t -FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm -zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k -XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT -bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU -RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK -1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt -2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ -Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 -AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT ------END CERTIFICATE----- - -certSIGN ROOT CA -================ ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD -VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa -Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE -CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I -JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH -rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 -ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD -0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 -AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B -Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB -AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 -SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 -x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt -vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz -TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -CNNIC ROOT -========== ------BEGIN CERTIFICATE----- -MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE -ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw -OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD -o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz -VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT -VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or -czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK -y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC -wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S -lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 -Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM -O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 -BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 -G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m -mxE= ------END CERTIFICATE----- - -ApplicationCA - Japanese Government -=================================== ------BEGIN CERTIFICATE----- -MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT -SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw -MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl -cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 -fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN -wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE -jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu -nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU -WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV -BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD -vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs -o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g -/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD -io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW -dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL -rosot4LKGAfmt1t06SAZf7IbiVQ= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G3 -============================================= ------BEGIN CERTIFICATE----- -MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE -BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 -IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy -eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz -NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo -YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT -LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j -K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE -c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C -IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu -dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr -2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 -cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE -Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD -AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s -t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt ------END CERTIFICATE----- - -thawte Primary Root CA - G2 -=========================== ------BEGIN CERTIFICATE----- -MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC -VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu -IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg -Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV -MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG -b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt -IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS -LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 -8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU -mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN -G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K -rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== ------END CERTIFICATE----- - -thawte Primary Root CA - G3 -=========================== ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE -BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 -aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w -ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh -d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD -VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG -A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At -P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC -+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY -7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW -vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ -KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK -A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu -t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC -8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm -er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= ------END CERTIFICATE----- - -GeoTrust Primary Certification Authority - G2 -============================================= ------BEGIN CERTIFICATE----- -MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu -Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 -OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg -MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl -b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG -BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc -KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ -EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m -ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 -npaqBA+K ------END CERTIFICATE----- - -VeriSign Universal Root Certification Authority -=============================================== ------BEGIN CERTIFICATE----- -MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE -BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO -ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk -IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv -cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl -IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj -1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP -MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 -9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I -AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR -tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G -CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O -a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud -DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 -Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx -Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx -P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P -wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 -mJO37M2CYfE45k+XmCpajQ== ------END CERTIFICATE----- - -VeriSign Class 3 Public Primary Certification Authority - G4 -============================================================ ------BEGIN CERTIFICATE----- -MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC -VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 -b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz -ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU -cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo -b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 -Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz -rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw -HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u -Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD -A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx -AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== ------END CERTIFICATE----- - -NetLock Arany (Class Gold) Főtanúsítvány -============================================ ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G -A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 -dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB -cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx -MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO -ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 -c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu -0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw -/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk -H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw -fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 -neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW -qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta -YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna -NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu -dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -Staat der Nederlanden Root CA - G2 -================================== ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE -CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g -Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC -TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l -ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ -5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn -vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj -CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil -e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR -OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI -CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 -48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi -trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 -qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB -AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC -ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA -A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz -+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj -f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN -kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk -CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF -URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb -CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h -oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV -IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm -66+KAQ== ------END CERTIFICATE----- - -CA Disig -======== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK -QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw -MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz -bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm -GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD -Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo -hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt -ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w -gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P -AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz -aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff -ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa -BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t -WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 -mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K -ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA -4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- - -Juur-SK -======= ------BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA -c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw -DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG -SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy -aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf -TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC -+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw -UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa -Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF -MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD -HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh -AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA -cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr -AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw -cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE -FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G -A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo -ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL -abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 -IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh -Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 -yyqcjg== ------END CERTIFICATE----- - -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - -SecureSign RootCA11 -=================== ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi -SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS -b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw -KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 -cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL -TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO -wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq -g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP -O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA -bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX -t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh -OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r -bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ -Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 -y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 -lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - -ACEDICOM Root -============= ------BEGIN CERTIFICATE----- -MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD -T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 -MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG -A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk -WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD -YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew -MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb -m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk -HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT -xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 -3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 -2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq -TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz -4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU -9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv -bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg -aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP -eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk -zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 -ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI -KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq -nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE -I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp -MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o -tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== ------END CERTIFICATE----- - -Verisign Class 1 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ -VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2 -yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa -XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n -0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ -RjXZ+Hxb ------END CERTIFICATE----- - -Verisign Class 3 Public Primary Certification Authority -======================================================= ------BEGIN CERTIFICATE----- -MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow -XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA -A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 -f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol -hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky -CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX -bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ -D/xwzoiQ ------END CERTIFICATE----- - -Microsec e-Szigno Root CA 2009 -============================== ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER -MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv -c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE -BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt -U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA -fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG -0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA -pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm -1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC -AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf -QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE -FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o -lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX -I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 -yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi -LXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi -=================================================== ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz -ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 -MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 -cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u -aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY -8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y -jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI -JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk -9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG -SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d -F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq -D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 -Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- - -GlobalSign Root CA - R3 -======================= ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt -iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ -0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 -rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl -OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 -xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 -lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 -EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E -bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 -YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r -kpeDMdmztcpHWD9f ------END CERTIFICATE----- - -TC TrustCenter Universal CA III -=============================== ------BEGIN CERTIFICATE----- -MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC -REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy -IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe -Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU -QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex -KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt -QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO -juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut -CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1 -M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G -A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA -g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+ -KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK -BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV -CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq -woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== ------END CERTIFICATE----- - -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - -Izenpe.com -========== ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG -EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz -MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu -QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ -03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK -ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU -+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC -PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT -OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK -F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK -0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ -0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB -leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID -AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ -SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG -NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O -BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l -Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga -kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q -hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs -g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 -aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 -nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC -ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo -Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z -WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- - -Chambers of Commerce Root - 2008 -================================ ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy -Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl -ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF -EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl -cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA -XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj -h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ -ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk -NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g -D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 -lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ -0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 -EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI -G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ -BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh -bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh -bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC -CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH -AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 -wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH -3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU -RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 -M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 -YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF -9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK -zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG -nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ ------END CERTIFICATE----- - -Global Chambersign Root - 2008 -============================== ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD -MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv -bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu -QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx -NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg -Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ -QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf -VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf -XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 -ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB -/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA -TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M -H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe -Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF -HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB -AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT -BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE -BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm -aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm -aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp -1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 -dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG -/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 -ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s -dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg -9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH -foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du -qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr -P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq -c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- - -Go Daddy Root Certificate Authority - G2 -======================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu -MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G -A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq -9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD -+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd -fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl -NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 -BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac -vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r -5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV -N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 ------END CERTIFICATE----- - -Starfield Root Certificate Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw -DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg -VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB -dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv -W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs -bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk -N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf -ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU -JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol -TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx -4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw -F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ -c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -Starfield Services Root Certificate Authority - G2 -================================================== ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl -IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT -dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 -h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa -hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP -LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB -rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG -SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP -E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy -xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza -YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 ------END CERTIFICATE----- - -AffirmTrust Commercial -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw -MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb -DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV -C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 -BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww -MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV -HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG -hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi -qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv -0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh -sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -AffirmTrust Networking -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw -MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE -Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI -dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 -/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb -h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV -HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu -UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 -12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 -WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 -/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -AffirmTrust Premium -=================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy -OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy -dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn -BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV -5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs -+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd -GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R -p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI -S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 -6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 -/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo -+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv -MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC -6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S -L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK -+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV -BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg -IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 -g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb -zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== ------END CERTIFICATE----- - -AffirmTrust Premium ECC -======================= ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV -BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx -MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U -cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ -N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW -BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK -BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X -57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM -eQ== ------END CERTIFICATE----- - -Certum Trusted Network CA -========================= ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK -ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy -MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU -ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC -l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J -J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 -fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 -cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB -Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw -DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj -jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 -mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj -Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -Certinomis - Autorité Racine -============================= ------BEGIN CERTIFICATE----- -MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK -Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg -LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG -A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw -JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa -wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly -Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw -2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N -jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q -c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC -lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb -xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g -530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna -4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ -KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x -WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva -R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 -nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B -CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv -JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE -qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b -WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE -wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ -vgt2Fl43N+bYdJeimUV5 ------END CERTIFICATE----- - -Root CA Generalitat Valenciana -============================== ------BEGIN CERTIFICATE----- -MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE -ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 -IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 -WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE -CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 -F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B -ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ -D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte -JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB -AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n -dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB -ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl -AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA -YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy -AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA -aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt -AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA -YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu -AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA -OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 -dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV -BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G -A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S -b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh -TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz -Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 -NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH -iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt -+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= ------END CERTIFICATE----- - -A-Trust-nQual-03 -================ ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE -Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy -a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R -dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw -RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 -ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 -c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA -zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n -yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE -SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 -iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V -cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV -eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 -ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr -sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd -JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS -mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 -ahq97BvIxYSazQ== ------END CERTIFICATE----- - -TWCA Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ -VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG -EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB -IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx -QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC -oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP -4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r -y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG -9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC -mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW -QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY -T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny -Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -Security Communication RootCA2 -============================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC -SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy -aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ -+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R -3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV -spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K -EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 -QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj -u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk -3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q -tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 -mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -EC-ACC -====== ------BEGIN CERTIFICATE----- -MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE -BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w -ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD -VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE -CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT -BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 -MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt -SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl -Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh -cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK -w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT -ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 -HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a -E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw -0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD -VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 -Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l -dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ -lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa -Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe -l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 -E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D -5EI= ------END CERTIFICATE----- - -Hellenic Academic and Research Institutions RootCA 2011 -======================================================= ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT -O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y -aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT -AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo -IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI -1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa -71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u -8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH -3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ -MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 -MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu -b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt -XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD -/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N -7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- - -Actalis Authentication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM -BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE -AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky -MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz -IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ -wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa -by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 -zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f -YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 -oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l -EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 -hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 -EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 -jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY -iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI -WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 -JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx -K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ -Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC -4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo -2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz -lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem -OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 -vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -Trustis FPS Root CA -=================== ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG -EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 -IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV -BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ -RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk -H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa -cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt -o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA -AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd -BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c -GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC -yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P -8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV -l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl -iB6XzCGcKQENZetX2fNXlrtIzYE= ------END CERTIFICATE----- - -StartCom Certification Authority -================================ ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu -ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 -NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk -LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg -U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y -o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ -Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d -eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt -2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z -6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ -osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ -untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc -UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT -37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ -Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 -dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu -c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv -bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 -aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t -L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG -cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 -fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm -N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN -Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T -tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX -e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA -2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs -HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib -D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= ------END CERTIFICATE----- - -StartCom Certification Authority G2 -=================================== ------BEGIN CERTIFICATE----- -MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN -U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE -ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O -o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG -4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi -Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul -Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs -O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H -vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L -nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS -FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa -z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ -KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K -2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk -J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ -JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG -/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc -nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld -blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc -l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm -7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm -obp573PYtlNXLfbQ4ddI ------END CERTIFICATE----- - -Buypass Class 2 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X -DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 -g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn -9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b -/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU -CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff -awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI -zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn -Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX -Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs -M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI -osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S -aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd -DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD -LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 -oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC -wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS -CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN -rJgWVqA= ------END CERTIFICATE----- - -Buypass Class 3 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X -DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH -sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR -5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh -7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ -ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH -2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV -/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ -RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA -Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq -j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G -uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG -Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 -ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 -KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz -6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug -UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe -eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi -Cp/HuZc= ------END CERTIFICATE----- - -TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı -====================================================== ------BEGIN CERTIFICATE----- -MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF -bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP -MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg -QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X -DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl -a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN -BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp -bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N -YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv -KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya -KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT -rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC -AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s -Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I -aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO -Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb -BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK -poRq0Tl9 ------END CERTIFICATE----- - -T-TeleSec GlobalRoot Class 3 -============================ ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM -IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU -cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx -MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz -dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD -ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK -9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU -NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF -iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W -0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr -AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb -fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT -ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h -P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== ------END CERTIFICATE----- - -EE Certification Centre Root CA -=============================== ------BEGIN CERTIFICATE----- -MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG -EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy -dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw -MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB -UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy -ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM -TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 -rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw -93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN -P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ -MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF -BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj -xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM -lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u -uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU -3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM -dcGWxZ0= ------END CERTIFICATE----- diff --git a/tests/Entities/AppSecretProofTest.php b/tests/Entities/AppSecretProofTest.php deleted file mode 100755 index 7c1c7ec64..000000000 --- a/tests/Entities/AppSecretProofTest.php +++ /dev/null @@ -1,45 +0,0 @@ -assertEquals('12f5dcbb7557d24b1d37fd180c45991c5999f325ece0af331c00a85d762f2b95', $appSecretProof); - } - - public function testAnAppSecretProofEntityCanBeReturnedAsAString() - { - $appSecretProof = new AppSecretProof('foo_access_token', 'foo_app_secret'); - - $this->assertEquals('12f5dcbb7557d24b1d37fd180c45991c5999f325ece0af331c00a85d762f2b95', (string) $appSecretProof); - } - -} diff --git a/tests/Entities/FacebookAppTest.php b/tests/Entities/FacebookAppTest.php index 34e6caf4a..b938855f1 100644 --- a/tests/Entities/FacebookAppTest.php +++ b/tests/Entities/FacebookAppTest.php @@ -27,6 +27,10 @@ class FacebookAppTest extends \PHPUnit_Framework_TestCase { + + /** + * @var FacebookApp + */ private $app; public function setUp() @@ -44,7 +48,7 @@ public function testGetSecret() $this->assertEquals('secret', $this->app->getSecret()); } - public function testGetAccessToken() + public function testAnAppAccessTokenCanBeGenerated() { $accessToken = $this->app->getAccessToken(); @@ -60,4 +64,5 @@ public function testSerialization() $this->assertEquals('id', $newApp->getId()); $this->assertEquals('secret', $newApp->getSecret()); } + } diff --git a/tests/Entities/SignedRequestTest.php b/tests/Entities/SignedRequestTest.php index 67096fdcf..0218fda05 100644 --- a/tests/Entities/SignedRequestTest.php +++ b/tests/Entities/SignedRequestTest.php @@ -23,16 +23,21 @@ */ namespace Facebook\Tests\Entities; +use Facebook\Entities\FacebookApp; use Facebook\Entities\SignedRequest; class SignedRequestTest extends \PHPUnit_Framework_TestCase { - public $appSecret = 'foo_app_secret'; + /** + * @var FacebookApp + */ + protected $app; - public $rawSignedRequest = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; + protected $rawSignature = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8='; + protected $rawPayload = 'eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; - public $payloadData = [ + protected $payloadData = [ 'oauth_token' => 'foo_token', 'algorithm' => 'HMAC-SHA256', 'issued_at' => 321, @@ -42,10 +47,22 @@ class SignedRequestTest extends \PHPUnit_Framework_TestCase 'foo' => 'bar', ]; - public function testValidSignedRequestsWillPassFormattingValidation() + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_app_secret'); + } + + public function testAValidSignedRequestCanBeCreated() { - $sr = SignedRequest::make($this->payloadData, $this->appSecret); - SignedRequest::validateFormat($sr); + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($this->payloadData); + + $srTwo = new SignedRequest($this->app, $rawSignedRequest); + $payload = $srTwo->getPayload(); + + $expectedRawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $this->assertEquals($expectedRawSignedRequest, $rawSignedRequest); + $this->assertEquals($this->payloadData, $payload); } /** @@ -53,51 +70,31 @@ public function testValidSignedRequestsWillPassFormattingValidation() */ public function testInvalidSignedRequestsWillFailFormattingValidation() { - SignedRequest::validateFormat('invalid_signed_request'); - } - - public function testSignatureAndPayloadCanBeSeparatedInSignedRequests() - { - list($sig, $payload) = SignedRequest::split('sig.payload'); - - $this->assertEquals('sig', $sig); - $this->assertEquals('payload', $payload); + new SignedRequest($this->app, 'invalid_signed_request'); } public function testBase64EncodingIsUrlSafe() { - $encodedData = SignedRequest::base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); + $sr = new SignedRequest($this->app); + $encodedData = $sr->base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); $this->assertEquals('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4_Lnx-', $encodedData); } public function testAUrlSafeBase64EncodedStringCanBeDecoded() { - $decodedData = SignedRequest::base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); + $sr = new SignedRequest($this->app); + $decodedData = $sr->base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); $this->assertEquals('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~', $decodedData); } - public function testAValidEncodedSignatureCanBeDecoded() - { - $decodedSig = SignedRequest::decodeSignature('c2ln'); - - $this->assertEquals('sig', $decodedSig); - } - /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ public function testAnImproperlyEncodedSignatureWillThrowAnException() { - SignedRequest::decodeSignature('foo!'); - } - - public function testAValidEncodedPayloadCanBeDecoded() - { - $decodedPayload = SignedRequest::decodePayload('WyJwYXlsb2FkIl0='); - - $this->assertEquals(['payload'], $decodedPayload); + new SignedRequest($this->app, 'foo_sig.' . $this->rawPayload); } /** @@ -105,12 +102,7 @@ public function testAValidEncodedPayloadCanBeDecoded() */ public function testAnImproperlyEncodedPayloadWillThrowAnException() { - SignedRequest::decodePayload('foo!'); - } - - public function testSignedRequestDataMustContainTheHmacSha256Algorithm() - { - SignedRequest::validateAlgorithm($this->payloadData); + new SignedRequest($this->app, $this->rawSignature . '.foo_payload'); } /** @@ -120,36 +112,19 @@ public function testNonApprovedAlgorithmsWillThrowAnException() { $signedRequestData = $this->payloadData; $signedRequestData['algorithm'] = 'FOO-ALGORITHM'; - SignedRequest::validateAlgorithm($signedRequestData); - } - - public function testASignatureHashCanBeGeneratedFromBase64EncodedData() - { - $hashedSig = SignedRequest::hashSignature('WyJwYXlsb2FkIl0=', $this->appSecret); - $expectedSig = base64_decode('bFofyO2sERX73y8uvuX26SLodv0mZ+Zk18d8b3zhD+s='); - $this->assertEquals($expectedSig, $hashedSig); - } + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($signedRequestData); - public function testTwoBinaryStringsCanBeComparedForSignatureValidation() - { - $hashedSig = base64_decode('bFofyO2sERX73y8uvuX26SLodv0mZ+Zk18d8b3zhD+s='); - SignedRequest::validateSignature($hashedSig, $hashedSig); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testNonSameBinaryStringsWillThrowAnExceptionForSignatureValidation() - { - $hashedSig1 = base64_decode('bFofyO2sERX73y8uvuX26SLodv0mZ+Zk18d8b3zhD+s='); - $hashedSig2 = base64_decode('GJy4HzkRtCeZA0cJjdZJtGfovcdxgl/AERI20S4MY7c='); - SignedRequest::validateSignature($hashedSig1, $hashedSig2); + new SignedRequest($this->app, $rawSignedRequest); } public function testASignedRequestWillPassCsrfValidation() { - SignedRequest::validateCsrf($this->payloadData, 'foo_state'); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest, 'foo_state'); + + $this->assertEquals($this->payloadData, $sr->getPayload()); } /** @@ -157,30 +132,27 @@ public function testASignedRequestWillPassCsrfValidation() */ public function testASignedRequestWithIncorrectCsrfDataWillThrowAnException() { - SignedRequest::validateCsrf($this->payloadData, 'invalid_foo_state'); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + new SignedRequest($this->app, $rawSignedRequest, 'invalid_foo_state'); } - public function testARawSignedRequestCanBeValidatedAndDecoded() + public function testAsRawSignedRequestCanBeValidatedAndDecoded() { - $payload = SignedRequest::parse($this->rawSignedRequest, 'foo_state', $this->appSecret); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); - $this->assertEquals($this->payloadData, $payload); + $this->assertEquals($this->payloadData, $sr->getPayload()); } - public function testARawSignedRequestCanBeInjectedIntoTheConstructorToInstantiateANewEntity() + public function testARawSignedRequestCanBeValidatedAndDecoded() { - $signedRequest = new SignedRequest($this->rawSignedRequest, 'foo_state', $this->appSecret); - - $rawSignedRequest = $signedRequest->getRawSignedRequest(); - $payloadData = $signedRequest->getPayload(); - $userId = $signedRequest->getUserId(); - $hasOAuthData = $signedRequest->hasOAuthData(); - - $this->assertInstanceOf('\Facebook\Entities\SignedRequest', $signedRequest); - $this->assertEquals($this->rawSignedRequest, $rawSignedRequest); - $this->assertEquals($this->payloadData, $payloadData); - $this->assertEquals(123, $userId); - $this->assertTrue($hasOAuthData); + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); + + $this->assertEquals($sr->getPayload(), $this->payloadData); + $this->assertEquals($sr->getRawSignedRequest(), $rawSignedRequest); + $this->assertEquals(123, $sr->getUserId()); + $this->assertTrue($sr->hasOAuthData()); } } diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 91e35e9ca..506d359cf 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -23,17 +23,24 @@ */ namespace Facebook\Tests\Exceptions; +use Facebook\Entities\FacebookApp; +use Facebook\Entities\FacebookRequest; +use Facebook\Entities\FacebookResponse; use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookAuthorizationException; -use Facebook\Exceptions\FacebookOtherException; -use Facebook\Exceptions\FacebookServerException; -use Facebook\Exceptions\FacebookPermissionException; -use Facebook\Exceptions\FacebookClientException; -use Facebook\Exceptions\FacebookThrottleException; class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); + } + public function testAuthorizationExceptions() { $params = [ @@ -44,58 +51,59 @@ public function testAuthorizationExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(100, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['code'] = 102; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(102, $exception->getCode()); $params['error']['code'] = 190; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(190, $exception->getCode()); $params['error']['type'] = 'OAuthException'; $params['error']['code'] = 0; $params['error']['error_subcode'] = 458; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(458, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 460; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(460, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 463; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(463, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 467; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(467, $exception->getSubErrorCode()); $params['error']['error_subcode'] = 0; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(0, $exception->getSubErrorCode()); } @@ -109,20 +117,21 @@ public function testServerExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 500); - $this->assertTrue($exception instanceof FacebookServerException); + + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); $this->assertEquals(1, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(500, $exception->getHttpStatusCode()); $params['error']['code'] = 2; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookServerException); + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); $this->assertEquals(2, $exception->getCode()); } @@ -136,26 +145,26 @@ public function testThrottleExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookThrottleException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); $this->assertEquals(4, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['code'] = 17; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookThrottleException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); $this->assertEquals(17, $exception->getCode()); $params['error']['code'] = 341; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookThrottleException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); $this->assertEquals(341, $exception->getCode()); } @@ -169,20 +178,20 @@ public function testUserIssueExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(230, $exception->getCode()); $this->assertEquals(459, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['error_subcode'] = 464; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookAuthorizationException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(464, $exception->getSubErrorCode()); } @@ -196,32 +205,32 @@ public function testPermissionExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(10, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); $params['error']['code'] = 200; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(200, $exception->getCode()); $params['error']['code'] = 250; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(250, $exception->getCode()); $params['error']['code'] = 299; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookPermissionException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); $this->assertEquals(299, $exception->getCode()); } @@ -235,14 +244,14 @@ public function testClientExceptions() 'type' => 'exception' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 401); - $this->assertTrue($exception instanceof FacebookClientException); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookClientException', $exception->getPrevious()); $this->assertEquals(506, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(401, $exception->getHttpStatusCode()); } @@ -256,14 +265,14 @@ public function testOtherException() 'type' => 'feature' ], ]; - $json = json_encode($params); - $exception = FacebookResponseException::create($json, $params, 200); - $this->assertTrue($exception instanceof FacebookOtherException); + $response = new FacebookResponse($this->request, json_encode($params), 200); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookOtherException', $exception->getPrevious()); $this->assertEquals(42, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('feature', $exception->getErrorType()); $this->assertEquals('ship love', $exception->getMessage()); - $this->assertEquals($json, $exception->getRawResponse()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); $this->assertEquals(200, $exception->getHttpStatusCode()); } diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 48c9b2de4..b60ca9436 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -30,6 +30,7 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; use Facebook\Entities\FacebookRequest; +use Facebook\Entities\AccessToken; use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface @@ -162,6 +163,26 @@ public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); } + public function testAnAccessTokenCanBeSetAsAString() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken('foo_token'); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('foo_token', (string) $accessToken); + } + + public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken(new AccessToken('bar_token')); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertEquals('bar_token', (string) $accessToken); + } + /** * @expectedException \InvalidArgumentException */ diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index f7e1b2482..9eaaee094 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -56,15 +56,35 @@ public function testCanOpenGetCurlConnection() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with([ - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_HTTPHEADER => ['X-Foo-Header: X-Bar'], - CURLOPT_URL => 'http://foo.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 123, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - ]) + ->with(m::on(function($arg) { + + // array_diff() will sometimes trigger error on child-arrays + if (['X-Foo-Header: X-Bar'] !== $arg[CURLOPT_HTTPHEADER]) { + return false; + } + unset($arg[CURLOPT_HTTPHEADER]); + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_URL => 'http://foo.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 123, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) ->once() ->andReturn(null); @@ -79,33 +99,42 @@ public function testCanOpenCurlConnectionWithPostBody() ->andReturn(null); $this->curlMock ->shouldReceive('setopt_array') - ->with([ - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_HTTPHEADER => [], - CURLOPT_URL => 'http://bar.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POSTFIELDS => 'baz=bar', - ]) + ->with(m::on(function($arg) { + + // array_diff() will sometimes trigger error on child-arrays + if ([] !== $arg[CURLOPT_HTTPHEADER]) { + return false; + } + unset($arg[CURLOPT_HTTPHEADER]); + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_URL => 'http://bar.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 60, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_POSTFIELDS => 'baz=bar', + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) ->once() ->andReturn(null); $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', [], 60); } - public function testCanAddBundledCert() - { - $this->curlMock - ->shouldReceive('setopt') - ->with(CURLOPT_CAINFO, '/.fb_ca_chain_bundle\.crt$/') - ->once() - ->andReturn(null); - - $this->curlClient->addBundledCert(); - } - public function testCanCloseConnection() { $this->curlMock @@ -116,24 +145,6 @@ public function testCanCloseConnection() $this->curlClient->closeConnection(); } - public function testTrySendRequest() - { - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn('foo response'); - $this->curlMock - ->shouldReceive('errno') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('error') - ->once() - ->andReturn(null); - - $this->curlClient->tryToSendRequest(); - } - public function testIsolatesTheHeaderAndBody() { $this->curlMock @@ -271,10 +282,6 @@ public function testCanSendNormalRequest() ->shouldReceive('errno') ->once() ->andReturn(null); - $this->curlMock - ->shouldReceive('error') - ->once() - ->andReturn(null); $this->curlMock ->shouldReceive('getinfo') ->with(CURLINFO_HEADER_SIZE) diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index b5bb678fa..1a71d36af 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -25,6 +25,10 @@ use Mockery as m; use Facebook\HttpClients\FacebookGuzzleHttpClient; +use GuzzleHttp\Message\Request; +use GuzzleHttp\Message\Response; +use GuzzleHttp\Stream\Stream; +use GuzzleHttp\Exception\RequestException; class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient { @@ -47,38 +51,44 @@ public function setUp() public function testCanSendNormalRequest() { - $responseMock = m::mock('GuzzleHttp\Message\ResponseInterface'); - $responseMock - ->shouldReceive('getStatusCode') - ->once() - ->andReturn(200); - $responseMock - ->shouldReceive('getHeaders') - ->once() - ->andReturn($this->fakeHeadersAsArray); - $responseMock - ->shouldReceive('getBody') - ->once() - ->andReturn($this->fakeRawBody); + $request = new Request('GET', 'http://foo.com'); - $options = [ - 'headers' => ['X-foo' => 'bar'], - 'body' => 'foo_body', - 'timeout' => 123, - 'connect_timeout' => 10, - ]; + $body = Stream::factory($this->fakeRawBody); + $response = new Response(200, $this->fakeHeadersAsArray, $body); - $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', $options) - ->andReturn($requestMock); + ->with('GET', 'http://foo.com/', m::on(function($arg) { + + // array_diff_assoc() will sometimes trigger error on child-arrays + if (['X-foo' => 'bar'] !== $arg['headers']) { + return false; + } + unset($arg['headers']); + + $caInfo = array_diff_assoc($arg, [ + 'body' => 'foo_body', + 'timeout' => 123, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); $this->guzzleMock ->shouldReceive('send') ->once() - ->with($requestMock) - ->andReturn($responseMock); + ->with($request) + ->andReturn($response); $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); @@ -93,33 +103,41 @@ public function testCanSendNormalRequest() */ public function testThrowsExceptionOnClientError() { - $requestMock = m::mock('GuzzleHttp\Message\RequestInterface'); - $exceptionMock = m::mock( - 'GuzzleHttp\Exception\RequestException', - [ - 'Foo Error', - $requestMock, - null, - m::mock('GuzzleHttp\Ring\Exception\RingException'), - ]); - - $options = [ - 'headers' => [], - 'body' => 'foo_body', - 'timeout' => 60, - 'connect_timeout' => 10, - ]; + $request = new Request('GET', 'http://foo.com'); $this->guzzleMock ->shouldReceive('createRequest') ->once() - ->with('GET', 'http://foo.com/', $options) - ->andReturn($requestMock); + ->with('GET', 'http://foo.com/', m::on(function($arg) { + + // array_diff_assoc() will sometimes trigger error on child-arrays + if ([] !== $arg['headers']) { + return false; + } + unset($arg['headers']); + + $caInfo = array_diff_assoc($arg, [ + 'body' => 'foo_body', + 'timeout' => 60, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); $this->guzzleMock ->shouldReceive('send') ->once() - ->with($requestMock) - ->andThrow($exceptionMock); + ->with($request) + ->andThrow(new RequestException('Foo', $request)); $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); } diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index fc1e99114..9f9247c5f 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -60,8 +60,8 @@ public function testCanSendNormalRequest() $this->streamMock ->shouldReceive('streamContextCreate') ->once() - ->with(\Mockery::on(function($arg) { - if (!isset($arg['http']) || !isset($arg['ssl'])) { + ->with(m::on(function($arg) { + if ( ! isset($arg['http']) || ! isset($arg['ssl'])) { return false; } @@ -75,11 +75,17 @@ public function testCanSendNormalRequest() return false; } - if ($arg['ssl']['verify_peer'] !== true) { + $caInfo = array_diff_assoc($arg['ssl'], [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, + ]); + + if (count($caInfo) !== 1) { return false; } - if (false === preg_match('/.fb_ca_chain_bundle\.crt$/', $arg['ssl']['cafile'])) { + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['cafile'])) { return false; } From 781cab1b8d0bc3ca5a80d8ba84ddfe8a75cc360f Mon Sep 17 00:00:00 2001 From: SammyK Date: Mon, 8 Dec 2014 19:11:35 -0600 Subject: [PATCH 077/407] Updated docs --- docs/Facebook.fbmd | 4 +- docs/FacebookClient.fbmd | 87 +++++++ docs/FacebookFile.fbmd | 2 +- docs/FacebookSDKException.fbmd | 19 ++ docs/FacebookSession.fbmd | 71 ------ docs/GraphObject.fbmd | 405 +++++++++++++++++++++++++++----- docs/post_links.fbmd | 22 +- docs/retrieve_user_profile.fbmd | 46 ++-- docs/upload_photo.fbmd | 58 ++--- 9 files changed, 515 insertions(+), 199 deletions(-) create mode 100644 docs/FacebookClient.fbmd create mode 100644 docs/FacebookSDKException.fbmd delete mode 100644 docs/FacebookSession.fbmd diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 188b323a9..d75692ca4 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -145,9 +145,9 @@ Returns the instance of `Facebook\Entities\FacebookApp` for the instantiated ser ### getClient() {#get-client} ~~~~ -public FacebookClient getClient() +public Facebook\FacebookClient getClient() ~~~~ -Returns the instance of `Facebook\FacebookClient` for the instantiated service. +Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) for the instantiated service. diff --git a/docs/FacebookClient.fbmd b/docs/FacebookClient.fbmd new file mode 100644 index 000000000..f78e26753 --- /dev/null +++ b/docs/FacebookClient.fbmd @@ -0,0 +1,87 @@ + +# 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 {#overview} + +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. + +~~~~ +$fb = new Facebook\Facebook(/* */); +$fbClient = $fb->getClient(); +~~~~ + +Alternatively you could instantiate a new `Facebook\FacebookClient` service directly. + +~~~~ +$fbApp = new Facebook\Entities\FacebookApp('{app_id}', '{app_secret}'); +$fbClient = new Facebook\FacebookClient($fbApp, $enableBeta = false); +~~~~ + +The Graph API has a number of different base URL's based on what request you're trying 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 {#instance-methods} + +### getHttpClientHandler() {#get-http-client-handler} +~~~~ +public Facebook\HttpClients\FacebookHttpClientInterface getHttpClientHandler() +~~~~ +Returns the instance of [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface) that the service is using. + + + +### setHttpClientHandler() {#set-http-client-handler} +~~~~ +public setHttpClientHandler(Facebook\HttpClients\FacebookHttpClientInterface $client) +~~~~ +If you've coded your own HTTP client to the [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface), you can inject it into the service using this method. + + + +### enableBetaMode() {#enable-beta-mode} +~~~~ +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() {#send-request} +~~~~ +public Facebook\Entities\FacebookResponse sendRequest(Facebook\Entities\FacebookRequest $request) +~~~~ +Sends a non-batch request to Graph. + +Takes a [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) 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\Entities\FacebookResponse`](/docs/php/FacebookResponse). + +If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) will be thrown. + +If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) will be thrown. + + + +### sendBatchRequest() {#send-batch-request} +~~~~ +public Facebook\Entities\FacebookBatchResponse sendBatchRequest(Facebook\Entities\FacebookBatchRequest $batchRequest) +~~~~ +Sends a batch request to Graph. + +Takes a [`Facebook\Entities\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) 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\Entities\FacebookBatchResponse`](/docs/php/FacebookBatchResponse). + +If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) will be thrown. + +If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) will be thrown. + diff --git a/docs/FacebookFile.fbmd b/docs/FacebookFile.fbmd index ade8f09cb..7efcf5958 100644 --- a/docs/FacebookFile.fbmd +++ b/docs/FacebookFile.fbmd @@ -23,7 +23,7 @@ Alternatively, you can use the `fileToUpload()` factory on the `Facebook\Faceboo ~~~~ $fb = new Facebook\Facebook(/* . . . */); -$myFileToUpload = $fb->fileToUpload('/path/to/file.jpg'), +$myFileToUpload = $fb->fileToUpload('/path/to/file.jpg'); ~~~~ diff --git a/docs/FacebookSDKException.fbmd b/docs/FacebookSDKException.fbmd new file mode 100644 index 000000000..6bffc6efa --- /dev/null +++ b/docs/FacebookSDKException.fbmd @@ -0,0 +1,19 @@ + +# FacebookSDKException for the Facebook SDK for PHP + +Represents an exception thrown by the SDK. + + + +## Facebook\Exceptions\FacebookSDKException {#overview} + +A `FacebookSDKException` is thrown when something goes wrong. For example if an invalid signed request is sent to the `Facebook\Entities\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](/docs/php/FacebookResponseException). + + + +## Instance Methods {#instance-methods} + +`FacebookSDKException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. + diff --git a/docs/FacebookSession.fbmd b/docs/FacebookSession.fbmd deleted file mode 100644 index 8de267e74..000000000 --- a/docs/FacebookSession.fbmd +++ /dev/null @@ -1,71 +0,0 @@ - -# FacebookSession for the Facebook SDK for PHP - -Represents a Facebook Session, which is used when making requests to the Graph API. - - - -## Facebook\FacebookSession {#overview} - -Usage: - -~~~~ -use Facebook\FacebookSession; - -FacebookSession::setDefaultApplication('app-id', 'app-secret'); - -// If you already have a valid access token: -$session = new FacebookSession('access-token'); - -// If you're making app-level requests: -$session = FacebookSession::newAppSession(); - -// To validate the session: -try { - $session->validate(); -} catch (FacebookResponseException $ex) { - // Session not valid, Graph API returned an exception with the reason. - echo $ex->getMessage(); -} catch (\Exception $ex) { - // Graph API returned info, but it may mismatch the current app or have expired. - echo $ex->getMessage(); -} -~~~~ - - - -## Static Methods {#static-methods} - -### setDefaultApplication {#setdefaultapp} -`setDefaultApplication(string $appId, string $appSecret)` -Configures and app ID and secret that will be used by default throughout the SDK (but can be overridden whenever necessary using parameters to other methods. -### validate {#validate} -`validate(Facebook\GraphSessionInfo $sessionInfo, string $appId = NULL, string $appSecret = NULL)` -Ensures that the provided GraphSessionInfo is valid, throwing an exception if not. It does this by ensuring the app ID in the token info matches the given (or default) app ID, ensuring the token itself is valid, and ensuring that the expiration time has not passed. -### newAppSession {#newappsession} -`newAppSession(string $appId = NULL, string $appSecret = NULL)` -Returns a `Facebook\FacebookSession` configured with a token for the app which can be used for publishing and for requesting app-level information. -### newSessionFromSignedRequest {#newsessionfromsr} -`newSessionFromSignedRequest(string $signedRequest)` -Returns a `Facebook\FacebookSession` for the given signed request. - - - -## Instance Methods {#instance-methods} - -### getToken {#gettoken} -`getToken()` -Returns the token string for the session. -### getSessionInfo {#getsessioninfo} -`getSessionInfo(string $appId = NULL, string $appSecret = NULL)` -Equivalent to calling the /debug_token endpoint of the Graph API to get the details for the access token for this session. Returns a `Facebook\GraphSessionInfo` object. -### getLongLivedSession {#getlonglivedsession} -`getLongLivedSession(string $appId = NULL, string $appSecret = NULL)` -Returns a new `Facebook\FacebookSession` resulting from extending a short-lived access token. This method will make a network request. If you know you already have a long-lived session, you do not need to call this. The only time you get a short-lived session as of March 2014 is from the Facebook SDK for JavaScript. If this session is not short-lived, this method will return `$this`. A long-lived session is on the order of months. A short-lived session is on the order of hours. You can figure out whether a session is short-lived or long-lived by checking the expiration date in the session info, but it's not a precise thing. -### getExchangeToken {#getexchangetoken} -`getExchangeToken(string $appId = NULL, string $appSecret = NULL)` -Returns an exchange token string which can be sent back to clients and exchanged for a device-linked access token. You need this when your user did not log in on a particular device, but you want to be able to make Graph API calls from that device as this user. -### validate {#validatei} -`validate(string $appId = NULL, string $appSecret = NULL)` -Ensures that a session is valid, throwing an exception if not. It does this by fetching the token info, ensuring the app ID in the token info matches the given (or default) app ID, ensuring the token itself is valid, and ensuring that the expiration time has not passed. - \ No newline at end of file diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd index 2829d0ff9..df5fe8b4a 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphObject.fbmd @@ -1,12 +1,11 @@ # GraphObject for the Facebook SDK for PHP -A `GraphObject` is a collection that represents a node returned by the Graph API. - +A `Facebook\GraphNodes\GraphObject` is a collection that represents a node returned by the Graph API. -## Facebook\GraphObject {#overview} +## Facebook\GraphNodes\GraphObject {#overview} This base class has several subclasses: @@ -14,11 +13,17 @@ This base class has several subclasses: [__GraphPage__](#page-instance-methods) [__GraphAlbum__](#album-instance-methods) [__GraphLocation__](#location-instance-methods) -[__GraphSessionInfo__](#sessioninfo-instance-methods) +[__GraphSessionInfo__](#sessioninfo-instance-methods) + +`GraphObject`'s are obtained from a [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse) object which represents a response from the Graph API. Usage: ~~~~ +$fb = new Facebook\Facebook(\* *\); +// Returns a `Facebook\Entities\FacebookResponse` object +$response = $fb->get('/something'); + // Get the base class GraphObject from the response $object = $response->getGraphObject(); @@ -40,7 +45,6 @@ echo $loc->getCountry(); $info = $session->getSessionInfo()); echo $info->getExpiresAt(); ~~~~ - @@ -101,84 +105,367 @@ Provides a way to map over the data within the collection just like `array_map() ## GraphUser Instance Methods {#user-instance-methods} -### getId {#getid} -`getId()` +The `GraphUser` collection represents a [User](https://developers.facebook.com/docs/graph-api/reference/user) Graph node. + +### Auto-cast properties {#user-auto-casting} + +The following properties on the `GraphUser` collection will get automatically cast as `GraphObject` subtypes: + +FB(devsite:markdown-wiki:table { + columns: ['Property','GraphObject subtype',], + rows: [ + [ + '`hometown`', + '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + ], + [ + '`location`', + '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + ], + [ + '`significant_other`', + '[`Facebook\GraphNodes\GraphUser`](#user-instance-methods)', + ], + ], +}) + +All getter methods return `null` if the property does not exist on the node. + +### getId() {#user-getid} +~~~~ +public string|null getId() +~~~~ Returns the `id` property for the user as a string if present. -### getName {#getname} -`getName()` + +### getName() {#user-getname} +~~~~ +public string|null getName() +~~~~ Returns the `name` property for the user as a string if present. -### getFirstName {#getfirstname} -`getFirstName()` + +### getFirstName() {#user-getfirstname} +~~~~ +public string|null getFirstName() +~~~~ Returns the `first_name` property for the user as a string if present. -### getMiddleName {#getmiddlename} -`getMiddleName()` + +### getMiddleName() {#user-getmiddlename} +~~~~ +public string|null getMiddleName() +~~~~ Returns the `middle_name` property for the user as a string if present. -### getLastName {#getlastname} -`getLastName()` + +### getLastName() {#user-getlastname} +~~~~ +public string|null getLastName() +~~~~ Returns the `last_name` property for the user as a string if present. -### getLink {#getlink} -`getLink()` + +### getLink() {#user-getlink} +~~~~ +public string|null getLink() +~~~~ Returns the `link` property for the user as a string if present. -### getUsername {#getusername} -`getUsername()` -Returns the `username` property for the user as a string if present. -### getBirthday {#getbirthday} -`getBirthday()` + +### getBirthday() {#user-getbirthday} +~~~~ +public \DateTime|null getBirthday() +~~~~ Returns the `birthday` property for the user as a `\DateTime` if present. -### getLocation {#getlocation} -`getLocation()` -Returns the `location` property for the user as a `Facebook\GraphLocation` if present.' + +### getLocation() {#user-getlocation} +~~~~ +public Facebook\GraphNodes\GraphPage|null getLocation() +~~~~ +Returns the `location` property for the user as a `Facebook\GraphNodes\GraphPage` if present. + +### getHometown() {#user-gethometown} +~~~~ +public Facebook\GraphNodes\GraphPage|null getHometown() +~~~~ +Returns the `hometown` property for the user as a `Facebook\GraphNodes\GraphPage` if present. + +### getSignificantOther() {#user-getsignificantother} +~~~~ +public Facebook\GraphNodes\GraphUser|null getHometown() +~~~~ +Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. + + + +## GraphPage Instance Methods {#page-instance-methods} + +The `GraphPage` collection represents a [Page](https://developers.facebook.com/docs/graph-api/reference/page) Graph node. + +### Auto-cast properties {#page-auto-casting} + +The following properties on the `GraphPage` collection will get automatically cast as `GraphObject` subtypes: + +FB(devsite:markdown-wiki:table { + columns: ['Property','GraphObject subtype',], + rows: [ + [ + '`best_page`', + '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + ], + [ + '`global_brand_parent_page`', + '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + ], + [ + '`location`', + '[`Facebook\GraphNodes\GraphLocation`](#location-instance-methods)', + ], + ], +}) + +All getter methods return `null` if the property does not exist on the node. + +### getId() {#page-getid} +~~~~ +public string|null getId() +~~~~ +Returns the `id` property for the page as a string if present. + +### getName() {#page-getname} +~~~~ +public string|null getName() +~~~~ +Returns the `name` property for the page as a string if present. + +### getCategory() {#page-getcategory} +~~~~ +public string|null getCategory() +~~~~ +Returns the `category` property for the page as a string if present. + +### getBestPage() {#page-getbestpage} +~~~~ +public Facebook\GraphNodes\GraphPage|null getBestPage() +~~~~ +Returns the `best_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. + +### getGlobalBrandParentPage() {#page-getglobalbrandparentpage} +~~~~ +public Facebook\GraphNodes\GraphPage|null getGlobalBrandParentPage() +~~~~ +Returns the `global_brand_parent_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. + +### getLocation() {#page-getlocation} +~~~~ +public Facebook\GraphNodes\GraphLocation|null getLocation() +~~~~ +Returns the `location` property for the page as a `Facebook\GraphNodes\GraphLocation` if present. + +### getAccessToken() {#page-getaccesstoken} +~~~~ +public string|null getAccessToken() +~~~~ +Returns the `access_token` property for the page if present. (Only available in the `/me/accounts` context.) + +### getPerms() {#page-getperms} +~~~~ +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 {#album-instance-methods} + +The `GraphAlbum` collection represents an [Album](https://developers.facebook.com/docs/graph-api/reference/album) Graph node. + +### Auto-cast properties {#album-auto-casting} + +The following properties on the `GraphAlbum` collection will get automatically cast as `GraphObject` subtypes: + +FB(devsite:markdown-wiki:table { + columns: ['Property','GraphObject subtype',], + rows: [ + [ + '`from`', + '[`Facebook\GraphNodes\GraphUser`](#user-instance-methods)', + ], + [ + '`place`', + '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + ], + ], +}) + +All getter methods return `null` if the property does not exist on the node. + +### getId() {#album-getid} +~~~~ +public string|null getId() +~~~~ +Returns the `id` property for the album as a string if present. + +### getName() {#album-getname} +~~~~ +public string|null getName() +~~~~ +Returns the `name` property for the album as a string if present. + +### getCanUpload() {#album-getcanupload} +~~~~ +public boolean|null getCanUpload() +~~~~ +Returns the `can_upload` property for the album as a boolean if present. + +### getCount() {#album-getcount} +~~~~ +public int|null getCount() +~~~~ +Returns the `count` property for the album as an integer if present. + +### getCoverPhoto() {#album-getcoverphoto} +~~~~ +public string|null getCoverPhoto() +~~~~ +Returns the `cover_photo` property for the album as a string if present. + +### getCreatedTime() {#album-getcreatedtime} +~~~~ +public \DateTime|null getCreatedTime() +~~~~ +Returns the `created_time` property for the album as a `\DateTime` if present. + +### getUpdatedTime() {#album-getupdatedtime} +~~~~ +public \DateTime|null getUpdatedTime() +~~~~ +Returns the `updated_time` property for the album as a `\DateTime` if present. + +### getDescription() {#album-getdescription} +~~~~ +public string|null getDescription() +~~~~ +Returns the `description` property for the album as a string if present. + +### getFrom() {#album-getfrom} +~~~~ +public Facebook\GraphNodes\GraphUser|null getFrom() +~~~~ +Returns the `from` property for the album as a `Facebook\GraphNodes\GraphUser` if present. + +### getPlace() {#album-getplace} +~~~~ +public Facebook\GraphNodes\GraphPage|null getPlace() +~~~~ +Returns the `place` property for the album as a `Facebook\GraphNodes\GraphPage` if present. + +### getLink() {#album-getlink} +~~~~ +public string|null getLink() +~~~~ +Returns the `link` property for the album as a string if present. + +### getLocation() {#album-getlocation} +~~~~ +public Facebook\GraphNodes\GraphObject|string|null getLocation() +~~~~ +Returns the `location` property for the album as a `Facebook\GraphNodes\GraphObject` or string if present. + +### getPrivacy() {#album-getprivacy} +~~~~ +public string|null getPrivacy() +~~~~ +Returns the `privacy` property for the album as a string if present. + +### getType() {#album-gettype} +~~~~ +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 {#location-instance-methods} -### getStreet {#getstreet} -`getStreet()` +All getter methods return `null` if the property does not exist on the node. + +### getStreet() {#location-getstreet} +~~~~ +public string|null getStreet() +~~~~ Returns the `street` property for the location as a string if present. -### getCity {#getcity} -`getCity()` + +### getCity() {#location-getcity} +~~~~ +public string|null getCity() +~~~~ Returns the `city` property for the location as a string if present. -### getState {#getstate} -`getState()` -Returns the `state` property for the location as a string if present. -### getCountry {#getcountry} -`getCountry()` + +### getCountry() {#location-getcountry} +~~~~ +public string|null getCountry() +~~~~ Returns the `country` property for the location as a string if present. -### getZip {#getzip} -`getZip()` -Returns the `zip` property for the user as a location if present. -### getLatitude {#getlat} -`getLatitude()` -Returns the `latitude` property for the location as a float if present. -### getLongitude {#getlon} -`getLongitude()` + +### getZip() {#location-getzip} +~~~~ +public string|null getZip() +~~~~ +Returns the `zip` property for the location as a string if present. + +### getLatitude() {#location-getlatitude} +~~~~ +public float|null getLatitude() +~~~~ Returns the `latitude` property for the location as a float if present. + +### getLongitude() {#location-getlongitude} +~~~~ +public float|null getLongitude() +~~~~ +Returns the `longitude` property for the location as a float if present. ## GraphSessionInfo Instance Methods {#sessioninfo-instance-methods} -### getAppId {#getappid} -`getAppId()` +All getter methods return `null` if the property does not exist on the node. + +### getAppId() {#sessioninfo-getappid} +~~~~ +public string|null getAppId() +~~~~ Returns the `app_id` property for the session as a string if present. -### getApplication {#getapp} -`getApplication()` + +### getApplication() {#sessioninfo-getapplication} +~~~~ +public string|null getApplication() +~~~~ Returns the `application` property for the session as a string if present. -### getExpiresAt {#getexpires} -`getExpiresAt()` -Returns the `expires_at` property for the session as a \DateTime if present. -### getIsValid {#getvalid} -`getIsValid()` + +### getExpiresAt() {#sessioninfo-getexpiresat} +~~~~ +public \DateTime|null getExpiresAt() +~~~~ +Returns the `expires_at` property for the session as a `\DateTime` if present. + +### getIsValid() {#sessioninfo-getisvalid} +~~~~ +public boolean|null getIsValid() +~~~~ Returns the `is_valid` property for the session as a boolean if present. -### getIssuedAt {#getissued} -`getIssuedAt()` -Returns the `issued_at` property for the session as a \DateTime if present. -### getScopes {#getscopes} -`getScopes()` + +### getIssuedAt() {#sessioninfo-getissuedat} +~~~~ +public \DateTime|null getIssuedAt() +~~~~ +Returns the `issued_at` property for the session as a `\DateTime` if present. + +### getScopes() {#sessioninfo-getscopes} +~~~~ +public array|null getScopes() +~~~~ Returns the `scopes` property for the session as an array if present. -### getId {#getuid} -`getId()` + +### getUserId() {#sessioninfo-getuserid} +~~~~ +public array|null getUserId() +~~~~ Returns the `user_id` property for the session as a string if present. - diff --git a/docs/post_links.fbmd b/docs/post_links.fbmd index e1ea71c0a..2ddf2499f 100644 --- a/docs/post_links.fbmd +++ b/docs/post_links.fbmd @@ -3,16 +3,15 @@ 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](/docs/php/reference#helpers). You must have requested the `publish_actions` permission when logging in the user for this to work. +It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook`](/docs/php/Facebook), [`GraphObject`](/docs/php/GraphObject), and [`FacebookResponseException`](/docs/php/FacebookResponseException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +## Example {#example} ~~~~ -use Facebook\Exceptions\FacebookResponseException; - $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -24,14 +23,19 @@ $linkData = [ ]; try { + // Returns a `Facebook\Entities\FacebookResponse` object $response = $fb->post('/me/feed', $linkData, '{access-token}'); - $graphObject = $response->getGraphObject(); +} 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; +} - echo 'Posted with id: ' . $graphObject['id']; +$graphObject = $response->getGraphObject(); -} catch(FacebookResponseException $e) { - echo 'There was an error: ' . $e->getMessage(); -} +echo 'Posted with id: ' . $graphObject['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/retrieve_user_profile.fbmd b/docs/retrieve_user_profile.fbmd index 37f6cad9a..c82c7172a 100644 --- a/docs/retrieve_user_profile.fbmd +++ b/docs/retrieve_user_profile.fbmd @@ -3,36 +3,36 @@ 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 set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). +It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). -For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`GraphUser`](/docs/php/GraphObject/#user-instance-methods), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookResponseException`](/docs/php/FacebookResponseException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +## Example {#example} ~~~~ -use Facebook\FacebookRequest; -use Facebook\GraphUser; -use Facebook\FacebookResponseException; - -if($session) { - - try { - - $user_profile = (new FacebookRequest( - $session, 'GET', '/me' - ))->execute()->getGraphObject(GraphUser::className()); - - echo "Name: " . $user_profile->getName(); - - } catch(FacebookResponseException $e) { - - echo "Exception occurred, code: " . $e->getCode(); - echo " with message: " . $e->getMessage(); +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + ]); + +try { + // Returns a `Facebook\Entities\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(); ~~~~ - \ No newline at end of file + diff --git a/docs/upload_photo.fbmd b/docs/upload_photo.fbmd index 477726e32..f48844412 100644 --- a/docs/upload_photo.fbmd +++ b/docs/upload_photo.fbmd @@ -3,47 +3,37 @@ 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 set your default app id and secret, and acquired a `FacebookSession` using an access token or one of the login helper classes found [here](/docs/php). You must have requested the `publish_actions` scope when logging in the user for this to work. - -For more information, see the documentation for [`GraphObject`](/docs/php/GraphObject), [`FacebookRequest`](/docs/php/FacebookRequest), and [`FacebookResponseException`](/docs/php/FacebookResponseException). +It assumes that you've already acquired an access token using one of the helper classes found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +## Example {#example} ~~~~ -use Facebook\FacebookRequest; -use Facebook\GraphObject; -use Facebook\FacebookResponseException; - -if($session) { - - try { - - // Upload to a user's profile. The photo will be in the - // first album in the profile. You can also upload to - // a specific album by using /ALBUM_ID as the path - $response = (new FacebookRequest( - $session, 'POST', '/me/photos', [ - 'source' => new CURLFile('path/to/file.name', 'image/png'), - 'message' => 'User provided message' - ] - ))->execute()->getGraphObject(); - - // If you're not using PHP 5.5 or later, change the file reference to: - // 'source' => '@/path/to/file.name' - - echo "Posted with id: " . $response->getProperty('id'); - - } catch(FacebookResponseException $e) { - - echo "Exception occurred, code: " . $e->getCode(); - echo " with message: " . $e->getMessage(); +$fb = new Facebook\Facebook(/* . . . */); + +$data = [ + 'message' => 'My awesome photo upload example.', + 'source' => $fb->fileToUpload('/path/to/photo.jpg'), +]; + +try { + // Returns a `Facebook\Entities\FacebookResponse` object + $response = $fb->post('/me/photos', $data); +} 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; +} - } +$graphObject = $response->getGraphObject(); -} +echo 'Photo ID: ' . $graphObject['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). - \ No newline at end of file +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). + From c3ea3c5b349d2776fcfadcc7b3e3cc74d898ba22 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Dec 2014 14:22:14 -0600 Subject: [PATCH 078/407] Move app secret proof --- src/Facebook/Entities/AccessToken.php | 12 ++++++++++++ src/Facebook/Entities/FacebookRequest.php | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/Entities/AccessToken.php index ea4eeb607..2df38f4c7 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/Entities/AccessToken.php @@ -72,6 +72,18 @@ public function __construct($accessToken, $expiresAt = 0, $machineId = null) $this->machineId = $machineId; } + /** + * Generate an app secret proof to sign a request to Graph. + * + * @param string $appSecret The app secret. + * + * @return string + */ + public function getAppSecretProof($appSecret) + { + return hash_hmac('sha256', $this->accessToken, $appSecret); + } + /** * Setter for expires_at. * diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/Entities/FacebookRequest.php index f8c1efcdc..e9208f32e 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/Entities/FacebookRequest.php @@ -162,6 +162,16 @@ public function getAccessToken() return $this->accessToken; } + /** + * Return the access token for this request an an AccessToken entity. + * + * @return AccessToken|null + */ + public function getAccessTokenEntity() + { + return $this->accessToken ? new AccessToken($this->accessToken) : null; + } + /** * Set the FacebookApp entity used for this request. * @@ -189,11 +199,11 @@ public function getApp() */ public function getAppSecretProof() { - if ( ! $accessToken = $this->getAccessToken()) { + if ( ! $accessTokenEntity = $this->getAccessTokenEntity()) { return null; } - return hash_hmac('sha256', $accessToken, $this->app->getSecret()); + return $accessTokenEntity->getAppSecretProof($this->app->getSecret()); } /** From d3c513f395d8a630231ce573da6c81609511e8d9 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Dec 2014 21:48:00 -0600 Subject: [PATCH 079/407] More documentaion updates --- docs/Facebook.fbmd | 20 ++++ docs/FacebookApp.fbmd | 67 +++++++++++ docs/FacebookBatchRequest.fbmd | 128 ++++++++++++++++++++ docs/FacebookBatchResponse.fbmd | 84 +++++++++++++ docs/FacebookRequest.fbmd | 206 +++++++++++++++++++++++++++----- docs/FacebookResponse.fbmd | 204 +++++++++++++++++++++++++------ docs/SignedRequest.fbmd | 101 ++++++++++++++++ 7 files changed, 745 insertions(+), 65 deletions(-) create mode 100644 docs/FacebookApp.fbmd create mode 100644 docs/FacebookBatchRequest.fbmd create mode 100644 docs/FacebookBatchResponse.fbmd create mode 100644 docs/SignedRequest.fbmd diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index d75692ca4..03befb082 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -294,6 +294,26 @@ $request = $fb->request('GET', '/{node-id}'); ~~~~ + +### sendRequest() {#send-request} +~~~~ +public Facebook\Entities\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. + +~~~~ +$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.2'); +~~~~ + + ### sendBatchRequest() {#send-batch-request} ~~~~ diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd new file mode 100644 index 000000000..f919fe495 --- /dev/null +++ b/docs/FacebookApp.fbmd @@ -0,0 +1,67 @@ + +# 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\Entities\FacebookApp` entity represents the Facebook app that is making the requests to the Graph API. + + + +## Facebook\Entities\FacebookApp {#overview} + +To instantiate a new `Facebook\Entities\FacebookApp` entity, pass the app ID and app secret to the constructor. + +~~~~ +$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +~~~~ + +Alternatively you can obtain the `Facebook\Entities\FacebookApp` entity from the [`Facebook\Facebook`](/docs/php/Facebook) super service class. + +~~~~ +$fb = new Facebook\Facebook([/* . . . */]); +$fbApp = $fb->getApp(); +~~~~ + +In the most common cases, you'll rarely be using the `FacebookApp` entity directly but it plays an important role in the internal workings of the SDK. + + + +## Instance Methods {#instance-methods} + +### getAccessToken() {#get-access-token} +~~~~ +public Facebook\Entities\AccessToken getAccessToken() +~~~~ +Returns an app access token in the form of a [`Facebook\Entities\AccessToken`](/docs/php/AccessToken) entity. + + + +### getId() {#get-id} +~~~~ +public string getId() +~~~~ +Returns an the app id. + + + +### getSecret() {#get-secret} +~~~~ +public string getSecret() +~~~~ +Returns an the app secret. + + + +## Serialization {#serialization} + +The `Facebook\Entities\FacebookApp` entity implements the `\Serializable` interface so it can be serialized and unserialized. + +~~~~ +$fbApp = new Facebook\Entities\FacebookApp('foo-app-id', 'foo-app-secret'); + +$serializedFacebookApp = serialize($fbApp); +// C:29:"Facebook\\Entities\\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/FacebookBatchRequest.fbmd b/docs/FacebookBatchRequest.fbmd new file mode 100644 index 000000000..726843927 --- /dev/null +++ b/docs/FacebookBatchRequest.fbmd @@ -0,0 +1,128 @@ + +# FacebookBatchRequest for the Facebook SDK for PHP + +Represents a batch request that will be sent to the Graph API. + + + +## Facebook\Entities\FacebookBatchRequest {#overview} + +You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor. + +~~~~ +use Facebook\Entities\FacebookBatchRequest; + +$request = new FacebookBatchRequest( + Facebook\Entities\FacebookApp $app, + array $requests, + string|null $accessToken, + string|null $graphVersion +); +~~~~ + +The `$requests` array is an array of [`Facebook\Entities\FacebookRequest`'s](/docs/php/FacebookRequest) 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()`](/docs/php/Facebook#send-batch-request) or [`Facebook\FacebookClient::sendBatchRequest()`](/docs/php/FacebookClient#send-batch-request). + +Usage: + +~~~~ +$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +$requests = [ + new Facebook\Entities\FacebookRequest(/* */), + new Facebook\Entities\FacebookRequest(/* */), +]; +$batchRequest = new Facebook\Entities\FacebookBatchRequest($fbApp, $requests, '{access-token}'); + +// Send the batch request to Graph +try { + $batchResponse = $fb->getClient()->sendBatchRequest($batchRequest); +} 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; +} + +// OR + +$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 {#instance-methods} + +Since the `Facebook\Entities\FacebookBatchRequest` is extended from the [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. + +### add() {#add} +~~~~ +public add( + array|Facebook\Entities\FacebookBatchRequest $request, + string|null $name + ) +~~~~ +Adds a request to be sent in the batch request. The `$request` can be a single [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) or an array of `Facebook\Entities\FacebookRequest`'s. + +The `$name` argument is optional and is used to identify the request in the batch. + + + +### getRequests() {#get-requests} +~~~~ +public array getRequests() +~~~~ +Returns the array of [`Facebook\Entities\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent in the batch request. + + + +## Array Access {#array-access} + +Since `Facebook\Entities\FacebookBatchRequest` implements `\IteratorAggregate` and `\ArrayAccess`, the requests can be accessed via array syntax and can also be iterated over. + +~~~~ +$fb = new Facebook\Facebook(/* . . . */); +$requests = [ + 'foo' => $fb->request('GET', '/me'), + 'bar' => $fb->request('POST', '/me/feed', [/* */]), +]; +$batchRequest = new Facebook\Entities\FacebookBatchRequest($fb->getApp(), $requests, '{access-token}'); + +var_dump($batchRequest[0]); +/* +array(2) { + 'name' => string(3) "foo" + 'request' => class Facebook\Entities\FacebookRequest + . . . +*/ +~~~~ + diff --git a/docs/FacebookBatchResponse.fbmd b/docs/FacebookBatchResponse.fbmd new file mode 100644 index 000000000..dece6dd01 --- /dev/null +++ b/docs/FacebookBatchResponse.fbmd @@ -0,0 +1,84 @@ + +# FacebookBatchResponse for the Facebook SDK for PHP + +Represents a batch response returned from the Graph API. + + + +## Facebook\Entities\FacebookBatchResponse {#overview} + +After sending a batch request to the Graph API, the response will be returned in the form of a `Facebook\Entities\FacebookBatchResponse` entity. + +Usage: + +~~~~ +$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\Entities\FacebookBatchResponse . . . +~~~~ + + + +## Instance Methods {#instance-methods} + +Since the `Facebook\Entities\FacebookBatchResponse` is extended from the [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. + +### getResponses() {#get-responses} +~~~~ +public array getResponses() +~~~~ +Returns the array of [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse) entities that were returned from Graph. + + + +## Array Access {#array-access} + +Since `Facebook\Entities\FacebookBatchResponse` implements `\IteratorAggregate` and `\ArrayAccess`, the responses can be accessed via array syntax and can also be iterated over. + +~~~~ +$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\Entities\FacebookResponse . . . +~~~~ + diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index f04759b66..cb59d4ab2 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -13,7 +13,7 @@ You can instantiate a new `FacebookRequest` entity directly by sending the argum use Facebook\Entities\FacebookRequest; $request = new FacebookRequest( - FacebookApp $app, + Facebook\Entities\FacebookApp $app, string $accessToken, string $method, string $endpoint, @@ -23,44 +23,194 @@ $request = new FacebookRequest( ); ~~~~ -Alternatively, you can make use of the `Facebook\Facebook::request()` factory to create new `FacebookRequest` instances. [See full `Facebook\Facebook` reference](/docs/php/Facebook) +Alternatively, you can make use of the [`request()` factory provided by `Facebook\Facebook`](/docs/php/Facebook#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()`](/docs/php/Facebook#send-batch-request) or [`Facebook\FacebookClient::sendBatchRequest()`](/docs/php/FacebookClient#send-batch-request). Usage: ~~~~ -// Make a new request and execute it. +$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +$request = new Facebook\Entities\FacebookRequest($fbApp, '{access-token}', 'GET', '/me'); + +// OR + +$fb = new Facebook\Facebook(/* . . . */); +$request = $fb->request('GET', '/me'); + +// Send the request to Graph try { - $response = (new FacebookRequest($session, 'GET', '/me'))->execute(); - $object = $response->getGraphObject(); - echo $object->getProperty('name'); -} catch (FacebookResponseException $ex) { - echo $ex->getMessage(); -} catch (\Exception $ex) { - echo $ex->getMessage(); + $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; } -// You can chain methods together and get a strongly typed GraphUser -$me = (new FacebookRequest( - $session, 'GET', '/me' -))->execute()->getGraphObject(GraphUser::className); -echo $me->getName(); +$object = $response->getGraphObject(); + +echo 'User name: ' . $object['name']; ~~~~ ## Instance Methods {#instance-methods} -### execute {#execute} -`execute()` -Returns a `Facebook\FacebookResponse` from this request, from which a strongly-typed result can be retrieved. Throws an exception if the request fails. If the error is returned from Facebook, as opposed to a networking issue, a `Facebook\FacebookResponseException` is thrown. -### getPath {#getpath} -`getPath()` -Returns a copy of the path for the request, not including the version. -### getParameters {#getparams} -`getParameters()` -Returns a copy of the parameters array for the request. -### getSession {#getsession} -`getSession()` -Returns the `Facebook\FacebookSession` object associated with this request. - \ No newline at end of file +### setAccessToken() {#set-access-token} +~~~~ +public setAccessToken(string|Facebook\Entities\AccessToken $accessToken) +~~~~ +Sets the access token to be used for the request. + + + +### getAccessToken() {#get-access-token} +~~~~ +public string getAccessToken() +~~~~ +Returns the access token to be used for the request in the form of a string. + + + +### setApp() {#set-app} +~~~~ +public setApp(Facebook\Entities\FacebookApp $app) +~~~~ +Sets the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity used with this request. + + + +### getApp() {#get-app} +~~~~ +public Facebook\Entities\FacebookApp getApp() +~~~~ +Returns the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity used with this request. + + + +### getAppSecretProof() {#get-app-secret-proof} +~~~~ +public string getAppSecretProof() +~~~~ +Returns the [app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests/#appsecret_proof) to sign the request. + + + +### setMethod() {#set-method} +~~~~ +public setMethod(string $method) +~~~~ +Sets the HTTP verb to use for the request. + + + +### getMethod() {#get-method} +~~~~ +public string setMethod() +~~~~ +Returns the HTTP verb to use for the request. + + + +### setEndpoint() {#set-endpoint} +~~~~ +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. + +~~~~ +$request->setEndpoint('/me'); +~~~~ + + + +### getEndpoint() {#get-endpoint} +~~~~ +public string getEndpoint() +~~~~ +Returns the Graph URL endpoint to be used with the request. + + + +### setHeaders() {#set-headers} +~~~~ +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. + +~~~~ +$request->setHeaders([ + 'X-foo-header' => 'Something', +]); +~~~~ + + + +### getHeaders() {#get-headers} +~~~~ +public array getHeaders() +~~~~ +Returns the request headers that will be sent with the request. The eTag headers `If-None-Match` are appended automatically. + + + +### setETag() {#set-etag} +~~~~ +public setETag(string $eTag) +~~~~ +Sets the eTag that will be using for matching the `If-None-Match` header. + + + +### setParams() {#set-params} +~~~~ +public setParams(array $params) +~~~~ +For `GET` requests, the array of params will be converted to a query string and appended to the URL. + +~~~~ +$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() {#get-params} +~~~~ +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() {#get-graph-version} +~~~~ +public string getGraphVersion() +~~~~ +Returns the Graph version prefix to be used with the request. + + + +### getUrl() {#get-url} +~~~~ +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`](/docs/php/FacebookClient). + +~~~~ +$fb = new Facebook\Facebook(/* . . . */); +$request = $fb->request('GET', '/me', ['fields' => 'id,name']); + +$url = $request->getUrl(); +// /v2.2/me?fields=id,name&access_token=token&appsecret_proof=proof +~~~~ + diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index 4e1cef9d7..0cc090afa 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -5,53 +5,183 @@ Represents a response from the Graph API. -## Facebook\FacebookResponse {#overview} +## Facebook\Entities\FacebookResponse {#overview} + +After sending a request to the Graph API, the response will be returned in the form of a `Facebook\Entities\FacebookResponse` entity. Usage: ~~~~ -// A FacebookResponse is returned from an executed FacebookRequest +$fb = new Facebook\Facebook(/* . . . */); + +// Send the request to Graph try { - $response = (new FacebookRequest($session, 'GET', '/me'))->execute(); - // You can get the request back: - $request = $response->getRequest(); - // You can get the response as a GraphObject: - $object = $response->getGraphObject(); - // You can get the response as a subclass of GraphObject: - $me = $response->getGraphObject(GraphUser::className()); - // If this response has multiple pages, you can get a request for the next or previous pages: - $nextPageRequest = $response->getRequestForNextPage(); - $previousPageRequest = $response->getRequestForPreviousPage(); -} catch (FacebookResponseException $ex) { - echo $ex->getMessage(); -} catch (\Exception $ex) { - echo $ex->getMessage(); + $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; } -// You can also chain the methods together: -$me = (new FacebookRequest( - $session, 'GET', '/me' -))->execute()->getGraphObject(GraphUser::className); -echo $me->getName(); +var_dump($response); +// class Facebook\Entities\FacebookResponse . . . ~~~~ ## Instance Methods {#instance-methods} -### getGraphObject {#getgraphobject} -`getGraphObject(string $type = 'Facebook\GraphObject')` -Returns the result as a `GraphObject`. If specified, a strongly-typed subclass of `GraphObject` is returned. -### getGraphObjectList {#getgraphobjectlist} -`getGraphObjectList(string $type = 'Facebook\GraphObject')` -Returns an array of `GraphObject` returned by this request. If specified, a strongly-typed subclass of `GraphObject` is returned. -### getRequest {#getrequest} -`getRequest()` -Returns the `FacebookRequest` that produced this response. -### getRequestForNextPage {#getnextpage} -`getRequestForNextPage()` -If the response has paginated data, produces a `FacebookRequest` for the next pge of data. -### getRequestForPreviousPage {#getpreviouspage} -`getRequestForPreviousPage()` -If the response has paginated data, produces a `FacebookRequest` for the previous page of data. - \ No newline at end of file +### getRequest() {#get-request} +~~~~ +public Facebook\Entities\FacebookRequest getRequest() +~~~~ +Returns the original [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. + + + +### getAccessToken() {#get-access-token} +~~~~ +public string getAccessToken() +~~~~ +Returns the access token that was used for the original request in the form of a string. + + + +### getApp() {#get-app} +~~~~ +public Facebook\Entities\FacebookApp getApp() +~~~~ +Returns the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. + + + +### getHttpStatusCode() {#get-http-status-code} +~~~~ +public int getHttpStatusCode() +~~~~ +Returns the HTTP response code for this response. + + + +### getHeaders() {#get-headers} +~~~~ +public array getHeaders() +~~~~ +Returns the response headers that were returned. + + + +### getBody() {#get-body} +~~~~ +public string getBody() +~~~~ +Returns the raw, unparsed body of the response as a string. + + + +### getDecodedBody() {#get-decoded-body} +~~~~ +public array getDecodedBody() +~~~~ +Returns the parsed body of the response as an array. + + + +### getAppSecretProof() {#get-app-secret-proof} +~~~~ +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() {#get-etag} +~~~~ +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() {#get-graph-version} +~~~~ +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() {#is-error} +~~~~ +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() {#throw-exception} +~~~~ +public throwException() +~~~~ +Throws the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. + + + +### getThrownException() {#get-thrown-exception} +~~~~ +public Facebook\Exceptions\FacebookResponseException getThrownException() +~~~~ +Returns the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. This is mainly useful for dealing with [responses to batch requests](/docs/php/FacebookBatchResponse). + + + +### getGraphObject() {#get-graph-object} +~~~~ +public Facebook\GraphNodes\GraphObject getGraphObject() +~~~~ +Returns the response data in the form of a [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject) collection. + + + +### getGraphAlbum() {#get-graph-album} +~~~~ +public Facebook\GraphNodes\GraphAlbum getGraphAlbum() +~~~~ +Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphObject#album-instance-methods) collection. + + + +### getGraphPage() {#get-graph-page} +~~~~ +public Facebook\GraphNodes\GraphPage getGraphPage() +~~~~ +Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphObject#page-instance-methods) collection. + + + +### getGraphSessionInfo() {#get-graph-session-info} +~~~~ +public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() +~~~~ +Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphObject#sessioninfo-instance-methods) collection. + + + +### getGraphUser() {#get-graph-user} +~~~~ +public Facebook\GraphNodes\GraphUser getGraphUser() +~~~~ +Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods) collection. + + + +### getGraphList() {#get-graph-list} +~~~~ +public Facebook\GraphNodes\GraphList getGraphList() +~~~~ +Returns the response data in the form of a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) collection. + diff --git a/docs/SignedRequest.fbmd b/docs/SignedRequest.fbmd new file mode 100644 index 000000000..60b1174ca --- /dev/null +++ b/docs/SignedRequest.fbmd @@ -0,0 +1,101 @@ + +# SignedRequest entity for the Facebook SDK for PHP + +The `Facebook\Entities\SignedRequest` entity represents a signed request. + + + +## Facebook\Entities\SignedRequest {#overview} + +[Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) contain payloads of data that can be validated against a hash signature to ensure it is from Facebook. The `Facebook\Entities\SignedRequest` entity can validate a signed request signature and decode the payload. + +To instantiate a new `Facebook\Entities\SignedRequest` entity, pass the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity and raw signed request to the constructor. + +~~~~ +$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +$signedRequest = new Facebook\Entities\SignedRequest($fbApp, 'raw.signed_request'); +~~~~ + +Usually `Facebook\Entities\SignedRequest` entities are obtained using one of the [helpers](/docs/php/sdk_reference#helpers). + +~~~~ +$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 {#instance-methods} + +### getRawSignedRequest() {#get-raw-signed-request} +~~~~ +public string|null getRawSignedRequest() +~~~~ +Returns the original raw signed request in the form of a string. + + + +### getPayload() {#get-payload} +~~~~ +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() {#get} +~~~~ +public string|null get(string $key, string|null $default) +~~~~ +Returns a field from the signed request payload or `$default` if the value does not exist. + + + +### getUserId() {#get-user-id} +~~~~ +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() {#has-oauth-data} +~~~~ +public boolean hasOAuthData() +~~~~ +Returns `true` if the payload data contains either an `oauth_token` or `code` field. Returns `false` if neither value exists. + + + +### make() {#make} +~~~~ +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\Entities\FacebookApp` entity. This can be useful for testing purposes. + +~~~~ +$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +$signedRequest = new Facebook\Entities\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=" +~~~~ + From d7e185379e0cac27b2d06b2ff00662c540ad90da Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Dec 2014 21:54:01 -0600 Subject: [PATCH 080/407] Removed CSRF from signed request --- src/Facebook/Entities/SignedRequest.php | 31 ++----------------------- tests/Entities/SignedRequestTest.php | 17 -------------- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/src/Facebook/Entities/SignedRequest.php b/src/Facebook/Entities/SignedRequest.php index f6bc89e55..245e4aa4a 100644 --- a/src/Facebook/Entities/SignedRequest.php +++ b/src/Facebook/Entities/SignedRequest.php @@ -42,11 +42,6 @@ class SignedRequest */ protected $rawSignedRequest; - /** - * @var string|null Pseudo-random string to prevent CSRF. - */ - protected $state; - /** * @var array The payload from the decrypted signed request. */ @@ -57,9 +52,8 @@ class SignedRequest * * @param FacebookApp $facebookApp The FacebookApp entity. * @param string|null $rawSignedRequest The raw signed request. - * @param string|null $state Pseudo-random string to prevent CSRF. */ - public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null, $state = null) + public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null) { $this->app = $facebookApp; @@ -68,7 +62,6 @@ public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null, } $this->rawSignedRequest = $rawSignedRequest; - $this->state = $state; $this->parse(); } @@ -106,6 +99,7 @@ public function get($key, $default = null) if (isset($this->payload[$key])) { return $this->payload[$key]; } + return $default; } @@ -165,7 +159,6 @@ protected function parse() // Payload validation $this->validateAlgorithm(); - $this->validateCsrf(); } /** @@ -299,26 +292,6 @@ protected function validateSignature($hashedSig, $sig) ); } - /** - * Validates a signed request against CSRF. - * - * @throws FacebookSDKException - */ - protected function validateCsrf() - { - if ( ! $this->state) { - return; - } - - if ($this->get('state') === $this->state) { - return; - } - - throw new FacebookSDKException( - 'Signed request did not pass CSRF validation.', 604 - ); - } - /** * Base64 decoding which replaces characters: * + instead of - diff --git a/tests/Entities/SignedRequestTest.php b/tests/Entities/SignedRequestTest.php index 0218fda05..0992dfeb9 100644 --- a/tests/Entities/SignedRequestTest.php +++ b/tests/Entities/SignedRequestTest.php @@ -119,23 +119,6 @@ public function testNonApprovedAlgorithmsWillThrowAnException() new SignedRequest($this->app, $rawSignedRequest); } - public function testASignedRequestWillPassCsrfValidation() - { - $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; - $sr = new SignedRequest($this->app, $rawSignedRequest, 'foo_state'); - - $this->assertEquals($this->payloadData, $sr->getPayload()); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testASignedRequestWithIncorrectCsrfDataWillThrowAnException() - { - $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; - new SignedRequest($this->app, $rawSignedRequest, 'invalid_foo_state'); - } - public function testAsRawSignedRequestCanBeValidatedAndDecoded() { $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; From beb6005dc02e49de731c303ecdcae38d1975fc24 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 10 Dec 2014 16:21:11 -0600 Subject: [PATCH 081/407] Fix for order of validation on redirect helper --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index e6f1219ec..beb17875d 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -168,11 +168,12 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') */ public function getAccessToken(FacebookClient $client, $redirectUrl = null) { - $this->validateCsrf(); if ( ! $code = $this->getCode()) { return null; } + $this->validateCsrf(); + $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); // At minimum we need to remove the state param $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']); From 63b1bca120a6380bbf9ce83d3c18fa148faf052f Mon Sep 17 00:00:00 2001 From: SammyK Date: Sat, 13 Dec 2014 09:10:40 -0600 Subject: [PATCH 082/407] Killed entities folder --- CHANGELOG.md | 4 +- README.md | 2 +- docs/Facebook.fbmd | 44 +++++++++---------- docs/FacebookApp.fbmd | 20 ++++----- docs/FacebookBatchRequest.fbmd | 30 ++++++------- docs/FacebookBatchResponse.fbmd | 14 +++--- docs/FacebookCanvasHelper.fbmd | 10 ++--- docs/FacebookClient.fbmd | 14 +++--- docs/FacebookJavaScriptHelper.fbmd | 8 ++-- docs/FacebookRequest.fbmd | 20 ++++----- docs/FacebookResponse.fbmd | 14 +++--- docs/FacebookSDKException.fbmd | 2 +- docs/GraphObject.fbmd | 4 +- docs/SignedRequest.fbmd | 20 ++++----- docs/post_links.fbmd | 4 +- docs/retrieve_user_profile.fbmd | 4 +- docs/sdk_getting_started.fbmd | 26 +++++------ docs/sdk_reference.fbmd | 14 +++--- docs/upload_photo.fbmd | 4 +- src/Facebook/{Entities => }/AccessToken.php | 3 +- .../Exceptions/FacebookResponseException.php | 2 +- src/Facebook/Facebook.php | 8 +--- src/Facebook/{Entities => }/FacebookApp.php | 2 +- .../{Entities => }/FacebookBatchRequest.php | 2 +- .../{Entities => }/FacebookBatchResponse.php | 2 +- src/Facebook/FacebookClient.php | 4 -- .../{Entities => }/FacebookRequest.php | 3 +- .../{Entities => }/FacebookResponse.php | 2 +- src/Facebook/GraphNodes/GraphList.php | 2 +- .../GraphNodes/GraphObjectFactory.php | 2 +- .../Helpers/FacebookPageTabHelper.php | 2 +- .../Helpers/FacebookRedirectLoginHelper.php | 4 +- .../FacebookSignedRequestFromInputHelper.php | 6 +-- src/Facebook/{Entities => }/SignedRequest.php | 2 +- tests/{Entities => }/AccessTokenTest.php | 14 +++--- .../FacebookResponseExceptionTest.php | 6 +-- tests/{Entities => }/FacebookAppTest.php | 8 ++-- .../FacebookBatchRequestTest.php | 12 ++--- .../FacebookBatchResponseTest.php | 22 +++++----- tests/FacebookClientTest.php | 10 ++--- tests/{Entities => }/FacebookRequestTest.php | 12 ++--- tests/{Entities => }/FacebookResponseTest.php | 10 ++--- tests/FacebookTest.php | 10 ++--- tests/GraphNodes/GraphAlbumTest.php | 4 +- tests/GraphNodes/GraphListTest.php | 10 ++--- tests/GraphNodes/GraphObjectFactoryTest.php | 8 ++-- tests/GraphNodes/GraphPageTest.php | 4 +- tests/GraphNodes/GraphSessionInfoTest.php | 4 +- tests/GraphNodes/GraphUserTest.php | 4 +- tests/Helpers/FacebookCanvasHelperTest.php | 2 +- .../Helpers/FacebookJavaScriptHelperTest.php | 2 +- tests/Helpers/FacebookPageTabHelperTest.php | 2 +- .../FacebookRedirectLoginHelperTest.php | 8 ++-- ...cebookSignedRequestFromInputHelperTest.php | 10 ++--- tests/{Entities => }/SignedRequestTest.php | 6 +-- 55 files changed, 230 insertions(+), 242 deletions(-) rename src/Facebook/{Entities => }/AccessToken.php (99%) rename src/Facebook/{Entities => }/FacebookApp.php (98%) rename src/Facebook/{Entities => }/FacebookBatchRequest.php (99%) rename src/Facebook/{Entities => }/FacebookBatchResponse.php (99%) rename src/Facebook/{Entities => }/FacebookRequest.php (99%) rename src/Facebook/{Entities => }/FacebookResponse.php (99%) rename src/Facebook/{Entities => }/SignedRequest.php (99%) rename tests/{Entities => }/AccessTokenTest.php (95%) rename tests/{Entities => }/FacebookAppTest.php (89%) rename tests/{Entities => }/FacebookBatchRequestTest.php (97%) rename tests/{Entities => }/FacebookBatchResponseTest.php (92%) rename tests/{Entities => }/FacebookRequestTest.php (95%) rename tests/{Entities => }/FacebookResponseTest.php (95%) rename tests/{Entities => }/SignedRequestTest.php (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f44da0c0..07b914ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ As you may have already noticed, the Facebook SDK v4 does not follow strict [sem - Moved response collection objects to `GraphNodes\*` directory - Moved helpers to `Helpers\*` directory - Moved `FacebookRequest` and `FacebookResponse` to `Entities\*` directory - - Killed `FacebookSession` in favor of `Facebook\Entities\AccessToken` + - Killed `FacebookSession` in favor of `Facebook\AccessToken` - Added `FacebookClient` service - Renamed `FacebookRequestException` to `FacebookResponseException` - Renamed `FacebookHttpable` to `FacebookHttpClientInterface` @@ -21,7 +21,7 @@ As you may have already noticed, the Facebook SDK v4 does not follow strict [sem - Added support for "rerequest" authorization - [`AccessToken`] Added serialization support - Added `ext-mbstring` to composer require - - Added `Facebook\Entities\FacebookApp` entity + - Added `Facebook\FacebookApp` entity - Namespaced tests - Grouped functional tests under `functional` group - Added `Facebook\Facebook` super service diff --git a/README.md b/README.md index 502943bf0..c720fbf03 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ $fb = new Facebook\Facebook([ //'default_access_token' => '{access-token}', // optional ]); -// Use one of the helper classes to get a Facebook\Entities\AccessToken entity. +// Use one of the helper classes to get a Facebook\AccessToken entity. // $helper = $fb->getRedirectLoginHelper(); // $helper = $fb->getJavaScriptHelper(); // $helper = $fb->getCanvasHelper(); diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 72bffa69d..f9c4b4b5f 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -67,7 +67,7 @@ The ID of your Facebook app (required). 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\Entities\AccessToken`. If any other value is provided an `InvalidArgumentException` will be thrown. Defaults to `null`. +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/support/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`. @@ -163,7 +163,7 @@ $fb = new Facebook\Facebook(); ~~~~ public FacebookApp getApp() ~~~~ -Returns the instance of `Facebook\Entities\FacebookApp` for the instantiated service. +Returns the instance of `Facebook\FacebookApp` for the instantiated service. @@ -177,34 +177,34 @@ Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) fo ### getLastResponse() {#get-last-response} ~~~~ -public Facebook\Entities\FacebookResponse|Facebook\Entities\FacebookBatchResponse|null getLastResponse() +public Facebook\FacebookResponse|Facebook\FacebookBatchResponse|null getLastResponse() ~~~~ -Returns the last response received from the Graph API in the form of a `Facebook\Entities\FacebookResponse` or `Facebook\Entities\FacebookBatchResponse`. +Returns the last response received from the Graph API in the form of a `Facebook\FacebookResponse` or `Facebook\FacebookBatchResponse`. ### getDefaultAccessToken() {#get-default-access-token} ~~~~ -public Facebook\Entities\AccessToken|null getDefaultAccessToken() +public Facebook\AccessToken|null getDefaultAccessToken() ~~~~ -Returns the default fallback `Facebook\Entities\AccessToken` 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()`. +Returns the default fallback `Facebook\AccessToken` 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() {#set-default-access-token} ~~~~ -public setDefaultAccessToken(string|Facebook\Entities\AccessToken $accessToken) +public setDefaultAccessToken(string|Facebook\AccessToken $accessToken) ~~~~ -Sets the default access token to be use with all requests sent to Graph. The access token can be in string or `Facebook\Entities\AccessToken` format. +Sets the default access token to be use with all requests sent to Graph. The access token can be in string or `Facebook\AccessToken` format. ~~~~ $fb->setDefaultAccessToken('{my-access-token}'); // . . . OR . . . -$accessToken = new Facebook\Entities\AccessToken('{my-access-token}'); +$accessToken = new Facebook\AccessToken('{my-access-token}'); $fb->setDefaultAccessToken($accessToken); ~~~~ @@ -222,7 +222,7 @@ Returns the default version of Graph. If the `default_graph_version` configurati ### get() {#get} ~~~~ -public Facebook\Entities\FacebookResponse get( +public Facebook\FacebookResponse get( string $endpoint, string|AccessToken|null $accessToken, string|null $eTag, @@ -230,7 +230,7 @@ public Facebook\Entities\FacebookResponse get( ) ~~~~ -Sends a GET request to Graph and returns a `Facebook\Entities\FacebookResponse`. +Sends a GET request to Graph and returns a `Facebook\FacebookResponse`. `$endpoint` The url to send to Graph without the version prefix (required). @@ -240,7 +240,7 @@ $fb->get('/me'); ~~~ `$accessToken` -The access token (as a `string` or `Facebook\Entities\AccessToken`) 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. +The access token (as a `string` or `Facebook\AccessToken`) 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/reference/ads-api/etags-reference/). Set this to the eTag from a previous request to get a `304 Not Modified` response if the data has not changed. @@ -252,7 +252,7 @@ Set the Graph version to something other than what was set in the `default_graph ### post() {#post} ~~~~ -public Facebook\Entities\FacebookResponse post( +public Facebook\FacebookResponse post( string $endpoint, array $params, string|AccessToken|null $accessToken, @@ -261,7 +261,7 @@ public Facebook\Entities\FacebookResponse post( ) ~~~~ -Sends a POST request to Graph and returns a `Facebook\Entities\FacebookResponse`. +Sends a POST request to Graph and returns a `Facebook\FacebookResponse`. The arguments are the same as `get()` above with the exception of `$params`. @@ -276,7 +276,7 @@ $response = $fb->post('/me/feed', ['message' => 'Foo message']); ### delete() {#delete} ~~~~ -public Facebook\Entities\FacebookResponse delete( +public Facebook\FacebookResponse delete( string $endpoint, string|AccessToken|null $accessToken, string|null $eTag, @@ -284,7 +284,7 @@ public Facebook\Entities\FacebookResponse delete( ) ~~~~ -Sends a DELETE request to Graph and returns a `Facebook\Entities\FacebookResponse`. +Sends a DELETE request to Graph and returns a `Facebook\FacebookResponse`. The arguments are the same as `get()` above. @@ -296,7 +296,7 @@ $response = $fb->delete('/{node-id}'); ### request() {#request} ~~~~ -public Facebook\Entities\FacebookRequest request( +public Facebook\FacebookRequest request( string $method, string $endpoint, array $params, @@ -306,7 +306,7 @@ public Facebook\Entities\FacebookRequest request( ) ~~~~ -Instantiates a new `Facebook\Entities\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). +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`. @@ -321,7 +321,7 @@ $request = $fb->request('GET', '/{node-id}'); ### sendRequest() {#send-request} ~~~~ -public Facebook\Entities\FacebookResponse sendRequest( +public Facebook\FacebookResponse sendRequest( string $method, string $endpoint, array $params, @@ -341,19 +341,19 @@ $response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.2') ### sendBatchRequest() {#send-batch-request} ~~~~ -public Facebook\Entities\FacebookBatchResponse sendBatchRequest( +public Facebook\FacebookBatchResponse sendBatchRequest( array $requests, string|AccessToken|null $accessToken, string|null $graphVersion ) ~~~~ -Sends an array of `Facebook\Entities\FacebookRequest` entities as a batch request to Graph. +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\Entities\FacebookRequest` entities. This can be a numeric or associative array but every value of the array has to be of type `Facebook\Entities\FacebookRequest`. +An array of `Facebook\FacebookRequest` entities. This can be a numeric or associative array but every value of the array has to be of type `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/#operations). diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index f919fe495..f5557ee8b 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -1,19 +1,19 @@ # 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\Entities\FacebookApp` entity represents the Facebook app that is making the requests to the Graph API. +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. -## Facebook\Entities\FacebookApp {#overview} +## Facebook\FacebookApp {#overview} -To instantiate a new `Facebook\Entities\FacebookApp` entity, pass the app ID and app secret to the constructor. +To instantiate a new `Facebook\FacebookApp` entity, pass the app ID and app secret to the constructor. ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); ~~~~ -Alternatively you can obtain the `Facebook\Entities\FacebookApp` entity from the [`Facebook\Facebook`](/docs/php/Facebook) super service class. +Alternatively you can obtain the `Facebook\FacebookApp` entity from the [`Facebook\Facebook`](/docs/php/Facebook) super service class. ~~~~ $fb = new Facebook\Facebook([/* . . . */]); @@ -28,9 +28,9 @@ In the most common cases, you'll rarely be using the `FacebookApp` entity direct ### getAccessToken() {#get-access-token} ~~~~ -public Facebook\Entities\AccessToken getAccessToken() +public Facebook\AccessToken getAccessToken() ~~~~ -Returns an app access token in the form of a [`Facebook\Entities\AccessToken`](/docs/php/AccessToken) entity. +Returns an app access token in the form of a [`Facebook\AccessToken`](/docs/php/AccessToken) entity. @@ -52,13 +52,13 @@ Returns an the app secret. ## Serialization {#serialization} -The `Facebook\Entities\FacebookApp` entity implements the `\Serializable` interface so it can be serialized and unserialized. +The `Facebook\FacebookApp` entity implements the `\Serializable` interface so it can be serialized and unserialized. ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('foo-app-id', 'foo-app-secret'); +$fbApp = new Facebook\FacebookApp('foo-app-id', 'foo-app-secret'); $serializedFacebookApp = serialize($fbApp); -// C:29:"Facebook\\Entities\\FacebookApp":54:{a:2:{i:0;s:10:"foo-app-id";i:1;s:14:"foo-app-secret";}} +// 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(); diff --git a/docs/FacebookBatchRequest.fbmd b/docs/FacebookBatchRequest.fbmd index 726843927..8c56ba257 100644 --- a/docs/FacebookBatchRequest.fbmd +++ b/docs/FacebookBatchRequest.fbmd @@ -5,34 +5,34 @@ Represents a batch request that will be sent to the Graph API. -## Facebook\Entities\FacebookBatchRequest {#overview} +## Facebook\FacebookBatchRequest {#overview} You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor. ~~~~ -use Facebook\Entities\FacebookBatchRequest; +use Facebook\FacebookBatchRequest; $request = new FacebookBatchRequest( - Facebook\Entities\FacebookApp $app, + Facebook\FacebookApp $app, array $requests, string|null $accessToken, string|null $graphVersion ); ~~~~ -The `$requests` array is an array of [`Facebook\Entities\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent as a batch request. +The `$requests` array is an array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) 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()`](/docs/php/Facebook#send-batch-request) or [`Facebook\FacebookClient::sendBatchRequest()`](/docs/php/FacebookClient#send-batch-request). Usage: ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); +$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); $requests = [ - new Facebook\Entities\FacebookRequest(/* */), - new Facebook\Entities\FacebookRequest(/* */), + new Facebook\FacebookRequest(/* */), + new Facebook\FacebookRequest(/* */), ]; -$batchRequest = new Facebook\Entities\FacebookBatchRequest($fbApp, $requests, '{access-token}'); +$batchRequest = new Facebook\FacebookBatchRequest($fbApp, $requests, '{access-token}'); // Send the batch request to Graph try { @@ -82,16 +82,16 @@ foreach ($batchResponse as $key => $response) { ## Instance Methods {#instance-methods} -Since the `Facebook\Entities\FacebookBatchRequest` is extended from the [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. +Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. ### add() {#add} ~~~~ public add( - array|Facebook\Entities\FacebookBatchRequest $request, + array|Facebook\FacebookBatchRequest $request, string|null $name ) ~~~~ -Adds a request to be sent in the batch request. The `$request` can be a single [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) or an array of `Facebook\Entities\FacebookRequest`'s. +Adds a request to be sent in the batch request. The `$request` can be a single [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) or an array of `Facebook\FacebookRequest`'s. The `$name` argument is optional and is used to identify the request in the batch. @@ -101,13 +101,13 @@ The `$name` argument is optional and is used to identify the request in the batc ~~~~ public array getRequests() ~~~~ -Returns the array of [`Facebook\Entities\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent in the batch request. +Returns the array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent in the batch request. ## Array Access {#array-access} -Since `Facebook\Entities\FacebookBatchRequest` implements `\IteratorAggregate` and `\ArrayAccess`, the requests can be accessed via array syntax and can also be iterated over. +Since `Facebook\FacebookBatchRequest` implements `\IteratorAggregate` and `\ArrayAccess`, the requests can be accessed via array syntax and can also be iterated over. ~~~~ $fb = new Facebook\Facebook(/* . . . */); @@ -115,13 +115,13 @@ $requests = [ 'foo' => $fb->request('GET', '/me'), 'bar' => $fb->request('POST', '/me/feed', [/* */]), ]; -$batchRequest = new Facebook\Entities\FacebookBatchRequest($fb->getApp(), $requests, '{access-token}'); +$batchRequest = new Facebook\FacebookBatchRequest($fb->getApp(), $requests, '{access-token}'); var_dump($batchRequest[0]); /* array(2) { 'name' => string(3) "foo" - 'request' => class Facebook\Entities\FacebookRequest + 'request' => class Facebook\FacebookRequest . . . */ ~~~~ diff --git a/docs/FacebookBatchResponse.fbmd b/docs/FacebookBatchResponse.fbmd index dece6dd01..569bbda6c 100644 --- a/docs/FacebookBatchResponse.fbmd +++ b/docs/FacebookBatchResponse.fbmd @@ -5,9 +5,9 @@ Represents a batch response returned from the Graph API. -## Facebook\Entities\FacebookBatchResponse {#overview} +## Facebook\FacebookBatchResponse {#overview} -After sending a batch request to the Graph API, the response will be returned in the form of a `Facebook\Entities\FacebookBatchResponse` entity. +After sending a batch request to the Graph API, the response will be returned in the form of a `Facebook\FacebookBatchResponse` entity. Usage: @@ -41,26 +41,26 @@ foreach ($batchResponse as $key => $response) { } var_dump($batchResponse); -// class Facebook\Entities\FacebookBatchResponse . . . +// class Facebook\FacebookBatchResponse . . . ~~~~ ## Instance Methods {#instance-methods} -Since the `Facebook\Entities\FacebookBatchResponse` is extended from the [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. +Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. ### getResponses() {#get-responses} ~~~~ public array getResponses() ~~~~ -Returns the array of [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse) entities that were returned from Graph. +Returns the array of [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entities that were returned from Graph. ## Array Access {#array-access} -Since `Facebook\Entities\FacebookBatchResponse` implements `\IteratorAggregate` and `\ArrayAccess`, the responses can be accessed via array syntax and can also be iterated over. +Since `Facebook\FacebookBatchResponse` implements `\IteratorAggregate` and `\ArrayAccess`, the responses can be accessed via array syntax and can also be iterated over. ~~~~ $requests = [ @@ -79,6 +79,6 @@ foreach ($batchResponse as $key => $response) { } var_dump($batchResponse['foo']); -// class Facebook\Entities\FacebookResponse . . . +// class Facebook\FacebookResponse . . . ~~~~ diff --git a/docs/FacebookCanvasHelper.fbmd b/docs/FacebookCanvasHelper.fbmd index 2f879b500..2bb13957d 100644 --- a/docs/FacebookCanvasHelper.fbmd +++ b/docs/FacebookCanvasHelper.fbmd @@ -4,7 +4,7 @@ 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). ~~~ -Facebook\Helpers\FacebookCanvasHelper( Facebook\Entities\FacebookApp $facebookApp ) +Facebook\Helpers\FacebookCanvasHelper( Facebook\FacebookApp $facebookApp ) ~~~ @@ -67,7 +67,7 @@ if (isset($accessToken)) { ### __construct() {#construct} ~~~~ -public FacebookCanvasHelper __construct( Facebook\Entities\FacebookApp $app ) +public FacebookCanvasHelper __construct( Facebook\FacebookApp $app ) ~~~~ Upon instantiation, `FacebookCanvasHelper` validates and decrypts the signed request that was sent via POST if present. @@ -75,7 +75,7 @@ Upon instantiation, `FacebookCanvasHelper` validates and decrypts the signed req ### getAccessToken() {#get-access-token} ~~~ -public Facebook\Entities\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) +public Facebook\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) ~~~ Checks the signed request for authentication data and tries to obtain an access token access token. @@ -119,9 +119,9 @@ Gets the value that is set in the `app_data` property if present. ### getSignedRequest() {#get-signed-request} ~~~ -public Facebook\Entities\SignedRequest|null getSignedRequest() +public Facebook\SignedRequest|null getSignedRequest() ~~~ -Returns the signed request as a [`Facebook\Entities\SignedRequest`](/docs/php/SignedRequest) entity if present. +Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedRequest) entity if present. diff --git a/docs/FacebookClient.fbmd b/docs/FacebookClient.fbmd index f78e26753..a4f0dc781 100644 --- a/docs/FacebookClient.fbmd +++ b/docs/FacebookClient.fbmd @@ -19,7 +19,7 @@ $fbClient = $fb->getClient(); Alternatively you could instantiate a new `Facebook\FacebookClient` service directly. ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('{app_id}', '{app_secret}'); +$fbApp = new Facebook\FacebookApp('{app_id}', '{app_secret}'); $fbClient = new Facebook\FacebookClient($fbApp, $enableBeta = false); ~~~~ @@ -57,13 +57,13 @@ Tells the service to send requests to the beta URL's which include [https://grap ### sendRequest() {#send-request} ~~~~ -public Facebook\Entities\FacebookResponse sendRequest(Facebook\Entities\FacebookRequest $request) +public Facebook\FacebookResponse sendRequest(Facebook\FacebookRequest $request) ~~~~ Sends a non-batch request to Graph. -Takes a [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. +Takes a [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) 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\Entities\FacebookResponse`](/docs/php/FacebookResponse). +Returns the response from Graph in the form of a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse). If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) will be thrown. @@ -73,13 +73,13 @@ If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookRe ### sendBatchRequest() {#send-batch-request} ~~~~ -public Facebook\Entities\FacebookBatchResponse sendBatchRequest(Facebook\Entities\FacebookBatchRequest $batchRequest) +public Facebook\FacebookBatchResponse sendBatchRequest(Facebook\FacebookBatchRequest $batchRequest) ~~~~ Sends a batch request to Graph. -Takes a [`Facebook\Entities\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. +Takes a [`Facebook\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) 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\Entities\FacebookBatchResponse`](/docs/php/FacebookBatchResponse). +Returns the response from Graph in the form of a [`Facebook\FacebookBatchResponse`](/docs/php/FacebookBatchResponse). If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) will be thrown. diff --git a/docs/FacebookJavaScriptHelper.fbmd b/docs/FacebookJavaScriptHelper.fbmd index 14f0d853e..112ed8a19 100644 --- a/docs/FacebookJavaScriptHelper.fbmd +++ b/docs/FacebookJavaScriptHelper.fbmd @@ -65,7 +65,7 @@ It's important to note that on first access, or if a session has since expired, ### __construct() {#construct} ~~~~ -public FacebookJavaScriptHelper __construct( Facebook\Entities\FacebookApp $app ) +public FacebookJavaScriptHelper __construct( Facebook\FacebookApp $app ) ~~~~ Upon instantiation, `FacebookJavaScriptHelper` validates and decrypts the signed request that exists in the cookie set by the JavaScript SDK if present. @@ -73,7 +73,7 @@ Upon instantiation, `FacebookJavaScriptHelper` validates and decrypts the signed ### getAccessToken() {#get-access-token} ~~~ -public Facebook\Entities\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) +public Facebook\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) ~~~ Checks the signed request for authentication data and tries to obtain an access token access token. @@ -109,9 +109,9 @@ if ($signedRequest) { ### getSignedRequest() {#get-signed-request} ~~~ -public Facebook\Entities\SignedRequest|null getSignedRequest() +public Facebook\SignedRequest|null getSignedRequest() ~~~ -Returns the signed request as a [`Facebook\Entities\SignedRequest`](/docs/php/SignedRequest) entity if present. +Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedRequest) entity if present. diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index cb59d4ab2..9d4ba56ef 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -5,15 +5,15 @@ Represents a request that will be sent to the Graph API. -## Facebook\Entities\FacebookRequest {#overview} +## Facebook\FacebookRequest {#overview} You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. ~~~~ -use Facebook\Entities\FacebookRequest; +use Facebook\FacebookRequest; $request = new FacebookRequest( - Facebook\Entities\FacebookApp $app, + Facebook\FacebookApp $app, string $accessToken, string $method, string $endpoint, @@ -30,8 +30,8 @@ The `FacebookRequest` entity does not actually make any calls to the Graph API, Usage: ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); -$request = new Facebook\Entities\FacebookRequest($fbApp, '{access-token}', 'GET', '/me'); +$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); +$request = new Facebook\FacebookRequest($fbApp, '{access-token}', 'GET', '/me'); // OR @@ -62,7 +62,7 @@ echo 'User name: ' . $object['name']; ### setAccessToken() {#set-access-token} ~~~~ -public setAccessToken(string|Facebook\Entities\AccessToken $accessToken) +public setAccessToken(string|Facebook\AccessToken $accessToken) ~~~~ Sets the access token to be used for the request. @@ -78,17 +78,17 @@ Returns the access token to be used for the request in the form of a string. ### setApp() {#set-app} ~~~~ -public setApp(Facebook\Entities\FacebookApp $app) +public setApp(Facebook\FacebookApp $app) ~~~~ -Sets the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity used with this request. +Sets the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. ### getApp() {#get-app} ~~~~ -public Facebook\Entities\FacebookApp getApp() +public Facebook\FacebookApp getApp() ~~~~ -Returns the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity used with this request. +Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index 0cc090afa..f013d528a 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -5,9 +5,9 @@ Represents a response from the Graph API. -## Facebook\Entities\FacebookResponse {#overview} +## Facebook\FacebookResponse {#overview} -After sending a request to the Graph API, the response will be returned in the form of a `Facebook\Entities\FacebookResponse` entity. +After sending a request to the Graph API, the response will be returned in the form of a `Facebook\FacebookResponse` entity. Usage: @@ -28,7 +28,7 @@ try { } var_dump($response); -// class Facebook\Entities\FacebookResponse . . . +// class Facebook\FacebookResponse . . . ~~~~ @@ -37,9 +37,9 @@ var_dump($response); ### getRequest() {#get-request} ~~~~ -public Facebook\Entities\FacebookRequest getRequest() +public Facebook\FacebookRequest getRequest() ~~~~ -Returns the original [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. +Returns the original [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. @@ -53,9 +53,9 @@ Returns the access token that was used for the original request in the form of a ### getApp() {#get-app} ~~~~ -public Facebook\Entities\FacebookApp getApp() +public Facebook\FacebookApp getApp() ~~~~ -Returns the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. +Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. diff --git a/docs/FacebookSDKException.fbmd b/docs/FacebookSDKException.fbmd index 6bffc6efa..07c0cb967 100644 --- a/docs/FacebookSDKException.fbmd +++ b/docs/FacebookSDKException.fbmd @@ -7,7 +7,7 @@ Represents an exception thrown by the SDK. ## Facebook\Exceptions\FacebookSDKException {#overview} -A `FacebookSDKException` is thrown when something goes wrong. For example if an invalid signed request is sent to the `Facebook\Entities\SignedRequest` entity, it will throw an `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](/docs/php/FacebookResponseException). diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd index df5fe8b4a..c07cf74a8 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphObject.fbmd @@ -15,13 +15,13 @@ This base class has several subclasses: [__GraphLocation__](#location-instance-methods) [__GraphSessionInfo__](#sessioninfo-instance-methods) -`GraphObject`'s are obtained from a [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse) object which represents a response from the Graph API. +`GraphObject`'s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents a response from the Graph API. Usage: ~~~~ $fb = new Facebook\Facebook(\* *\); -// Returns a `Facebook\Entities\FacebookResponse` object +// Returns a `Facebook\FacebookResponse` object $response = $fb->get('/something'); // Get the base class GraphObject from the response diff --git a/docs/SignedRequest.fbmd b/docs/SignedRequest.fbmd index 60b1174ca..7dddcea1c 100644 --- a/docs/SignedRequest.fbmd +++ b/docs/SignedRequest.fbmd @@ -1,22 +1,22 @@ # SignedRequest entity for the Facebook SDK for PHP -The `Facebook\Entities\SignedRequest` entity represents a signed request. +The `Facebook\SignedRequest` entity represents a signed request. -## Facebook\Entities\SignedRequest {#overview} +## Facebook\SignedRequest {#overview} -[Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) contain payloads of data that can be validated against a hash signature to ensure it is from Facebook. The `Facebook\Entities\SignedRequest` entity can validate a signed request signature and decode the payload. +[Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) 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\Entities\SignedRequest` entity, pass the [`Facebook\Entities\FacebookApp`](/docs/php/FacebookApp) entity and raw signed request to the constructor. +To instantiate a new `Facebook\SignedRequest` entity, pass the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity and raw signed request to the constructor. ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); -$signedRequest = new Facebook\Entities\SignedRequest($fbApp, 'raw.signed_request'); +$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); +$signedRequest = new Facebook\SignedRequest($fbApp, 'raw.signed_request'); ~~~~ -Usually `Facebook\Entities\SignedRequest` entities are obtained using one of the [helpers](/docs/php/sdk_reference#helpers). +Usually `Facebook\SignedRequest` entities are obtained using one of the [helpers](/docs/php/sdk_reference#helpers). ~~~~ $fb = new Facebook\Facebook([/* . . . */]); @@ -82,11 +82,11 @@ Returns `true` if the payload data contains either an `oauth_token` or `code` fi ~~~~ 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\Entities\FacebookApp` entity. This can be useful for testing purposes. +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. ~~~~ -$fbApp = new Facebook\Entities\FacebookApp('{app-id}', '{app-secret}'); -$signedRequest = new Facebook\Entities\SignedRequest($fbApp); +$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); +$signedRequest = new Facebook\SignedRequest($fbApp); $payload = [ 'algorithm' => 'HMAC-SHA256', diff --git a/docs/post_links.fbmd b/docs/post_links.fbmd index 2ddf2499f..52fb5fb13 100644 --- a/docs/post_links.fbmd +++ b/docs/post_links.fbmd @@ -5,7 +5,7 @@ This example covers posting a link to the current user's timeline using the Grap It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). @@ -23,7 +23,7 @@ $linkData = [ ]; try { - // Returns a `Facebook\Entities\FacebookResponse` object + // 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(); diff --git a/docs/retrieve_user_profile.fbmd b/docs/retrieve_user_profile.fbmd index c82c7172a..7f7431a81 100644 --- a/docs/retrieve_user_profile.fbmd +++ b/docs/retrieve_user_profile.fbmd @@ -5,7 +5,7 @@ This example covers getting profile information for the current user and printin It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). @@ -19,7 +19,7 @@ $fb = new Facebook\Facebook([ ]); try { - // Returns a `Facebook\Entities\FacebookResponse` object + // 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(); diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index c9698aa75..61f4970f1 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -106,10 +106,10 @@ require_once __DIR__ . '/facebook-sdk-v4.1/autoload.php'; ### The `FacebookApp` entity -Before we can send requests to the Graph API, we need to load our app configuration into a `Facebook\Entities\FacebookApp` entity. +Before we can send requests to the Graph API, we need to load our app configuration into a `Facebook\FacebookApp` entity. ~~~ -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; $facebookApp = new FacebookApp('{app-id}', '{app-secret}'); ~~~ @@ -143,7 +143,7 @@ For most websites, you'll use the `[Facebook\Helpers\FacebookRedirectLoginHelper ~~~ # login.php -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\Helpers\FacebookRedirectLoginHelper; $facebookApp = new FacebookApp('{app-id}', '{app-secret}'); @@ -157,7 +157,7 @@ echo 'Log in with Facebook!'; ~~~ # login-callback.php -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\FacebookClient; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\Exceptions\FacebookResponseException; @@ -182,10 +182,10 @@ if (isset($accessToken)) { } ~~~ -If your app is on Facebook Canvas, use the `getAccessToken()` method on [FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) to get an `Facebook\Entities\AccessToken` entity for the user. +If your app is on Facebook Canvas, use the `getAccessToken()` method on [FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) to get an `Facebook\AccessToken` entity for the user. ~~~ -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\FacebookClient; use Facebook\Helpers\FacebookCanvasLoginHelper; use Facebook\Exceptions\FacebookResponseException; @@ -212,10 +212,10 @@ if (isset($accessToken)) { } ~~~ -If you're already using the Facebook SDK for JavaScript to authenticate users, you can also log them in on the server side with the [FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper). The `getAccessToken()` method will return a `Facebook\Entities\AccessToken` entity. +If you're already using the Facebook SDK for JavaScript to authenticate users, you can also log them in on the server side with the [FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper). The `getAccessToken()` method will return a `Facebook\AccessToken` entity. ~~~ -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\FacebookClient; use Facebook\Helpers\FacebookJavaScriptLoginHelper; use Facebook\Exceptions\FacebookResponseException; @@ -240,10 +240,10 @@ if (isset($accessToken)) { } ~~~ -You can also create a `Facebook\Entities\AccessToken` entity with an access token you've acquired through some other means, by passing it to the constructor. +You can also create a `Facebook\AccessToken` entity with an access token you've acquired through some other means, by passing it to the constructor. ~~~ -use Facebook\Entities\AccessToken; +use Facebook\AccessToken; $accessToken = new AccessToken('{access-token}'); ~~~ @@ -252,11 +252,11 @@ $accessToken = new AccessToken('{access-token}'); ## Making Requests to the Graph API {#making-requests} -Once you have created a `Facebook\Entities\FacebookApp` entity, instantiated a `Facebook\FacebookClient` and obtained an access token, you can begin making calls to the Graph API with the [`Facebook\Entities\FacebookRequest`](/docs/php/FacebookRequest) entity. +Once you have created a `Facebook\FacebookApp` entity, instantiated a `Facebook\FacebookClient` and obtained an access token, you can begin making calls to the Graph API with the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity. ~~~ -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; use Facebook\FacebookClient; use Facebook\GraphNodes\GraphUser; use Facebook\Exceptions\FacebookResponseException; diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index c53f9f4a2..d446a5b22 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -33,31 +33,31 @@ FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\Entities\AccessToken](/docs/php/AccessToken)`', + '`[Facebook\AccessToken](/docs/php/AccessToken)`', 'An entity that represents an access token and is required to send requests to Graph.', ], [ - '`[Facebook\Entities\FacebookApp](/docs/php/FacebookApp)`', + '`[Facebook\FacebookApp](/docs/php/FacebookApp)`', 'An entity that represents a Facebook app and is required to send requests to Graph.', ], [ - '`[Facebook\Entities\FacebookBatchRequest](/docs/php/FacebookBatchRequest)`', + '`[Facebook\FacebookBatchRequest](/docs/php/FacebookBatchRequest)`', 'An entity that represents a batch request to be sent to Graph.', ], [ - '`[Facebook\Entities\FacebookBatchResponse](/docs/php/FacebookBatchResponse)`', + '`[Facebook\FacebookBatchResponse](/docs/php/FacebookBatchResponse)`', 'An entity that represents a response from Graph after sending a batch request.', ], [ - '`[Facebook\Entities\FacebookRequest](/docs/php/FacebookRequest)`', + '`[Facebook\FacebookRequest](/docs/php/FacebookRequest)`', 'An entity that represents a request to be sent to Graph.', ], [ - '`[Facebook\Entities\FacebookResponse](/docs/php/FacebookResponse)`', + '`[Facebook\FacebookResponse](/docs/php/FacebookResponse)`', 'An entity that represents a response from Graph.', ], [ - '`[Facebook\Entities\SignedRequest](/docs/php/SignedRequest)`', + '`[Facebook\SignedRequest](/docs/php/SignedRequest)`', 'An entity that represents a signed request.', ], ], diff --git a/docs/upload_photo.fbmd b/docs/upload_photo.fbmd index f48844412..99e72bba8 100644 --- a/docs/upload_photo.fbmd +++ b/docs/upload_photo.fbmd @@ -5,7 +5,7 @@ This example covers uploading a photo to the current User's profile using the Gr It assumes that you've already acquired an access token using one of the helper classes found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\Entities\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). @@ -20,7 +20,7 @@ $data = [ ]; try { - // Returns a `Facebook\Entities\FacebookResponse` object + // Returns a `Facebook\FacebookResponse` object $response = $fb->post('/me/photos', $data); } catch(Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph returned an error: ' . $e->getMessage(); diff --git a/src/Facebook/Entities/AccessToken.php b/src/Facebook/AccessToken.php similarity index 99% rename from src/Facebook/Entities/AccessToken.php rename to src/Facebook/AccessToken.php index 2df38f4c7..9b6937ff9 100644 --- a/src/Facebook/Entities/AccessToken.php +++ b/src/Facebook/AccessToken.php @@ -21,11 +21,10 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; -use Facebook\FacebookClient; use Facebook\GraphNodes\GraphSessionInfo; /** diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index bb4b083cc..bc6e2a507 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -23,7 +23,7 @@ */ namespace Facebook\Exceptions; -use Facebook\Entities\FacebookResponse; +use Facebook\FacebookResponse; /** * Class FacebookResponseException diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 796eda2ab..05ca95005 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -23,12 +23,6 @@ */ namespace Facebook; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\AccessToken; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookBatchRequest; -use Facebook\Entities\FacebookResponse; -use Facebook\Entities\FacebookBatchResponse; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; use Facebook\GraphNodes\GraphList; @@ -297,7 +291,7 @@ public function setDefaultAccessToken($accessToken) throw new \InvalidArgumentException( 'The default access token must be of type "string"' - . ' or Facebook\Entities\AccessToken' + . ' or Facebook\AccessToken' ); } diff --git a/src/Facebook/Entities/FacebookApp.php b/src/Facebook/FacebookApp.php similarity index 98% rename from src/Facebook/Entities/FacebookApp.php rename to src/Facebook/FacebookApp.php index f426cfa13..feef6c2c4 100644 --- a/src/Facebook/Entities/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; class FacebookApp implements \Serializable { diff --git a/src/Facebook/Entities/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php similarity index 99% rename from src/Facebook/Entities/FacebookBatchRequest.php rename to src/Facebook/FacebookBatchRequest.php index 30106b51c..0e409d722 100755 --- a/src/Facebook/Entities/FacebookBatchRequest.php +++ b/src/Facebook/FacebookBatchRequest.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; use ArrayIterator; use IteratorAggregate; diff --git a/src/Facebook/Entities/FacebookBatchResponse.php b/src/Facebook/FacebookBatchResponse.php similarity index 99% rename from src/Facebook/Entities/FacebookBatchResponse.php rename to src/Facebook/FacebookBatchResponse.php index 269ab781f..c0e47f7b4 100755 --- a/src/Facebook/Entities/FacebookBatchResponse.php +++ b/src/Facebook/FacebookBatchResponse.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; use ArrayIterator; use IteratorAggregate; diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index 706822d5a..caf6c33fb 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -23,10 +23,6 @@ */ namespace Facebook; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookBatchRequest; -use Facebook\Entities\FacebookResponse; -use Facebook\Entities\FacebookBatchResponse; use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; diff --git a/src/Facebook/Entities/FacebookRequest.php b/src/Facebook/FacebookRequest.php similarity index 99% rename from src/Facebook/Entities/FacebookRequest.php rename to src/Facebook/FacebookRequest.php index e9208f32e..49db0a5ab 100755 --- a/src/Facebook/Entities/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -21,9 +21,8 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; -use Facebook\Facebook; use Facebook\Url\FacebookUrlManipulator; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; diff --git a/src/Facebook/Entities/FacebookResponse.php b/src/Facebook/FacebookResponse.php similarity index 99% rename from src/Facebook/Entities/FacebookResponse.php rename to src/Facebook/FacebookResponse.php index 34f4069b0..74fa38256 100755 --- a/src/Facebook/Entities/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; use Facebook\GraphNodes\GraphObjectFactory; use Facebook\Exceptions\FacebookResponseException; diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 94bc93b27..684bad38b 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -23,7 +23,7 @@ */ namespace Facebook\GraphNodes; -use Facebook\Entities\FacebookRequest; +use Facebook\FacebookRequest; use Facebook\Url\FacebookUrlManipulator; use Facebook\Exceptions\FacebookSDKException; diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 67dbe934e..53c5bf879 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -23,7 +23,7 @@ */ namespace Facebook\GraphNodes; -use Facebook\Entities\FacebookResponse; +use Facebook\FacebookResponse; use Facebook\Exceptions\FacebookSDKException; /** diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 9d8535b5d..5a7eb1c75 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -23,7 +23,7 @@ */ namespace Facebook\Helpers; -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; /** * Class FacebookPageTabHelper diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 7621e45ab..d438ce249 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -24,8 +24,8 @@ namespace Facebook\Helpers; use Facebook\Facebook; -use Facebook\Entities\AccessToken; -use Facebook\Entities\FacebookApp; +use \Facebook\AccessToken; +use \Facebook\FacebookApp; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\Url\FacebookUrlManipulator; diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index 5f45d5b34..ac95d693b 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -23,9 +23,9 @@ */ namespace Facebook\Helpers; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\SignedRequest; -use Facebook\Entities\AccessToken; +use Facebook\FacebookApp; +use Facebook\SignedRequest; +use Facebook\AccessToken; use Facebook\FacebookClient; /** diff --git a/src/Facebook/Entities/SignedRequest.php b/src/Facebook/SignedRequest.php similarity index 99% rename from src/Facebook/Entities/SignedRequest.php rename to src/Facebook/SignedRequest.php index 245e4aa4a..f93c355d6 100644 --- a/src/Facebook/Entities/SignedRequest.php +++ b/src/Facebook/SignedRequest.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Entities; +namespace Facebook; use Facebook\Exceptions\FacebookSDKException; diff --git a/tests/Entities/AccessTokenTest.php b/tests/AccessTokenTest.php similarity index 95% rename from tests/Entities/AccessTokenTest.php rename to tests/AccessTokenTest.php index 26b702c7a..8f36f55b2 100644 --- a/tests/Entities/AccessTokenTest.php +++ b/tests/AccessTokenTest.php @@ -21,11 +21,11 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; use Mockery as m; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\AccessToken; +use Facebook\FacebookApp; +use Facebook\AccessToken; use Facebook\GraphNodes\GraphSessionInfo; class AccessTokenTest extends \PHPUnit_Framework_TestCase @@ -133,7 +133,7 @@ public function testAShortLivedAccessTokenCabBeExtended() $longLivedAccessToken = $accessToken->extend($app, $client); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $longLivedAccessToken); + $this->assertInstanceOf('Facebook\AccessToken', $longLivedAccessToken); $this->assertEquals('long_token', (string)$longLivedAccessToken); $this->assertEquals('foo_machine', $longLivedAccessToken->getMachineId()); $this->assertEquals(time() + 123, $longLivedAccessToken->getExpiresAt()->getTimeStamp()); @@ -164,7 +164,7 @@ public function testACodeCanBeUsedToObtainAnAccessToken() $accessTokenFromCode = AccessToken::getAccessTokenFromCode('foo_code', $app, $client); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessTokenFromCode); + $this->assertInstanceOf('Facebook\AccessToken', $accessTokenFromCode); $this->assertEquals('new_long_token', (string)$accessTokenFromCode); $this->assertEquals('foo_machine', $accessTokenFromCode->getMachineId()); $this->assertEquals(time() + 123, $accessTokenFromCode->getExpiresAt()->getTimeStamp()); @@ -201,7 +201,7 @@ private function createFacebookClientMockWithResponse($response) $client = m::mock('Facebook\FacebookClient'); $client ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) + ->with(m::type('Facebook\FacebookRequest')) ->once() ->andReturn($response); return $client; @@ -219,7 +219,7 @@ private function createFacebookResponseMockWithDecodedBody($decodedBody) private function createFacebookResponseMock() { - return m::mock('Facebook\Entities\FacebookResponse'); + return m::mock('Facebook\FacebookResponse'); } private function createFacebookResponseMockWithNoExpiresAt() diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 506d359cf..15691a0e3 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -23,9 +23,9 @@ */ namespace Facebook\Tests\Exceptions; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookResponse; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; use Facebook\Exceptions\FacebookResponseException; class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase diff --git a/tests/Entities/FacebookAppTest.php b/tests/FacebookAppTest.php similarity index 89% rename from tests/Entities/FacebookAppTest.php rename to tests/FacebookAppTest.php index b938855f1..bf2e8e4cf 100644 --- a/tests/Entities/FacebookAppTest.php +++ b/tests/FacebookAppTest.php @@ -21,9 +21,9 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; class FacebookAppTest extends \PHPUnit_Framework_TestCase { @@ -52,7 +52,7 @@ public function testAnAppAccessTokenCanBeGenerated() { $accessToken = $this->app->getAccessToken(); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('id|secret', (string) $accessToken); } @@ -60,7 +60,7 @@ public function testSerialization() { $newApp = unserialize(serialize($this->app)); - $this->assertInstanceOf('Facebook\Entities\FacebookApp', $newApp); + $this->assertInstanceOf('Facebook\FacebookApp', $newApp); $this->assertEquals('id', $newApp->getId()); $this->assertEquals('secret', $newApp->getSecret()); } diff --git a/tests/Entities/FacebookBatchRequestTest.php b/tests/FacebookBatchRequestTest.php similarity index 97% rename from tests/Entities/FacebookBatchRequestTest.php rename to tests/FacebookBatchRequestTest.php index cc0e946de..fced05c11 100755 --- a/tests/Entities/FacebookBatchRequestTest.php +++ b/tests/FacebookBatchRequestTest.php @@ -21,12 +21,12 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; use Facebook\Facebook; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookBatchRequest; +use \Facebook\FacebookApp; +use \Facebook\FacebookRequest; +use \Facebook\FacebookBatchRequest; use Facebook\FileUpload\FacebookFile; class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase @@ -254,7 +254,7 @@ public function testBatchRequestsWithFilesGetConvertedToAnArray() { $request = new FacebookRequest(null, null, 'POST', '/bar', [ 'message' => 'foobar', - 'source' => new FacebookFile(__DIR__ . '/../foo.txt'), + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), ]); $batchRequest = $this->createBatchRequest(); @@ -306,7 +306,7 @@ public function testPreppingABatchRequestProperlyMovesTheFiles() $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); $batchRequest->add(new FacebookRequest(null, null, 'POST', '/me/photos', [ 'message' => 'foobar', - 'source' => new FacebookFile(__DIR__ . '/../foo.txt'), + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), ])); $batchRequest->prepareRequestsForBatch(); diff --git a/tests/Entities/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php similarity index 92% rename from tests/Entities/FacebookBatchResponseTest.php rename to tests/FacebookBatchResponseTest.php index 3f5c466e9..f7d8ea9eb 100755 --- a/tests/Entities/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -21,24 +21,24 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookResponse; -use Facebook\Entities\FacebookBatchRequest; -use Facebook\Entities\FacebookBatchResponse; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; +use Facebook\FacebookBatchRequest; +use Facebook\FacebookBatchResponse; class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookApp + * @var \Facebook\FacebookApp */ protected $app; /** - * @var \Facebook\Entities\FacebookRequest + * @var \Facebook\FacebookRequest */ protected $request; @@ -108,7 +108,7 @@ public function testABatchResponseCanBeIteratedOver() foreach ($batchResponse as $key => $responseEntity) { $this->assertTrue(in_array($key, ['req_one', 'req_two', 'req_three'])); - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $responseEntity); + $this->assertInstanceOf('Facebook\FacebookResponse', $responseEntity); } } @@ -130,8 +130,8 @@ public function testTheOriginalRequestCanBeObtainedForEachRequest() $batchRequest = new FacebookBatchRequest($this->app, $requests); $batchResponse = new FacebookBatchResponse($batchRequest, $response); - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $batchResponse[0]); - $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $batchResponse[0]->getRequest()); + $this->assertInstanceOf('Facebook\FacebookResponse', $batchResponse[0]); + $this->assertInstanceOf('Facebook\FacebookRequest', $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 2b0b0bd68..d7d1a45a3 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -25,9 +25,9 @@ use Facebook\Exceptions\FacebookSDKException; use Facebook\Facebook; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookBatchRequest; +use \Facebook\FacebookApp; +use \Facebook\FacebookRequest; +use \Facebook\FacebookBatchRequest; use Facebook\FacebookClient; use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; @@ -148,7 +148,7 @@ public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() $fbRequest = new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'); $response = $this->fbClient->sendRequest($fbRequest); - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $response); + $this->assertInstanceOf('Facebook\FacebookResponse', $response); $this->assertEquals(200, $response->getHttpStatusCode()); $this->assertEquals('{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}', $response->getBody()); } @@ -164,7 +164,7 @@ public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGra $fbBatchClient = new FacebookClient(new MyFooBatchClientHandler()); $response = $fbBatchClient->sendBatchRequest($fbBatchRequest); - $this->assertInstanceOf('Facebook\Entities\FacebookBatchResponse', $response); + $this->assertInstanceOf('Facebook\FacebookBatchResponse', $response); $this->assertEquals('GET', $response[0]->getRequest()->getMethod()); $this->assertEquals('POST', $response[1]->getRequest()->getMethod()); } diff --git a/tests/Entities/FacebookRequestTest.php b/tests/FacebookRequestTest.php similarity index 95% rename from tests/Entities/FacebookRequestTest.php rename to tests/FacebookRequestTest.php index 5ba2b1da2..3aea64f6e 100755 --- a/tests/Entities/FacebookRequestTest.php +++ b/tests/FacebookRequestTest.php @@ -21,11 +21,11 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; use Facebook\Facebook; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; +use \Facebook\FacebookApp; +use \Facebook\FacebookRequest; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; @@ -37,7 +37,7 @@ public function testAnEmptyRequestEntityCanInstantiate() $app = new FacebookApp('123', 'foo_secret'); $request = new FacebookRequest($app); - $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $request); + $this->assertInstanceOf('Facebook\FacebookRequest', $request); } /** @@ -172,7 +172,7 @@ public function testAuthenticationParamsAreStrippedAndReapplied() public function testAFileCanBeAddedToParams() { - $myFile = new FacebookFile(__DIR__ . '/../foo.txt'); + $myFile = new FacebookFile(__DIR__ . '/foo.txt'); $params = [ 'name' => 'Foo Bar', 'source' => $myFile, @@ -190,7 +190,7 @@ public function testAFileCanBeAddedToParams() public function testAVideoCanBeAddedToParams() { - $myFile = new FacebookVideo(__DIR__ . '/../foo.txt'); + $myFile = new FacebookVideo(__DIR__ . '/foo.txt'); $params = [ 'name' => 'Foo Bar', 'source' => $myFile, diff --git a/tests/Entities/FacebookResponseTest.php b/tests/FacebookResponseTest.php similarity index 95% rename from tests/Entities/FacebookResponseTest.php rename to tests/FacebookResponseTest.php index 5ebba834a..cdc98f88a 100755 --- a/tests/Entities/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -21,17 +21,17 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookResponse; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; class FacebookResponseTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookRequest + * @var \Facebook\FacebookRequest */ protected $request; diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 330784ac1..6e392be9a 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -30,8 +30,8 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\AccessToken; +use \Facebook\FacebookRequest; +use \Facebook\AccessToken; use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface @@ -177,7 +177,7 @@ public function testAnAccessTokenCanBeSetAsAString() $fb->setDefaultAccessToken('foo_token'); $accessToken = $fb->getDefaultAccessToken(); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('foo_token', (string) $accessToken); } @@ -187,7 +187,7 @@ public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() $fb->setDefaultAccessToken(new AccessToken('bar_token')); $accessToken = $fb->getDefaultAccessToken(); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('bar_token', (string) $accessToken); } @@ -336,7 +336,7 @@ public function testPaginationReturnsProperResponse() $this->assertEquals('Foo', $nextPage[0]['name']); $lastResponse = $fb->getLastResponse(); - $this->assertInstanceOf('Facebook\Entities\FacebookResponse', $lastResponse); + $this->assertInstanceOf('Facebook\FacebookResponse', $lastResponse); $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); } diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 32c065866..0af00322d 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -30,13 +30,13 @@ class GraphAlbumTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\FacebookResponse */ protected $responseMock; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } public function testDatesGetCastToDateTime() diff --git a/tests/GraphNodes/GraphListTest.php b/tests/GraphNodes/GraphListTest.php index 1590a77db..5419bfb92 100644 --- a/tests/GraphNodes/GraphListTest.php +++ b/tests/GraphNodes/GraphListTest.php @@ -23,15 +23,15 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphList; class GraphListTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookRequest + * @var \Facebook\FacebookRequest */ protected $request; @@ -106,8 +106,8 @@ public function testCanInstantiateNewPaginationRequest() $nextPage = $graphList->getNextPageRequest(); $prevPage = $graphList->getPreviousPageRequest(); - $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $nextPage); - $this->assertInstanceOf('Facebook\Entities\FacebookRequest', $prevPage); + $this->assertInstanceOf('Facebook\FacebookRequest', $nextPage); + $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); $this->assertNotSame($this->request, $nextPage); $this->assertNotSame($this->request, $prevPage); $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index 6690d4adf..e6df80279 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -23,9 +23,9 @@ */ namespace Facebook\Tests\GraphNodes; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\FacebookRequest; -use Facebook\Entities\FacebookResponse; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; use Facebook\GraphNodes\GraphObjectFactory; use Facebook\GraphNodes\GraphObject; @@ -41,7 +41,7 @@ class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookRequest + * @var \Facebook\FacebookRequest */ protected $request; diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php index bb88e07b0..d2069bd14 100644 --- a/tests/GraphNodes/GraphPageTest.php +++ b/tests/GraphNodes/GraphPageTest.php @@ -30,13 +30,13 @@ class GraphPageTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\FacebookResponse */ protected $responseMock; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } public function testPagePropertiesReturnGraphPageObjects() diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index 34939a403..8b3da8442 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -30,13 +30,13 @@ class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\FacebookResponse */ protected $responseMock; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } public function testDatesGetCastToDateTime() diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index 8f7de1ea4..db73b9a9e 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -30,13 +30,13 @@ class GraphUserTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\Entities\FacebookResponse + * @var \Facebook\FacebookResponse */ protected $responseMock; public function setUp() { - $this->responseMock = m::mock('\\Facebook\\Entities\\FacebookResponse'); + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } public function testDatesGetCastToDateTime() diff --git a/tests/Helpers/FacebookCanvasHelperTest.php b/tests/Helpers/FacebookCanvasHelperTest.php index d436838ab..9c296ccd9 100644 --- a/tests/Helpers/FacebookCanvasHelperTest.php +++ b/tests/Helpers/FacebookCanvasHelperTest.php @@ -23,7 +23,7 @@ */ namespace Facebook\Tests\Helpers; -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\Helpers\FacebookCanvasHelper; class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase diff --git a/tests/Helpers/FacebookJavaScriptHelperTest.php b/tests/Helpers/FacebookJavaScriptHelperTest.php index 1e1f10275..00d5423a2 100644 --- a/tests/Helpers/FacebookJavaScriptHelperTest.php +++ b/tests/Helpers/FacebookJavaScriptHelperTest.php @@ -23,7 +23,7 @@ */ namespace Facebook\Tests\Helpers; -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\Helpers\FacebookJavaScriptHelper; class FacebookJavaScriptLoginHelperTest extends \PHPUnit_Framework_TestCase diff --git a/tests/Helpers/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php index 5c2e4e12a..9fe26425c 100644 --- a/tests/Helpers/FacebookPageTabHelperTest.php +++ b/tests/Helpers/FacebookPageTabHelperTest.php @@ -23,7 +23,7 @@ */ namespace Facebook\Tests\Helpers; -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\Helpers\FacebookPageTabHelper; class FacebookPageTabHelperTest extends \PHPUnit_Framework_TestCase diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index c58cae610..3780409f4 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -25,7 +25,7 @@ use Mockery as m; use Facebook\Facebook; -use Facebook\Entities\FacebookApp; +use \Facebook\FacebookApp; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; @@ -101,7 +101,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $_GET['state'] = 'foo_state'; $_GET['code'] = 'foo_code'; - $response = m::mock('Facebook\Entities\FacebookResponse'); + $response = m::mock('Facebook\FacebookResponse'); $response ->shouldReceive('getDecodedBody') ->once() @@ -112,7 +112,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $client = m::mock('Facebook\FacebookClient'); $client ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) + ->with(m::type('Facebook\FacebookRequest')) ->once() ->andReturn($response); @@ -121,7 +121,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $accessToken = $helper->getAccessToken($client, self::REDIRECT_URL); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('access_token_from_code', (string) $accessToken); } diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index f3f2970d9..793978782 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\Helpers; use Mockery as m; -use Facebook\Entities\FacebookApp; +use Facebook\FacebookApp; use Facebook\Helpers\FacebookSignedRequestFromInputHelper; class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper { @@ -101,13 +101,13 @@ public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessTok $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); $accessToken = $this->helper->getAccessToken($client); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('foo_token', (string) $accessToken); } public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() { - $response = m::mock('Facebook\Entities\FacebookResponse'); + $response = m::mock('Facebook\FacebookResponse'); $response ->shouldReceive('getDecodedBody') ->once() @@ -118,14 +118,14 @@ public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() $client = m::mock('Facebook\FacebookClient'); $client ->shouldReceive('sendRequest') - ->with(m::type('Facebook\Entities\FacebookRequest')) + ->with(m::type('Facebook\FacebookRequest')) ->once() ->andReturn($response); $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); $accessToken = $this->helper->getAccessToken($client); - $this->assertInstanceOf('Facebook\Entities\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('access_token_from_code', (string) $accessToken); } diff --git a/tests/Entities/SignedRequestTest.php b/tests/SignedRequestTest.php similarity index 97% rename from tests/Entities/SignedRequestTest.php rename to tests/SignedRequestTest.php index 0992dfeb9..e47cd59ab 100644 --- a/tests/Entities/SignedRequestTest.php +++ b/tests/SignedRequestTest.php @@ -21,10 +21,10 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Entities; +namespace Facebook\Tests; -use Facebook\Entities\FacebookApp; -use Facebook\Entities\SignedRequest; +use Facebook\FacebookApp; +use Facebook\SignedRequest; class SignedRequestTest extends \PHPUnit_Framework_TestCase { From 005dda3c547be24d7c18ada172663ef25e13eb6a Mon Sep 17 00:00:00 2001 From: George Date: Sun, 21 Dec 2014 12:38:07 +0200 Subject: [PATCH 083/407] Update GraphUser.php The field gender is missing from GraphUser object. --- src/Facebook/GraphNodes/GraphUser.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 607225ed0..7b06bf8c9 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -90,6 +90,16 @@ public function getLastName() { return $this->getProperty('last_name'); } + + /** + * Returns the gender for the user as a string if present. + * + * @return string|null + */ + public function getGender() + { + return $this->getProperty('gender'); + } /** * Returns the Facebook URL for the user as a string if available. From 3b501c4823d12041ea813cac4f16a665c399a033 Mon Sep 17 00:00:00 2001 From: mkrasilnikov Date: Sun, 21 Dec 2014 02:02:23 +0300 Subject: [PATCH 084/407] add graph picture 5.4 supported 5.4 supported remove author tag --- src/Facebook/GraphNodes/GraphPicture.php | 73 ++++++++++++++++++++++++ src/Facebook/GraphNodes/GraphUser.php | 11 ++++ tests/GraphNodes/GraphUserTest.php | 31 +++++++++- 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/Facebook/GraphNodes/GraphPicture.php diff --git a/src/Facebook/GraphNodes/GraphPicture.php b/src/Facebook/GraphNodes/GraphPicture.php new file mode 100644 index 000000000..711bb04a2 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphPicture.php @@ -0,0 +1,73 @@ +getProperty('is_silhouette'); + } + + /** + * Returns the url of user picture if it exists + * + * @return string|null + */ + public function getUrl() + { + return $this->getProperty('url'); + } + + /** + * Returns the width of user picture if it exists + * + * @return int|null + */ + public function getWidth() + { + return $this->getProperty('width'); + } + + /** + * Returns the height of user picture if it exists + * + * @return int|null + */ + public function getHeight() + { + return $this->getProperty('height'); + } + +} diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 607225ed0..de3058ffc 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -39,6 +39,7 @@ class GraphUser extends GraphObject 'hometown' => 'Facebook\\GraphNodes\\GraphPage', 'location' => 'Facebook\\GraphNodes\\GraphPage', 'significant_other' => 'Facebook\\GraphNodes\\GraphUser', + 'picture' => 'Facebook\\GraphNodes\\GraphPicture', ]; /** @@ -141,4 +142,14 @@ public function getSignificantOther() return $this->getProperty('significant_other'); } + /** + * Returns the picture of the user as a GraphPicture + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getProperty('picture'); + } + } diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index db73b9a9e..ea4b4d673 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests\GraphNodes; +use Facebook\FacebookResponse; use Mockery as m; use Facebook\GraphNodes\GraphObjectFactory; @@ -30,7 +31,7 @@ class GraphUserTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\FacebookResponse + * @var FacebookResponse */ protected $responseMock; @@ -109,4 +110,32 @@ public function testUserPropertiesWillGetCastAsGraphUserObjects() $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); } + public function testPicturePropertiesWillGetCastAsGraphPictureObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'picture' => [ + 'is_silhouette' => true, + 'url' => 'http://foo.bar', + 'width' => 200, + 'height' => 200, + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $Picture = $graphObject->getPicture(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPicture', $Picture); + $this->assertTrue($Picture->isSilhouette()); + $this->assertEquals(200, $Picture->getWidth()); + $this->assertEquals(200, $Picture->getHeight()); + $this->assertEquals('http://foo.bar', $Picture->getUrl()); + } } From f10ebbe83728baf30fa3099269e622d5ab5ad764 Mon Sep 17 00:00:00 2001 From: Hardik Bhadani Date: Tue, 23 Dec 2014 23:28:33 +0530 Subject: [PATCH 085/407] add support for re-authentication add base method makeUrl, and different method to get loginUrls --- .../Helpers/FacebookRedirectLoginHelper.php | 114 +++++++++++++++--- 1 file changed, 95 insertions(+), 19 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index d438ce249..304b29db2 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -149,6 +149,38 @@ public function detectPseudoRandomStringGenerator() ); } + /** + * Stores CSRF state and returns a URL to which the user should be sent to + * in order to continue the login process with Facebook. The + * provided redirectUrl should invoke the handleRedirect method. + * If a previous request to certain permission(s) was declined + * by the user, rerequest should be set to true or the permission(s) + * will not be re-asked. + * + * @param array $params Array of parameters to generate Url + * @param string $version Optional Graph API version if not default (v2.0). + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + private function makeUrl(array $params, $version, $separator) + { + $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; + + $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); + $this->persistentDataHandler->set('state', $state); + + $params += [ + 'client_id' => $this->app->getId(), + 'state' => $state, + 'response_type' => 'code', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + ]; + + return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . + http_build_query($params, null, $separator); + } + /** * Stores CSRF state and returns a URL to which the user should be sent to * in order to continue the login process with Facebook. The @@ -160,7 +192,6 @@ public function detectPseudoRandomStringGenerator() * @param string $redirectUrl The URL Facebook should redirect users to * after login. * @param array $scope List of permissions to request during login. - * @param boolean $rerequest Toggle for this authentication to be a rerequest. * @param string $version Optional Graph API version if not default (v2.0). * @param string $separator The separator to use in http_build_query(). * @@ -168,30 +199,15 @@ public function detectPseudoRandomStringGenerator() */ public function getLoginUrl($redirectUrl, array $scope = [], - $rerequest = false, $version = null, $separator = '&') { - $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; - - $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); - $this->persistentDataHandler->set('state', $state); - $params = [ - 'client_id' => $this->app->getId(), - 'redirect_uri' => $redirectUrl, - 'state' => $state, - 'response_type' => 'code', - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'scope' => implode(',', $scope) + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) ]; - if ($rerequest) { - $params['auth_type'] = 'rerequest'; - } - - return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . - http_build_query($params, null, $separator); + return $this->makeUrl($params, $version, $separator); } /** @@ -213,6 +229,66 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, $separator); } + /** + * Stores CSRF state and returns a URL to which the user should be sent to + * in order to continue the login process with Facebook. The + * provided redirectUrl should invoke the handleRedirect method. + * If a previous request to certain permission(s) was declined + * by the user, rerequest should be set to true or the permission(s) + * will not 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 $version Optional Graph API version if not default (v2.0). + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getReRequestUrl($redirectUrl, + array $scope = [], + $version = null, + $separator = '&') + { + $params = [ + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope), + 'auth_type' => 'rerequest' + ]; + + return $this->makeUrl($params, $version, $separator); + } + + /** + * Stores CSRF state and returns a URL to which the user should be sent to + * in order to continue the login process with Facebook. The + * provided redirectUrl should invoke the handleRedirect method. + * If a previous request to certain permission(s) was declined + * by the user, rerequest should be set to true or the permission(s) + * will not 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 $version Optional Graph API version if not default (v2.0). + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getReAuthenticationUrl($redirectUrl, + array $scope = [], + $version = null, + $separator = '&') + { + $params = [ + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope), + 'auth_type' => 'reauthenticate' + ]; + + return $this->makeUrl($params, $version, $separator); + } + /** * Takes a valid code from a login redirect, and returns an AccessToken entity. * From 4f63cca1eec0a9ebed4d7a103c736d9a12d53bfe Mon Sep 17 00:00:00 2001 From: Hardik Bhadani Date: Wed, 24 Dec 2014 00:22:58 +0530 Subject: [PATCH 086/407] update description and refactor code --- .../Helpers/FacebookRedirectLoginHelper.php | 53 ++++++------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 304b29db2..8b4614d56 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -153,17 +153,17 @@ public function detectPseudoRandomStringGenerator() * Stores CSRF state and returns a URL to which the user should be sent to * in order to continue the login process with Facebook. The * provided redirectUrl should invoke the handleRedirect method. - * If a previous request to certain permission(s) was declined - * by the user, rerequest should be set to true or the permission(s) - * will not be re-asked. * - * @param array $params Array of parameters to generate Url + * @param string $redirectUrl The URL Facebook should redirect users to + * after login. + * @param array $scope List of permissions to request during login. * @param string $version Optional Graph API version if not default (v2.0). * @param string $separator The separator to use in http_build_query(). + * @param array $params Array of parameters to generate URL. * * @return string */ - private function makeUrl(array $params, $version, $separator) + private function makeUrl($redirectUrl, array $scope, $version, $separator, array $params = []) { $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; @@ -175,6 +175,8 @@ private function makeUrl(array $params, $version, $separator) 'state' => $state, 'response_type' => 'code', 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) ]; return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . @@ -182,12 +184,7 @@ private function makeUrl(array $params, $version, $separator) } /** - * Stores CSRF state and returns a URL to which the user should be sent to - * in order to continue the login process with Facebook. The - * provided redirectUrl should invoke the handleRedirect method. - * If a previous request to certain permission(s) was declined - * by the user, rerequest should be set to true or the permission(s) - * will not be re-asked. + * 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. @@ -202,12 +199,7 @@ public function getLoginUrl($redirectUrl, $version = null, $separator = '&') { - $params = [ - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope) - ]; - - return $this->makeUrl($params, $version, $separator); + return $this->makeUrl($redirectUrl, $scope, $version, $separator); } /** @@ -230,12 +222,8 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') } /** - * Stores CSRF state and returns a URL to which the user should be sent to - * in order to continue the login process with Facebook. The - * provided redirectUrl should invoke the handleRedirect method. - * If a previous request to certain permission(s) was declined - * by the user, rerequest should be set to true or the permission(s) - * will not be re-asked. + * 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. @@ -251,21 +239,15 @@ public function getReRequestUrl($redirectUrl, $separator = '&') { $params = [ - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope), 'auth_type' => 'rerequest' ]; - return $this->makeUrl($params, $version, $separator); + return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); } /** - * Stores CSRF state and returns a URL to which the user should be sent to - * in order to continue the login process with Facebook. The - * provided redirectUrl should invoke the handleRedirect method. - * If a previous request to certain permission(s) was declined - * by the user, rerequest should be set to true or the permission(s) - * will not be re-asked. + * 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. @@ -281,14 +263,13 @@ public function getReAuthenticationUrl($redirectUrl, $separator = '&') { $params = [ - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope), 'auth_type' => 'reauthenticate' ]; - return $this->makeUrl($params, $version, $separator); + return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); + } - + /** * Takes a valid code from a login redirect, and returns an AccessToken entity. * From 30ff06d7ec01648dbdce005bcfd6d72d6e331186 Mon Sep 17 00:00:00 2001 From: Hardik Bhadani Date: Wed, 24 Dec 2014 14:45:28 +0530 Subject: [PATCH 087/407] fix 2 space indentation --- .../Helpers/FacebookRedirectLoginHelper.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 8b4614d56..64fe31da7 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -171,12 +171,12 @@ private function makeUrl($redirectUrl, array $scope, $version, $separator, arra $this->persistentDataHandler->set('state', $state); $params += [ - 'client_id' => $this->app->getId(), - 'state' => $state, - 'response_type' => 'code', - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope) + 'client_id' => $this->app->getId(), + 'state' => $state, + 'response_type' => 'code', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) ]; return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . @@ -239,9 +239,8 @@ public function getReRequestUrl($redirectUrl, $separator = '&') { $params = [ - 'auth_type' => 'rerequest' + 'auth_type' => 'rerequest' ]; - return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); } @@ -263,9 +262,8 @@ public function getReAuthenticationUrl($redirectUrl, $separator = '&') { $params = [ - 'auth_type' => 'reauthenticate' + 'auth_type' => 'reauthenticate' ]; - return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); } From fec115db8772df86580639527045407473a5bf9a Mon Sep 17 00:00:00 2001 From: Hardik Bhadani Date: Wed, 24 Dec 2014 15:08:17 +0530 Subject: [PATCH 088/407] small fix --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 64fe31da7..3ac963311 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -180,7 +180,7 @@ private function makeUrl($redirectUrl, array $scope, $version, $separator, arra ]; return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . - http_build_query($params, null, $separator); + http_build_query($params, null, $separator); } /** @@ -265,7 +265,6 @@ public function getReAuthenticationUrl($redirectUrl, 'auth_type' => 'reauthenticate' ]; return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); - } /** From 5f9bd5be0908bd2134311f1290ff42ca7891289d Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Wed, 31 Dec 2014 20:59:37 +0100 Subject: [PATCH 089/407] Fix auth Exception --- docs/FacebookResponseException.fbmd | 4 +-- docs/sdk_reference.fbmd | 10 +++--- ...hp => FacebookAuthenticationException.php} | 4 +-- .../Exceptions/FacebookResponseException.php | 10 +++--- .../FacebookResponseExceptionTest.php | 32 +++++++++---------- 5 files changed, 30 insertions(+), 30 deletions(-) rename src/Facebook/Exceptions/{FacebookPermissionException.php => FacebookAuthenticationException.php} (91%) diff --git a/docs/FacebookResponseException.fbmd b/docs/FacebookResponseException.fbmd index 43e535e26..c3fc98b56 100644 --- a/docs/FacebookResponseException.fbmd +++ b/docs/FacebookResponseException.fbmd @@ -9,9 +9,9 @@ Represents an exception thrown by executing a Facebook request. This base class has several subclasses: -`FacebookAuthorizationException` +`FacebookAuthenticationException` `FacebookClientException` -`FacebookPermissionException` +`FacebookAuthorizationException` `FacebookServerException` `FacebookThrottleException` `FacebookOtherException` diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index d446a5b22..624e1cebc 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -72,9 +72,13 @@ When an error occurs, the SDK will throw an exception. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ + [ + '`[Facebook\Exceptions\FacebookAuthenticationException](/docs/php/FacebookAuthenticationException)`', + 'Thrown when Graph returns an authentication error.', + ], [ '`[Facebook\Exceptions\FacebookAuthorizationException](/docs/php/FacebookAuthorizationException)`', - 'Thrown when Graph returns an authorization error.', + 'Thrown when Graph returns a user permissions error.', ], [ '`[Facebook\Exceptions\FacebookClientException](/docs/php/FacebookClientException)`', @@ -84,10 +88,6 @@ FB(devsite:markdown-wiki:table { '`[Facebook\Exceptions\FacebookOtherException](/docs/php/FacebookOtherException)`', 'Thrown when Graph returns an error that is unknown to the SDK.', ], - [ - '`[Facebook\Exceptions\FacebookPermissionException](/docs/php/FacebookPermissionException)`', - 'Thrown when Graph returns a user permissions error.', - ], [ '`[Facebook\Exceptions\FacebookResponseException](/docs/php/FacebookResponseException)`', 'The base exception to all Graph error responses. This exception is never thrown directly.', diff --git a/src/Facebook/Exceptions/FacebookPermissionException.php b/src/Facebook/Exceptions/FacebookAuthenticationException.php similarity index 91% rename from src/Facebook/Exceptions/FacebookPermissionException.php rename to src/Facebook/Exceptions/FacebookAuthenticationException.php index 3d9c175a3..13578f0de 100644 --- a/src/Facebook/Exceptions/FacebookPermissionException.php +++ b/src/Facebook/Exceptions/FacebookAuthenticationException.php @@ -24,10 +24,10 @@ namespace Facebook\Exceptions; /** - * Class FacebookPermissionException + * Class FacebookAuthenticationException * @package Facebook */ -class FacebookPermissionException extends FacebookSDKException +class FacebookAuthenticationException extends FacebookSDKException { } \ No newline at end of file diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index bc6e2a507..17ff74243 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -89,7 +89,7 @@ public static function create(FacebookResponse $response) case 463: case 464: case 467: - return new static($response, new FacebookAuthorizationException($message, $code)); + return new static($response, new FacebookAuthenticationException($message, $code)); break; } } @@ -99,7 +99,7 @@ public static function create(FacebookResponse $response) case 100: case 102: case 190: - return new static($response, new FacebookAuthorizationException($message, $code)); + return new static($response, new FacebookAuthenticationException($message, $code)); break; // Server issue, possible downtime @@ -123,13 +123,13 @@ public static function create(FacebookResponse $response) // Missing Permissions if ($code == 10 || ($code >= 200 && $code <= 299)) { - return new static($response, new FacebookPermissionException($message, $code)); + return new static($response, new FacebookAuthorizationException($message, $code)); } // OAuth authentication error if (isset($data['error']['type']) - and $data['error']['type'] === 'OAuthException') { - return new static($response, new FacebookAuthorizationException($message, $code)); + && $data['error']['type'] === 'OAuthException') { + return new static($response, new FacebookAuthenticationException($message, $code)); } // All others diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 15691a0e3..1947733b1 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -41,7 +41,7 @@ public function setUp() $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); } - public function testAuthorizationExceptions() + public function testAuthenticationExceptions() { $params = [ 'error' => [ @@ -54,7 +54,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('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); $this->assertEquals(100, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -65,13 +65,13 @@ public function testAuthorizationExceptions() $params['error']['code'] = 102; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $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\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); $this->assertEquals(190, $exception->getCode()); $params['error']['type'] = 'OAuthException'; @@ -79,31 +79,31 @@ public function testAuthorizationExceptions() $params['error']['error_subcode'] = 458; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $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\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $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\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $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\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $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\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); $this->assertEquals(0, $exception->getSubErrorCode()); } @@ -180,7 +180,7 @@ public function testUserIssueExceptions() ]; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); $this->assertEquals(230, $exception->getCode()); $this->assertEquals(459, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -191,11 +191,11 @@ 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\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); $this->assertEquals(464, $exception->getSubErrorCode()); } - public function testPermissionExceptions() + public function testAuthorizationExceptions() { $params = [ 'error' => [ @@ -207,7 +207,7 @@ public function testPermissionExceptions() ]; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(10, $exception->getCode()); $this->assertEquals(0, $exception->getSubErrorCode()); $this->assertEquals('exception', $exception->getErrorType()); @@ -218,19 +218,19 @@ public function testPermissionExceptions() $params['error']['code'] = 200; $response = new FacebookResponse($this->request, json_encode($params), 401); $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookPermissionException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $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\FacebookPermissionException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $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\FacebookPermissionException', $exception->getPrevious()); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); $this->assertEquals(299, $exception->getCode()); } From 1e1d079bf3c9f3eea9d23390f728e413d6c97eb5 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 13:23:30 -0600 Subject: [PATCH 090/407] remove occurences of "use \Facebook" --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 4 ++-- tests/FacebookBatchRequestTest.php | 6 +++--- tests/FacebookClientTest.php | 6 +++--- tests/FacebookRequestTest.php | 4 ++-- tests/FacebookTest.php | 6 +++--- tests/Helpers/FacebookRedirectLoginHelperTest.php | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 3ac963311..e5440e841 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -24,8 +24,8 @@ namespace Facebook\Helpers; use Facebook\Facebook; -use \Facebook\AccessToken; -use \Facebook\FacebookApp; +use Facebook\AccessToken; +use Facebook\FacebookApp; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\Url\FacebookUrlManipulator; diff --git a/tests/FacebookBatchRequestTest.php b/tests/FacebookBatchRequestTest.php index fced05c11..cffbd6eba 100755 --- a/tests/FacebookBatchRequestTest.php +++ b/tests/FacebookBatchRequestTest.php @@ -24,9 +24,9 @@ namespace Facebook\Tests; use Facebook\Facebook; -use \Facebook\FacebookApp; -use \Facebook\FacebookRequest; -use \Facebook\FacebookBatchRequest; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookBatchRequest; use Facebook\FileUpload\FacebookFile; class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index d7d1a45a3..e31819719 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -25,9 +25,9 @@ use Facebook\Exceptions\FacebookSDKException; use Facebook\Facebook; -use \Facebook\FacebookApp; -use \Facebook\FacebookRequest; -use \Facebook\FacebookBatchRequest; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; +use Facebook\FacebookBatchRequest; use Facebook\FacebookClient; use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; diff --git a/tests/FacebookRequestTest.php b/tests/FacebookRequestTest.php index 3aea64f6e..39ccd521a 100755 --- a/tests/FacebookRequestTest.php +++ b/tests/FacebookRequestTest.php @@ -24,8 +24,8 @@ namespace Facebook\Tests; use Facebook\Facebook; -use \Facebook\FacebookApp; -use \Facebook\FacebookRequest; +use Facebook\FacebookApp; +use Facebook\FacebookRequest; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 6e392be9a..ea6e05cda 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -30,8 +30,8 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; -use \Facebook\FacebookRequest; -use \Facebook\AccessToken; +use Facebook\FacebookRequest; +use Facebook\AccessToken; use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface @@ -249,7 +249,7 @@ public function testUrandomCsprgCanBeForced() '/dev/urandom not found or is not readable.' ); } - + $config = array_merge($this->config, [ 'persistent_data_handler' => 'memory', // To keep session errors from happening 'pseudo_random_string_generator' => 'urandom' diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 3780409f4..04864341b 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -25,7 +25,7 @@ use Mockery as m; use Facebook\Facebook; -use \Facebook\FacebookApp; +use Facebook\FacebookApp; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; @@ -124,7 +124,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $this->assertInstanceOf('Facebook\AccessToken', $accessToken); $this->assertEquals('access_token_from_code', (string) $accessToken); } - + public function testACustomCsprsgCanBeInjected() { $app = new FacebookApp('123', 'foo_app_secret'); From 61e3dba6a3aae5638883dec77cf8dd493d9d4fb9 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 13:41:06 -0600 Subject: [PATCH 091/407] remove references to "\\" --- src/Facebook/GraphNodes/GraphAlbum.php | 4 ++-- src/Facebook/GraphNodes/GraphObjectFactory.php | 2 +- src/Facebook/GraphNodes/GraphPage.php | 6 +++--- src/Facebook/GraphNodes/GraphUser.php | 10 +++++----- src/Facebook/autoload.php | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index 4b7db406d..0e9421676 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -35,8 +35,8 @@ class GraphAlbum extends GraphObject * @var array Maps object key names to Graph object types. */ protected static $graphObjectMap = [ - 'from' => '\\Facebook\\GraphNodes\\GraphUser', - 'place' => '\\Facebook\\GraphNodes\\GraphPage', + 'from' => '\Facebook\GraphNodes\GraphUser', + 'place' => '\Facebook\GraphNodes\GraphPage', ]; /** diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 53c5bf879..4b78d0ba0 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -306,7 +306,7 @@ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKe // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; - + return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); } diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index e88ed2d34..8950128fb 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -34,9 +34,9 @@ class GraphPage extends GraphObject * @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', + 'best_page' => '\Facebook\GraphNodes\GraphPage', + 'global_brand_parent_page' => '\Facebook\GraphNodes\GraphPage', + 'location' => '\Facebook\GraphNodes\GraphLocation', ]; /** diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 036cf7614..1e25d4bb7 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -36,10 +36,10 @@ class GraphUser extends GraphObject * @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', + 'hometown' => '\Facebook\GraphNodes\GraphPage', + 'location' => '\Facebook\GraphNodes\GraphPage', + 'significant_other' => '\Facebook\GraphNodes\GraphUser', + 'picture' => '\Facebook\GraphNodes\GraphPicture', ]; /** @@ -91,7 +91,7 @@ public function getLastName() { return $this->getProperty('last_name'); } - + /** * Returns the gender for the user as a string if present. * diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index f620fd13d..503e5ce94 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -43,7 +43,7 @@ spl_autoload_register(function ($class) { // project-specific namespace prefix - $prefix = 'Facebook\\'; + $prefix = '\Facebook\\'; // base directory for the namespace prefix $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/'; @@ -67,4 +67,4 @@ if (file_exists($file)) { require $file; } -}); \ No newline at end of file +}); From 0fe4a4d18295f7c41457f3352b2c70c23f8bb0be Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 13:45:37 -0600 Subject: [PATCH 092/407] removing references to @author per @SammyK --- src/Facebook/Exceptions/FacebookResponseException.php | 2 -- src/Facebook/GraphNodes/GraphLocation.php | 4 +--- src/Facebook/GraphNodes/GraphObject.php | 2 -- src/Facebook/GraphNodes/GraphSessionInfo.php | 2 -- src/Facebook/GraphNodes/GraphUser.php | 2 -- src/Facebook/Helpers/FacebookCanvasHelper.php | 2 -- src/Facebook/Helpers/FacebookJavaScriptHelper.php | 2 -- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 -- 8 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 17ff74243..a22f0d453 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -28,8 +28,6 @@ /** * Class FacebookResponseException * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class FacebookResponseException extends FacebookSDKException { diff --git a/src/Facebook/GraphNodes/GraphLocation.php b/src/Facebook/GraphNodes/GraphLocation.php index aa72be325..feff80f48 100644 --- a/src/Facebook/GraphNodes/GraphLocation.php +++ b/src/Facebook/GraphNodes/GraphLocation.php @@ -26,8 +26,6 @@ /** * Class GraphLocation * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class GraphLocation extends GraphObject { @@ -102,4 +100,4 @@ public function getLongitude() return $this->getProperty('longitude'); } -} \ No newline at end of file +} diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index 63292b5fc..04bbe537b 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -26,8 +26,6 @@ /** * Class GraphObject * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class GraphObject extends Collection { diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index 094497ff7..86cf648cf 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -26,8 +26,6 @@ /** * Class GraphSessionInfo * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class GraphSessionInfo extends GraphObject { diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 1e25d4bb7..167af81bd 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -26,8 +26,6 @@ /** * Class GraphUser * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class GraphUser extends GraphObject { diff --git a/src/Facebook/Helpers/FacebookCanvasHelper.php b/src/Facebook/Helpers/FacebookCanvasHelper.php index 72cc33580..b3a8ee16f 100644 --- a/src/Facebook/Helpers/FacebookCanvasHelper.php +++ b/src/Facebook/Helpers/FacebookCanvasHelper.php @@ -26,8 +26,6 @@ /** * Class FacebookCanvasLoginHelper * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class FacebookCanvasHelper extends FacebookSignedRequestFromInputHelper { diff --git a/src/Facebook/Helpers/FacebookJavaScriptHelper.php b/src/Facebook/Helpers/FacebookJavaScriptHelper.php index 042fb2ad9..bd8d077b8 100644 --- a/src/Facebook/Helpers/FacebookJavaScriptHelper.php +++ b/src/Facebook/Helpers/FacebookJavaScriptHelper.php @@ -26,8 +26,6 @@ /** * Class FacebookJavaScriptLoginHelper * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class FacebookJavaScriptHelper extends FacebookSignedRequestFromInputHelper { diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index e5440e841..a3eecc12e 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -41,8 +41,6 @@ /** * Class FacebookRedirectLoginHelper * @package Facebook - * @author Fosco Marotto - * @author David Poll */ class FacebookRedirectLoginHelper { From 4fe77141e2565db1dfb71a9f0ee3154ba60e6713 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 13:51:23 -0600 Subject: [PATCH 093/407] removing deprecated method --- src/Facebook/Helpers/FacebookPageTabHelper.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 5a7eb1c75..36d80d52e 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -70,19 +70,6 @@ public function getPageData($key, $default = null) return $default; } - /** - * @TODO Deprecated: Remove after November 5, 2014 - * @see https://developers.facebook.com/blog/post/2014/08/07/Graph-API-v2.1/ - * - * Returns true if the page is liked by the user. - * - * @return boolean - */ - public function isLiked() - { - return $this->getPageData('liked') === true; - } - /** * Returns true if the user is an admin. * From 3c557801758be8dbc6485fd28d261909f5fbb6f1 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 13:54:44 -0600 Subject: [PATCH 094/407] removing unused method per @SammyK --- .../FacebookSignedRequestFromInputHelper.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index ac95d693b..ac018733a 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -131,20 +131,6 @@ public function getUserId() */ abstract public function getRawSignedRequest(); - /** - * Get raw signed request from GET input. - * - * @return string|null - */ - public function getRawSignedRequestFromGet() - { - if (isset($_GET['signed_request'])) { - return $_GET['signed_request']; - } - - return null; - } - /** * Get raw signed request from POST input. * From 5a278676b19d807b723ee4ce14d21dbba27750a1 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 13:56:04 -0600 Subject: [PATCH 095/407] remove state dingleberries per @SammyK --- .../Helpers/FacebookSignedRequestFromInputHelper.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index ac018733a..bf627532b 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -45,11 +45,6 @@ abstract class FacebookSignedRequestFromInputHelper */ protected $app; - /** - * @var string|null Random string to prevent CSRF. - */ - public $state; - /** * Initialize the helper and process available signed request data. * @@ -75,7 +70,7 @@ public function instantiateSignedRequest($rawSignedRequest = null) return; } - $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest, $this->state); + $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest); } /** From 78a3ac481882b862e87ede98db1075c498537a42 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 16:16:42 -0600 Subject: [PATCH 096/407] adding AchievementNode and stub for ApplicationNode --- src/Facebook/GraphNodes/GraphAchievement.php | 114 +++++++++++++++++ src/Facebook/GraphNodes/GraphApplication.php | 42 +++++++ src/Facebook/GraphNodes/GraphObject.php | 1 + .../GraphNodes/GraphObjectFactory.php | 14 ++- tests/GraphNodes/GraphAchievementTest.php | 117 ++++++++++++++++++ tests/GraphNodes/GraphNodeTest.php | 50 ++++++++ 6 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 src/Facebook/GraphNodes/GraphAchievement.php create mode 100644 src/Facebook/GraphNodes/GraphApplication.php create mode 100644 tests/GraphNodes/GraphAchievementTest.php create mode 100644 tests/GraphNodes/GraphNodeTest.php diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php new file mode 100644 index 000000000..037ea4884 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -0,0 +1,114 @@ + '\Facebook\GraphNodes\GraphUser', + 'application' => '\Facebook\GraphNodes\GraphApplication', + ]; + + /** + * Returns the ID for the achievement. + * + * @return string|null + */ + public function getId() + { + return $this->getProperty('id'); + } + + /** + * Returns the user who achieved this. + * + * @return string|null + */ + public function getFrom() + { + return $this->getProperty('from'); + } + + /** + * Returns the time at which this was achieved. + * + * @return string|null + */ + public function getPublishTime() + { + return $this->getProperty('publish_time'); + } + + /** + * Returns the app in which the user achieved this. + * + * @return string|null + */ + public function getApplication() + { + return $this->getProperty('application'); + } + + /** + * Returns information about the achievement type this instance is + * connected with. + * + * @return string|null + */ + public function getData() + { + return $this->getProperty('data'); + } + + /** + * Returns the type of achievement. + * + * @see https://developers.facebook.com/docs/graph-api/reference/v2.2/achievement + * + * @return string + */ + public function getType() + { + return 'game.achievement'; + } + + /** + * Indicates whether gaining the achievement published a feed story for + * the user. + * + * @return boolean + */ + public function isNoFeedStory() + { + return (bool) $this->getProperty('no_feed_story'); + } +} diff --git a/src/Facebook/GraphNodes/GraphApplication.php b/src/Facebook/GraphNodes/GraphApplication.php new file mode 100644 index 000000000..b2c3e79ae --- /dev/null +++ b/src/Facebook/GraphNodes/GraphApplication.php @@ -0,0 +1,42 @@ +getProperty('id'); + } +} diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index 63292b5fc..c0e618529 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -152,6 +152,7 @@ public function shouldCastAsDateTime($key) 'issued_at', 'expires_at', 'birthday', + 'publish_time' ], true); } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 53c5bf879..6e534cd14 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -91,6 +91,18 @@ public function makeGraphObject($subclassName = null) return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } + /** + * Convenience method for creating a GraphAchievement collection. + * + * @return GraphAchievement + * + * @throws FacebookSDKException + */ + public function makeGraphAchievement() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); + } + /** * Convenience method for creating a GraphAlbum collection. * @@ -306,7 +318,7 @@ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKe // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; - + return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); } diff --git a/tests/GraphNodes/GraphAchievementTest.php b/tests/GraphNodes/GraphAchievementTest.php new file mode 100644 index 000000000..14e6015e2 --- /dev/null +++ b/tests/GraphNodes/GraphAchievementTest.php @@ -0,0 +1,117 @@ + '1337' + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphObject = $factory->makeGraphAchievement(); + + $id = $graphObject->getId(); + + $this->assertEquals($dataFromGraph['id'], $id); + } + + public function testTypeIsAlwaysString() + { + $dataFromGraph = [ + 'id' => '1337' + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphObject = $factory->makeGraphAchievement(); + + $type = $graphObject->getType(); + + $this->assertEquals('game.achievement', $type); + } + + public function testNoFeedStoryIsBoolean() + { + $dataFromGraph = [ + 'no_feed_story' => (rand(0,1) == 1) + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphObject = $factory->makeGraphAchievement(); + + $isNoFeedStory = $graphObject->isNoFeedStory(); + + $this->assertTrue(is_bool($isNoFeedStory)); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'publish_time' => '2014-07-15T03:54:34+0000' + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphObject = $factory->makeGraphAchievement(); + + $publishTime = $graphObject->getPublishTime(); + + $this->assertInstanceOf('DateTime', $publishTime); + } + + public function testFromGetsCastAsGraphUser() + { + $dataFromGraph = [ + 'from' => [ + 'id' => '1337', + 'name' => 'Foo McBar' + ] + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphObject = $factory->makeGraphAchievement(); + + $from = $graphObject->getFrom(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphUser', $from); + } + + public function testApplicationGetsCastAsGraphApplication() + { + $dataFromGraph = [ + 'application' => [ + 'id' => '1337' + ] + ]; + + $factory = $this->makeFactoryWithData($dataFromGraph); + $graphObject = $factory->makeGraphAchievement(); + + $app = $graphObject->getApplication(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphApplication', $app); + } +} diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php new file mode 100644 index 000000000..3088c2862 --- /dev/null +++ b/tests/GraphNodes/GraphNodeTest.php @@ -0,0 +1,50 @@ +responseMock = m::mock('\Facebook\FacebookResponse'); + } + + protected function makeFactoryWithData($data) + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($data); + return new GraphObjectFactory($this->responseMock); + } +} From 0bb6b4bcc1ae3a4dc32c409a1655728828dd43e5 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Wed, 28 Jan 2015 16:44:15 -0600 Subject: [PATCH 097/407] cleaning up documentation. testing the filters :) --- src/Facebook/GraphNodes/GraphAchievement.php | 12 ++++++------ tests/GraphNodes/GraphNodeTest.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php index 037ea4884..2bc3afb73 100644 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -51,7 +51,7 @@ public function getId() /** * Returns the user who achieved this. * - * @return string|null + * @return GraphUser|null */ public function getFrom() { @@ -61,7 +61,7 @@ public function getFrom() /** * Returns the time at which this was achieved. * - * @return string|null + * @return \DateTime|null */ public function getPublishTime() { @@ -71,7 +71,7 @@ public function getPublishTime() /** * Returns the app in which the user achieved this. * - * @return string|null + * @return GraphApplication|null */ public function getApplication() { @@ -82,7 +82,7 @@ public function getApplication() * Returns information about the achievement type this instance is * connected with. * - * @return string|null + * @return array|null */ public function getData() { @@ -105,10 +105,10 @@ public function getType() * Indicates whether gaining the achievement published a feed story for * the user. * - * @return boolean + * @return boolean|null */ public function isNoFeedStory() { - return (bool) $this->getProperty('no_feed_story'); + return $this->getProperty('no_feed_story'); } } diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php index 3088c2862..a0ab7a707 100644 --- a/tests/GraphNodes/GraphNodeTest.php +++ b/tests/GraphNodes/GraphNodeTest.php @@ -29,7 +29,7 @@ abstract class GraphNodeTest extends \PHPUnit_Framework_TestCase { /** - * @var \Facebook\FacebookResponse + * @var \Facebook\FacebookResponse|\Mockery\MockInterface */ protected $responseMock; From f662db5a95c30a919aeb63e363fc79d6de87a189 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 27 Jan 2015 11:29:40 -0600 Subject: [PATCH 098/407] Refactored OAuth 2.0 functionality --- src/Facebook/AccessToken.php | 433 ------------------ src/Facebook/Authentication/AccessToken.php | 161 +++++++ .../Authentication/AccessTokenMetadata.php | 374 +++++++++++++++ src/Facebook/Authentication/OAuth2Client.php | 300 ++++++++++++ src/Facebook/Facebook.php | 31 +- src/Facebook/FacebookApp.php | 2 + src/Facebook/FacebookRequest.php | 4 +- .../Helpers/FacebookPageTabHelper.php | 9 +- .../Helpers/FacebookRedirectLoginHelper.php | 80 ++-- .../FacebookSignedRequestFromInputHelper.php | 25 +- tests/AccessTokenTest.php | 239 ---------- tests/Authentication/AccessTokenMetadata.php | 139 ++++++ tests/Authentication/AccessTokenTest.php | 112 +++++ tests/Authentication/OAuth2ClientTest.php | 198 ++++++++ tests/FacebookAppTest.php | 2 +- tests/FacebookTest.php | 8 +- tests/Helpers/FacebookCanvasHelperTest.php | 3 +- .../Helpers/FacebookJavaScriptHelperTest.php | 3 +- tests/Helpers/FacebookPageTabHelperTest.php | 3 +- .../FacebookRedirectLoginHelperTest.php | 61 ++- ...cebookSignedRequestFromInputHelperTest.php | 57 +-- 21 files changed, 1431 insertions(+), 813 deletions(-) delete mode 100644 src/Facebook/AccessToken.php create mode 100644 src/Facebook/Authentication/AccessToken.php create mode 100644 src/Facebook/Authentication/AccessTokenMetadata.php create mode 100644 src/Facebook/Authentication/OAuth2Client.php delete mode 100644 tests/AccessTokenTest.php create mode 100644 tests/Authentication/AccessTokenMetadata.php create mode 100644 tests/Authentication/AccessTokenTest.php create mode 100644 tests/Authentication/OAuth2ClientTest.php diff --git a/src/Facebook/AccessToken.php b/src/Facebook/AccessToken.php deleted file mode 100644 index 9b6937ff9..000000000 --- a/src/Facebook/AccessToken.php +++ /dev/null @@ -1,433 +0,0 @@ -accessToken = $accessToken; - if ($expiresAt) { - $this->setExpiresAtFromTimeStamp($expiresAt); - } - $this->machineId = $machineId; - } - - /** - * Generate an app secret proof to sign a request to Graph. - * - * @param string $appSecret The app secret. - * - * @return string - */ - public function getAppSecretProof($appSecret) - { - return hash_hmac('sha256', $this->accessToken, $appSecret); - } - - /** - * Setter for expires_at. - * - * @param int $timeStamp - */ - protected function setExpiresAtFromTimeStamp($timeStamp) - { - $dt = new \DateTime(); - $dt->setTimestamp($timeStamp); - $this->expiresAt = $dt; - } - - /** - * Getter for expiresAt. - * - * @return \DateTime|null - */ - public function getExpiresAt() - { - return $this->expiresAt; - } - - /** - * Getter for machineId. - * - * @return string|null - */ - public function getMachineId() - { - return $this->machineId; - } - - /** - * Determines whether or not this is a long-lived token. - * - * @return bool - */ - public function isLongLived() - { - if ($this->expiresAt) { - return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); - } - return false; - } - - /** - * Checks the expiration of the access token. - * - * @return boolean|null - */ - public function isExpired() - { - if ($this->getExpiresAt() instanceof \DateTime) { - return $this->getExpiresAt()->getTimestamp() < time(); - } - - // Not all access tokens return an expiration. E.g. an app access token. - return false; - } - - /** - * Checks the validity of the access token. - * - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * @param string|null $machineId Unique client identifier. - * - * @return boolean - */ - public function isValid(FacebookApp $app, FacebookClient $client, $machineId = null) - { - $accessTokenInfo = $this->getInfo($app, $client); - $machineId = $machineId ?: $this->machineId; - return static::validateAccessToken($accessTokenInfo, $app, $machineId); - } - - /** - * Ensures the provided GraphSessionInfo object is valid, - * throwing an exception if not. Ensures the appId matches, - * that the machineId matches if it's being used, - * that the token is valid and has not expired. - * - * @param GraphSessionInfo $tokenInfo - * @param FacebookApp $app The FacebookApp entity. - * @param string|null $machineId - * - * @return boolean - */ - public static function validateAccessToken(GraphSessionInfo $tokenInfo, - FacebookApp $app, - $machineId = null) - { - $appIdIsValid = $tokenInfo->getProperty('app_id') == $app->getId(); - $machineIdIsValid = $tokenInfo->getProperty('machine_id') == $machineId; - $accessTokenIsValid = $tokenInfo->getIsValid(); - - // Not all access tokens return an expiration. E.g. an app access token. - if ($tokenInfo->getExpiresAt() instanceof \DateTime) { - $accessTokenIsStillAlive = $tokenInfo->getExpiresAt()->getTimestamp() >= time(); - } else { - $accessTokenIsStillAlive = true; - } - - return $appIdIsValid && $machineIdIsValid && $accessTokenIsValid && $accessTokenIsStillAlive; - } - - /** - * Get a valid access token from a code. - * - * @param string $code - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * @param string|null $redirectUri - * @param string|null $machineId - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public static function getAccessTokenFromCode($code, - FacebookApp $app, - FacebookClient $client, - $redirectUri = '', - $machineId = null) - { - $params = [ - 'code' => $code, - 'redirect_uri' => $redirectUri, - ]; - - if ($machineId) { - $params['machine_id'] = $machineId; - } - - return static::requestAccessToken($params, $app, $client); - } - - /** - * Get a valid code from an access token. - * - * @param AccessToken|string $accessToken - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * @param string|null $redirectUri - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public static function getCodeFromAccessToken($accessToken, - FacebookApp $app, - FacebookClient $client, - $redirectUri = '') - { - $accessToken = (string) $accessToken; - - $params = [ - 'access_token' => $accessToken, - 'redirect_uri' => $redirectUri, - ]; - - return static::requestCode($params, $app, $client); - } - - /** - * Exchanges a short lived access token with a long lived access token. - * - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public function extend(FacebookApp $app, FacebookClient $client) - { - $params = [ - 'grant_type' => 'fb_exchange_token', - 'fb_exchange_token' => $this->accessToken, - ]; - - return static::requestAccessToken($params, $app, $client); - } - - /** - * Request an access token based on a set of params. - * - * @param array $params - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public static function requestAccessToken(array $params, FacebookApp $app, FacebookClient $client) - { - $response = static::request('/oauth/access_token', $params, $app, $client); - $data = $response->getDecodedBody(); - - if (!isset($data['access_token'])) { - throw new FacebookSDKException('Access token was not returned from Graph.', 401); - } - - // Graph returns two different key names for expiration time - // on the same endpoint. Doh! :/ - $expiresAt = 0; - if (isset($data['expires'])) { - // For exchanging a short lived token with a long lived token. - // The expiration time in seconds will be returned as "expires". - $expiresAt = time() + $data['expires']; - } elseif (isset($data['expires_in'])) { - // For exchanging a code for a short lived access token. - // The expiration time in seconds will be returned as "expires_in". - // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code - $expiresAt = time() + $data['expires_in']; - } - $machineId = isset($data['machine_id']) ? $data['machine_id'] : null; - return new static($data['access_token'], $expiresAt, $machineId); - } - - /** - * Request a code from a long lived access token. - * - * @param array $params - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * - * @return string - * - * @throws FacebookSDKException - */ - public static function requestCode(array $params, FacebookApp $app, FacebookClient $client) - { - $response = static::request('/oauth/client_code', $params, $app, $client); - $data = $response->getDecodedBody(); - - if (isset($data['code'])) { - return $data['code']; - } - - throw new FacebookSDKException('Code was not returned from Graph.', 401); - } - - /** - * Send a request to Graph with an app access token. - * - * @param string $endpoint - * @param array $params - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * - * @return FacebookResponse - * - * @throws FacebookResponseException - */ - protected static function request($endpoint, array $params, FacebookApp $app, FacebookClient $client) - { - if (!isset($params['client_id'])) { - $params['client_id'] = $app->getId(); - } - if (!isset($params['client_secret'])) { - $params['client_secret'] = $app->getSecret(); - } - - // The response for this endpoint is not JSON, so it must be handled - // differently, not as a GraphObject. - $request = new FacebookRequest( - $app, - $app->getAccessToken(), - 'GET', - $endpoint - ); - // We know what we're doing here. - // We want to send the access token as a param. - $request->dangerouslySetParams($params); - - return $client->sendRequest($request); - } - - /** - * Get more info about an access token. - * - * @param FacebookApp $app The FacebookApp entity. - * @param FacebookClient $client The Facebook client. - * - * @return GraphSessionInfo - */ - public function getInfo(FacebookApp $app, FacebookClient $client) - { - $params = ['input_token' => $this->accessToken]; - - $request = new FacebookRequest( - $app, - $app->getAccessToken(), - 'GET', - '/debug_token', - $params - ); - $response = $client->sendRequest($request); - $graphObject = $response->getGraphSessionInfo(); - - // Update the data on this token - if ($graphObject->getExpiresAt()) { - $this->expiresAt = $graphObject->getExpiresAt(); - } - - return $graphObject; - } - - /** - * Returns the access token as a string. - * - * @return string - */ - public function __toString() - { - return $this->accessToken; - } - - /** - * Serialize the entity. - * - * @return string - */ - public function serialize() - { - $expiresAt = null; - if ($this->expiresAt instanceof \DateTime) { - $expiresAt = $this->expiresAt->getTimestamp(); - } - - return serialize([$this->accessToken, $expiresAt, $this->machineId]); - } - - /** - * Unserialize the entity. - * - * @param string $serialized - */ - public function unserialize($serialized) - { - list($accessToken, $expiresAt, $machineId) = unserialize($serialized); - - $this->__construct($accessToken, $expiresAt, $machineId); - } - -} diff --git a/src/Facebook/Authentication/AccessToken.php b/src/Facebook/Authentication/AccessToken.php new file mode 100644 index 000000000..1fb039bc1 --- /dev/null +++ b/src/Facebook/Authentication/AccessToken.php @@ -0,0 +1,161 @@ +value = $accessToken; + if ($expiresAt) { + $this->setExpiresAtFromTimeStamp($expiresAt); + } + } + + /** + * Generate an app secret proof to sign a request to Graph. + * + * @param string $appSecret The app secret. + * + * @return string + */ + public function getAppSecretProof($appSecret) + { + return hash_hmac('sha256', $this->value, $appSecret); + } + + /** + * Getter for expiresAt. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->expiresAt; + } + + /** + * Determines whether or not this is an app access token. + * + * @return bool + */ + public function isAppAccessToken() + { + return strpos($this->value, '|') !== false; + } + + /** + * Determines whether or not this is a long-lived token. + * + * @return bool + */ + public function isLongLived() + { + if ($this->expiresAt) { + return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); + } + + if ($this->isAppAccessToken()) { + return true; + } + + return false; + } + + /** + * Checks the expiration of the access token. + * + * @return boolean|null + */ + public function isExpired() + { + if ($this->getExpiresAt() instanceof \DateTime) { + return $this->getExpiresAt()->getTimestamp() < time(); + } + + if ($this->isAppAccessToken()) { + return false; + } + + return null; + } + + /** + * Returns the access token as a string. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns the access token as a string. + * + * @return string + */ + public function __toString() + { + return $this->getValue(); + } + + /** + * Setter for expires_at. + * + * @param int $timeStamp + */ + protected function setExpiresAtFromTimeStamp($timeStamp) + { + $dt = new \DateTime(); + $dt->setTimestamp($timeStamp); + $this->expiresAt = $dt; + } + +} diff --git a/src/Facebook/Authentication/AccessTokenMetadata.php b/src/Facebook/Authentication/AccessTokenMetadata.php new file mode 100644 index 000000000..51657e933 --- /dev/null +++ b/src/Facebook/Authentication/AccessTokenMetadata.php @@ -0,0 +1,374 @@ +metadata = $metadata['data']; + + $this->castTimestampsToDateTime(); + } + + /** + * 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 + */ + public function getProperty($field, $default = null) + { + if (isset($this->metadata[$field])) { + return $this->metadata[$field]; + } + + return $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) + { + if ( ! isset($this->metadata[$parentField])) { + return $default; + } + + if ( ! isset($this->metadata[$parentField][$field])) { + return $default; + } + + return $this->metadata[$parentField][$field]; + } + + /** + * Returns a value from the error metadata. + * + * @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) + { + return $this->getChildProperty('error', $field, $default); + } + + /** + * Returns a value from the "metadata" metadata. *Brain explodes* + * + * @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) + { + return $this->getChildProperty('metadata', $field, $default); + } + + /** + * The ID of the application this access token is for. + * + * @return string|null + */ + public function getAppId() + { + return $this->getProperty('app_id'); + } + + /** + * Name of the application this access token is for. + * + * @return string|null + */ + public function getApplication() + { + return $this->getProperty('application'); + } + + /** + * Any error that a request to the graph api + * would return due to the access token. + * + * @return bool|null + */ + public function isError() + { + return $this->getProperty('error') !== null; + } + + /** + * The error code for the error. + * + * @return int|null + */ + public function getErrorCode() + { + return $this->getErrorProperty('code'); + } + + /** + * The error message for the error. + * + * @return string|null + */ + public function getErrorMessage() + { + return $this->getErrorProperty('message'); + } + + /** + * The error subcode for the error. + * + * @return int|null + */ + public function getErrorSubcode() + { + return $this->getErrorProperty('subcode'); + } + + /** + * DateTime when this access token expires. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->getProperty('expires_at'); + } + + /** + * Whether the access token is still valid or not. + * + * @return boolean|null + */ + public function getIsValid() + { + return $this->getProperty('is_valid'); + } + + /** + * DateTime when this access token was issued. + * + * Note that the issued_at field is not returned + * for short-lived access tokens. + * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug + * + * @return \DateTime|null + */ + public function getIssuedAt() + { + return $this->getProperty('issued_at'); + } + + /** + * General metadata associated with the access token. + * Can contain data like 'sso', 'auth_type', 'auth_nonce'. + * + * @return array|null + */ + public function getMetadata() + { + return $this->getProperty('metadata'); + } + + /** + * The 'sso' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getSso() + { + return $this->getMetadataProperty('sso'); + } + + /** + * The 'auth_type' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getAuthType() + { + return $this->getMetadataProperty('auth_type'); + } + + /** + * The 'auth_nonce' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getAuthNonce() + { + return $this->getMetadataProperty('auth_nonce'); + } + + /** + * For impersonated access tokens, the ID of + * the page this token contains. + * + * @return string|null + */ + public function getProfileId() + { + return $this->getProperty('profile_id'); + } + + /** + * List of permissions that the user has granted for + * the app in this access token. + * + * @return array + */ + public function getScopes() + { + return $this->getProperty('scopes'); + } + + /** + * The ID of the user this access token is for. + * + * @return string|null + */ + public function getUserId() + { + return $this->getProperty('user_id'); + } + + /** + * Ensures the app ID from the access token + * metadata is what we expect. + * + * @param string $appId + * + * @throws FacebookSDKException + */ + public function validateAppId($appId) + { + if ($this->getAppId() !== $appId) { + throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401); + } + } + + /** + * Ensures the user ID from the access token + * metadata is what we expect. + * + * @param string $userId + * + * @throws FacebookSDKException + */ + public function validateUserId($userId) + { + if ($this->getUserId() !== $userId) { + throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401); + } + } + + /** + * Ensures the access token has not expired yet. + * + * @throws FacebookSDKException + */ + public function validateExpiration() + { + if ( ! $this->getExpiresAt() instanceof \DateTime) { + return; + } + + if ($this->getExpiresAt()->getTimestamp() < time()) { + throw new FacebookSDKException('Inspection of access token metadata shows that the access token has expired.', 401); + } + } + + /** + * Converts a unix timestamp into a DateTime entity. + * + * @param int $timestamp + * + * @return \DateTime + */ + private function convertTimestampToDateTime($timestamp) + { + $dt = new \DateTime(); + $dt->setTimestamp($timestamp); + + return $dt; + } + + /** + * Casts the unix timestamps as DateTime entities. + */ + private function castTimestampsToDateTime() + { + foreach (static::$dateProperties as $key) { + if (isset($this->metadata[$key])) { + $this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]); + } + } + } + +} diff --git a/src/Facebook/Authentication/OAuth2Client.php b/src/Facebook/Authentication/OAuth2Client.php new file mode 100644 index 000000000..851184e76 --- /dev/null +++ b/src/Facebook/Authentication/OAuth2Client.php @@ -0,0 +1,300 @@ +app = $app; + $this->client = $client; + $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + } + + /** + * Returns the last FacebookRequest that was sent. + * Useful for debugging and testing. + * + * @return FacebookRequest|null + */ + public function getLastRequest() + { + return $this->lastRequest; + } + + /** + * Get the metadata associated with the access token. + * + * @param AccessToken|string $accessToken The access token to debug. + * + * @return AccessTokenMetadata + */ + public function debugToken($accessToken) + { + $accessToken = $accessToken instanceof AccessToken + ? $accessToken->getValue() + : $accessToken; + + $params = ['input_token' => $accessToken]; + + $this->lastRequest = new FacebookRequest( + $this->app, + $this->app->getAccessToken(), + 'GET', + '/debug_token', + $params, + null, + $this->graphVersion + ); + $response = $this->client->sendRequest($this->lastRequest); + $metadata = $response->getDecodedBody(); + + return new AccessTokenMetadata($metadata); + } + + /** + * Generates an authorization URL to begin the process of authenticating a user. + * + * @param string $redirectUrl The callback URL to redirect to. + * @param array $scope An array of permissions to request. + * @param string $state The CSPRNG-generated CSRF value. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getAuthorizationUrl($redirectUrl, array $scope = [], $state, array $params = [], $separator = '&') + { + $params += [ + 'client_id' => $this->app->getId(), + 'state' => $state, + 'response_type' => 'code', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) + ]; + + return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . + http_build_query($params, null, $separator); + } + + /** + * Get a valid access token from a code. + * + * @param string $code + * @param string $redirectUri + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getAccessTokenFromCode($code, $redirectUri = '') + { + $params = [ + 'code' => $code, + 'redirect_uri' => $redirectUri, + ]; + + return $this->requestAnAccessToken($params); + } + + /** + * Exchanges a short-lived access token with a long-lived access token. + * + * @param AccessToken|string $accessToken + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getLongLivedAccessToken($accessToken) + { + $accessToken = $accessToken instanceof AccessToken + ? $accessToken->getValue() + : $accessToken; + + $params = [ + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => $accessToken, + ]; + + return $this->requestAnAccessToken($params); + } + + /** + * Get a valid code from an access token. + * + * @param AccessToken|string $accessToken + * @param string $redirectUri + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') + { + $params = [ + 'redirect_uri' => $redirectUri, + ]; + + $response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken); + $data = $response->getDecodedBody(); + + if ( ! isset($data['code'])) { + throw new FacebookSDKException('Code was not returned from Graph.', 401); + } + + return $data['code']; + } + + /** + * Send a request to the OAuth endpoint. + * + * @param array $params + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + protected function requestAnAccessToken(array $params) + { + $response = $this->sendRequestWithClientParams('/oauth/access_token', $params); + $data = $response->getDecodedBody(); + + if ( ! isset($data['access_token'])) { + throw new FacebookSDKException('Access token was not returned from Graph.', 401); + } + + // Graph returns two different key names for expiration time + // on the same endpoint. Doh! :/ + $expiresAt = 0; + if (isset($data['expires'])) { + // For exchanging a short lived token with a long lived token. + // The expiration time in seconds will be returned as "expires". + $expiresAt = time() + $data['expires']; + } elseif (isset($data['expires_in'])) { + // For exchanging a code for a short lived access token. + // The expiration time in seconds will be returned as "expires_in". + // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code + $expiresAt = time() + $data['expires_in']; + } + + return new AccessToken($data['access_token'], $expiresAt); + } + + /** + * Send a request to Graph with an app access token. + * + * @param string $endpoint + * @param array $params + * @param string|null $accessToken + * + * @return FacebookResponse + * + * @throws FacebookResponseException + */ + protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null) + { + $params += $this->getClientParams(); + + $accessToken = $accessToken ?: $this->app->getAccessToken(); + + $this->lastRequest = new FacebookRequest( + $this->app, + $accessToken, + 'GET', + $endpoint, + $params, + null, + $this->graphVersion + ); + + return $this->client->sendRequest($this->lastRequest); + } + + /** + * Returns the client_* params for OAuth requests. + * + * @return array + */ + protected function getClientParams() + { + return [ + 'client_id' => $this->app->getId(), + 'client_secret' => $this->app->getSecret(), + ]; + } + +} diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 05ca95005..c9bc90529 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -23,6 +23,8 @@ */ namespace Facebook; +use Facebook\Authentication\AccessToken; +use Facebook\Authentication\OAuth2Client; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; use Facebook\GraphNodes\GraphList; @@ -84,6 +86,11 @@ class Facebook */ protected $client; + /** + * @var OAuth2Client The OAuth 2.0 client service. + */ + protected $oAuth2Client; + /** * @var UrlDetectionInterface|null The URL detection handler. */ @@ -236,6 +243,22 @@ public function getClient() return $this->client; } + /** + * Returns the OAuth 2.0 client service. + * + * @return OAuth2Client + */ + public function getOAuth2Client() + { + if ( ! $this->oAuth2Client instanceof OAuth2Client) { + $app = $this->getApp(); + $client = $this->getClient(); + $this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion); + } + + return $this->oAuth2Client; + } + /** * Returns the last response returned from Graph. * @@ -313,7 +336,7 @@ public function getDefaultGraphVersion() public function getRedirectLoginHelper() { return new FacebookRedirectLoginHelper( - $this->app, + $this->getOAuth2Client(), $this->persistentDataHandler, $this->urlDetectionHandler, $this->pseudoRandomStringGenerator @@ -327,7 +350,7 @@ public function getRedirectLoginHelper() */ public function getJavaScriptHelper() { - return new FacebookJavaScriptHelper($this->app); + return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion); } /** @@ -337,7 +360,7 @@ public function getJavaScriptHelper() */ public function getCanvasHelper() { - return new FacebookCanvasHelper($this->app); + return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion); } /** @@ -347,7 +370,7 @@ public function getCanvasHelper() */ public function getPageTabHelper() { - return new FacebookPageTabHelper($this->app); + return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion); } /** diff --git a/src/Facebook/FacebookApp.php b/src/Facebook/FacebookApp.php index feef6c2c4..cc21a8d6c 100644 --- a/src/Facebook/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -23,6 +23,8 @@ */ namespace Facebook; +use Facebook\Authentication\AccessToken; + class FacebookApp implements \Serializable { diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index 49db0a5ab..eb1953d8b 100755 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -23,6 +23,7 @@ */ namespace Facebook; +use Facebook\Authentication\AccessToken; use Facebook\Url\FacebookUrlManipulator; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; @@ -122,8 +123,9 @@ public function __construct( public function setAccessToken($accessToken) { $this->accessToken = $accessToken instanceof AccessToken - ? (string) $accessToken + ? $accessToken->getValue() : $accessToken; + return $this; } diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 5a7eb1c75..33d912b78 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -24,6 +24,7 @@ namespace Facebook\Helpers; use Facebook\FacebookApp; +use Facebook\FacebookClient; /** * Class FacebookPageTabHelper @@ -42,12 +43,14 @@ class FacebookPageTabHelper extends FacebookCanvasHelper * Initialize the helper and process available signed request data. * * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The client to make HTTP requests. + * @param string|null $graphVersion The version of Graph to use. */ - public function __construct(FacebookApp $app) + public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) { - parent::__construct($app); + parent::__construct($app, $client, $graphVersion); - if (!$this->signedRequest) { + if ( ! $this->signedRequest) { return; } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 3ac963311..988f17b43 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -23,9 +23,8 @@ */ namespace Facebook\Helpers; -use Facebook\Facebook; -use \Facebook\AccessToken; -use \Facebook\FacebookApp; +use Facebook\Authentication\AccessToken; +use Facebook\Authentication\OAuth2Client; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\Url\FacebookUrlManipulator; @@ -36,7 +35,6 @@ use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; use Facebook\Exceptions\FacebookSDKException; -use Facebook\FacebookClient; /** * Class FacebookRedirectLoginHelper @@ -53,9 +51,9 @@ class FacebookRedirectLoginHelper const CSRF_LENGTH = 32; /** - * @var FacebookApp The FacebookApp entity. + * @var OAuth2Client The OAuth 2.0 client service. */ - protected $app; + protected $oAuth2Client; /** * @var UrlDetectionInterface The URL detection handler. @@ -74,20 +72,18 @@ class FacebookRedirectLoginHelper protected $pseudoRandomStringGenerator; /** - * Constructs a RedirectLoginHelper for a given appId. - * - * @param FacebookApp $app The FacebookApp entity. + * @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(FacebookApp $app, + public function __construct(OAuth2Client $oAuth2Client, PersistentDataInterface $persistentDataHandler = null, UrlDetectionInterface $urlHandler = null, PseudoRandomStringGeneratorInterface $prsg = null) { - $this->app = $app; + $this->oAuth2Client = $oAuth2Client; $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); $this->pseudoRandomStringGenerator = $prsg ?: $this->detectPseudoRandomStringGenerator(); @@ -151,36 +147,22 @@ public function detectPseudoRandomStringGenerator() /** * Stores CSRF state and returns a URL to which the user should be sent to - * in order to continue the login process with Facebook. The - * provided redirectUrl should invoke the handleRedirect method. + * 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 string $version Optional Graph API version if not default (v2.0). + * @param array $params An array of parameters to generate URL. * @param string $separator The separator to use in http_build_query(). - * @param array $params Array of parameters to generate URL. * * @return string */ - private function makeUrl($redirectUrl, array $scope, $version, $separator, array $params = []) + private function makeUrl($redirectUrl, array $scope, array $params = [], $separator = '&') { - $version = $version ?: Facebook::DEFAULT_GRAPH_VERSION; - $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state); - $params += [ - 'client_id' => $this->app->getId(), - 'state' => $state, - 'response_type' => 'code', - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope) - ]; - - return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . - http_build_query($params, null, $separator); + return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $scope, $state, $params, $separator); } /** @@ -189,17 +171,15 @@ private function makeUrl($redirectUrl, array $scope, $version, $separator, arra * @param string $redirectUrl The URL Facebook should redirect users to * after login. * @param array $scope List of permissions to request during login. - * @param string $version Optional Graph API version if not default (v2.0). * @param string $separator The separator to use in http_build_query(). * * @return string */ public function getLoginUrl($redirectUrl, array $scope = [], - $version = null, $separator = '&') { - return $this->makeUrl($redirectUrl, $scope, $version, $separator); + return $this->makeUrl($redirectUrl, $scope, [], $separator); } /** @@ -211,13 +191,24 @@ public function getLoginUrl($redirectUrl, * @param string $separator The separator to use in http_build_query(). * * @return string + * + * @throws FacebookSDKException */ public function getLogoutUrl($accessToken, $next, $separator = '&') { + if ( ! $accessToken instanceof AccessToken) { + $accessToken = new AccessToken($accessToken); + } + + if ($accessToken->isAppAccessToken()) { + throw new FacebookSDKException('Cannot generate a logout URL with an app access token.', 722); + } + $params = [ 'next' => $next, - 'access_token' => (string) $accessToken, + 'access_token' => $accessToken->getValue(), ]; + return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, $separator); } @@ -228,20 +219,17 @@ public function getLogoutUrl($accessToken, $next, $separator = '&') * @param string $redirectUrl The URL Facebook should redirect users to * after login. * @param array $scope List of permissions to request during login. - * @param string $version Optional Graph API version if not default (v2.0). * @param string $separator The separator to use in http_build_query(). * * @return string */ public function getReRequestUrl($redirectUrl, array $scope = [], - $version = null, $separator = '&') { - $params = [ - 'auth_type' => 'rerequest' - ]; - return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); + $params = ['auth_type' => 'rerequest']; + + return $this->makeUrl($redirectUrl, $scope, $params, $separator); } /** @@ -251,33 +239,29 @@ public function getReRequestUrl($redirectUrl, * @param string $redirectUrl The URL Facebook should redirect users to * after login. * @param array $scope List of permissions to request during login. - * @param string $version Optional Graph API version if not default (v2.0). * @param string $separator The separator to use in http_build_query(). * * @return string */ public function getReAuthenticationUrl($redirectUrl, array $scope = [], - $version = null, $separator = '&') { - $params = [ - 'auth_type' => 'reauthenticate' - ]; - return $this->makeUrl($redirectUrl, $scope, $version, $separator, $params); + $params = ['auth_type' => 'reauthenticate']; + + return $this->makeUrl($redirectUrl, $scope, $params, $separator); } /** * Takes a valid code from a login redirect, and returns an AccessToken entity. * - * @param FacebookClient $client The Facebook client. * @param string|null $redirectUrl The redirect URL. * * @return AccessToken|null * * @throws FacebookSDKException */ - public function getAccessToken(FacebookClient $client, $redirectUrl = null) + public function getAccessToken($redirectUrl = null) { if ( ! $code = $this->getCode()) { return null; @@ -289,7 +273,7 @@ public function getAccessToken(FacebookClient $client, $redirectUrl = null) // At minimum we need to remove the state param $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']); - return AccessToken::getAccessTokenFromCode($code, $this->app, $client, $redirectUrl); + return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl); } /** diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index ac95d693b..97885dd2b 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -23,10 +23,12 @@ */ namespace Facebook\Helpers; +use Facebook\Facebook; use Facebook\FacebookApp; -use Facebook\SignedRequest; -use Facebook\AccessToken; use Facebook\FacebookClient; +use Facebook\SignedRequest; +use Facebook\Authentication\AccessToken; +use Facebook\Authentication\OAuth2Client; /** * Class FacebookSignedRequestFromInputHelper @@ -45,6 +47,11 @@ abstract class FacebookSignedRequestFromInputHelper */ protected $app; + /** + * @var OAuth2Client The OAuth 2.0 client service. + */ + protected $oAuth2Client; + /** * @var string|null Random string to prevent CSRF. */ @@ -54,10 +61,14 @@ abstract class FacebookSignedRequestFromInputHelper * Initialize the helper and process available signed request data. * * @param FacebookApp $app The FacebookApp entity. + * @param FacebookClient $client The client to make HTTP requests. + * @param string|null $graphVersion The version of Graph to use. */ - public function __construct(FacebookApp $app) + public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) { $this->app = $app; + $graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + $this->oAuth2Client = new OAuth2Client($this->app, $client, $graphVersion); $this->instantiateSignedRequest(); } @@ -81,20 +92,18 @@ public function instantiateSignedRequest($rawSignedRequest = null) /** * Returns an AccessToken entity from the signed request. * - * @param FacebookClient $client The Facebook client. - * * @return AccessToken|null * * @throws \Facebook\Exceptions\FacebookSDKException */ - public function getAccessToken(FacebookClient $client) + public function getAccessToken() { if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { $code = $this->signedRequest->get('code'); $accessToken = $this->signedRequest->get('oauth_token'); - if ($code && !$accessToken) { - return AccessToken::getAccessTokenFromCode($code, $this->app, $client); + if ($code && ! $accessToken) { + return $this->oAuth2Client->getAccessTokenFromCode($code); } $expiresAt = $this->signedRequest->get('expires', 0); diff --git a/tests/AccessTokenTest.php b/tests/AccessTokenTest.php deleted file mode 100644 index 8f36f55b2..000000000 --- a/tests/AccessTokenTest.php +++ /dev/null @@ -1,239 +0,0 @@ -assertEquals('foo_token', (string) $accessToken); - } - - public function testShortLivedAccessTokensCanBeDetected() - { - $anHourAndAHalf = time() + (1.5 * 60); - $accessToken = new AccessToken('foo_token', $anHourAndAHalf); - - $isLongLived = $accessToken->isLongLived(); - - $this->assertFalse($isLongLived, 'Expected access token to be short lived.'); - } - - public function testLongLivedAccessTokensCanBeDetected() - { - $accessToken = new AccessToken('foo_token', $this->aWeekFromNow()); - - $isLongLived = $accessToken->isLongLived(); - - $this->assertTrue($isLongLived, 'Expected access token to be long lived.'); - } - - public function testATokenIsValidatedOnTheAppIdAndMachineIdAndTokenValidityAndTokenExpiration() - { - $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', true, $this->aWeekFromNow()); - $app = new FacebookApp('123', 'foo_secret'); - - $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); - - $this->assertTrue($isValid, 'Expected access token to be valid.'); - } - - public function testATokenWillNotBeValidIfTheAppIdDoesNotMatch() - { - $graphSession = $this->createGraphSessionInfo('1337', 'foo_machine', true, $this->aWeekFromNow()); - $app = new FacebookApp('123', 'foo_secret'); - - $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); - - $this->assertFalse($isValid, 'Expected access token to be invalid because the app ID does not match.'); - } - - public function testATokenWillNotBeValidIfTheMachineIdDoesNotMatch() - { - $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', true, $this->aWeekFromNow()); - $app = new FacebookApp('123', 'foo_secret'); - - $isValid = AccessToken::validateAccessToken($graphSession, $app, 'bar_machine'); - - $this->assertFalse($isValid, 'Expected access token to be invalid because the machine ID does not match.'); - } - - public function testATokenWillNotBeValidIfTheCollectionTellsUsItsNotValid() - { - $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', false, $this->aWeekFromNow()); - $app = new FacebookApp('123', 'foo_secret'); - - $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); - - $this->assertFalse($isValid, 'Expected access token to be invalid because the collection says it is not valid.'); - } - - public function testATokenWillNotBeValidIfTheTokenHasExpired() - { - $expiredTime = time() - (60 * 60 * 24 * 7); - $graphSession = $this->createGraphSessionInfo('123', 'foo_machine', true, $expiredTime); - $app = new FacebookApp('123', 'foo_secret'); - - $isValid = AccessToken::validateAccessToken($graphSession, $app, 'foo_machine'); - - $this->assertFalse($isValid, 'Expected access token to be invalid because it has expired.'); - } - - public function testInfoAboutAnAccessTokenCanBeObtainedFromGraph() - { - $app = new FacebookApp('123', 'foo_secret'); - $response = $this->createFacebookResponseMockWithNoExpiresAt(); - $client = $this->createFacebookClientMockWithResponse($response); - $accessToken = new AccessToken('foo_token'); - - $accessTokenInfo = $accessToken->getInfo($app, $client); - - $this->assertSame($response, $accessTokenInfo); - } - - public function testAShortLivedAccessTokenCabBeExtended() - { - $app = new FacebookApp('123', 'foo_secret'); - $response = $this->createFacebookResponseMockWithDecodedBody([ - 'access_token' => 'long_token', - 'expires' => 123, - 'machine_id' => 'foo_machine', - ]); - $client = $this->createFacebookClientMockWithResponse($response); - $accessToken = new AccessToken('foo_token'); - - $longLivedAccessToken = $accessToken->extend($app, $client); - - $this->assertInstanceOf('Facebook\AccessToken', $longLivedAccessToken); - $this->assertEquals('long_token', (string)$longLivedAccessToken); - $this->assertEquals('foo_machine', $longLivedAccessToken->getMachineId()); - $this->assertEquals(time() + 123, $longLivedAccessToken->getExpiresAt()->getTimeStamp()); - } - - public function testALongLivedAccessTokenCanBeUsedToObtainACode() - { - $app = new FacebookApp('123', 'foo_secret'); - $response = $this->createFacebookResponseMockWithDecodedBody([ - 'code' => 'foo_code', - ]); - $client = $this->createFacebookClientMockWithResponse($response); - - $code = AccessToken::getCodeFromAccessToken('foo_token', $app, $client); - - $this->assertEquals('foo_code', $code); - } - - public function testACodeCanBeUsedToObtainAnAccessToken() - { - $app = new FacebookApp('123', 'foo_secret'); - $response = $this->createFacebookResponseMockWithDecodedBody([ - 'access_token' => 'new_long_token', - 'expires' => 123, - 'machine_id' => 'foo_machine', - ]); - $client = $this->createFacebookClientMockWithResponse($response); - - $accessTokenFromCode = AccessToken::getAccessTokenFromCode('foo_code', $app, $client); - - $this->assertInstanceOf('Facebook\AccessToken', $accessTokenFromCode); - $this->assertEquals('new_long_token', (string)$accessTokenFromCode); - $this->assertEquals('foo_machine', $accessTokenFromCode->getMachineId()); - $this->assertEquals(time() + 123, $accessTokenFromCode->getExpiresAt()->getTimeStamp()); - } - - public function testAccessTokenCanBeSerialized() - { - $accessToken = new AccessToken('foo', time(), 'bar'); - - $newAccessToken = unserialize(serialize($accessToken)); - - $this->assertEquals((string) $accessToken, (string) $newAccessToken); - $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); - $this->assertEquals($accessToken->getMachineId(), $newAccessToken->getMachineId()); - } - - private function createGraphSessionInfo($appId, $machineId, $isValid, $expiresAt) - { - return new GraphSessionInfo([ - 'app_id' => $appId, - 'machine_id' => $machineId, - 'is_valid' => $isValid, - 'expires_at' => $expiresAt - ]); - } - - private function aWeekFromNow() - { - return time() + (60 * 60 * 24 * 7);//a week from now - } - - private function createFacebookClientMockWithResponse($response) - { - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\FacebookRequest')) - ->once() - ->andReturn($response); - return $client; - } - - private function createFacebookResponseMockWithDecodedBody($decodedBody) - { - $response = $this->createFacebookResponseMock(); - $response - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($decodedBody); - return $response; - } - - private function createFacebookResponseMock() - { - return m::mock('Facebook\FacebookResponse'); - } - - private function createFacebookResponseMockWithNoExpiresAt() - { - $response = $this->createFacebookResponseMock(); - $response - ->shouldReceive('getGraphSessionInfo') - ->once() - ->andReturn($response); - $response - ->shouldReceive('getExpiresAt') - ->once() - ->andReturn(null); - return $response; - } - -} diff --git a/tests/Authentication/AccessTokenMetadata.php b/tests/Authentication/AccessTokenMetadata.php new file mode 100644 index 000000000..b8c1053dd --- /dev/null +++ b/tests/Authentication/AccessTokenMetadata.php @@ -0,0 +1,139 @@ + [ + 'app_id' => '123', + 'application' => 'Foo App', + 'error' => [ + 'code' => 190, + 'message' => 'Foo error message.', + 'subcode' => 463, + ], + 'issued_at' => 1422110200, + 'expires_at' => 1422115200, + 'is_valid' => false, + 'metadata' => [ + 'sso' => 'iphone-sso', + 'auth_type' => 'rerequest', + 'auth_nonce' => 'no-replicatey', + ], + 'scopes' => ['public_profile', 'basic_info', 'user_friends'], + 'profile_id' => '1000', + 'user_id' => '1337', + ], + ]; + + public function testDatesGetCastToDateTime() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + + $expires = $metadata->getExpiresAt(); + $issuedAt = $metadata->getIssuedAt(); + + $this->assertInstanceOf('DateTime', $expires); + $this->assertInstanceOf('DateTime', $issuedAt); + } + + public function testAllTheGettersReturnTheProperValue() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + + $this->assertEquals('123', $metadata->getAppId()); + $this->assertEquals('Foo App', $metadata->getApplication()); + $this->assertTrue($metadata->isError(), 'Expected an error'); + $this->assertEquals('190', $metadata->getErrorCode()); + $this->assertEquals('Foo error message.', $metadata->getErrorMessage()); + $this->assertEquals('463', $metadata->getErrorSubcode()); + $this->assertFalse($metadata->getIsValid(), 'Expected the access token to not be valid'); + $this->assertEquals('iphone-sso', $metadata->getSso()); + $this->assertEquals('rerequest', $metadata->getAuthType()); + $this->assertEquals('no-replicatey', $metadata->getAuthNonce()); + $this->assertEquals('1000', $metadata->getProfileId()); + $this->assertEquals(['public_profile', 'basic_info', 'user_friends'], $metadata->getScopes()); + $this->assertEquals('1337', $metadata->getUserId()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidMetadataWillThrow() + { + new AccessTokenMetadata(['foo' => 'bar']); + } + + public function testAnExpectedAppIdWillNotThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateAppId('123'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnUnexpectedAppIdWillThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateAppId('foo'); + } + + public function testAnExpectedUserIdWillNotThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateUserId('1337'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnUnexpectedUserIdWillThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateUserId('foo'); + } + + public function testAnActiveAccessTokenWillNotThrow() + { + $this->graphResponseData['data']['expires_at'] = time() + 1000; + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateExpiration(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnExpiredAccessTokenWillThrow() + { + $this->graphResponseData['data']['expires_at'] = time() - 1000; + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateExpiration(); + } + +} diff --git a/tests/Authentication/AccessTokenTest.php b/tests/Authentication/AccessTokenTest.php new file mode 100644 index 000000000..e2a9fd782 --- /dev/null +++ b/tests/Authentication/AccessTokenTest.php @@ -0,0 +1,112 @@ +assertEquals('foo_token', $accessToken->getValue()); + $this->assertEquals('foo_token', (string) $accessToken); + } + + public function testAnAppSecretProofWillBeProperlyGenerated() + { + $accessToken = new AccessToken('foo_token'); + + $appSecretProof = $accessToken->getAppSecretProof('shhhhh!is.my.secret'); + + $this->assertEquals('796ba0d8a6b339e476a7b166a9e8ac0a395f7de736dc37de5f2f4397f5854eb8', $appSecretProof); + } + + public function testAnAppAccessTokenCanBeDetected() + { + $normalToken = new AccessToken('foo_token'); + $isNormalToken = $normalToken->isAppAccessToken(); + + $this->assertFalse($isNormalToken, 'Normal access token not expected to look like an app access token.'); + + $appToken = new AccessToken('123|secret'); + $isAppToken = $appToken->isAppAccessToken(); + + $this->assertTrue($isAppToken, 'App access token expected to look like an app access token.'); + } + + public function testShortLivedAccessTokensCanBeDetected() + { + $anHourAndAHalf = time() + (1.5 * 60); + $accessToken = new AccessToken('foo_token', $anHourAndAHalf); + + $isLongLived = $accessToken->isLongLived(); + + $this->assertFalse($isLongLived, 'Expected access token to be short lived.'); + } + + public function testLongLivedAccessTokensCanBeDetected() + { + $accessToken = new AccessToken('foo_token', $this->aWeekFromNow()); + + $isLongLived = $accessToken->isLongLived(); + + $this->assertTrue($isLongLived, 'Expected access token to be long lived.'); + } + + public function testAnAppAccessTokenDoesNotExpire() + { + $appToken = new AccessToken('123|secret'); + $hasExpired = $appToken->isExpired(); + + $this->assertFalse($hasExpired, 'App access token not expected to expire.'); + } + + public function testAnAccessTokenCanExpire() + { + $expireTime = time() - 100; + $appToken = new AccessToken('foo_token', $expireTime); + $hasExpired = $appToken->isExpired(); + + $this->assertTrue($hasExpired, 'Expected 100 second old access token to be expired.'); + } + + public function testAccessTokenCanBeSerialized() + { + $accessToken = new AccessToken('foo', time(), 'bar'); + + $newAccessToken = unserialize(serialize($accessToken)); + + $this->assertEquals((string) $accessToken, (string) $newAccessToken); + $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); + } + + private function aWeekFromNow() + { + return time() + (60 * 60 * 24 * 7);//a week from now + } + +} diff --git a/tests/Authentication/OAuth2ClientTest.php b/tests/Authentication/OAuth2ClientTest.php new file mode 100644 index 000000000..6715dfd56 --- /dev/null +++ b/tests/Authentication/OAuth2ClientTest.php @@ -0,0 +1,198 @@ +response = '{"data":{"user_id":"444"}}'; + } + + public function setAccessTokenResponse() { + $this->response = '{"access_token":"my_access_token","expires":"1422115200"}'; + } + + public function setCodeResponse() { + $this->response = '{"code":"my_neat_code"}'; + } + + public function sendRequest(FacebookRequest $request) { + return new FacebookResponse( + $request, + $this->response, + 200, + [] + ); + } +} + +class OAuth2ClientTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @const The foo Graph version + */ + const TESTING_GRAPH_VERSION = 'v1337'; + + /** + * @var FooFacebookClientForOAuth2Test + */ + protected $client; + + /** + * @var OAuth2Client + */ + protected $oauth; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_secret'); + $this->client = new FooFacebookClientForOAuth2Test(); + $this->oauth = new OAuth2Client($app, $this->client, static::TESTING_GRAPH_VERSION); + } + + public function testCanGetMetadataFromAnAccessToken() + { + $this->client->setMetadataResponse(); + + $metadata = $this->oauth->debugToken('baz_token'); + + $this->assertInstanceOf('Facebook\Authentication\AccessTokenMetadata', $metadata); + $this->assertEquals('444', $metadata->getUserId()); + + $expectedParams = [ + 'input_token' => 'baz_token', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/debug_token', $request->getEndpoint()); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); + } + + public function testCanBuildAuthorizationUrl() + { + $scope = ['email', 'base_foo']; + $authUrl = $this->oauth->getAuthorizationUrl('https://foo.bar', $scope, 'foo_state', ['foo' => 'bar'], '*'); + + $this->assertContains('*', $authUrl); + + $expectedUrl = 'https://www.facebook.com/' . static::TESTING_GRAPH_VERSION . '/dialog/oauth?'; + $this->assertTrue(strpos($authUrl, $expectedUrl) === 0, 'Unexpected base authorization URL returned from getAuthorizationUrl().'); + + $params = [ + 'client_id' => '123', + 'redirect_uri' => 'https://foo.bar', + 'state' => 'foo_state', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'scope' => implode(',', $scope), + 'foo' => 'bar', + ]; + foreach ($params as $key => $value) { + $this->assertContains($key . '=' . urlencode($value), $authUrl); + } + } + + public function testCanGetAccessTokenFromCode() + { + $this->client->setAccessTokenResponse(); + + $accessToken = $this->oauth->getAccessTokenFromCode('bar_code', 'foo_uri'); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('my_access_token', $accessToken->getValue()); + + $expectedParams = [ + 'code' => 'bar_code', + 'redirect_uri' => 'foo_uri', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/oauth/access_token', $request->getEndpoint()); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); + } + + public function testCanGetLongLivedAccessToken() + { + $this->client->setAccessTokenResponse(); + + $accessToken = $this->oauth->getLongLivedAccessToken('short_token'); + + $this->assertEquals('my_access_token', $accessToken->getValue()); + + $expectedParams = [ + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => 'short_token', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals($expectedParams, $request->getParams()); + } + + public function testCanGetCodeFromLongLivedAccessToken() + { + $this->client->setCodeResponse(); + + $code = $this->oauth->getCodeFromLongLivedAccessToken('long_token', 'foo_uri'); + + $this->assertEquals('my_neat_code', $code); + + $expectedParams = [ + 'access_token' => 'long_token', + 'redirect_uri' => 'foo_uri', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'appsecret_proof' => '7e91300ea91be4166282611d4fc700b473466f3ea2981dafbf492fc096995bf1', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals('/oauth/client_code', $request->getEndpoint()); + } + +} diff --git a/tests/FacebookAppTest.php b/tests/FacebookAppTest.php index bf2e8e4cf..796a81cf0 100644 --- a/tests/FacebookAppTest.php +++ b/tests/FacebookAppTest.php @@ -52,7 +52,7 @@ public function testAnAppAccessTokenCanBeGenerated() { $accessToken = $this->app->getAccessToken(); - $this->assertInstanceOf('Facebook\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); $this->assertEquals('id|secret', (string) $accessToken); } diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 6e392be9a..b5da16153 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -30,8 +30,8 @@ use Facebook\PersistentData\PersistentDataInterface; use Facebook\Url\UrlDetectionInterface; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; -use \Facebook\FacebookRequest; -use \Facebook\AccessToken; +use Facebook\FacebookRequest; +use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphList; class FooClientInterface implements FacebookHttpClientInterface @@ -177,7 +177,7 @@ public function testAnAccessTokenCanBeSetAsAString() $fb->setDefaultAccessToken('foo_token'); $accessToken = $fb->getDefaultAccessToken(); - $this->assertInstanceOf('Facebook\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); $this->assertEquals('foo_token', (string) $accessToken); } @@ -187,7 +187,7 @@ public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() $fb->setDefaultAccessToken(new AccessToken('bar_token')); $accessToken = $fb->getDefaultAccessToken(); - $this->assertInstanceOf('Facebook\AccessToken', $accessToken); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); $this->assertEquals('bar_token', (string) $accessToken); } diff --git a/tests/Helpers/FacebookCanvasHelperTest.php b/tests/Helpers/FacebookCanvasHelperTest.php index 9c296ccd9..9f4c7b744 100644 --- a/tests/Helpers/FacebookCanvasHelperTest.php +++ b/tests/Helpers/FacebookCanvasHelperTest.php @@ -24,6 +24,7 @@ namespace Facebook\Tests\Helpers; use Facebook\FacebookApp; +use Facebook\FacebookClient; use Facebook\Helpers\FacebookCanvasHelper; class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase @@ -39,7 +40,7 @@ class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase public function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); - $this->helper = new FacebookCanvasHelper($app); + $this->helper = new FacebookCanvasHelper($app, new FacebookClient()); } public function testSignedRequestDataCanBeRetrievedFromPostData() diff --git a/tests/Helpers/FacebookJavaScriptHelperTest.php b/tests/Helpers/FacebookJavaScriptHelperTest.php index 00d5423a2..2fae603d7 100644 --- a/tests/Helpers/FacebookJavaScriptHelperTest.php +++ b/tests/Helpers/FacebookJavaScriptHelperTest.php @@ -24,6 +24,7 @@ namespace Facebook\Tests\Helpers; use Facebook\FacebookApp; +use Facebook\FacebookClient; use Facebook\Helpers\FacebookJavaScriptHelper; class FacebookJavaScriptLoginHelperTest extends \PHPUnit_Framework_TestCase @@ -36,7 +37,7 @@ public function testARawSignedRequestCanBeRetrievedFromCookieData() $_COOKIE['fbsr_123'] = $this->rawSignedRequestAuthorized; $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookJavaScriptHelper($app); + $helper = new FacebookJavaScriptHelper($app, new FacebookClient()); $rawSignedRequest = $helper->getRawSignedRequest(); diff --git a/tests/Helpers/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php index 9fe26425c..5d5b33d4e 100644 --- a/tests/Helpers/FacebookPageTabHelperTest.php +++ b/tests/Helpers/FacebookPageTabHelperTest.php @@ -24,6 +24,7 @@ namespace Facebook\Tests\Helpers; use Facebook\FacebookApp; +use Facebook\FacebookClient; use Facebook\Helpers\FacebookPageTabHelper; class FacebookPageTabHelperTest extends \PHPUnit_Framework_TestCase @@ -36,7 +37,7 @@ public function testPageDataCanBeAccessed() $_POST['signed_request'] = $this->rawSignedRequestAuthorized; $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookPageTabHelper($app); + $helper = new FacebookPageTabHelper($app, new FacebookClient()); $this->assertFalse($helper->isAdmin()); $this->assertEquals('42', $helper->getPageId()); diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 3780409f4..4a6303b58 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -23,9 +23,10 @@ */ namespace Facebook\Tests\Helpers; -use Mockery as m; use Facebook\Facebook; -use \Facebook\FacebookApp; +use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\Authentication\OAuth2Client; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; @@ -37,6 +38,13 @@ public function getPseudoRandomString($length) { } } +class FooRedirectLoginOAuth2Client extends OAuth2Client +{ + public function getAccessTokenFromCode($code, $redirectUri = '', $machineId = null) { + return 'foo_token_from_code|' . $code . '|' . $redirectUri; + } +} + class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase { @@ -45,20 +53,26 @@ class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase */ protected $persistentDataHandler; + /** + * @var FacebookRedirectLoginHelper + */ + protected $redirectLoginHelper; + const REDIRECT_URL = 'http://invalid.zzz'; public function setUp() { $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); + + $app = new FacebookApp('123', 'foo_app_secret'); + $oAuth2Client = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); + $this->redirectLoginHelper = new FacebookRedirectLoginHelper($oAuth2Client, $this->persistentDataHandler); } public function testLoginURL() { - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); - $scope = ['foo','bar']; - $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL, $scope, true, 'v1337'); + $loginUrl = $this->redirectLoginHelper->getLoginUrl(self::REDIRECT_URL, $scope); $expectedUrl = 'https://www.facebook.com/v1337/dialog/oauth?'; $this->assertTrue(strpos($loginUrl, $expectedUrl) === 0, 'Unexpected base login URL returned from getLoginUrl().'); @@ -77,10 +91,7 @@ public function testLoginURL() public function testLogoutURL() { - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); - - $logoutUrl = $helper->getLogoutUrl('foo_token', self::REDIRECT_URL); + $logoutUrl = $this->redirectLoginHelper->getLogoutUrl('foo_token', self::REDIRECT_URL); $expectedUrl = 'https://www.facebook.com/logout.php?'; $this->assertTrue(strpos($logoutUrl, $expectedUrl) === 0, 'Unexpected base logout URL returned from getLogoutUrl().'); @@ -101,35 +112,17 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $_GET['state'] = 'foo_state'; $_GET['code'] = 'foo_code'; - $response = m::mock('Facebook\FacebookResponse'); - $response - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'access_token' => 'access_token_from_code', - 'expires' => 555, - ]); - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\FacebookRequest')) - ->once() - ->andReturn($response); + $accessToken = $this->redirectLoginHelper->getAccessToken(self::REDIRECT_URL); - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); - - $accessToken = $helper->getAccessToken($client, self::REDIRECT_URL); - - $this->assertInstanceOf('Facebook\AccessToken', $accessToken); - $this->assertEquals('access_token_from_code', (string) $accessToken); + $this->assertEquals('foo_token_from_code|foo_code|' . self::REDIRECT_URL, (string) $accessToken); } public function testACustomCsprsgCanBeInjected() { $app = new FacebookApp('123', 'foo_app_secret'); + $accessTokenClient = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); $fooPrsg = new FooPseudoRandomStringGenerator(); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler, null, $fooPrsg); + $helper = new FacebookRedirectLoginHelper($accessTokenClient, $this->persistentDataHandler, null, $fooPrsg); $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); @@ -138,11 +131,9 @@ public function testACustomCsprsgCanBeInjected() public function testThePseudoRandomStringGeneratorWillAutoDetectCsprsg() { - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookRedirectLoginHelper($app, $this->persistentDataHandler); $this->assertInstanceOf( 'Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface', - $helper->getPseudoRandomStringGenerator() + $this->redirectLoginHelper->getPseudoRandomStringGenerator() ); } diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 793978782..98847c0a6 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -23,8 +23,10 @@ */ namespace Facebook\Tests\Helpers; -use Mockery as m; use Facebook\FacebookApp; +use Facebook\FacebookClient; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; use Facebook\Helpers\FacebookSignedRequestFromInputHelper; class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper { @@ -33,6 +35,18 @@ public function getRawSignedRequest() { } } +class FooSignedRequestHelperFacebookClient extends FacebookClient +{ + public function sendRequest(FacebookRequest $request) { + $params = $request->getParams(); + $rawResponse = json_encode([ + 'access_token' => 'foo_access_token_from:' . $params['code'], + ]); + + return new FacebookResponse($request, $rawResponse, 200); + } +} + class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCase { @@ -48,7 +62,7 @@ class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCa public function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); - $this->helper = new FooSignedRequestHelper($app); + $this->helper = new FooSignedRequestHelper($app, new FooSignedRequestHelperFacebookClient()); } public function testSignedRequestDataCanBeRetrievedFromGetData() @@ -80,53 +94,28 @@ public function testSignedRequestDataCanBeRetrievedFromCookieData() public function testAccessTokenWillBeNullWhenAUserHasNotYetAuthorizedTheApp() { - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->never(); - $this->helper->instantiateSignedRequest($this->rawSignedRequestUnauthorized); - $accessToken = $this->helper->getAccessToken($client); + $accessToken = $this->helper->getAccessToken(); $this->assertNull($accessToken); } public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessToken() { - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->never(); - $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); - $accessToken = $this->helper->getAccessToken($client); + $accessToken = $this->helper->getAccessToken(); - $this->assertInstanceOf('Facebook\AccessToken', $accessToken); - $this->assertEquals('foo_token', (string) $accessToken); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_token', $accessToken->getValue()); } public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() { - $response = m::mock('Facebook\FacebookResponse'); - $response - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn([ - 'access_token' => 'access_token_from_code', - 'expires' => 555, - ]); - $client = m::mock('Facebook\FacebookClient'); - $client - ->shouldReceive('sendRequest') - ->with(m::type('Facebook\FacebookRequest')) - ->once() - ->andReturn($response); - $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); - $accessToken = $this->helper->getAccessToken($client); + $accessToken = $this->helper->getAccessToken(); - $this->assertInstanceOf('Facebook\AccessToken', $accessToken); - $this->assertEquals('access_token_from_code', (string) $accessToken); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_access_token_from:foo_code', $accessToken->getValue()); } } From f447564610bf0f6ca255be33e156159fe75277b2 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Thu, 29 Jan 2015 10:04:29 -0600 Subject: [PATCH 099/407] tests that test non-existent code are kind of silly. --- .../Helpers/FacebookSignedRequestFromInputHelperTest.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 793978782..4111e59ee 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -51,15 +51,6 @@ public function setUp() $this->helper = new FooSignedRequestHelper($app); } - public function testSignedRequestDataCanBeRetrievedFromGetData() - { - $_GET['signed_request'] = 'foo_signed_request'; - - $rawSignedRequest = $this->helper->getRawSignedRequestFromGet(); - - $this->assertEquals('foo_signed_request', $rawSignedRequest); - } - public function testSignedRequestDataCanBeRetrievedFromPostData() { $_POST['signed_request'] = 'foo_signed_request'; From 24cb7acd3012ed9eca16971f05b4dbc2c695eae9 Mon Sep 17 00:00:00 2001 From: SammyK Date: Mon, 2 Feb 2015 18:04:34 -0500 Subject: [PATCH 100/407] Add travis-ci badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c720fbf03..1599d347b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ Facebook SDK for PHP ==================== -[![Development Version](http://img.shields.io/badge/Development%20Version-4.1.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) +[![Development Version](https://img.shields.io/badge/Development%20Version-4.1.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access Facebook From 9785d6a3cb1b0122fd8adcfdadc6418cbea25a8b Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Tue, 3 Feb 2015 09:26:30 +0100 Subject: [PATCH 101/407] Better Travis-CI - Use `before_install` and `install` - Remove deprecated composer `--dev` option - Use the required PHPUnit to run tests --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1dcaaf77c..00fc1343a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,14 +6,16 @@ php: - 5.6 - hhvm -before_script: +before_install: - composer self-update - - composer install --prefer-source --no-interaction --dev + +install: + - composer install --prefer-source --no-interaction script: - - phpunit --coverage-text --exclude-group integration + - vendor/bin/phpunit --coverage-text --exclude-group integration matrix: allow_failures: - php: hhvm - fast_finish: true \ No newline at end of file + fast_finish: true From a6a4673ed899eb327f76c055be8659a7abfac22c Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Tue, 3 Feb 2015 09:35:19 +0100 Subject: [PATCH 102/407] Using Travis-CI container-based infrastructure --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 00fc1343a..5a7c5c971 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,8 @@ php: - 5.6 - hhvm +sudo: false + before_install: - composer self-update From 05df6575c3e1bf43784488fa9937db6baff10f72 Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 8 Feb 2015 14:23:23 -0500 Subject: [PATCH 103/407] Started work on docs --- CHANGELOG.md | 2 +- docs/AccessToken.fbmd | 62 +++++ docs/Facebook.fbmd | 41 ++- docs/FacebookApp.fbmd | 13 +- docs/FacebookRedirectLoginHelper.fbmd | 151 +++++++++-- docs/GraphObject.fbmd | 65 ++--- ...ost_links.fbmd => example_post_links.fbmd} | 0 ...bmd => example_retrieve_user_profile.fbmd} | 0 ...d_photo.fbmd => example_upload_photo.fbmd} | 0 docs/sdk_getting_started.fbmd | 243 +++++++++++------- docs/sdk_landing_page.fbmd | 27 +- docs/sdk_reference.fbmd | 204 ++++++++------- 12 files changed, 514 insertions(+), 294 deletions(-) create mode 100644 docs/AccessToken.fbmd rename docs/{post_links.fbmd => example_post_links.fbmd} (100%) rename docs/{retrieve_user_profile.fbmd => example_retrieve_user_profile.fbmd} (100%) rename docs/{upload_photo.fbmd => example_upload_photo.fbmd} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07b914ac4..0689188d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ As you may have already noticed, the Facebook SDK v4 does not follow strict [sem ## 4.1.x -- 4.1.0 (2014-??-??) +- 4.1.0 (2015-??-??) - Added batch support - Added `graph.beta.facebook.com` support - Moved exception classes to `Exception\*` directory diff --git a/docs/AccessToken.fbmd b/docs/AccessToken.fbmd new file mode 100644 index 000000000..0ba0696d4 --- /dev/null +++ b/docs/AccessToken.fbmd @@ -0,0 +1,62 @@ + +# 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 {#overview} + +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() {#get-value} +~~~~ +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() {#get-expires-at} +~~~~ +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() {#is-expired} +~~~~ +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() {#is-long-lived} +~~~~ +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 `null`. [See more about long-lived and short-lived access tokens](https://developers.facebook.com/docs/facebook-login/access-tokens#extending). + +### isAppAccessToken() {#is-app-access-token} +~~~~ +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() {#is-app-secret-proof} +~~~~ +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 {#from-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. + +~~~~ +$expires = time() + 60 * 60 * 2; +$accessToken = new Facebook\Authentication\AccessToken('{example-access-token}', $expires); +~~~~ + diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index f9c4b4b5f..e0cb2fe76 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -13,6 +13,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', // . . . ]); ~~~~ @@ -174,6 +175,14 @@ public Facebook\FacebookClient getClient() Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) for the instantiated service. + +### getOAuth2Client() {#get-oauth2-client} +~~~~ +public Facebook\Authentication\OAuth2Client getOAuth2Client() +~~~~ +Returns an instance of [`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client). + + ### getLastResponse() {#get-last-response} ~~~~ @@ -182,13 +191,21 @@ public Facebook\FacebookResponse|Facebook\FacebookBatchResponse|null getLastResp Returns the last response received from the Graph API in the form of a `Facebook\FacebookResponse` or `Facebook\FacebookBatchResponse`. + +### getUrlDetectionHandler() {#get-url-detection-handler} +~~~~ +public Facebook\Url\UrlDetectionInterface getUrlDetectionHandler() +~~~~ +Returns an instance of [`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface). + + ### getDefaultAccessToken() {#get-default-access-token} ~~~~ -public Facebook\AccessToken|null getDefaultAccessToken() +public Facebook\Authentication\AccessToken|null getDefaultAccessToken() ~~~~ -Returns the default fallback `Facebook\AccessToken` 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()`. +Returns the default fallback [`AccessToken`](/docs/php/AccessToken) 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()`. @@ -197,18 +214,18 @@ Returns the default fallback `Facebook\AccessToken` entity that is being used wi public setDefaultAccessToken(string|Facebook\AccessToken $accessToken) ~~~~ -Sets the default access token to be use with all requests sent to Graph. The access token can be in string or `Facebook\AccessToken` format. +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`](/docs/php/AccessToken). ~~~~ $fb->setDefaultAccessToken('{my-access-token}'); // . . . OR . . . -$accessToken = new Facebook\AccessToken('{my-access-token}'); +$accessToken = new Facebook\Authentication\AccessToken('{my-access-token}'); $fb->setDefaultAccessToken($accessToken); ~~~~ -This setting will overwrite the value from `default_access_token` if it was passed to the `Facebook\Facebook` constructor. +This setting will overwrite the value from `default_access_token` option if it was passed to the `Facebook\Facebook` constructor. @@ -240,13 +257,13 @@ $fb->get('/me'); ~~~ `$accessToken` -The access token (as a `string` or `Facebook\AccessToken`) 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. +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/reference/ads-api/etags-reference/). Set this to the eTag from a previous request to get a `304 Not Modified` response if the data has not changed. `$graphVersion` -Set the Graph version to something other than what was set in the `default_graph_version` configuration option or `Facebook\Facebook::DEFAULT_GRAPH_VERSION`. +This will overwrite the Graph version that was set in the `default_graph_version` configuration option. @@ -353,7 +370,7 @@ Sends an array of `Facebook\FacebookRequest` entities as a batch request to Grap 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 of type `Facebook\FacebookRequest`. +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/#operations). @@ -365,6 +382,8 @@ $requests = [ ]; $batchResponse = $fb->sendBatchRequest($requests); ~~~~ + +[See a full batch example](/docs/php/howto/example_batch_request). @@ -425,7 +444,7 @@ $helper = $fb->getPageTabHelper(); public Facebook\GraphNodes\GraphList|null next(Facebook\GraphNodes\GraphList $graphList) ~~~~ -Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) object. If the next page returns no results, `null` will be returned. +Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) collection. If the next page returns no results, `null` will be returned. ~~~~ // Iterate over 5 pages max @@ -461,7 +480,7 @@ if (count($photosList) > 0) { public Facebook\GraphNodes\GraphList|null previous(Facebook\GraphNodes\GraphList $graphList) ~~~~ -Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` object. Functions just like `next()` above, but in the opposite direction of pagination. +Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` collection. Functions just like `next()` above, but in the opposite direction of pagination. @@ -470,7 +489,7 @@ Requests and returns the previous page of results in a `Facebook\GraphNodes\Grap public Facebook\FileUpload\FacebookFile fileToUpload(string $pathToFile) ~~~~ -When a valid path to a local or remote file is provided, `fileToUpload()` will returns a `FacebookFile` that can be used in the params in a POST request to Graph. +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. ~~~~ // Upload a photo for a user diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index f5557ee8b..65e73b589 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -2,6 +2,11 @@ # 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. + +%FB(devsite:markdown-wiki:info-card { + content: "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.", + type: 'warning', +}) @@ -20,7 +25,7 @@ $fb = new Facebook\Facebook([/* . . . */]); $fbApp = $fb->getApp(); ~~~~ -In the most common cases, you'll rarely be using the `FacebookApp` entity directly but it plays an important role in the internal workings of the SDK. +You'll rarely be using the `FacebookApp` entity directly unless you're doing some extreme customizations of the PHP SDK. But this entity plays an important role in the internal workings of the PHP SDK. @@ -28,9 +33,9 @@ In the most common cases, you'll rarely be using the `FacebookApp` entity direct ### getAccessToken() {#get-access-token} ~~~~ -public Facebook\AccessToken getAccessToken() +public Facebook\Authentication\AccessToken getAccessToken() ~~~~ -Returns an app access token in the form of a [`Facebook\AccessToken`](/docs/php/AccessToken) entity. +Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessToken) entity. @@ -52,7 +57,7 @@ Returns an the app secret. ## Serialization {#serialization} -The `Facebook\FacebookApp` entity implements the `\Serializable` interface so it can be serialized and unserialized. +The `Facebook\FacebookApp` entity can be serialized and unserialized. ~~~~ $fbApp = new Facebook\FacebookApp('foo-app-id', 'foo-app-secret'); diff --git a/docs/FacebookRedirectLoginHelper.fbmd b/docs/FacebookRedirectLoginHelper.fbmd index 115ef8b3a..249c1627a 100644 --- a/docs/FacebookRedirectLoginHelper.fbmd +++ b/docs/FacebookRedirectLoginHelper.fbmd @@ -7,46 +7,147 @@ The most commonly used helper is the `FacebookRedirectLoginHelper` which allows ## Usage {#usage} -If your web app uses Facebook Login on the back-end, you'll need to redirect your visitors to a URL at Facebook to initiate a login request. Facebook then redirects the user to your apps callback URL, providing session data. This helper class will generate the login URL for you, and can process and validate the data from Facebook, returning a `FacebookSession` on success. +Facebook Login is achieved via OAuth 2.0. But you don't really have to know much about OAuth 2.0 since the PHP SDK does all the heavy lifting for you. -This class can be extended, and the `storeState($state)` and `loadState()` methods overridden, to store the state check using another method besides the default `$_SESSION`. -~~~~ +### Obtaining an instance of FacebookRedirectLoginHelper -$helper = new FacebookRedirectLoginHelper($redirect_url, $appId = NULL, $appSecret = NULL); -echo 'Login with Facebook'; +You can obtain an instance of the `FacebookRedirectLoginHelper` from the `getRedirectLoginHelper()` method on the `Facebook\Facebook` service. -~~~~ +~~~ +$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. + +~~~ +# 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!'; +~~~ + +%FB(devsite:markdown-wiki:info-card { + content: "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.", + type: 'warning', +}) Then, in your callback page (at the redirect url) when Facebook sends the user back: -~~~~ +~~~ +# login-callback.php +$fb = new Facebook\Facebook([/* . . . */]); -$helper = new FacebookRedirectLoginHelper($redirect_url); +$helper = $fb->getRedirectLoginHelper(); try { - $session = $helper->getSessionFromRedirect(); -} catch(FacebookResponseException $ex) { - // When Facebook returns an error -} catch(\Exception $ex) { - // When validation fails or other local issues + $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 ($session) { - // Logged in. + +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 {#instance-methods} +### getLoginUrl() {#get-login-url} ~~~~ +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. -## Instance Methods {#instance-methods} +### getReRequestUrl() {#get-re-request-url} +~~~~ +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() {#get-re-authentication-url} +~~~~ +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() {#get-logout-url} +~~~~ +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() {#get-access-token} +~~~~ +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 {#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`](/docs/php/PersistentDataInterface). + + +### 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`](/docs/php/PseudoRandomStringGeneratorInterface) allows you to inject your own custom CSPRNG. + + +### URL detection -### getLoginUrl {#getloginurl} -`getLoginUrl()` -Generates the URL to redirect a web visitor to Facebook to login to your app. -### getLogoutUrl {#getlogouturl} -`getLogoutUrl($next_url)` -Generates the URL to redirect a web visitor to Facebook to logout, with a url to redirect to after. -### getSessionFromRedirect {#getsessionfromredirect} -`getSessionFromRedirect()` -Processes the redirect data from Facebook, if present. Returns a `FacebookSession` or `null`. +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`](/docs/php/UrlDetectionInterface). \ No newline at end of file diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd index c07cf74a8..3b5e9ec63 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphObject.fbmd @@ -13,9 +13,10 @@ This base class has several subclasses: [__GraphPage__](#page-instance-methods) [__GraphAlbum__](#album-instance-methods) [__GraphLocation__](#location-instance-methods) -[__GraphSessionInfo__](#sessioninfo-instance-methods) +[__GraphPicture__](#picture-instance-methods) +[__GraphAchievement__](#achievement-instance-methods) -`GraphObject`'s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents a response from the Graph API. +`GraphObject`'s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents an HTTP response from the Graph API. Usage: @@ -25,7 +26,7 @@ $fb = new Facebook\Facebook(\* *\); $response = $fb->get('/something'); // Get the base class GraphObject from the response -$object = $response->getGraphObject(); +$node = $response->getGraphObject(); // Get the response typed as a GraphUser $user = $response->getGraphUser()); @@ -34,16 +35,12 @@ $user = $response->getGraphUser()); $page = $response->getGraphPage(); // User example -echo $object->getProperty('name'); -echo $user->getName(); +echo $node->getProperty('name'); // From GraphObject +echo $user->getName(); // From GraphUser // Location example -echo $object->getProperty('country'); -echo $loc->getCountry(); - -// SessionInfo example -$info = $session->getSessionInfo()); -echo $info->getExpiresAt(); +echo $node->getProperty('country'); // From GraphObject +echo $location->getCountry(); // From GraphLocation ~~~~ @@ -423,49 +420,25 @@ Returns the `longitude` property for the location as a float if present. -## GraphSessionInfo Instance Methods {#sessioninfo-instance-methods} +## GraphPicture Instance Methods {#picture-instance-methods} All getter methods return `null` if the property does not exist on the node. -### getAppId() {#sessioninfo-getappid} -~~~~ -public string|null getAppId() -~~~~ -Returns the `app_id` property for the session as a string if present. - -### getApplication() {#sessioninfo-getapplication} -~~~~ -public string|null getApplication() -~~~~ -Returns the `application` property for the session as a string if present. - -### getExpiresAt() {#sessioninfo-getexpiresat} -~~~~ -public \DateTime|null getExpiresAt() -~~~~ -Returns the `expires_at` property for the session as a `\DateTime` if present. - -### getIsValid() {#sessioninfo-getisvalid} +### getUrl() {#picture-geturl} ~~~~ -public boolean|null getIsValid() +public string|null getUrl() ~~~~ -Returns the `is_valid` property for the session as a boolean if present. +Returns the `url` property for the picture as a string if present. + -### getIssuedAt() {#sessioninfo-getissuedat} -~~~~ -public \DateTime|null getIssuedAt() -~~~~ -Returns the `issued_at` property for the session as a `\DateTime` if present. + +## GraphAchievement Instance Methods {#achievement-instance-methods} -### getScopes() {#sessioninfo-getscopes} -~~~~ -public array|null getScopes() -~~~~ -Returns the `scopes` property for the session as an array if present. +All getter methods return `null` if the property does not exist on the node. -### getUserId() {#sessioninfo-getuserid} +### getId() {#achievement-getid} ~~~~ -public array|null getUserId() +public string|null getId() ~~~~ -Returns the `user_id` property for the session as a string if present. +Returns the `id` property for the achievement as a string if present. diff --git a/docs/post_links.fbmd b/docs/example_post_links.fbmd similarity index 100% rename from docs/post_links.fbmd rename to docs/example_post_links.fbmd diff --git a/docs/retrieve_user_profile.fbmd b/docs/example_retrieve_user_profile.fbmd similarity index 100% rename from docs/retrieve_user_profile.fbmd rename to docs/example_retrieve_user_profile.fbmd diff --git a/docs/upload_photo.fbmd b/docs/example_upload_photo.fbmd similarity index 100% rename from docs/upload_photo.fbmd rename to docs/example_upload_photo.fbmd diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 61f4970f1..149abf2d5 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -1,7 +1,7 @@ # Getting started with the Facebook SDK for PHP -The Facebook SDK for PHP provides developers with a modern, native library for accessing the Graph API and taking advantage of Facebook Login. Usually this means you're developing with PHP for a Facebook Canvas app, building your own website, or adding server-side functionality to an app that already uses the [Facebook SDK for JavaScript](/docs/reference/javascript/). +Whether you're developing a website with Facebook login, creating a Facebook Canvas app or Page tab, the Facebook PHP SDK does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. @@ -23,13 +23,11 @@ It would be advantageous to familiarize yourself with the concepts of [namespaci ## Installing the Facebook SDK for PHP {#installation} -There are two methods to install the Facebook PHP SDK. The preferred method is with [Composer](https://getcomposer.org/). If are unable to use Composer for your project, you can still install the SDK manually by downloading the source files and including the autoloader. +There are two methods to install the Facebook PHP SDK. The recommended installation method is by using [Composer](#install-composer). If are unable to use Composer for your project, you can still [install the SDK manually](#install-manually) by downloading the source files and including the autoloader. -## Installation Method 1 (recommended) {#composer} - -### Installing with Composer +## Installing with Composer (recommended) {#install-composer} [Composer](https://getcomposer.org/) is the recommended way to install the Facebook SDK for PHP. Simply add the following "require" entry to the `composer.json` file in the root of your project. @@ -41,6 +39,11 @@ There are two methods to install the Facebook PHP SDK. The preferred method is w } ~~~ +%FB(devsite:markdown-wiki:info-card { + content: "The Facebook SDK v4 does not follow [SemVer](http://semver.org/). The versioning format used for the SDK is `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions are squashed together but there shouldn't be any breaking changes between `MINOR|PATCH` releases. That's why it is important to use all three version numbers in composer when using the `~` operator, e.g. `~4.1.0`. This will ensure you don't inadvertently download a version with breaking changes in it.", + type: 'warning', +}) + Then run `composer install` from the command line, and composer will 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. @@ -51,9 +54,7 @@ require_once __DIR__ . '/vendor/autoload.php'; -## Installation Method 2 (if you really have to) {#autoloader} - -### Manually installing with the autoloader +## Manually installing (if you really have to) {#install-manually} First, download the source code and unzip it wherever you like in your project. @@ -67,7 +68,7 @@ First, download the source code and unzip it wherever you like in your project. Then include the autoloader provided in the SDK at the top of your script. ~~~ -require_once __DIR__ . '/path/to/facebook-php-sdk-v4/autoload.php'; +require_once __DIR__ . '/path/to/facebook-php-sdk-v4/src/Facebook/autoload.php'; ~~~ The autoloader should be able to auto-detect the proper location of the source code. @@ -79,16 +80,22 @@ The source code includes myriad files that aren't necessary for use in a product %FB(devsite:markdown-wiki:info-card { content: "For this example we'll assume the root of your website is `/var/html`.", - type: 'warning', + type: 'info', }) -After downloading the source code with the button above, extract the files in a temporary directory. Find the file called `autoloader.php` and move it into the `src/Facebook` folder. +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 3rd-party code. For this example we'll now rename the `Facebook` directory to `facebook-sdk-v4.1`. +Move the folder `src/Facebook` to the root of your website installation or where ever you like to put 3rd-party code. For this example we'll rename the `Facebook` directory to `facebook-sdk-v4.1`. The path the the core SDK files should now be located in `/var/html/facebook-sdk-v4.1` and inside will also be the `autolaoder.php` file. -Assuming we have a script called `index.php` in the root of our web project, we need to include the autoloader. But before we do, we need to define the new location of the source code before the `require_once` statement. We put his at the top of our script. +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. + +~~~ +require_once __DIR__ . '/facebook-sdk-v4.1/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. ~~~ define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v4.1/'); @@ -104,107 +111,110 @@ require_once __DIR__ . '/facebook-sdk-v4.1/autoload.php'; type: 'warning', }) -### The `FacebookApp` entity - -Before we can send requests to the Graph API, we need to load our app configuration into a `Facebook\FacebookApp` entity. +Before we can send requests to the Graph API, we need to load our app configuration into the `Facebook\Facebook` service. ~~~ -use Facebook\FacebookApp; - -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); ~~~ -The `FacebookApp` entity is one of the core dependencies that we need to pass along to the other objects. - -### The `FacebookClient` service +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](http://developers.facebook.com/apps). -In order to send requests to Graph we need to use the `Facebook\FacebookClient` service. - -~~~ -use Facebook\FacebookClient; +%FB(devsite:markdown-wiki:info-card { + content: "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 PHP SDK will choose one for you and it might not be one that is compatible with your app.", + type: 'warning', +}) -$facebookClient = new FacebookClient(); -~~~ +The `Facebook\Facebook` service ties all the components of the PHP SDK together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). ## Authentication and authorization {#authentication} -The SDK can be used to support logging into your site using a Facebook account. On the server-side, the SDK provides helper classes for the most common scenarios. +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 access tokens with the SDK using the [helper classes](/docs/php/reference#helpers). +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](/docs/php/reference#helpers). -For most websites, you'll use the `[Facebook\Helpers\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper)` 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. + +### Obtaining an access token from redirect {#authentication-redirect} + +For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) 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`](/docs/php/AccessToken) entity. %FB(devsite:markdown-wiki:info-card { - content: "For this example we'll assume `login.php` will present the login link and the user will be redirect to `login-callback.php` where we will obtain the access token.", - type: 'warning', + content: "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.", + type: 'info', }) ~~~ # login.php -use Facebook\FacebookApp; -use Facebook\Helpers\FacebookRedirectLoginHelper; - -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +$fb = new Facebook\Facebook([/* . . . */]); -$helper = new FacebookRedirectLoginHelper($facebookApp); +$helper = $fb->getRedirectLoginHelper(); $permissions = ['email', 'user_likes']; // optional $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions); echo 'Log in with Facebook!'; ~~~ +%FB(devsite:markdown-wiki:info-card { + content: "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.", + type: 'warning', +}) + ~~~ # login-callback.php -use Facebook\FacebookApp; -use Facebook\FacebookClient; -use Facebook\Helpers\FacebookRedirectLoginHelper; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; +$fb = new Facebook\Facebook([/* . . . */]); -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); - -$facebookClient = new FacebookClient(); -$helper = new FacebookRedirectLoginHelper(); +$helper = $fb->getRedirectLoginHelper(); try { - $accessToken = $helper->getAccessTokenFromRedirect($facebookClient); -} catch(FacebookResponseException $e) { + $accessToken = $helper->getAccessToken(); +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { + 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 + // 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'] } ~~~ -If your app is on Facebook Canvas, use the `getAccessToken()` method on [FacebookCanvasLoginHelper](/docs/php/FacebookCanvasLoginHelper) to get an `Facebook\AccessToken` entity for the user. -~~~ -use Facebook\FacebookApp; -use Facebook\FacebookClient; -use Facebook\Helpers\FacebookCanvasLoginHelper; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; +### Obtaining an access token from a Facebook Canvas context {#authentication-canvas} -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) to get an [`AccessToken`](/docs/php/AccessToken) entity for the user. -$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); +%FB(devsite:markdown-wiki:info-card { + content: "The `FacebookCanvasHelper` will detect a [signed request](https://developers.facebook.com/docs/reference/login/signed-request) 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](#authentication-redirect) or by using the [JavaScript SDK](https://developers.facebook.com/docs/javascript) and then use the PHP SDK to [obtain the access token from the cookie](#authentication-javascript) the JavaScript SDK set.", + type: 'warning', +}) + +~~~ +# example-canvas-app.php +$fb = new Facebook\Facebook([/* . . . */]); -$facebookClient = new FacebookClient(); -$canvasHelper = new FacebookCanvasLoginHelper($facebookApp); +$helper = $fb->getCanvasHelper(); try { - $accessToken = $canvasHelper->getAccessToken($facebookClient); -} catch(FacebookResponseException $e) { + $accessToken = $helper->getAccessToken(); +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { + 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)) { @@ -212,27 +222,31 @@ if (isset($accessToken)) { } ~~~ -If you're already using the Facebook SDK for JavaScript to authenticate users, you can also log them in on the server side with the [FacebookJavaScriptLoginHelper](/docs/php/FacebookJavaScriptLoginHelper). The `getAccessToken()` method will return a `Facebook\AccessToken` entity. +%FB(devsite:markdown-wiki:info-card { + content: "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`](/docs/php/FacebookPageTabHelper)", + type: 'info', +}) -~~~ -use Facebook\FacebookApp; -use Facebook\FacebookClient; -use Facebook\Helpers\FacebookJavaScriptLoginHelper; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +### Obtaining an access token from the JavaScript SDK {#authentication-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](/docs/php/FacebookJavaScriptHelper). The `getAccessToken()` method will return an [`AccessToken`](/docs/php/AccessToken) entity. -$facebookClient = new FacebookClient(); -$helper = new FacebookJavaScriptLoginHelper($facebookApp); +~~~ +# example-obtain-from-js-cookie-app.php +$fb = new Facebook\Facebook([/* . . . */]); + +$helper = $fb->getJavaScriptHelper(); try { - $accessToken = $helper->getAccessToken($facebookClient); -} catch(FacebookResponseException $e) { + $accessToken = $helper->getAccessToken(); +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { + 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)) { @@ -240,46 +254,75 @@ if (isset($accessToken)) { } ~~~ -You can also create a `Facebook\AccessToken` entity with an access token you've acquired through some other means, by passing it to the constructor. +%FB(devsite:markdown-wiki:info-card { + content: "Make sure you set the `{cookie:true}` option when you [initialize the JavaScript SDK](https://developers.facebook.com/docs/javascript/reference/FB.init). This will make the JavaScript SDK set a cookie on your domain containing information about the user in the form of a signed request.", + type: 'warning', +}) + + + +## Extending the access token {#extending-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`](/docs/php/OAuth2Client). ~~~ -use Facebook\AccessToken; +// OAuth 2.0 client handler +$oAuth2Client = $fb->getOAuth2Client(); -$accessToken = new AccessToken('{access-token}'); +// 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#extending). ## Making Requests to the Graph API {#making-requests} -Once you have created a `Facebook\FacebookApp` entity, instantiated a `Facebook\FacebookClient` and obtained an access token, you can begin making calls to the Graph API with the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity. +Once you have an instance of the `Facebook\Facebook` service and obtained an access token, you can begin making calls to the Graph API. -~~~ -use Facebook\FacebookApp; -use Facebook\FacebookRequest; -use Facebook\FacebookClient; -use Facebook\GraphNodes\GraphUser; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; +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. -$facebookApp = new FacebookApp('{app-id}', '{app-secret}'); +~~~ +$fb = new Facebook\Facebook([/* . . . */]); -// Get the Facebook\GraphNodes\GraphUser object for the current user: -$facebookClient = new FacebookClient(); -$request = new FacebookRequest($facebookApp, '{access-token}', 'GET', '/me'); +// Sets the default fallback access token so we don't have to pass it to each request +$fb->setDefaultAccessToken('{access-token}'); try { - $facebookResponse = $facebookClient->sendRequest($request); - $me = $facebookResponse->getGraphObject(GraphUser::className()); - echo 'Logged in as ' . $me->getName(); -} catch(FacebookResponseException $e) { + $response = $fb->get('/me'); + $userNode = $response->getGraphUser(); +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { + 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`](/docs/php/FacebookResponse) 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`](/docs/php/GraphObject#user-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. + +~~~ +try { + $response = $fb->get('/me'); +} catch(Facebook\Exceptions\FacebookSDKException $e) { + // . . . + exit; } + +$plainOldArray = $response->getDecodedBody(); ~~~ -For a full list of classes, see the [API reference page](/docs/php/reference). - \ No newline at end of file +For a full list of all of the components that make up the PHP SDK, see the [PHP SDK reference page](/docs/php/reference). + diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd index 30ddc8f97..fee95cda2 100644 --- a/docs/sdk_landing_page.fbmd +++ b/docs/sdk_landing_page.fbmd @@ -1,7 +1,9 @@ # Facebook SDK v4.1 for PHP -The Facebook SDK for PHP provides developers with a modern, native library for accessing the Graph API and taking advantage of Facebook Login. Usually this means you're developing with PHP for a Facebook Canvas app, building your own website, or adding server-side functionality to an app that already uses the [Facebook SDK for JavaScript](/docs/reference/javascript/). +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](/docs/reference/javascript/) to give the front-end user the best possible user experience. But it doesn't end there, the Facebook PHP SDK makes it easy to upload photos and videos and send batch requests to the Graph API among other things. And PHP SDK has many extensibility points giving PHP developers full control of how the PHP SDK 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 PHP SDK does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. Take a look through our guide, [Getting Started with the Facebook SDK for PHP](/docs/php/gettingstarted), and then check out some of the examples below. @@ -9,15 +11,26 @@ Take a look through our guide, [Getting Started with the Facebook SDK for PHP](/ ## Examples {#examples} -* [Retrieve a users profile](/docs/php/howto/profilewithgraphapi) -* [Post a link to a users feed](/docs/php/howto/postwithgraphapi) -* [Upload a photo to a users profile](/docs/php/howto/uploadphoto) - +For more complete examples, check out the [examples from the official repo on GitHub](). @todo + +- **Authentication & Signed Requests** + - [Facebook Login (OAuth 2.0)](/docs/php/howto/example_facebook_login) @todo + - [Obtaining an access token from the JavaScript SDK](/docs/php/howto/example_access_token_from_javascript) @todo + - [Obtaining an access token within a Facebook Canvas context](/docs/php/howto/example_access_token_from_canvas) @todo + - [Obtaining an access token within a Facebook Page tab context](/docs/php/howto/example_access_token_from_page_tab) @todo +- **User profile** + - [Retrieve a user's profile](/docs/php/howto/example_retrieve_user_profile) + - [Post a link to a user's feed](/docs/php/howto/example_post_links) +- **File Uploads** + - [Upload a photo to a user's profile](/docs/php/howto/example_upload_photo) + - [Upload a video to a user's profile](/docs/php/howto/example_upload_video) @todo +- **Batch Requests** + - [Sending requests in a batch](/docs/php/howto/example_batch_request) @todo + - [Uploading files in a batch](/docs/php/howto/example_batch_upload) @todo ## API Reference {#reference} For a full list of classes, see the API [reference page](/docs/php/reference). - - \ No newline at end of file + diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 624e1cebc..596f403fc 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -5,172 +5,172 @@ Below is the API reference for the Facebook PHP SDK. -# Services {#services} +# Core API {#core-api} -Services orchestrate multiple components of the SDK. +These classes are at the core of the Facebook PHP SDK. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\Facebook](/docs/php/Facebook)`', + '[`Facebook\Facebook`](/docs/php/Facebook)', 'The main service object that helps tie all the SDK components together.', ], [ - '`[Facebook\FacebookClient](/docs/php/FacebookClient)`', - 'A service object to send requests and receive responses from the Graph API.', + '[`Facebook\FacebookApp`](/docs/php/FacebookApp)', + 'An entity that represents a Facebook app and is required to send requests to Graph.', ], ], }) -# Entities {#entities} +# Authentication {#authentication} -Entities are representations of "real-world things". +These classes facilitate authenticating a Facebook user with OAuth 2.0. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\AccessToken](/docs/php/AccessToken)`', - 'An entity that represents an access token and is required to send requests to Graph.', - ], - [ - '`[Facebook\FacebookApp](/docs/php/FacebookApp)`', - 'An entity that represents a Facebook app and is required to send requests to Graph.', - ], - [ - '`[Facebook\FacebookBatchRequest](/docs/php/FacebookBatchRequest)`', - 'An entity that represents a batch request to be sent to Graph.', + '[`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper)', + 'An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link.', ], [ - '`[Facebook\FacebookBatchResponse](/docs/php/FacebookBatchResponse)`', - 'An entity that represents a response from Graph after sending a batch request.', + '[`Facebook\Authentication\AccessToken`](/docs/php/AccessToken)', + 'An entity that represents an access token.', ], [ - '`[Facebook\FacebookRequest](/docs/php/FacebookRequest)`', - 'An entity that represents a request to be sent to Graph.', + '[`Facebook\Authentication\AccessTokenMetadata`](/docs/php/AccessTokenMetadata)', + 'An entity that represents metadata from an access token.', ], [ - '`[Facebook\FacebookResponse](/docs/php/FacebookResponse)`', - 'An entity that represents a response from Graph.', - ], - [ - '`[Facebook\SignedRequest](/docs/php/SignedRequest)`', - 'An entity that represents a signed request.', + '[`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client)', + 'An OAuth 2.0 client that sends and receives HTTP requests related to user authentication.', ], ], }) -# Exceptions {#exeptions} +# Requests and Responses {#requests-and-responses} -When an error occurs, the SDK will throw an exception. +These classes are used in a Graph API request/response cycle. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\Exceptions\FacebookAuthenticationException](/docs/php/FacebookAuthenticationException)`', - 'Thrown when Graph returns an authentication error.', - ], - [ - '`[Facebook\Exceptions\FacebookAuthorizationException](/docs/php/FacebookAuthorizationException)`', - 'Thrown when Graph returns a user permissions error.', - ], - [ - '`[Facebook\Exceptions\FacebookClientException](/docs/php/FacebookClientException)`', - 'Thrown when Graph returns a duplicate post error.', - ], - [ - '`[Facebook\Exceptions\FacebookOtherException](/docs/php/FacebookOtherException)`', - 'Thrown when Graph returns an error that is unknown to the SDK.', + '[`Facebook\FacebookRequest`](/docs/php/FacebookRequest)', + 'An entity that represents an HTTP request to be sent to Graph.', ], [ - '`[Facebook\Exceptions\FacebookResponseException](/docs/php/FacebookResponseException)`', - 'The base exception to all Graph error responses. This exception is never thrown directly.', + '[`Facebook\FacebookResponse`](/docs/php/FacebookResponse)', + 'An entity that represents an HTTP response from Graph.', ], [ - '`[Facebook\Exceptions\FacebookSDKException](/docs/php/FacebookSDKException)`', - 'The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error.', + '[`Facebook\FacebookBatchRequest`](/docs/php/FacebookBatchRequest)', + 'An entity that represents an HTTP batch request to be sent to Graph.', ], [ - '`[Facebook\Exceptions\FacebookServerException](/docs/php/FacebookServerException)`', - 'Thrown when Graph returns a server error.', + '[`Facebook\FacebookBatchResponse`](/docs/php/FacebookBatchResponse)', + 'An entity that represents an HTTP response from Graph after sending a batch request.', ], [ - '`[Facebook\Exceptions\FacebookThrottleException](/docs/php/FacebookThrottleException)`', - 'Thrown when Graph returns a throttle error.', + '[`Facebook\FacebookClient`](/docs/php/FacebookClient)', + 'A service object to send HTTP requests and receive HTTP responses to and from the Graph API.', ], ], }) -# Graph nodes {#graph-nodes} +# Signed Requests {#signed-requests} -Graph nodes are collections that represent nodes returned by Graph. +Classes to help obtain and manage signed requests. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\GraphNodes\GraphObject](/docs/php/GraphObject)`', - 'The base collection object that represents a generic node.', - ], - [ - '`[Facebook\GraphNodes\GraphList](/docs/php/GraphList)`', - 'A list of GraphObject's with special methods to help paginate over the list.', + '[`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper)', + 'Used to obtain an access token or signed request from the cookie set by the JavaScript SDK.', ], [ - '`[Facebook\GraphNodes\GraphAlbum](/docs/php/GraphAlbum)`', - 'A collection that represents an album node.', + '[`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper)', + 'Used to obtain an access token or signed request from within the context of an app canvas.', ], [ - '`[Facebook\GraphNodes\GraphLocation](/docs/php/GraphLocation)`', - 'A collection that represents a location node.', + '[`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper)', + 'Used to obtain an access token or signed request from within the context of a page tab.', ], [ - '`[Facebook\GraphNodes\GraphPage](/docs/php/GraphPage)`', - 'A collection that represents a page node.', + '[`Facebook\SignedRequest`](/docs/php/SignedRequest)', + 'An entity that represents a signed request.', ], + ], +}) + + + +# Core Exceptions {#core-exceptions} + +These are the core exceptions that the SDK will throw when an error occurs. + +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ [ - '`[Facebook\GraphNodes\GraphSessionInfo](/docs/php/GraphSessionInfo)`', - '*(Deprecated)* A collection that represents a an access token node.', + '[`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException)', + 'The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error.', ], [ - '`[Facebook\GraphNodes\GraphUser](/docs/php/GraphUser)`', - 'A collection that represents a user node.', + '[`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException)', + 'The base exception to all Graph error responses. This exception is never thrown directly.', ], ], }) -# Helpers {#helpers} +# Graph Nodes and Edges {#graph-nodes-and-edges} -Helpers allow you to obtain access tokens and signed requests in various contexts. +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. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\Helpers\FacebookCanvasHelper](/docs/php/FacebookCanvasHelper)`', - 'Used to obtain an access token or signed request from within the context of an app canvas.', + '[`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject)', + 'The base collection object that represents a generic node.', ], [ - '`[Facebook\Helpers\FacebookJavaScriptHelper](/docs/php/FacebookJavaScriptHelper)`', - 'Used to obtain an access token or signed request from the cookie set by the JavaScript SDK.', + '[`Facebook\GraphNodes\GraphList`](/docs/php/GraphList)', + 'A collection of GraphObject's with special methods to help paginate over the edge.', ], [ - '`[Facebook\Helpers\FacebookPageTabHelper](/docs/php/FacebookPageTabHelper)`', - 'Used to obtain an access token or signed request from within the context of a page tab.', + '[`Facebook\GraphNodes\GraphAchievement`](/docs/php/GraphObject#achievement-instance-methods)', + 'A collection that represents an Achievement node.', + ], + [ + '[`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphObject#album-instance-methods)', + 'A collection that represents an Album node.', + ], + [ + '[`Facebook\GraphNodes\GraphLocation`](/docs/php/GraphObject#location-instance-methods)', + 'A collection that represents a Location node.', ], [ - '`[Facebook\Helpers\FacebookRedirectLoginHelper](/docs/php/FacebookRedirectLoginHelper)`', - 'Used to obtain a user access token from a redirect using a "Log in with Facebook" link.', + '[`Facebook\GraphNodes\GraphPage`](/docs/php/GraphObject#page-instance-methods)', + 'A collection that represents a Page node.', + ], + [ + '[`Facebook\GraphNodes\GraphPicture`](/docs/php/GraphObject#picture-instance-methods)', + 'A collection that represents a Picture node.', + ], + [ + '[`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods)', + 'A collection that represents a User node.', ], ], }) @@ -179,17 +179,17 @@ FB(devsite:markdown-wiki:table { # File Uploads {#file-uploads} -Special objects that represent files to be uploaded with a Graph request. +These are entities that represent files to be uploaded with a Graph request. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\FileUpload\FacebookFile](/docs/php/FacebookFile)`', + '[`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile)', 'Represents a generic file to be uploaded to the Graph API.', ], [ - '`[Facebook\FileUpload\FacebookVideo](/docs/php/FacebookVideo)`', + '[`Facebook\FileUpload\FacebookVideo`](/docs/php/FacebookVideo)', 'Represents a video file to be uploaded to the Graph API.', ], ], @@ -197,52 +197,56 @@ FB(devsite:markdown-wiki:table { -# HTTP clients {#http-clients} +# HTTP Clients {#http-clients} -Various HTTP clients that can be implemented to send and return requests to and from Graph. +Various HTTP clients that can be implemented to send and receive HTTP requests to and HTTP responses from Graph. FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`[Facebook\HttpClients\FacebookHttpCurlClient](/docs/php/FacebookHttpCurlClient)`', - 'The cURL HTTP client implementation. This is the default implementation.', + '[`Facebook\HttpClients\FacebookStreamHttpClient`](/docs/php/FacebookStreamHttpClient)', + 'The stream wrapper HTTP client implementation.', ], [ - '`[Facebook\HttpClients\FacebookStreamHttpClient](/docs/php/FacebookStreamHttpClient)`', - 'The stream wrapper HTTP client implementation. This is the fallback implementation if cURL is not detected.', + '[`Facebook\HttpClients\FacebookHttpCurlClient`](/docs/php/FacebookHttpCurlClient)', + 'The cURL HTTP client implementation.', ], [ - '`[Facebook\HttpClients\FacebookGuzzleHttpClient](/docs/php/FacebookGuzzleHttpClient)`', - 'The Guzzle HTTP client implementation. Requires installing Guzzle with Composer.', + '[`Facebook\HttpClients\FacebookGuzzleHttpClient`](/docs/php/FacebookGuzzleHttpClient)', + 'The Guzzle HTTP client implementation. (Requires installing Guzzle with Composer.)', ], ], }) -# Interfaces {#interfaces} +# Extensibility {#extensibility} -You can overwrite certain functionality of the SDK by coding to an interface. +You can overwrite certain functionality of the SDK by coding to an interface and injecting an instance of your custom functionality. FB(devsite:markdown-wiki:table { columns: ['Interface name','Description',], rows: [ [ - '`[Facebook\HttpClients\FacebookHttpClientInterface](/docs/php/FacebookHttpClientInterface)`', - 'Interface to code your own HTTP client implementation.', + '[`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface)', + 'An interface to code your own HTTP client implementation.', + ], + [ + '[`Facebook\Http\GraphRawResponse`](/docs/php/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](/docs/php/PersistentDataInterface)`', - 'Interface to code your own persistent data storage implementation.', + '[`Facebook\PersistentData\PersistentDataInterface`](/docs/php/PersistentDataInterface)', + 'An interface to code your own persistent data storage implementation.', ], [ - '`[Facebook\Url\UrlDetectionInterface](/docs/php/UrlDetectionInterface)`', - 'Interface to code your own URL detection logic.', + '[`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface)', + 'An interface to code your own URL detection logic.', ], [ - '`[Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface](/docs/php/PseudoRandomStringGeneratorInterface)`', - 'Interface to code your own cryptographically secure pseudo-random string generator.', + '[`Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface`](/docs/php/PseudoRandomStringGeneratorInterface)', + 'An interface to code your own cryptographically secure pseudo-random string generator.', ], ], }) From c38e53f0a403f5701a48e8541c169ce783745abb Mon Sep 17 00:00:00 2001 From: SammyK Date: Sun, 8 Feb 2015 15:01:52 -0500 Subject: [PATCH 104/407] Add PHP CodeSniffer and CONTRIBUTION instructions --- CONTRIBUTING.md | 45 ++++++++++++++++++++++++++++++++++++++------- composer.json | 1 + 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e45caf42a..ee390bf32 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,44 @@ Contributing ------------ -For us to accept contributions you will have to first have signed the -[Contributor License Agreement](https://developers.facebook.com/opensource/cla). +Contributions are **welcome** and will be fully **credited**. -When committing, keep all lines to less than 80 characters, and try to -follow the existing style. +We accept contributions via Pull Requests on [Github](https://github.com/facebook/facebook-php-sdk-v4). -Before creating a pull request, squash your commits into a single commit. -Add the comments where needed, and provide ample explanation in the -commit message. +## Pull Requests + +- **Sign the CLA** - For us to accept contributions you will have to first have signed the + [Contributor License Agreement](https://developers.facebook.com/opensource/cla). + +- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to run [PHP Code Sniffer](#running-php-code-sniffer) as you code. + +- **Add tests!** - Your patch won't be accepted if it doesn't have tests. + +- **Document any change in behaviour** - Make sure the README and the [documentation](https://github.com/facebook/facebook-php-sdk-v4/tree/master/docs) are kept up-to-date. + +- **Create topic branches** - Don't ask us to pull from your master branch. + +- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. + +- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting. + +- **Ensure tests pass!** - Please [run the tests](#running-tests) before submitting your pull request, and make sure they pass. We won't accept a patch until all tests pass. + +- **Ensure no coding standards violations** - Please [run PHP Code Sniffer](#running-php-code-sniffer) using the PSR-2 standard before submitting your pull request. A violation will cause the build to fail, so please make sure there are no violations. We can't accept a patch if the build fails. + + +## Running Tests + +``` bash +$ ./vendor/bin/phpunit +``` + + +## Running PHP Code Sniffer + +``` bash +$ ./vendor/bin/phpcs src --standard=psr2 -sp +``` + +**Happy coding**! diff --git a/composer.json b/composer.json index 63de9a546..b7f47052d 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "require-dev": { "phpunit/phpunit": "~4.0", "mockery/mockery": "~0.8", + "squizlabs/php_codesniffer": "~2.0", "guzzlehttp/guzzle": "~5.0" }, "suggest": { From 25692b6cf5d0d889db7875e189d9fefe483bc3c8 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Mon, 9 Feb 2015 19:28:52 -0600 Subject: [PATCH 105/407] making Facbebook\PseudiRandomString namespace PSR2 compliant --- .../McryptPseudoRandomStringGenerator.php | 64 +++++++------ .../OpenSslPseudoRandomStringGenerator.php | 81 ++++++++--------- .../PseudoRandomStringGeneratorInterface.php | 26 +++--- .../PseudoRandomStringGeneratorTrait.php | 62 ++++++------- .../UrandomPseudoRandomStringGenerator.php | 91 +++++++++---------- 5 files changed, 158 insertions(+), 166 deletions(-) diff --git a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php index 51c7fa3d0..558152bdf 100644 --- a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php @@ -27,44 +27,42 @@ class McryptPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { + use PseudoRandomStringGeneratorTrait; - use PseudoRandomStringGeneratorTrait; + /** + * @const string The error message when generating the string fails. + */ + const ERROR_MESSAGE = 'Unable to generate a cryptographically secure ' + .'pseudo-random string from mcrypt_create_iv(). '; - /** - * @const string The error message when generating the string fails. - */ - const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from mcrypt_create_iv(). '; - - /** - * @throws FacebookSDKException - */ - public function __construct() - { - if ( ! function_exists('mcrypt_create_iv')) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'The function mcrypt_create_iv() does not exist.' - ); + /** + * @throws FacebookSDKException + */ + public function __construct() + { + if (!function_exists('mcrypt_create_iv')) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'The function mcrypt_create_iv() does not exist.' + ); + } } - } - /** - * @inheritdoc - */ - public function getPseudoRandomString($length) - { - $this->validateLength($length); + /** + * @inheritdoc + */ + public function getPseudoRandomString($length) + { + $this->validateLength($length); - $binaryString = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); + $binaryString = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); - if ($binaryString === false) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'mcrypt_create_iv() returned an error.' - ); + if ($binaryString === false) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'mcrypt_create_iv() returned an error.' + ); + } + return $this->binToHex($binaryString, $length); } - - return $this->binToHex($binaryString, $length); - } - } diff --git a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php index 68a1c8895..bb01e0287 100644 --- a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php @@ -27,53 +27,52 @@ class OpenSslPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { + use PseudoRandomStringGeneratorTrait; - use PseudoRandomStringGeneratorTrait; + /** + * @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(). '; - /** - * @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(). '; - - /** - * @throws FacebookSDKException - */ - public function __construct() - { - if ( ! function_exists('openssl_random_pseudo_bytes')) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'The function openssl_random_pseudo_bytes() does not exist.' - ); + /** + * @throws FacebookSDKException + */ + public function __construct() + { + if (!function_exists('openssl_random_pseudo_bytes')) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'The function openssl_random_pseudo_bytes() does not exist.' + ); + } } - } - /** - * @inheritdoc - */ - public function getPseudoRandomString($length) - { - $this->validateLength($length); + /** + * @inheritdoc + */ + public function getPseudoRandomString($length) + { + $this->validateLength($length); - $wasCryptographicallyStrong = false; - $binaryString = openssl_random_pseudo_bytes($length, $wasCryptographicallyStrong); + $wasCryptographicallyStrong = false; + $binaryString = openssl_random_pseudo_bytes($length, $wasCryptographicallyStrong); - if ($binaryString === false) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'openssl_random_pseudo_bytes() returned an unknown error.' - ); - } + if ($binaryString === false) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'openssl_random_pseudo_bytes() returned an unknown error.' + ); + } - if ($wasCryptographicallyStrong !== true) { - 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.' - ); - } - - return $this->binToHex($binaryString, $length); - } + if ($wasCryptographicallyStrong !== true) { + 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.' + ); + } + return $this->binToHex($binaryString, $length); + } } diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php index 95aa1cdcf..fd27510ab 100755 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php @@ -29,18 +29,16 @@ */ interface PseudoRandomStringGeneratorInterface { - - /** - * Get a cryptographically secure pseudo-random string of arbitrary length. - * - * @see http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ - * - * @param int $length The length of the string to return. - * - * @return string - * - * @throws \Facebook\Exceptions\FacebookSDKException|\InvalidArgumentException - */ - public function getPseudoRandomString($length); - + /** + * Get a cryptographically secure pseudo-random string of arbitrary length. + * + * @see http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ + * + * @param int $length The length of the string to return. + * + * @return string + * + * @throws \Facebook\Exceptions\FacebookSDKException|\InvalidArgumentException + */ + public function getPseudoRandomString($length); } diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index 82da39f31..dbcf78e0d 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -25,40 +25,38 @@ 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' + ); + } - /** - * 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' + ); + } } - 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. + * + * @return string + */ + public function binToHex($binaryData, $length) + { + return mb_substr(bin2hex($binaryData), 0, $length); } - } - - /** - * 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. - * - * @return string - */ - public function binToHex($binaryData, $length) - { - return mb_substr(bin2hex($binaryData), 0, $length); - } - } diff --git a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php index 6706ee47d..ae4e9e6e9 100644 --- a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php @@ -28,59 +28,58 @@ class UrandomPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { - use PseudoRandomStringGeneratorTrait; + use PseudoRandomStringGeneratorTrait; - /** - * @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 string The error message when generating the string fails. + */ + const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from /dev/urandom. '; - /** - * @throws FacebookSDKException - */ - public function __construct() - { - if (ini_get('open_basedir')) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'There is an open_basedir constraint that prevents access to /dev/urandom.' - ); - } + /** + * @throws FacebookSDKException + */ + public function __construct() + { + if (ini_get('open_basedir')) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'There is an open_basedir constraint that prevents access to /dev/urandom.' + ); + } - if ( ! is_readable('/dev/urandom')) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'Unable to read from /dev/urandom.' - ); + if (!is_readable('/dev/urandom')) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Unable to read from /dev/urandom.' + ); + } } - } - /** - * @inheritdoc - */ - public function getPseudoRandomString($length) - { - $this->validateLength($length); + /** + * @inheritdoc + */ + public function getPseudoRandomString($length) + { + $this->validateLength($length); - $stream = fopen('/dev/urandom', 'rb'); - if ( ! is_resource($stream)) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'Unable to open stream to /dev/urandom.' - ); - } + $stream = fopen('/dev/urandom', 'rb'); + if (!is_resource($stream)) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Unable to open stream to /dev/urandom.' + ); + } - $binaryString = fread($stream, $length); - fclose($stream); + $binaryString = fread($stream, $length); + fclose($stream); - if( ! $binaryString) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'Stream to /dev/urandom returned no data.' - ); - } - - return $this->binToHex($binaryString, $length); - } + if (!$binaryString) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Stream to /dev/urandom returned no data.' + ); + } + return $this->binToHex($binaryString, $length); + } } From 8ca076f2b18302a27d626ff30c81c9aceccba4b2 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Mon, 9 Feb 2015 19:38:00 -0600 Subject: [PATCH 106/407] making Facbebook\PersistentData namespace PSR2 compliant --- .../FacebookMemoryPersistentDataHandler.php | 42 +++++------ .../FacebookSessionPersistentDataHandler.php | 74 +++++++++---------- .../PersistentDataInterface.php | 32 ++++---- 3 files changed, 72 insertions(+), 76 deletions(-) diff --git a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php index fef9b6d69..27832aef6 100644 --- a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php @@ -29,28 +29,26 @@ */ class FacebookMemoryPersistentDataHandler implements PersistentDataInterface { + /** + * @var array The session data to keep in memory. + */ + protected $sessionData = []; - /** - * @var array The session data to keep in memory. - */ - protected $sessionData = []; - - /** - * @inheritdoc - */ - public function get($key) - { - return isset($this->sessionData[$key]) - ? $this->sessionData[$key] - : null; - } - - /** - * @inheritdoc - */ - public function set($key, $value) - { - $this->sessionData[$key] = $value; - } + /** + * @inheritdoc + */ + public function get($key) + { + return isset($this->sessionData[$key]) + ? $this->sessionData[$key] + : null; + } + /** + * @inheritdoc + */ + public function set($key, $value) + { + $this->sessionData[$key] = $value; + } } diff --git a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php index 087fa72bf..40c2d5e81 100644 --- a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php @@ -31,45 +31,45 @@ */ class FacebookSessionPersistentDataHandler implements PersistentDataInterface { + /** + * @var string Prefix to use for session variables. + */ + protected $sessionPrefix = 'FBRLH_'; - /** - * @var string Prefix to use for session variables. - */ - protected $sessionPrefix = 'FBRLH_'; - - /** - * Init the session handler. - * - * @param boolean $enableSessionCheck - * - * @throws FacebookSDKException - */ - public function __construct($enableSessionCheck = true) - { - if ($enableSessionCheck - && session_status() !== PHP_SESSION_ACTIVE) { - throw new FacebookSDKException( - 'Sessions are not active. Please make sure session_start() is at the top of your script.', 720 - ); + /** + * Init the session handler. + * + * @param boolean $enableSessionCheck + * + * @throws FacebookSDKException + */ + public function __construct($enableSessionCheck = true) + { + if ($enableSessionCheck + && session_status() !== PHP_SESSION_ACTIVE) { + throw new FacebookSDKException( + 'Sessions are not active. Please make sure session_start() is '. + ' at the top of your script.', + 720 + ); + } } - } - - /** - * @inheritdoc - */ - public function get($key) - { - return isset($_SESSION[$this->sessionPrefix . $key]) - ? $_SESSION[$this->sessionPrefix . $key] - : null; - } - /** - * @inheritdoc - */ - public function set($key, $value) - { - $_SESSION[$this->sessionPrefix . $key] = $value; - } + /** + * @inheritdoc + */ + public function get($key) + { + return isset($_SESSION[$this->sessionPrefix . $key]) + ? $_SESSION[$this->sessionPrefix . $key] + : null; + } + /** + * @inheritdoc + */ + public function set($key, $value) + { + $_SESSION[$this->sessionPrefix . $key] = $value; + } } diff --git a/src/Facebook/PersistentData/PersistentDataInterface.php b/src/Facebook/PersistentData/PersistentDataInterface.php index 53dc5731c..942f25008 100644 --- a/src/Facebook/PersistentData/PersistentDataInterface.php +++ b/src/Facebook/PersistentData/PersistentDataInterface.php @@ -29,22 +29,20 @@ */ interface PersistentDataInterface { + /** + * Get a value from a persistent data store. + * + * @param string $key + * + * @return mixed + */ + public function get($key); - /** - * Get a value from a persistent data store. - * - * @param string $key - * - * @return mixed - */ - public function get($key); - - /** - * Set a value in the persistent data store. - * - * @param string $key - * @param mixed $value - */ - public function set($key, $value); - + /** + * Set a value in the persistent data store. + * + * @param string $key + * @param mixed $value + */ + public function set($key, $value); } From 38e0c6da0e20240870a7178d8d2cbb9cc6f38ca2 Mon Sep 17 00:00:00 2001 From: acymru Date: Mon, 9 Feb 2015 19:47:25 -0600 Subject: [PATCH 107/407] Reformatted error message for PseudoRandomStringGeneratorInterface --- src/Facebook/Facebook.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index c9bc90529..7e6b0d9ae 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -194,7 +194,8 @@ public function __construct(array $config = []) $this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator(); } else { throw new \InvalidArgumentException( - 'The pseudo_random_string_generator must be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface' + 'The pseudo_random_string_generator must be set to "mcrypt", "openssl", or "urandom", ' + . 'or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface' ); } } @@ -209,7 +210,7 @@ public function __construct(array $config = []) } else { throw new \InvalidArgumentException( 'The persistent_data_handler must be set to "session", "memory", ' - . ' or be an instance of Facebook\PersistentData\PersistentDataInterface' + . 'or be an instance of Facebook\PersistentData\PersistentDataInterface' ); } } From 93f2eafa9e5019b3ff1d772c05e1bdbf5c7cee52 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 9 Feb 2015 20:00:42 -0600 Subject: [PATCH 108/407] fixed enviroment variable false positive --- tests/FacebookTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 388df787d..c0c34d2ef 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -34,6 +34,9 @@ use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphList; +putenv(Facebook::APP_ID_ENV_NAME.'=234'); +putenv(Facebook::APP_SECRET_ENV_NAME.'=foo_secret'); + class FooClientInterface implements FacebookHttpClientInterface { public function send($url, $method, $body, array $headers, $timeOut) { @@ -75,6 +78,7 @@ class FacebookTest extends \PHPUnit_Framework_TestCase */ public function testInstantiatingWithoutAppIdThrows() { + putenv(Facebook::APP_ID_ENV_NAME.'='); $config = [ 'app_secret' => 'foo_secret', ]; @@ -86,6 +90,7 @@ public function testInstantiatingWithoutAppIdThrows() */ public function testInstantiatingWithoutAppSecretThrows() { + putenv(Facebook::APP_SECRET_ENV_NAME.'='); $config = [ 'app_id' => 'foo_id', ]; From 0d9911495c493a37d7651bb84c35f5d8dc26159b Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 11:06:46 -0600 Subject: [PATCH 109/407] converting get method to one 82 character line --- .../PersistentData/FacebookMemoryPersistentDataHandler.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php index 27832aef6..2d1682dd9 100644 --- a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php @@ -39,9 +39,7 @@ class FacebookMemoryPersistentDataHandler implements PersistentDataInterface */ public function get($key) { - return isset($this->sessionData[$key]) - ? $this->sessionData[$key] - : null; + return isset($this->sessionData[$key]) ? $this->sessionData[$key] : null; } /** From fce0742bef0236babf59cbe4aeb21aeac9895a5f Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 11:11:25 -0600 Subject: [PATCH 110/407] adding extra line between control statement and return --- .../PseudoRandomString/McryptPseudoRandomStringGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php index 558152bdf..b2c5eb306 100644 --- a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php @@ -63,6 +63,7 @@ public function getPseudoRandomString($length) 'mcrypt_create_iv() returned an error.' ); } + return $this->binToHex($binaryString, $length); } } From f110cc9e456e27818270b38e5069c5b8c1899b06 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 11:20:00 -0600 Subject: [PATCH 111/407] single line long error message string --- .../PseudoRandomString/McryptPseudoRandomStringGenerator.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php index b2c5eb306..63c271f73 100644 --- a/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/McryptPseudoRandomStringGenerator.php @@ -32,8 +32,7 @@ class McryptPseudoRandomStringGenerator implements PseudoRandomStringGeneratorIn /** * @const string The error message when generating the string fails. */ - const ERROR_MESSAGE = 'Unable to generate a cryptographically secure ' - .'pseudo-random string from mcrypt_create_iv(). '; + const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from mcrypt_create_iv(). '; /** * @throws FacebookSDKException From bed328a1c4bb599618c20d332ce1d2e37f51e2f9 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 11 Feb 2015 12:31:02 -0600 Subject: [PATCH 112/407] Added comments --- tests/FacebookTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index c0c34d2ef..16204dec2 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -34,8 +34,6 @@ use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphList; -putenv(Facebook::APP_ID_ENV_NAME.'=234'); -putenv(Facebook::APP_SECRET_ENV_NAME.'=foo_secret'); class FooClientInterface implements FacebookHttpClientInterface { @@ -78,6 +76,7 @@ class FacebookTest extends \PHPUnit_Framework_TestCase */ public function testInstantiatingWithoutAppIdThrows() { + // unset value so there is no fallback to test expected Exception putenv(Facebook::APP_ID_ENV_NAME.'='); $config = [ 'app_secret' => 'foo_secret', @@ -90,6 +89,7 @@ public function testInstantiatingWithoutAppIdThrows() */ public function testInstantiatingWithoutAppSecretThrows() { + // unset value so there is no fallback to test expected Exception putenv(Facebook::APP_SECRET_ENV_NAME.'='); $config = [ 'app_id' => 'foo_id', From 1c8593a68cd8a5fc7072738cfe900d5e9f9f26e1 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 11 Feb 2015 16:01:29 -0600 Subject: [PATCH 113/407] Fix for invalid PHP syntax --- .../PseudoRandomString/OpenSslPseudoRandomStringGenerator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php index bb01e0287..983ca6a6c 100644 --- a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php @@ -32,8 +32,8 @@ 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(). '; + const ERROR_MESSAGE = + 'Unable to generate a cryptographically secure pseudo-random string from openssl_random_pseudo_bytes(). '; /** * @throws FacebookSDKException From 7f26fe3f58aae7fd53767175cdddeb83f88dda35 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 17 Feb 2015 17:53:37 -0600 Subject: [PATCH 114/407] Alex L: removing useless line --- tests/FacebookTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 16204dec2..215d6df2c 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -34,7 +34,6 @@ use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphList; - class FooClientInterface implements FacebookHttpClientInterface { public function send($url, $method, $body, array $headers, $timeOut) { From a5ff7e0939b67a2a7c7a3e60cc20ff483fa6a87d Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Mon, 9 Feb 2015 19:17:39 -0600 Subject: [PATCH 115/407] making Facbebook\URL namespace PSR2 compliant --- .../Url/FacebookUrlDetectionHandler.php | 247 +++++++++-------- src/Facebook/Url/FacebookUrlManipulator.php | 250 +++++++++--------- src/Facebook/Url/UrlDetectionInterface.php | 13 +- 3 files changed, 254 insertions(+), 256 deletions(-) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index 90e5925d0..2cebe2ad5 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -30,142 +30,139 @@ class FacebookUrlDetectionHandler implements UrlDetectionInterface { - /** - * @inheritdoc - */ - public function getCurrentUrl() - { - return $this->getHttpScheme() . '://' - . $this->getHostName() - . $this->getServerVar('REQUEST_URI'); - } - - /** - * Get the currently active URL scheme. - * - * @return string - */ - protected function getHttpScheme() - { - return $this->isBehindSsl() ? 'https' : 'http'; - } - - /** - * Tries to detect if the server is running behind an SSL. - * - * @return boolean - */ - protected function isBehindSsl() - { - // Check for proxy first - $protocol = $this->getHeader('X_FORWARDED_PROTO'); - if ($protocol) { - return $this->protocolWithActiveSsl($protocol); + /** + * @inheritdoc + */ + public function getCurrentUrl() + { + return $this->getHttpScheme() . '://' + . $this->getHostName() + . $this->getServerVar('REQUEST_URI'); } - $protocol = $this->getServerVar('HTTPS'); - if ($protocol) { - return $this->protocolWithActiveSsl($protocol); + /** + * Get the currently active URL scheme. + * + * @return string + */ + protected function getHttpScheme() + { + return $this->isBehindSsl() ? 'https' : 'http'; } - return (string) $this->getServerVar('SERVER_PORT') === '443'; - } - - /** - * Detects an active SSL protocol value. - * - * @param string $protocol - * - * @return boolean - */ - protected function protocolWithActiveSsl($protocol) - { - $protocol = strtolower((string) $protocol); - return ( - $protocol === 'on' - || $protocol === '1' - || $protocol === 'https' - || $protocol === 'ssl' - ); - } - - /** - * Tries to detect the host name of the server. - * Some elements adapted from - * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php - * - * @return string - */ - protected function getHostName() - { - // Check for proxy first - if ($host = $this->getHeader('X_FORWARDED_HOST')) { - $elements = explode(',', $host); - $host = $elements[count($elements) - 1]; - } elseif ( ! $host = $this->getHeader('HOST')) { - if ( ! $host = $this->getServerVar('SERVER_NAME')) { - $host = $this->getServerVar('SERVER_ADDR'); - } + /** + * Tries to detect if the server is running behind an SSL. + * + * @return boolean + */ + protected function isBehindSsl() + { + // Check for proxy first + $protocol = $this->getHeader('X_FORWARDED_PROTO'); + if ($protocol) { + return $this->protocolWithActiveSsl($protocol); + } + + $protocol = $this->getServerVar('HTTPS'); + if ($protocol) { + return $this->protocolWithActiveSsl($protocol); + } + + return (string) $this->getServerVar('SERVER_PORT') === '443'; } - // trim and remove port number from host - // host is lowercase as per RFC 952/2181 - $host = strtolower(preg_replace('/:\d+$/', '', trim($host))); - - // Port number - $scheme = $this->getHttpScheme(); - $port = $this->getCurrentPort(); - $appendPort = ':' . $port; - - // Don't append port number if a normal port. - if ( - ($scheme == 'http' && $port == '80') - || ($scheme == 'https' && $port == '443') - ) { - $appendPort = ''; + /** + * Detects an active SSL protocol value. + * + * @param string $protocol + * + * @return boolean + */ + protected function protocolWithActiveSsl($protocol) + { + $protocol = strtolower((string) $protocol); + return ( + $protocol === 'on' + || $protocol === '1' + || $protocol === 'https' + || $protocol === 'ssl' + ); } - return $host . $appendPort; - } - - protected function getCurrentPort() - { - // Check for proxy first - $port = $this->getHeader('X_FORWARDED_PORT'); - if ($port) { - return (string) $port; + /** + * Tries to detect the host name of the server. + * Some elements adapted from + * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php + * + * @return string + */ + protected function getHostName() + { + // Check for proxy first + if ($host = $this->getHeader('X_FORWARDED_HOST')) { + $elements = explode(',', $host); + $host = $elements[count($elements) - 1]; + } elseif (!$host = $this->getHeader('HOST')) { + if (!$host = $this->getServerVar('SERVER_NAME')) { + $host = $this->getServerVar('SERVER_ADDR'); + } + } + + // trim and remove port number from host + // host is lowercase as per RFC 952/2181 + $host = strtolower(preg_replace('/:\d+$/', '', trim($host))); + + // Port number + $scheme = $this->getHttpScheme(); + $port = $this->getCurrentPort(); + $appendPort = ':' . $port; + + // Don't append port number if a normal port. + if (($scheme == 'http' && $port == '80') + || ($scheme == 'https' && $port == '443')) { + $appendPort = ''; + } + + return $host . $appendPort; } - $protocol = (string) $this->getHeader('X_FORWARDED_PROTO'); - if ($protocol === 'https') { - return '443'; + protected function getCurrentPort() + { + // Check for proxy first + $port = $this->getHeader('X_FORWARDED_PORT'); + if ($port) { + return (string) $port; + } + + $protocol = (string) $this->getHeader('X_FORWARDED_PROTO'); + if ($protocol === 'https') { + return '443'; + } + + return (string) $this->getServerVar('SERVER_PORT'); } - return (string) $this->getServerVar('SERVER_PORT'); - } - - /** - * Returns the a value from the $_SERVER super global. - * - * @param string $key - * - * @return string - */ - protected function getServerVar($key) - { - return isset($_SERVER[$key]) ? $_SERVER[$key] : ''; - } - - /** - * Gets a value from the HTTP request headers. - * - * @param string $key - * - * @return string - */ - protected function getHeader($key) - { - return $this->getServerVar('HTTP_' . $key); - } + /** + * Returns the a value from the $_SERVER super global. + * + * @param string $key + * + * @return string + */ + protected function getServerVar($key) + { + return isset($_SERVER[$key]) ? $_SERVER[$key] : ''; + } + /** + * Gets a value from the HTTP request headers. + * + * @param string $key + * + * @return string + */ + protected function getHeader($key) + { + return $this->getServerVar('HTTP_' . $key); + } } diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index f19eb3913..a625f457d 100755 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -29,138 +29,140 @@ */ class FacebookUrlManipulator { - - /** - * Remove params from a URL. - * - * @param string $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) - { - $parts = parse_url($url); - - $query = ''; - if (isset($parts['query'])) { - $params = []; - parse_str($parts['query'], $params); - - // Remove query params - foreach ($paramsToFilter as $paramName) { - unset($params[$paramName]); - } - - if (count($params) > 0) { - $query = '?' . http_build_query($params, null, '&'); - } + /** + * Remove params from a URL. + * + * @param string $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) + { + $parts = parse_url($url); + + $query = ''; + if (isset($parts['query'])) { + $params = []; + parse_str($parts['query'], $params); + + // Remove query params + foreach ($paramsToFilter as $paramName) { + unset($params[$paramName]); + } + + if (count($params) > 0) { + $query = '?' . http_build_query($params, null, '&'); + } + } + + $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; + $host = isset($parts['host']) ? $parts['host'] : ''; + $port = isset($parts['port']) ? ':' . $parts['port'] : ''; + $path = isset($parts['path']) ? $parts['path'] : ''; + $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; + + return $scheme . $host . $port . $path . $query . $fragment; } - $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; - $host = isset($parts['host']) ? $parts['host'] : ''; - $port = isset($parts['port']) ? ':' . $parts['port'] : ''; - $path = isset($parts['path']) ? $parts['path'] : ''; - $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; - - return $scheme . $host . $port . $path . $query . $fragment; - } - - /** - * Gracefully appends params to the URL. - * - * @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 = []) - { - if ( ! $newParams) { - return $url; + /** + * Gracefully appends params to the URL. + * + * @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 = []) + { + if (!$newParams) { + return $url; + } + + if (strpos($url, '?') === false) { + return $url . '?' . http_build_query($newParams, null, '&'); + } + + list($path, $query) = explode('?', $url, 2); + $existingParams = []; + parse_str($query, $existingParams); + + // Favor params from the original URL over $newParams + $newParams = array_merge($newParams, $existingParams); + + // Sort for a predicable order + ksort($newParams); + + return $path . '?' . http_build_query($newParams, null, '&'); } - if (strpos($url, '?') === false) { - return $url . '?' . http_build_query($newParams, null, '&'); + /** + * Returns the params from a URL in the form of an array. + * + * @param string $url The URL to parse the params from. + * + * @return array + */ + public static function getParamsAsArray($url) + { + $query = parse_url($url, PHP_URL_QUERY); + if (!$query) { + return []; + } + $params = []; + parse_str($query, $params); + + return $params; } - list($path, $query) = explode('?', $url, 2); - $existingParams = []; - parse_str($query, $existingParams); - - // Favor params from the original URL over $newParams - $newParams = array_merge($newParams, $existingParams); - - // Sort for a predicable order - ksort($newParams); - - return $path . '?' . http_build_query($newParams, null, '&'); - } - - /** - * Returns the params from a URL in the form of an array. - * - * @param string $url The URL to parse the params from. - * - * @return array - */ - public static function getParamsAsArray($url) - { - $query = parse_url($url, PHP_URL_QUERY); - if ( ! $query) { - return []; - } - $params = []; - parse_str($query, $params); - - return $params; - } - - /** - * Adds the params of the first URL to the second URL. - * Any params that already exist in the second URL will go untouched. - * - * @param string $urlToStealFrom The URL harvest the params from. - * @param string $urlToAddTo The URL that will receive the new params. - * - * @return string The $urlToAddTo with any new params from $urlToStealFrom. - */ - public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) - { - $newParams = static::getParamsAsArray($urlToStealFrom); - // Nothing new to add, return as-is - if ( ! $newParams) { - return $urlToAddTo; + /** + * Adds the params of the first URL to the second URL. + * Any params that already exist in the second URL will go untouched. + * + * @param string $urlToStealFrom The URL harvest the params from. + * @param string $urlToAddTo The URL that will receive the new params. + * + * @return string The $urlToAddTo with any new params from $urlToStealFrom. + */ + public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) + { + $newParams = static::getParamsAsArray($urlToStealFrom); + // Nothing new to add, return as-is + if (!$newParams) { + return $urlToAddTo; + } + + return static::appendParamsToUrl($urlToAddTo, $newParams); } - return static::appendParamsToUrl($urlToAddTo, $newParams); - } - - /** - * Check for a "/" prefix and prepend it if not exists. - * - * @param string|null $string - * - * @return string|null - */ - public static function forceSlashPrefix($string) - { - if (!$string) { - return $string; + /** + * Check for a "/" prefix and prepend it if not exists. + * + * @param string|null $string + * + * @return string|null + */ + public static function forceSlashPrefix($string) + { + if (!$string) { + return $string; + } + return strpos($string, '/') === 0 ? $string : '/' . $string; } - return strpos($string, '/') === 0 ? $string : '/' . $string; - } - - /** - * Trims off the hostname and Graph version from a URL. - * - * @param string $urlToTrim The URL the needs the surgery. - * - * @return string The $urlToTrim with the hostname and Graph version removed. - */ - public static function baseGraphUrlEndpoint($urlToTrim) - { - return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); - } + /** + * Trims off the hostname and Graph version from a URL. + * + * @param string $urlToTrim The URL the needs the surgery. + * + * @return string The $urlToTrim with the hostname and Graph version removed. + */ + public static function baseGraphUrlEndpoint($urlToTrim) + { + return '/' . preg_replace( + '/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', + '', + $urlToTrim + ); + } } diff --git a/src/Facebook/Url/UrlDetectionInterface.php b/src/Facebook/Url/UrlDetectionInterface.php index dbe44e92b..e7323c030 100755 --- a/src/Facebook/Url/UrlDetectionInterface.php +++ b/src/Facebook/Url/UrlDetectionInterface.php @@ -30,11 +30,10 @@ interface UrlDetectionInterface { - /** - * Get the currently active URL. - * - * @return string - */ - public function getCurrentUrl(); - + /** + * Get the currently active URL. + * + * @return string + */ + public function getCurrentUrl(); } From 5f1df61bc0db2d415e3e27d7dd14a6b5fb2e72f0 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 11:24:28 -0600 Subject: [PATCH 116/407] adding extra line between control statement and return --- src/Facebook/Url/FacebookUrlManipulator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index a625f457d..1d6640917 100755 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -147,6 +147,7 @@ public static function forceSlashPrefix($string) if (!$string) { return $string; } + return strpos($string, '/') === 0 ? $string : '/' . $string; } From 0a0273d916a8f9e36b607d525cef3d3ccdcc507b Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 11:28:16 -0600 Subject: [PATCH 117/407] refactor protocolWithActiveSsl method --- src/Facebook/Url/FacebookUrlDetectionHandler.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index 2cebe2ad5..c0d066bac 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -81,12 +81,7 @@ protected function isBehindSsl() protected function protocolWithActiveSsl($protocol) { $protocol = strtolower((string) $protocol); - return ( - $protocol === 'on' - || $protocol === '1' - || $protocol === 'https' - || $protocol === 'ssl' - ); + return in_array($protocol, array('on','1','https','ssl'), true); } /** From 6afb501b73e58626845ec228b13e07b134d27be7 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 11:30:32 -0600 Subject: [PATCH 118/407] refactoring getCurrentUrl to single line; playing nice --- src/Facebook/Url/FacebookUrlDetectionHandler.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index c0d066bac..ec3809c61 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -35,9 +35,7 @@ class FacebookUrlDetectionHandler implements UrlDetectionInterface */ public function getCurrentUrl() { - return $this->getHttpScheme() . '://' - . $this->getHostName() - . $this->getServerVar('REQUEST_URI'); + return $this->getHttpScheme() . '://' . $this->getHostName() . $this->getServerVar('REQUEST_URI'); } /** From c5f6c89dfa183eb7fb83b714c960261fbed32a13 Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 13:06:02 -0600 Subject: [PATCH 119/407] adding line return before return --- src/Facebook/Url/FacebookUrlDetectionHandler.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index ec3809c61..ea579d425 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -79,6 +79,7 @@ protected function isBehindSsl() protected function protocolWithActiveSsl($protocol) { $protocol = strtolower((string) $protocol); + return in_array($protocol, array('on','1','https','ssl'), true); } From 883406f8a6d2aca4f1d334e2f314b941a31fe5af Mon Sep 17 00:00:00 2001 From: Steven Maguire Date: Tue, 10 Feb 2015 13:06:27 -0600 Subject: [PATCH 120/407] adding spaces after commas in array :facepalm: --- src/Facebook/Url/FacebookUrlDetectionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index ea579d425..e37167842 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -80,7 +80,7 @@ protected function protocolWithActiveSsl($protocol) { $protocol = strtolower((string) $protocol); - return in_array($protocol, array('on','1','https','ssl'), true); + return in_array($protocol, array('on', '1', 'https', 'ssl'), true); } /** From 8f40ea0506ebefa27da29e2d4b4ce5d49526e5f9 Mon Sep 17 00:00:00 2001 From: Rocco Palladino Date: Mon, 9 Feb 2015 20:01:14 -0600 Subject: [PATCH 121/407] Bring Facebook\Http src and tests into PSR-2 compliance --- src/Facebook/Http/GraphRawResponse.php | 183 +++++++++-------- src/Facebook/Http/RequestBodyInterface.php | 13 +- src/Facebook/Http/RequestBodyMultipart.php | 212 ++++++++++---------- src/Facebook/Http/RequestBodyUrlEncoded.php | 41 ++-- tests/Http/GraphRawResponseTest.php | 77 +++---- tests/Http/RequestBodyMultipartTest.php | 63 +++--- tests/Http/RequestUrlEncodedTest.php | 19 +- 7 files changed, 300 insertions(+), 308 deletions(-) diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php index 2b69b40f3..82f8a42b8 100755 --- a/src/Facebook/Http/GraphRawResponse.php +++ b/src/Facebook/Http/GraphRawResponse.php @@ -30,109 +30,108 @@ class GraphRawResponse { - /** - * @var array The response headers in the form of an associative array. - */ - protected $headers; + /** + * @var array The response headers in the form of an associative array. + */ + protected $headers; - /** - * @var string The raw response body. - */ - protected $body; + /** + * @var string The raw response body. + */ + protected $body; - /** - * @var int The HTTP status response code. - */ - protected $httpResponseCode; + /** + * @var int The HTTP status response code. + */ + protected $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). - */ - public function __construct($headers, $body, $httpStatusCode = null) - { - if (is_numeric($httpStatusCode)) { - $this->httpResponseCode = (int) $httpStatusCode; - } + /** + * 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). + */ + public function __construct($headers, $body, $httpStatusCode = null) + { + if (is_numeric($httpStatusCode)) { + $this->httpResponseCode = (int) $httpStatusCode; + } - if (is_array($headers)) { - $this->headers = $headers; - } else { - $this->setHeadersFromString($headers); - } + if (is_array($headers)) { + $this->headers = $headers; + } else { + $this->setHeadersFromString($headers); + } - $this->body = $body; - } + $this->body = $body; + } - /** - * Return the response headers. - * - * @return array - */ - public function getHeaders() - { - return $this->headers; - } + /** + * Return the response headers. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } - /** - * Return the body of the response. - * - * @return string - */ - public function getBody() - { - return $this->body; - } + /** + * Return the body of the response. + * + * @return string + */ + public function getBody() + { + return $this->body; + } - /** - * Return the HTTP response code. - * - * @return int - */ - public function getHttpResponseCode() - { - return $this->httpResponseCode; - } + /** + * Return the HTTP response code. + * + * @return int + */ + public function getHttpResponseCode() + { + return $this->httpResponseCode; + } - /** - * Sets the HTTP response code from a raw header. - * - * @param string $rawResponseHeader - */ - public function setHttpResponseCodeFromHeader($rawResponseHeader) - { - preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $rawResponseHeader, $match); - $this->httpResponseCode = (int) $match[1]; - } + /** + * Sets the HTTP response code from a raw header. + * + * @param string $rawResponseHeader + */ + public function setHttpResponseCodeFromHeader($rawResponseHeader) + { + preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $rawResponseHeader, $match); + $this->httpResponseCode = (int) $match[1]; + } - /** - * Parse the raw headers and set as an array. - * - * @param string $rawHeaders The raw headers from the response. - */ - protected function setHeadersFromString($rawHeaders) - { - // Normalize line breaks - $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); + /** + * Parse the raw headers and set as an array. + * + * @param string $rawHeaders The raw headers from the response. + */ + protected function setHeadersFromString($rawHeaders) + { + // Normalize line breaks + $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); - // There will be multiple headers if a 301 was followed - // or a proxy was followed, etc - $headerCollection = explode("\n\n", trim($rawHeaders)); - // We just want the last response (at the end) - $rawHeader = array_pop($headerCollection); + // There will be multiple headers if a 301 was followed + // or a proxy was followed, etc + $headerCollection = explode("\n\n", trim($rawHeaders)); + // We just want the last response (at the end) + $rawHeader = array_pop($headerCollection); - $headerComponents = explode("\n", $rawHeader); - foreach ($headerComponents as $line) { - if (strpos($line, ': ') === false) { - $this->setHttpResponseCodeFromHeader($line); - } else { - list ($key, $value) = explode(': ', $line); - $this->headers[$key] = $value; - } + $headerComponents = explode("\n", $rawHeader); + foreach ($headerComponents as $line) { + if (strpos($line, ': ') === false) { + $this->setHttpResponseCodeFromHeader($line); + } else { + list ($key, $value) = explode(': ', $line); + $this->headers[$key] = $value; + } + } } - } - } diff --git a/src/Facebook/Http/RequestBodyInterface.php b/src/Facebook/Http/RequestBodyInterface.php index f8ac89403..0da6a8821 100755 --- a/src/Facebook/Http/RequestBodyInterface.php +++ b/src/Facebook/Http/RequestBodyInterface.php @@ -30,11 +30,10 @@ interface RequestBodyInterface { - /** - * Get the body of the request to send to Graph. - * - * @return string - */ - public function getBody(); - + /** + * Get the body of the request to send to Graph. + * + * @return string + */ + public function getBody(); } diff --git a/src/Facebook/Http/RequestBodyMultipart.php b/src/Facebook/Http/RequestBodyMultipart.php index 143927e3b..fad4c28ab 100644 --- a/src/Facebook/Http/RequestBodyMultipart.php +++ b/src/Facebook/Http/RequestBodyMultipart.php @@ -37,117 +37,113 @@ class RequestBodyMultipart implements RequestBodyInterface { - /** - * @var string The boundary. - */ - protected $boundary; - - /** - * @var array The parameters to send with this request. - */ - protected $params = []; - - /** - * @var array The files to send with this request. - */ - protected $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. - */ - public function __construct( - array $params = [], - array $files = [], - $boundary = null - ) { - $this->params = $params; - $this->files = $files; - $this->boundary = $boundary ?: uniqid(); - } - - /** - * @inheritdoc - */ - public function getBody() - { - $body = ''; - - // Compile normal params - foreach ($this->params as $k => $v) { - $body .= $this->getParamString($k, $v); + /** + * @var string The boundary. + */ + protected $boundary; + + /** + * @var array The parameters to send with this request. + */ + protected $params = []; + + /** + * @var array The files to send with this request. + */ + protected $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. + */ + public function __construct(array $params = [], array $files = [], $boundary = null) + { + $this->params = $params; + $this->files = $files; + $this->boundary = $boundary ?: uniqid(); } - // Compile files - foreach ($this->files as $k => $v) { - $body .= $this->getFileString($k, $v); + /** + * @inheritdoc + */ + public function getBody() + { + $body = ''; + + // Compile normal params + foreach ($this->params as $k => $v) { + $body .= $this->getParamString($k, $v); + } + + // Compile files + foreach ($this->files as $k => $v) { + $body .= $this->getFileString($k, $v); + } + + // Peace out + $body .= "--{$this->boundary}--\r\n"; + + return $body; + } + + /** + * Get the boundary + * + * @return string + */ + public function getBoundary() + { + return $this->boundary; } - // Peace out - $body .= "--{$this->boundary}--\r\n"; - - return $body; - } - - /** - * Get the boundary - * - * @return string - */ - public function getBoundary() - { - 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) - { - return sprintf( - "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n", - $this->boundary, - $name, - $file->getFileName(), - $this->getFileHeaders($file), - $file->getContents() - ); - } - - /** - * Get the string needed to transfer a POST field. - * - * @param string $name - * @param string $value - * - * @return string - */ - private function getParamString($name, $value) - { - return sprintf( - "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", - $this->boundary, - $name, - $value - ); - } - - /** - * Get the headers needed before transferring the content of a POST file. - * - * @param FacebookFile $file - * - * @return string - */ - protected function getFileHeaders(FacebookFile $file) - { - return "\r\nContent-Type: {$file->getMimetype()}"; - } + /** + * Get the string needed to transfer a file. + * + * @param string $name + * @param FacebookFile $file + * + * @return string + */ + private function getFileString($name, FacebookFile $file) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n", + $this->boundary, + $name, + $file->getFileName(), + $this->getFileHeaders($file), + $file->getContents() + ); + } + /** + * Get the string needed to transfer a POST field. + * + * @param string $name + * @param string $value + * + * @return string + */ + private function getParamString($name, $value) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", + $this->boundary, + $name, + $value + ); + } + + /** + * Get the headers needed before transferring the content of a POST file. + * + * @param FacebookFile $file + * + * @return string + */ + protected function getFileHeaders(FacebookFile $file) + { + return "\r\nContent-Type: {$file->getMimetype()}"; + } } diff --git a/src/Facebook/Http/RequestBodyUrlEncoded.php b/src/Facebook/Http/RequestBodyUrlEncoded.php index 0476694e8..8e6c5e651 100644 --- a/src/Facebook/Http/RequestBodyUrlEncoded.php +++ b/src/Facebook/Http/RequestBodyUrlEncoded.php @@ -30,27 +30,26 @@ class RequestBodyUrlEncoded implements RequestBodyInterface { - /** - * @var array The parameters to send with this request. - */ - protected $params = []; + /** + * @var array The parameters to send with this request. + */ + protected $params = []; - /** - * Creates a new GraphUrlEncodedBody entity. - * - * @param array $params - */ - public function __construct(array $params) - { - $this->params = $params; - } - - /** - * @inheritdoc - */ - public function getBody() - { - return http_build_query($this->params, null, '&'); - } + /** + * Creates a new GraphUrlEncodedBody entity. + * + * @param array $params + */ + public function __construct(array $params) + { + $this->params = $params; + } + /** + * @inheritdoc + */ + public function getBody() + { + return http_build_query($this->params, null, '&'); + } } diff --git a/tests/Http/GraphRawResponseTest.php b/tests/Http/GraphRawResponseTest.php index 5be134ad5..ecad26f56 100644 --- a/tests/Http/GraphRawResponseTest.php +++ b/tests/Http/GraphRawResponseTest.php @@ -28,54 +28,55 @@ class GraphRawResponseTest extends \PHPUnit_Framework_TestCase { - protected $fakeRawProxyHeader = "HTTP/1.0 200 Connection established + protected $fakeRawProxyHeader = "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 -Etag: \"9d86b21aa74d74e574bbb35ba13524a52deb96e3\" + protected $fakeRawHeader = <<
'"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', - 'Content-Type' => 'text/javascript; charset=UTF-8', - 'X-FB-Rev' => '9244768', - 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', - 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', - 'Access-Control-Allow-Origin' => '*', - ]; - - public function testCanSetTheHeadersFromAnArray() - { - $myHeaders = [ - 'foo' => 'bar', - 'baz' => 'faz', +Access-Control-Allow-Origin: *\r\n\r\n +HEADER; + protected $fakeHeadersAsArray = [ + 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', + 'Content-Type' => 'text/javascript; charset=UTF-8', + 'X-FB-Rev' => '9244768', + 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', + 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', + 'Access-Control-Allow-Origin' => '*', ]; - $response = new GraphRawResponse($myHeaders, ''); - $headers = $response->getHeaders(); - $this->assertEquals($myHeaders, $headers); - } + public function testCanSetTheHeadersFromAnArray() + { + $myHeaders = [ + 'foo' => 'bar', + 'baz' => 'faz', + ]; + $response = new GraphRawResponse($myHeaders, ''); + $headers = $response->getHeaders(); - public function testCanSetTheHeadersFromAString() - { - $response = new GraphRawResponse($this->fakeRawHeader, ''); - $headers = $response->getHeaders(); - $httpResponseCode = $response->getHttpResponseCode(); + $this->assertEquals($myHeaders, $headers); + } - $this->assertEquals($this->fakeHeadersAsArray, $headers); - $this->assertEquals(200, $httpResponseCode); - } + public function testCanSetTheHeadersFromAString() + { + $response = new GraphRawResponse($this->fakeRawHeader, ''); + $headers = $response->getHeaders(); + $httpResponseCode = $response->getHttpResponseCode(); - public function testWillIgnoreProxyHeaders() - { - $response = new GraphRawResponse($this->fakeRawProxyHeader . $this->fakeRawHeader, ''); - $headers = $response->getHeaders(); - $httpResponseCode = $response->getHttpResponseCode(); + $this->assertEquals($this->fakeHeadersAsArray, $headers); + $this->assertEquals(200, $httpResponseCode); + } - $this->assertEquals($this->fakeHeadersAsArray, $headers); - $this->assertEquals(200, $httpResponseCode); - } + public function testWillIgnoreProxyHeaders() + { + $response = new GraphRawResponse($this->fakeRawProxyHeader . $this->fakeRawHeader, ''); + $headers = $response->getHeaders(); + $httpResponseCode = $response->getHttpResponseCode(); + $this->assertEquals($this->fakeHeadersAsArray, $headers); + $this->assertEquals(200, $httpResponseCode); + } } diff --git a/tests/Http/RequestBodyMultipartTest.php b/tests/Http/RequestBodyMultipartTest.php index aca2d4473..f7574db17 100644 --- a/tests/Http/RequestBodyMultipartTest.php +++ b/tests/Http/RequestBodyMultipartTest.php @@ -29,41 +29,40 @@ class RequestBodyMultipartTest extends \PHPUnit_Framework_TestCase { - public function testCanProperlyEncodeAnArrayOfParams() - { - $message = new RequestBodyMultipart([ - 'foo' => 'bar', - 'scawy_vawues' => '@FooBar is a real twitter handle.', - ], [], 'foo_boundary'); - $body = $message->getBody(); + public function testCanProperlyEncodeAnArrayOfParams() + { + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ], [], 'foo_boundary'); + $body = $message->getBody(); - $expectedBody = "--foo_boundary\r\n"; - $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; - $expectedBody .= "--foo_boundary\r\n"; - $expectedBody .= "Content-Disposition: form-data; name=\"scawy_vawues\"\r\n\r\n@FooBar is a real twitter handle.\r\n"; - $expectedBody .= "--foo_boundary--\r\n"; + $expectedBody = "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"scawy_vawues\"\r\n\r\n@FooBar is a real twitter handle.\r\n"; + $expectedBody .= "--foo_boundary--\r\n"; - $this->assertEquals($expectedBody, $body); - } + $this->assertEquals($expectedBody, $body); + } - public function testCanProperlyEncodeFilesAndParams() - { - $file = new FacebookFile(__DIR__ . '/../foo.txt'); - $message = new RequestBodyMultipart([ - 'foo' => 'bar', - ], [ - 'foo_file' => $file, - ], 'foo_boundary'); - $body = $message->getBody(); + public function testCanProperlyEncodeFilesAndParams() + { + $file = new FacebookFile(__DIR__ . '/../foo.txt'); + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + ], [ + 'foo_file' => $file, + ], 'foo_boundary'); + $body = $message->getBody(); - $expectedBody = "--foo_boundary\r\n"; - $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 .= "--foo_boundary--\r\n"; - - $this->assertEquals($expectedBody, $body); - } + $expectedBody = "--foo_boundary\r\n"; + $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 .= "--foo_boundary--\r\n"; + $this->assertEquals($expectedBody, $body); + } } diff --git a/tests/Http/RequestUrlEncodedTest.php b/tests/Http/RequestUrlEncodedTest.php index 50f29bd0f..bad9675a0 100644 --- a/tests/Http/RequestUrlEncodedTest.php +++ b/tests/Http/RequestUrlEncodedTest.php @@ -28,15 +28,14 @@ class RequestBodyUrlEncodedTest extends \PHPUnit_Framework_TestCase { - public function testCanProperlyEncodeAnArrayOfParams() - { - $message = new RequestBodyUrlEncoded([ - 'foo' => 'bar', - 'scawy_vawues' => '@FooBar is a real twitter handle.', - ]); - $body = $message->getBody(); - - $this->assertEquals('foo=bar&scawy_vawues=%40FooBar+is+a+real+twitter+handle.', $body); - } + public function testCanProperlyEncodeAnArrayOfParams() + { + $message = new RequestBodyUrlEncoded([ + 'foo' => 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ]); + $body = $message->getBody(); + $this->assertEquals('foo=bar&scawy_vawues=%40FooBar+is+a+real+twitter+handle.', $body); + } } From ba5c0f38c702f1fdbd2343937927c0079b1d6832 Mon Sep 17 00:00:00 2001 From: Rocco Palladino Date: Mon, 9 Feb 2015 22:42:36 -0600 Subject: [PATCH 122/407] Bring Facebook/Authentication and associated tests in PSR-2 compliance --- src/Facebook/Authentication/AccessToken.php | 235 ++++--- .../Authentication/AccessTokenMetadata.php | 641 +++++++++--------- src/Facebook/Authentication/OAuth2Client.php | 503 +++++++------- .../Helpers/FacebookRedirectLoginHelper.php | 621 +++++++++-------- tests/Authentication/AccessTokenMetadata.php | 215 +++--- tests/Authentication/AccessTokenTest.php | 117 ++-- .../FooFacebookClientForOAuth2Test.php | 58 ++ tests/Authentication/OAuth2ClientTest.php | 293 ++++---- 8 files changed, 1349 insertions(+), 1334 deletions(-) create mode 100644 tests/Authentication/FooFacebookClientForOAuth2Test.php diff --git a/src/Facebook/Authentication/AccessToken.php b/src/Facebook/Authentication/AccessToken.php index 1fb039bc1..cbdb514ef 100644 --- a/src/Facebook/Authentication/AccessToken.php +++ b/src/Facebook/Authentication/AccessToken.php @@ -30,132 +30,131 @@ class AccessToken { - /** - * The access token value. - * - * @var string - */ - protected $value = ''; - - /** - * Date when token expires. - * - * @var \DateTime|null - */ - protected $expiresAt; - - /** - * Create a new access token entity. - * - * @param string $accessToken - * @param int $expiresAt - */ - public function __construct($accessToken, $expiresAt = 0) - { - $this->value = $accessToken; - if ($expiresAt) { - $this->setExpiresAtFromTimeStamp($expiresAt); + /** + * The access token value. + * + * @var string + */ + protected $value = ''; + + /** + * Date when token expires. + * + * @var \DateTime|null + */ + protected $expiresAt; + + /** + * Create a new access token entity. + * + * @param string $accessToken + * @param int $expiresAt + */ + public function __construct($accessToken, $expiresAt = 0) + { + $this->value = $accessToken; + if ($expiresAt) { + $this->setExpiresAtFromTimeStamp($expiresAt); + } } - } - - /** - * Generate an app secret proof to sign a request to Graph. - * - * @param string $appSecret The app secret. - * - * @return string - */ - public function getAppSecretProof($appSecret) - { - return hash_hmac('sha256', $this->value, $appSecret); - } - - /** - * Getter for expiresAt. - * - * @return \DateTime|null - */ - public function getExpiresAt() - { - return $this->expiresAt; - } - - /** - * Determines whether or not this is an app access token. - * - * @return bool - */ - public function isAppAccessToken() - { - return strpos($this->value, '|') !== false; - } - - /** - * Determines whether or not this is a long-lived token. - * - * @return bool - */ - public function isLongLived() - { - if ($this->expiresAt) { - return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); + + /** + * Generate an app secret proof to sign a request to Graph. + * + * @param string $appSecret The app secret. + * + * @return string + */ + public function getAppSecretProof($appSecret) + { + return hash_hmac('sha256', $this->value, $appSecret); + } + + /** + * Getter for expiresAt. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->expiresAt; } - if ($this->isAppAccessToken()) { - return true; + /** + * Determines whether or not this is an app access token. + * + * @return bool + */ + public function isAppAccessToken() + { + return strpos($this->value, '|') !== false; } - return false; - } - - /** - * Checks the expiration of the access token. - * - * @return boolean|null - */ - public function isExpired() - { - if ($this->getExpiresAt() instanceof \DateTime) { - return $this->getExpiresAt()->getTimestamp() < time(); + /** + * Determines whether or not this is a long-lived token. + * + * @return bool + */ + public function isLongLived() + { + if ($this->expiresAt) { + return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); + } + + if ($this->isAppAccessToken()) { + return true; + } + + return false; } - if ($this->isAppAccessToken()) { - return false; + /** + * Checks the expiration of the access token. + * + * @return boolean|null + */ + public function isExpired() + { + if ($this->getExpiresAt() instanceof \DateTime) { + return $this->getExpiresAt()->getTimestamp() < time(); + } + + if ($this->isAppAccessToken()) { + return false; + } + + return null; } - return null; - } - - /** - * Returns the access token as a string. - * - * @return string - */ - public function getValue() - { - return $this->value; - } - - /** - * Returns the access token as a string. - * - * @return string - */ - public function __toString() - { - return $this->getValue(); - } - - /** - * Setter for expires_at. - * - * @param int $timeStamp - */ - protected function setExpiresAtFromTimeStamp($timeStamp) - { - $dt = new \DateTime(); - $dt->setTimestamp($timeStamp); - $this->expiresAt = $dt; - } + /** + * Returns the access token as a string. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + /** + * Returns the access token as a string. + * + * @return string + */ + public function __toString() + { + return $this->getValue(); + } + + /** + * Setter for expires_at. + * + * @param int $timeStamp + */ + protected function setExpiresAtFromTimeStamp($timeStamp) + { + $dt = new \DateTime(); + $dt->setTimestamp($timeStamp); + $this->expiresAt = $dt; + } } diff --git a/src/Facebook/Authentication/AccessTokenMetadata.php b/src/Facebook/Authentication/AccessTokenMetadata.php index 51657e933..bea96dd71 100644 --- a/src/Facebook/Authentication/AccessTokenMetadata.php +++ b/src/Facebook/Authentication/AccessTokenMetadata.php @@ -35,340 +35,339 @@ class AccessTokenMetadata { - /** - * The access token metadata. - * - * @var array - */ - protected $metadata = []; - - /** - * Properties that should be cast as DateTime objects. - * - * @var array - */ - protected static $dateProperties = ['expires_at', 'issued_at']; - - /** - * @param array $metadata - * - * @throws FacebookSDKException - */ - public function __construct(array $metadata) - { - if ( ! isset($metadata['data'])) { - throw new FacebookSDKException('Unexpected debug token response data.', 401); + /** + * The access token metadata. + * + * @var array + */ + protected $metadata = []; + + /** + * Properties that should be cast as DateTime objects. + * + * @var array + */ + protected static $dateProperties = ['expires_at', 'issued_at']; + + /** + * @param array $metadata + * + * @throws FacebookSDKException + */ + public function __construct(array $metadata) + { + if (! isset($metadata['data'])) { + throw new FacebookSDKException('Unexpected debug token response data.', 401); + } + + $this->metadata = $metadata['data']; + + $this->castTimestampsToDateTime(); } - $this->metadata = $metadata['data']; - - $this->castTimestampsToDateTime(); - } - - /** - * 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 - */ - public function getProperty($field, $default = null) - { - if (isset($this->metadata[$field])) { - return $this->metadata[$field]; + /** + * 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 + */ + public function getProperty($field, $default = null) + { + if (isset($this->metadata[$field])) { + return $this->metadata[$field]; + } + + return $default; } - return $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) - { - if ( ! isset($this->metadata[$parentField])) { - return $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) + { + if (! isset($this->metadata[$parentField])) { + return $default; + } + + if (! isset($this->metadata[$parentField][$field])) { + return $default; + } + + return $this->metadata[$parentField][$field]; } - if ( ! isset($this->metadata[$parentField][$field])) { - return $default; + /** + * Returns a value from the error metadata. + * + * @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) + { + return $this->getChildProperty('error', $field, $default); } - return $this->metadata[$parentField][$field]; - } - - /** - * Returns a value from the error metadata. - * - * @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) - { - return $this->getChildProperty('error', $field, $default); - } - - /** - * Returns a value from the "metadata" metadata. *Brain explodes* - * - * @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) - { - return $this->getChildProperty('metadata', $field, $default); - } - - /** - * The ID of the application this access token is for. - * - * @return string|null - */ - public function getAppId() - { - return $this->getProperty('app_id'); - } - - /** - * Name of the application this access token is for. - * - * @return string|null - */ - public function getApplication() - { - return $this->getProperty('application'); - } - - /** - * Any error that a request to the graph api - * would return due to the access token. - * - * @return bool|null - */ - public function isError() - { - return $this->getProperty('error') !== null; - } - - /** - * The error code for the error. - * - * @return int|null - */ - public function getErrorCode() - { - return $this->getErrorProperty('code'); - } - - /** - * The error message for the error. - * - * @return string|null - */ - public function getErrorMessage() - { - return $this->getErrorProperty('message'); - } - - /** - * The error subcode for the error. - * - * @return int|null - */ - public function getErrorSubcode() - { - return $this->getErrorProperty('subcode'); - } - - /** - * DateTime when this access token expires. - * - * @return \DateTime|null - */ - public function getExpiresAt() - { - return $this->getProperty('expires_at'); - } - - /** - * Whether the access token is still valid or not. - * - * @return boolean|null - */ - public function getIsValid() - { - return $this->getProperty('is_valid'); - } - - /** - * DateTime when this access token was issued. - * - * Note that the issued_at field is not returned - * for short-lived access tokens. - * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug - * - * @return \DateTime|null - */ - public function getIssuedAt() - { - return $this->getProperty('issued_at'); - } - - /** - * General metadata associated with the access token. - * Can contain data like 'sso', 'auth_type', 'auth_nonce'. - * - * @return array|null - */ - public function getMetadata() - { - return $this->getProperty('metadata'); - } - - /** - * The 'sso' child property from the 'metadata' parent property. - * - * @return string|null - */ - public function getSso() - { - return $this->getMetadataProperty('sso'); - } - - /** - * The 'auth_type' child property from the 'metadata' parent property. - * - * @return string|null - */ - public function getAuthType() - { - return $this->getMetadataProperty('auth_type'); - } - - /** - * The 'auth_nonce' child property from the 'metadata' parent property. - * - * @return string|null - */ - public function getAuthNonce() - { - return $this->getMetadataProperty('auth_nonce'); - } - - /** - * For impersonated access tokens, the ID of - * the page this token contains. - * - * @return string|null - */ - public function getProfileId() - { - return $this->getProperty('profile_id'); - } - - /** - * List of permissions that the user has granted for - * the app in this access token. - * - * @return array - */ - public function getScopes() - { - return $this->getProperty('scopes'); - } - - /** - * The ID of the user this access token is for. - * - * @return string|null - */ - public function getUserId() - { - return $this->getProperty('user_id'); - } - - /** - * Ensures the app ID from the access token - * metadata is what we expect. - * - * @param string $appId - * - * @throws FacebookSDKException - */ - public function validateAppId($appId) - { - if ($this->getAppId() !== $appId) { - throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401); + /** + * Returns a value from the "metadata" metadata. *Brain explodes* + * + * @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) + { + return $this->getChildProperty('metadata', $field, $default); } - } - - /** - * Ensures the user ID from the access token - * metadata is what we expect. - * - * @param string $userId - * - * @throws FacebookSDKException - */ - public function validateUserId($userId) - { - if ($this->getUserId() !== $userId) { - throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401); + + /** + * The ID of the application this access token is for. + * + * @return string|null + */ + public function getAppId() + { + return $this->getProperty('app_id'); + } + + /** + * Name of the application this access token is for. + * + * @return string|null + */ + public function getApplication() + { + return $this->getProperty('application'); + } + + /** + * Any error that a request to the graph api + * would return due to the access token. + * + * @return bool|null + */ + public function isError() + { + return $this->getProperty('error') !== null; + } + + /** + * The error code for the error. + * + * @return int|null + */ + public function getErrorCode() + { + return $this->getErrorProperty('code'); + } + + /** + * The error message for the error. + * + * @return string|null + */ + public function getErrorMessage() + { + return $this->getErrorProperty('message'); + } + + /** + * The error subcode for the error. + * + * @return int|null + */ + public function getErrorSubcode() + { + return $this->getErrorProperty('subcode'); + } + + /** + * DateTime when this access token expires. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->getProperty('expires_at'); + } + + /** + * Whether the access token is still valid or not. + * + * @return boolean|null + */ + public function getIsValid() + { + return $this->getProperty('is_valid'); + } + + /** + * DateTime when this access token was issued. + * + * Note that the issued_at field is not returned + * for short-lived access tokens. + * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug + * + * @return \DateTime|null + */ + public function getIssuedAt() + { + return $this->getProperty('issued_at'); + } + + /** + * General metadata associated with the access token. + * Can contain data like 'sso', 'auth_type', 'auth_nonce'. + * + * @return array|null + */ + public function getMetadata() + { + return $this->getProperty('metadata'); + } + + /** + * The 'sso' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getSso() + { + return $this->getMetadataProperty('sso'); + } + + /** + * The 'auth_type' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getAuthType() + { + return $this->getMetadataProperty('auth_type'); + } + + /** + * The 'auth_nonce' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getAuthNonce() + { + return $this->getMetadataProperty('auth_nonce'); + } + + /** + * For impersonated access tokens, the ID of + * the page this token contains. + * + * @return string|null + */ + public function getProfileId() + { + return $this->getProperty('profile_id'); } - } - - /** - * Ensures the access token has not expired yet. - * - * @throws FacebookSDKException - */ - public function validateExpiration() - { - if ( ! $this->getExpiresAt() instanceof \DateTime) { - return; + + /** + * List of permissions that the user has granted for + * the app in this access token. + * + * @return array + */ + public function getScopes() + { + return $this->getProperty('scopes'); } - if ($this->getExpiresAt()->getTimestamp() < time()) { - throw new FacebookSDKException('Inspection of access token metadata shows that the access token has expired.', 401); + /** + * The ID of the user this access token is for. + * + * @return string|null + */ + public function getUserId() + { + return $this->getProperty('user_id'); } - } - - /** - * Converts a unix timestamp into a DateTime entity. - * - * @param int $timestamp - * - * @return \DateTime - */ - private function convertTimestampToDateTime($timestamp) - { - $dt = new \DateTime(); - $dt->setTimestamp($timestamp); - - return $dt; - } - - /** - * Casts the unix timestamps as DateTime entities. - */ - private function castTimestampsToDateTime() - { - foreach (static::$dateProperties as $key) { - if (isset($this->metadata[$key])) { - $this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]); - } + + /** + * Ensures the app ID from the access token + * metadata is what we expect. + * + * @param string $appId + * + * @throws FacebookSDKException + */ + public function validateAppId($appId) + { + if ($this->getAppId() !== $appId) { + throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401); + } } - } + /** + * Ensures the user ID from the access token + * metadata is what we expect. + * + * @param string $userId + * + * @throws FacebookSDKException + */ + public function validateUserId($userId) + { + if ($this->getUserId() !== $userId) { + throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401); + } + } + + /** + * Ensures the access token has not expired yet. + * + * @throws FacebookSDKException + */ + public function validateExpiration() + { + if (! $this->getExpiresAt() instanceof \DateTime) { + return; + } + + if ($this->getExpiresAt()->getTimestamp() < time()) { + throw new FacebookSDKException('Inspection of access token metadata shows that the access token has expired.', 401); + } + } + + /** + * Converts a unix timestamp into a DateTime entity. + * + * @param int $timestamp + * + * @return \DateTime + */ + private function convertTimestampToDateTime($timestamp) + { + $dt = new \DateTime(); + $dt->setTimestamp($timestamp); + + return $dt; + } + + /** + * Casts the unix timestamps as DateTime entities. + */ + private function castTimestampsToDateTime() + { + foreach (static::$dateProperties as $key) { + if (isset($this->metadata[$key])) { + $this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]); + } + } + } } diff --git a/src/Facebook/Authentication/OAuth2Client.php b/src/Facebook/Authentication/OAuth2Client.php index 851184e76..7460c08db 100644 --- a/src/Facebook/Authentication/OAuth2Client.php +++ b/src/Facebook/Authentication/OAuth2Client.php @@ -38,263 +38,262 @@ class OAuth2Client { - /** - * @const string The base authorization URL. - */ - const BASE_AUTHORIZATION_URL = 'https://www.facebook.com'; - - /** - * The FacebookApp entity. - * - * @var FacebookApp - */ - protected $app; - - /** - * The Facebook client. - * - * @var FacebookClient - */ - protected $client; - - /** - * The version of the Graph API to use. - * - * @var string - */ - protected $graphVersion; - - /** - * The last request sent to Graph. - * - * @var FacebookRequest|null - */ - protected $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) - { - $this->app = $app; - $this->client = $client; - $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; - } - - /** - * Returns the last FacebookRequest that was sent. - * Useful for debugging and testing. - * - * @return FacebookRequest|null - */ - public function getLastRequest() - { - return $this->lastRequest; - } - - /** - * Get the metadata associated with the access token. - * - * @param AccessToken|string $accessToken The access token to debug. - * - * @return AccessTokenMetadata - */ - public function debugToken($accessToken) - { - $accessToken = $accessToken instanceof AccessToken - ? $accessToken->getValue() - : $accessToken; - - $params = ['input_token' => $accessToken]; - - $this->lastRequest = new FacebookRequest( - $this->app, - $this->app->getAccessToken(), - 'GET', - '/debug_token', - $params, - null, - $this->graphVersion - ); - $response = $this->client->sendRequest($this->lastRequest); - $metadata = $response->getDecodedBody(); - - return new AccessTokenMetadata($metadata); - } - - /** - * Generates an authorization URL to begin the process of authenticating a user. - * - * @param string $redirectUrl The callback URL to redirect to. - * @param array $scope An array of permissions to request. - * @param string $state The CSPRNG-generated CSRF value. - * @param array $params An array of parameters to generate URL. - * @param string $separator The separator to use in http_build_query(). - * - * @return string - */ - public function getAuthorizationUrl($redirectUrl, array $scope = [], $state, array $params = [], $separator = '&') - { - $params += [ - 'client_id' => $this->app->getId(), - 'state' => $state, - 'response_type' => 'code', - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'redirect_uri' => $redirectUrl, - 'scope' => implode(',', $scope) - ]; - - return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . - http_build_query($params, null, $separator); - } - - /** - * Get a valid access token from a code. - * - * @param string $code - * @param string $redirectUri - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public function getAccessTokenFromCode($code, $redirectUri = '') - { - $params = [ - 'code' => $code, - 'redirect_uri' => $redirectUri, - ]; - - return $this->requestAnAccessToken($params); - } - - /** - * Exchanges a short-lived access token with a long-lived access token. - * - * @param AccessToken|string $accessToken - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public function getLongLivedAccessToken($accessToken) - { - $accessToken = $accessToken instanceof AccessToken - ? $accessToken->getValue() - : $accessToken; - - $params = [ - 'grant_type' => 'fb_exchange_token', - 'fb_exchange_token' => $accessToken, - ]; - - return $this->requestAnAccessToken($params); - } - - /** - * Get a valid code from an access token. - * - * @param AccessToken|string $accessToken - * @param string $redirectUri - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') - { - $params = [ - 'redirect_uri' => $redirectUri, - ]; - - $response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken); - $data = $response->getDecodedBody(); - - if ( ! isset($data['code'])) { - throw new FacebookSDKException('Code was not returned from Graph.', 401); + /** + * @const string The base authorization URL. + */ + const BASE_AUTHORIZATION_URL = 'https://www.facebook.com'; + + /** + * The FacebookApp entity. + * + * @var FacebookApp + */ + protected $app; + + /** + * The Facebook client. + * + * @var FacebookClient + */ + protected $client; + + /** + * The version of the Graph API to use. + * + * @var string + */ + protected $graphVersion; + + /** + * The last request sent to Graph. + * + * @var FacebookRequest|null + */ + protected $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) + { + $this->app = $app; + $this->client = $client; + $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; } - return $data['code']; - } - - /** - * Send a request to the OAuth endpoint. - * - * @param array $params - * - * @return AccessToken - * - * @throws FacebookSDKException - */ - protected function requestAnAccessToken(array $params) - { - $response = $this->sendRequestWithClientParams('/oauth/access_token', $params); - $data = $response->getDecodedBody(); - - if ( ! isset($data['access_token'])) { - throw new FacebookSDKException('Access token was not returned from Graph.', 401); + /** + * Returns the last FacebookRequest that was sent. + * Useful for debugging and testing. + * + * @return FacebookRequest|null + */ + public function getLastRequest() + { + return $this->lastRequest; } - // Graph returns two different key names for expiration time - // on the same endpoint. Doh! :/ - $expiresAt = 0; - if (isset($data['expires'])) { - // For exchanging a short lived token with a long lived token. - // The expiration time in seconds will be returned as "expires". - $expiresAt = time() + $data['expires']; - } elseif (isset($data['expires_in'])) { - // For exchanging a code for a short lived access token. - // The expiration time in seconds will be returned as "expires_in". - // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code - $expiresAt = time() + $data['expires_in']; + /** + * Get the metadata associated with the access token. + * + * @param AccessToken|string $accessToken The access token to debug. + * + * @return AccessTokenMetadata + */ + public function debugToken($accessToken) + { + $accessToken = $accessToken instanceof AccessToken + ? $accessToken->getValue() + : $accessToken; + + $params = ['input_token' => $accessToken]; + + $this->lastRequest = new FacebookRequest( + $this->app, + $this->app->getAccessToken(), + 'GET', + '/debug_token', + $params, + null, + $this->graphVersion + ); + $response = $this->client->sendRequest($this->lastRequest); + $metadata = $response->getDecodedBody(); + + return new AccessTokenMetadata($metadata); } - return new AccessToken($data['access_token'], $expiresAt); - } - - /** - * Send a request to Graph with an app access token. - * - * @param string $endpoint - * @param array $params - * @param string|null $accessToken - * - * @return FacebookResponse - * - * @throws FacebookResponseException - */ - protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null) - { - $params += $this->getClientParams(); - - $accessToken = $accessToken ?: $this->app->getAccessToken(); - - $this->lastRequest = new FacebookRequest( - $this->app, - $accessToken, - 'GET', - $endpoint, - $params, - null, - $this->graphVersion - ); - - return $this->client->sendRequest($this->lastRequest); - } - - /** - * Returns the client_* params for OAuth requests. - * - * @return array - */ - protected function getClientParams() - { - return [ - 'client_id' => $this->app->getId(), - 'client_secret' => $this->app->getSecret(), - ]; - } + /** + * Generates an authorization URL to begin the process of authenticating a user. + * + * @param string $redirectUrl The callback URL to redirect to. + * @param array $scope An array of permissions to request. + * @param string $state The CSPRNG-generated CSRF value. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], array $params = [], $separator = '&') + { + $params += [ + 'client_id' => $this->app->getId(), + 'state' => $state, + 'response_type' => 'code', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) + ]; + + return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . + http_build_query($params, null, $separator); + } + + /** + * Get a valid access token from a code. + * + * @param string $code + * @param string $redirectUri + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getAccessTokenFromCode($code, $redirectUri = '') + { + $params = [ + 'code' => $code, + 'redirect_uri' => $redirectUri, + ]; + + return $this->requestAnAccessToken($params); + } + + /** + * Exchanges a short-lived access token with a long-lived access token. + * + * @param AccessToken|string $accessToken + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getLongLivedAccessToken($accessToken) + { + $accessToken = $accessToken instanceof AccessToken + ? $accessToken->getValue() + : $accessToken; + + $params = [ + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => $accessToken, + ]; + + return $this->requestAnAccessToken($params); + } + + /** + * Get a valid code from an access token. + * + * @param AccessToken|string $accessToken + * @param string $redirectUri + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') + { + $params = [ + 'redirect_uri' => $redirectUri, + ]; + + $response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken); + $data = $response->getDecodedBody(); + + if (! isset($data['code'])) { + throw new FacebookSDKException('Code was not returned from Graph.', 401); + } + + return $data['code']; + } + + /** + * Send a request to the OAuth endpoint. + * + * @param array $params + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + protected function requestAnAccessToken(array $params) + { + $response = $this->sendRequestWithClientParams('/oauth/access_token', $params); + $data = $response->getDecodedBody(); + + if (! isset($data['access_token'])) { + throw new FacebookSDKException('Access token was not returned from Graph.', 401); + } + + // Graph returns two different key names for expiration time + // on the same endpoint. Doh! :/ + $expiresAt = 0; + if (isset($data['expires'])) { + // For exchanging a short lived token with a long lived token. + // The expiration time in seconds will be returned as "expires". + $expiresAt = time() + $data['expires']; + } elseif (isset($data['expires_in'])) { + // For exchanging a code for a short lived access token. + // The expiration time in seconds will be returned as "expires_in". + // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code + $expiresAt = time() + $data['expires_in']; + } + + return new AccessToken($data['access_token'], $expiresAt); + } + /** + * Send a request to Graph with an app access token. + * + * @param string $endpoint + * @param array $params + * @param string|null $accessToken + * + * @return FacebookResponse + * + * @throws FacebookResponseException + */ + protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null) + { + $params += $this->getClientParams(); + + $accessToken = $accessToken ?: $this->app->getAccessToken(); + + $this->lastRequest = new FacebookRequest( + $this->app, + $accessToken, + 'GET', + $endpoint, + $params, + null, + $this->graphVersion + ); + + return $this->client->sendRequest($this->lastRequest); + } + + /** + * Returns the client_* params for OAuth requests. + * + * @return array + */ + protected function getClientParams() + { + return [ + 'client_id' => $this->app->getId(), + 'client_secret' => $this->app->getSecret(), + ]; + } } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 84dd872da..0a32750bd 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -43,331 +43,324 @@ class FacebookRedirectLoginHelper { - /** - * @const int The length of CSRF string to validate the login link. - */ - const CSRF_LENGTH = 32; - - /** - * @var OAuth2Client The OAuth 2.0 client service. - */ - protected $oAuth2Client; - - /** - * @var UrlDetectionInterface The URL detection handler. - */ - protected $urlDetectionHandler; - - /** - * @var PersistentDataInterface The persistent data handler. - */ - protected $persistentDataHandler; - - /** - * @var PseudoRandomStringGeneratorInterface The cryptographically secure - * pseudo-random string generator. - */ - protected $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. - */ - public function __construct(OAuth2Client $oAuth2Client, - PersistentDataInterface $persistentDataHandler = null, - UrlDetectionInterface $urlHandler = null, - PseudoRandomStringGeneratorInterface $prsg = null) - { - $this->oAuth2Client = $oAuth2Client; - $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); - $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); - $this->pseudoRandomStringGenerator = $prsg ?: $this->detectPseudoRandomStringGenerator(); - } - - /** - * Returns the persistent data handler. - * - * @return PersistentDataInterface - */ - public function getPersistentDataHandler() - { - return $this->persistentDataHandler; - } - - /** - * Returns the URL detection handler. - * - * @return UrlDetectionInterface - */ - public function getUrlDetectionHandler() - { - return $this->urlDetectionHandler; - } - - /** - * Returns the cryptographically secure pseudo-random string generator. - * - * @return PseudoRandomStringGeneratorInterface - */ - public function getPseudoRandomStringGenerator() - { - return $this->pseudoRandomStringGenerator; - } - - /** - * Detects which pseudo-random string generator to use. - * - * @return PseudoRandomStringGeneratorInterface - * - * @throws FacebookSDKException - */ - public function detectPseudoRandomStringGenerator() - { - // Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically - // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() first. - if(function_exists('mcrypt_create_iv')) { - return new McryptPseudoRandomStringGenerator(); + /** + * @const int The length of CSRF string to validate the login link. + */ + const CSRF_LENGTH = 32; + + /** + * @var OAuth2Client The OAuth 2.0 client service. + */ + protected $oAuth2Client; + + /** + * @var UrlDetectionInterface The URL detection handler. + */ + protected $urlDetectionHandler; + + /** + * @var PersistentDataInterface The persistent data handler. + */ + protected $persistentDataHandler; + + /** + * @var PseudoRandomStringGeneratorInterface The cryptographically secure + * pseudo-random string generator. + */ + protected $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. + */ + public function __construct(OAuth2Client $oAuth2Client, PersistentDataInterface $persistentDataHandler = null, UrlDetectionInterface $urlHandler = null, PseudoRandomStringGeneratorInterface $prsg = null) + { + $this->oAuth2Client = $oAuth2Client; + $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); + $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); + $this->pseudoRandomStringGenerator = $prsg ?: $this->detectPseudoRandomStringGenerator(); } - if(function_exists('openssl_random_pseudo_bytes')) { - return new OpenSslPseudoRandomStringGenerator(); + + /** + * Returns the persistent data handler. + * + * @return PersistentDataInterface + */ + public function getPersistentDataHandler() + { + return $this->persistentDataHandler; + } + + /** + * Returns the URL detection handler. + * + * @return UrlDetectionInterface + */ + public function getUrlDetectionHandler() + { + return $this->urlDetectionHandler; + } + + /** + * Returns the cryptographically secure pseudo-random string generator. + * + * @return PseudoRandomStringGeneratorInterface + */ + public function getPseudoRandomStringGenerator() + { + return $this->pseudoRandomStringGenerator; + } + + /** + * Detects which pseudo-random string generator to use. + * + * @return PseudoRandomStringGeneratorInterface + * + * @throws FacebookSDKException + */ + public function detectPseudoRandomStringGenerator() + { + // Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically + // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() first. + if (function_exists('mcrypt_create_iv')) { + return new McryptPseudoRandomStringGenerator(); + } + + if (function_exists('openssl_random_pseudo_bytes')) { + return new OpenSslPseudoRandomStringGenerator(); + } + + if (! ini_get('open_basedir') && is_readable('/dev/urandom')) { + return new UrandomPseudoRandomStringGenerator(); + } + + throw new FacebookSDKException( + 'Unable to detect a cryptographically secure pseudo-random string generator.' + ); + } + + /** + * 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(). + * + * @return string + */ + private function makeUrl($redirectUrl, array $scope, array $params = [], $separator = '&') + { + $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); + $this->persistentDataHandler->set('state', $state); + + return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $state, $scope, $params, $separator); + } + + /** + * 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 + */ + public function getLoginUrl($redirectUrl, array $scope = [], $separator = '&') + { + return $this->makeUrl($redirectUrl, $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 + * + * @throws FacebookSDKException + */ + public function getLogoutUrl($accessToken, $next, $separator = '&') + { + if (! $accessToken instanceof AccessToken) { + $accessToken = new AccessToken($accessToken); + } + + if ($accessToken->isAppAccessToken()) { + throw new FacebookSDKException('Cannot generate a logout URL with an app access token.', 722); + } + + $params = [ + 'next' => $next, + 'access_token' => $accessToken->getValue(), + ]; + + return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, $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 + */ + public function getReRequestUrl($redirectUrl, array $scope = [], $separator = '&') + { + $params = ['auth_type' => 'rerequest']; + + return $this->makeUrl($redirectUrl, $scope, $params, $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 + */ + public function getReAuthenticationUrl($redirectUrl, array $scope = [], $separator = '&') + { + $params = ['auth_type' => 'reauthenticate']; + + return $this->makeUrl($redirectUrl, $scope, $params, $separator); + } + + /** + * Takes a valid code from a login redirect, and returns an AccessToken entity. + * + * @param string|null $redirectUrl The redirect URL. + * + * @return AccessToken|null + * + * @throws FacebookSDKException + */ + public function getAccessToken($redirectUrl = null) + { + if (! $code = $this->getCode()) { + return null; + } + + $this->validateCsrf(); + + $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); + // At minimum we need to remove the state param + $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']); + + return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl); + } + + /** + * Validate the request against a cross-site request forgery. + * + * @throws FacebookSDKException + */ + protected function validateCsrf() + { + $state = $this->getState(); + $savedState = $this->persistentDataHandler->get('state'); + + if (! $state || ! $savedState) { + throw new FacebookSDKException( + 'Cross-site request forgery validation failed. ' . + 'Required param "state" missing.' + ); + } + + if ($state !== $savedState) { + throw new FacebookSDKException( + 'Cross-site request forgery validation failed. ' . + 'The "state" param from the URL and session do not match.' + ); + } } - if( ! ini_get('open_basedir') && is_readable('/dev/urandom')) { - return new UrandomPseudoRandomStringGenerator(); + + /** + * Return the code. + * + * @return string|null + */ + protected function getCode() + { + return $this->getInput('code'); } - throw new FacebookSDKException( - 'Unable to detect a cryptographically secure pseudo-random string generator.' - ); - } - - /** - * 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(). - * - * @return string - */ - private function makeUrl($redirectUrl, array $scope, array $params = [], $separator = '&') - { - $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); - $this->persistentDataHandler->set('state', $state); - - return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $scope, $state, $params, $separator); - } - - /** - * 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 - */ - public function getLoginUrl($redirectUrl, - array $scope = [], - $separator = '&') - { - return $this->makeUrl($redirectUrl, $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 - * - * @throws FacebookSDKException - */ - public function getLogoutUrl($accessToken, $next, $separator = '&') - { - if ( ! $accessToken instanceof AccessToken) { - $accessToken = new AccessToken($accessToken); + /** + * Return the state. + * + * @return string|null + */ + protected function getState() + { + return $this->getInput('state'); } - if ($accessToken->isAppAccessToken()) { - throw new FacebookSDKException('Cannot generate a logout URL with an app access token.', 722); + /** + * Return the error code. + * + * @return string|null + */ + public function getErrorCode() + { + return $this->getInput('error_code'); } - $params = [ - 'next' => $next, - 'access_token' => $accessToken->getValue(), - ]; - - return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, $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 - */ - public function getReRequestUrl($redirectUrl, - array $scope = [], - $separator = '&') - { - $params = ['auth_type' => 'rerequest']; - - return $this->makeUrl($redirectUrl, $scope, $params, $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 - */ - public function getReAuthenticationUrl($redirectUrl, - array $scope = [], - $separator = '&') - { - $params = ['auth_type' => 'reauthenticate']; - - return $this->makeUrl($redirectUrl, $scope, $params, $separator); - } - - /** - * Takes a valid code from a login redirect, and returns an AccessToken entity. - * - * @param string|null $redirectUrl The redirect URL. - * - * @return AccessToken|null - * - * @throws FacebookSDKException - */ - public function getAccessToken($redirectUrl = null) - { - if ( ! $code = $this->getCode()) { - return null; + /** + * Returns the error. + * + * @return string|null + */ + public function getError() + { + return $this->getInput('error'); } - $this->validateCsrf(); - - $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); - // At minimum we need to remove the state param - $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']); - - return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl); - } - - /** - * Validate the request against a cross-site request forgery. - * - * @throws FacebookSDKException - */ - protected function validateCsrf() - { - $state = $this->getState(); - $savedState = $this->persistentDataHandler->get('state'); - - if ( ! $state || ! $savedState) { - throw new FacebookSDKException( - 'Cross-site request forgery validation failed. ' . - 'Required param "state" missing.' - ); + /** + * Returns the error reason. + * + * @return string|null + */ + public function getErrorReason() + { + return $this->getInput('error_reason'); } - if ($state !== $savedState) { - throw new FacebookSDKException( - 'Cross-site request forgery validation failed. ' . - 'The "state" param from the URL and session do not match.' - ); + + /** + * Returns the error description. + * + * @return string|null + */ + public function getErrorDescription() + { + return $this->getInput('error_description'); } - } - - /** - * Return the code. - * - * @return string|null - */ - protected function getCode() - { - return $this->getInput('code'); - } - - /** - * Return the state. - * - * @return string|null - */ - protected function getState() - { - return $this->getInput('state'); - } - - /** - * Return the error code. - * - * @return string|null - */ - public function getErrorCode() - { - return $this->getInput('error_code'); - } - - /** - * Returns the error. - * - * @return string|null - */ - public function getError() - { - return $this->getInput('error'); - } - - /** - * Returns the error reason. - * - * @return string|null - */ - public function getErrorReason() - { - return $this->getInput('error_reason'); - } - - /** - * Returns the error description. - * - * @return string|null - */ - public function getErrorDescription() - { - return $this->getInput('error_description'); - } - - /** - * Returns a value from a GET param. - * - * @param string $key - * - * @return string|null - */ - private function getInput($key) - { - return isset($_GET[$key]) ? $_GET[$key] : null; - } + /** + * Returns a value from a GET param. + * + * @param string $key + * + * @return string|null + */ + private function getInput($key) + { + return isset($_GET[$key]) ? $_GET[$key] : null; + } } diff --git a/tests/Authentication/AccessTokenMetadata.php b/tests/Authentication/AccessTokenMetadata.php index b8c1053dd..1b5450386 100644 --- a/tests/Authentication/AccessTokenMetadata.php +++ b/tests/Authentication/AccessTokenMetadata.php @@ -28,112 +28,111 @@ class AccessTokenMetadataTest extends \PHPUnit_Framework_TestCase { - protected $graphResponseData = [ - 'data' => [ - 'app_id' => '123', - 'application' => 'Foo App', - 'error' => [ - 'code' => 190, - 'message' => 'Foo error message.', - 'subcode' => 463, - ], - 'issued_at' => 1422110200, - 'expires_at' => 1422115200, - 'is_valid' => false, - 'metadata' => [ - 'sso' => 'iphone-sso', - 'auth_type' => 'rerequest', - 'auth_nonce' => 'no-replicatey', - ], - 'scopes' => ['public_profile', 'basic_info', 'user_friends'], - 'profile_id' => '1000', - 'user_id' => '1337', - ], - ]; - - public function testDatesGetCastToDateTime() - { - $metadata = new AccessTokenMetadata($this->graphResponseData); - - $expires = $metadata->getExpiresAt(); - $issuedAt = $metadata->getIssuedAt(); - - $this->assertInstanceOf('DateTime', $expires); - $this->assertInstanceOf('DateTime', $issuedAt); - } - - public function testAllTheGettersReturnTheProperValue() - { - $metadata = new AccessTokenMetadata($this->graphResponseData); - - $this->assertEquals('123', $metadata->getAppId()); - $this->assertEquals('Foo App', $metadata->getApplication()); - $this->assertTrue($metadata->isError(), 'Expected an error'); - $this->assertEquals('190', $metadata->getErrorCode()); - $this->assertEquals('Foo error message.', $metadata->getErrorMessage()); - $this->assertEquals('463', $metadata->getErrorSubcode()); - $this->assertFalse($metadata->getIsValid(), 'Expected the access token to not be valid'); - $this->assertEquals('iphone-sso', $metadata->getSso()); - $this->assertEquals('rerequest', $metadata->getAuthType()); - $this->assertEquals('no-replicatey', $metadata->getAuthNonce()); - $this->assertEquals('1000', $metadata->getProfileId()); - $this->assertEquals(['public_profile', 'basic_info', 'user_friends'], $metadata->getScopes()); - $this->assertEquals('1337', $metadata->getUserId()); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testInvalidMetadataWillThrow() - { - new AccessTokenMetadata(['foo' => 'bar']); - } - - public function testAnExpectedAppIdWillNotThrow() - { - $metadata = new AccessTokenMetadata($this->graphResponseData); - $metadata->validateAppId('123'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAnUnexpectedAppIdWillThrow() - { - $metadata = new AccessTokenMetadata($this->graphResponseData); - $metadata->validateAppId('foo'); - } - - public function testAnExpectedUserIdWillNotThrow() - { - $metadata = new AccessTokenMetadata($this->graphResponseData); - $metadata->validateUserId('1337'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAnUnexpectedUserIdWillThrow() - { - $metadata = new AccessTokenMetadata($this->graphResponseData); - $metadata->validateUserId('foo'); - } - - public function testAnActiveAccessTokenWillNotThrow() - { - $this->graphResponseData['data']['expires_at'] = time() + 1000; - $metadata = new AccessTokenMetadata($this->graphResponseData); - $metadata->validateExpiration(); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAnExpiredAccessTokenWillThrow() - { - $this->graphResponseData['data']['expires_at'] = time() - 1000; - $metadata = new AccessTokenMetadata($this->graphResponseData); - $metadata->validateExpiration(); - } - + protected $graphResponseData = [ + 'data' => [ + 'app_id' => '123', + 'application' => 'Foo App', + 'error' => [ + 'code' => 190, + 'message' => 'Foo error message.', + 'subcode' => 463, + ], + 'issued_at' => 1422110200, + 'expires_at' => 1422115200, + 'is_valid' => false, + 'metadata' => [ + 'sso' => 'iphone-sso', + 'auth_type' => 'rerequest', + 'auth_nonce' => 'no-replicatey', + ], + 'scopes' => ['public_profile', 'basic_info', 'user_friends'], + 'profile_id' => '1000', + 'user_id' => '1337', + ], + ]; + + public function testDatesGetCastToDateTime() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + + $expires = $metadata->getExpiresAt(); + $issuedAt = $metadata->getIssuedAt(); + + $this->assertInstanceOf('DateTime', $expires); + $this->assertInstanceOf('DateTime', $issuedAt); + } + + public function testAllTheGettersReturnTheProperValue() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + + $this->assertEquals('123', $metadata->getAppId()); + $this->assertEquals('Foo App', $metadata->getApplication()); + $this->assertTrue($metadata->isError(), 'Expected an error'); + $this->assertEquals('190', $metadata->getErrorCode()); + $this->assertEquals('Foo error message.', $metadata->getErrorMessage()); + $this->assertEquals('463', $metadata->getErrorSubcode()); + $this->assertFalse($metadata->getIsValid(), 'Expected the access token to not be valid'); + $this->assertEquals('iphone-sso', $metadata->getSso()); + $this->assertEquals('rerequest', $metadata->getAuthType()); + $this->assertEquals('no-replicatey', $metadata->getAuthNonce()); + $this->assertEquals('1000', $metadata->getProfileId()); + $this->assertEquals(['public_profile', 'basic_info', 'user_friends'], $metadata->getScopes()); + $this->assertEquals('1337', $metadata->getUserId()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidMetadataWillThrow() + { + new AccessTokenMetadata(['foo' => 'bar']); + } + + public function testAnExpectedAppIdWillNotThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateAppId('123'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnUnexpectedAppIdWillThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateAppId('foo'); + } + + public function testAnExpectedUserIdWillNotThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateUserId('1337'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnUnexpectedUserIdWillThrow() + { + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateUserId('foo'); + } + + public function testAnActiveAccessTokenWillNotThrow() + { + $this->graphResponseData['data']['expires_at'] = time() + 1000; + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateExpiration(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnExpiredAccessTokenWillThrow() + { + $this->graphResponseData['data']['expires_at'] = time() - 1000; + $metadata = new AccessTokenMetadata($this->graphResponseData); + $metadata->validateExpiration(); + } } diff --git a/tests/Authentication/AccessTokenTest.php b/tests/Authentication/AccessTokenTest.php index e2a9fd782..92269e4ae 100644 --- a/tests/Authentication/AccessTokenTest.php +++ b/tests/Authentication/AccessTokenTest.php @@ -28,85 +28,84 @@ class AccessTokenTest extends \PHPUnit_Framework_TestCase { - public function testAnAccessTokenCanBeReturnedAsAString() - { - $accessToken = new AccessToken('foo_token'); + public function testAnAccessTokenCanBeReturnedAsAString() + { + $accessToken = new AccessToken('foo_token'); - $this->assertEquals('foo_token', $accessToken->getValue()); - $this->assertEquals('foo_token', (string) $accessToken); - } + $this->assertEquals('foo_token', $accessToken->getValue()); + $this->assertEquals('foo_token', (string) $accessToken); + } - public function testAnAppSecretProofWillBeProperlyGenerated() - { - $accessToken = new AccessToken('foo_token'); + public function testAnAppSecretProofWillBeProperlyGenerated() + { + $accessToken = new AccessToken('foo_token'); - $appSecretProof = $accessToken->getAppSecretProof('shhhhh!is.my.secret'); + $appSecretProof = $accessToken->getAppSecretProof('shhhhh!is.my.secret'); - $this->assertEquals('796ba0d8a6b339e476a7b166a9e8ac0a395f7de736dc37de5f2f4397f5854eb8', $appSecretProof); - } + $this->assertEquals('796ba0d8a6b339e476a7b166a9e8ac0a395f7de736dc37de5f2f4397f5854eb8', $appSecretProof); + } - public function testAnAppAccessTokenCanBeDetected() - { - $normalToken = new AccessToken('foo_token'); - $isNormalToken = $normalToken->isAppAccessToken(); + public function testAnAppAccessTokenCanBeDetected() + { + $normalToken = new AccessToken('foo_token'); + $isNormalToken = $normalToken->isAppAccessToken(); - $this->assertFalse($isNormalToken, 'Normal access token not expected to look like an app access token.'); + $this->assertFalse($isNormalToken, 'Normal access token not expected to look like an app access token.'); - $appToken = new AccessToken('123|secret'); - $isAppToken = $appToken->isAppAccessToken(); + $appToken = new AccessToken('123|secret'); + $isAppToken = $appToken->isAppAccessToken(); - $this->assertTrue($isAppToken, 'App access token expected to look like an app access token.'); - } + $this->assertTrue($isAppToken, 'App access token expected to look like an app access token.'); + } - public function testShortLivedAccessTokensCanBeDetected() - { - $anHourAndAHalf = time() + (1.5 * 60); - $accessToken = new AccessToken('foo_token', $anHourAndAHalf); + public function testShortLivedAccessTokensCanBeDetected() + { + $anHourAndAHalf = time() + (1.5 * 60); + $accessToken = new AccessToken('foo_token', $anHourAndAHalf); - $isLongLived = $accessToken->isLongLived(); + $isLongLived = $accessToken->isLongLived(); - $this->assertFalse($isLongLived, 'Expected access token to be short lived.'); - } + $this->assertFalse($isLongLived, 'Expected access token to be short lived.'); + } - public function testLongLivedAccessTokensCanBeDetected() - { - $accessToken = new AccessToken('foo_token', $this->aWeekFromNow()); + public function testLongLivedAccessTokensCanBeDetected() + { + $accessToken = new AccessToken('foo_token', $this->aWeekFromNow()); - $isLongLived = $accessToken->isLongLived(); + $isLongLived = $accessToken->isLongLived(); - $this->assertTrue($isLongLived, 'Expected access token to be long lived.'); - } + $this->assertTrue($isLongLived, 'Expected access token to be long lived.'); + } - public function testAnAppAccessTokenDoesNotExpire() - { - $appToken = new AccessToken('123|secret'); - $hasExpired = $appToken->isExpired(); + public function testAnAppAccessTokenDoesNotExpire() + { + $appToken = new AccessToken('123|secret'); + $hasExpired = $appToken->isExpired(); - $this->assertFalse($hasExpired, 'App access token not expected to expire.'); - } + $this->assertFalse($hasExpired, 'App access token not expected to expire.'); + } - public function testAnAccessTokenCanExpire() - { - $expireTime = time() - 100; - $appToken = new AccessToken('foo_token', $expireTime); - $hasExpired = $appToken->isExpired(); + public function testAnAccessTokenCanExpire() + { + $expireTime = time() - 100; + $appToken = new AccessToken('foo_token', $expireTime); + $hasExpired = $appToken->isExpired(); - $this->assertTrue($hasExpired, 'Expected 100 second old access token to be expired.'); - } + $this->assertTrue($hasExpired, 'Expected 100 second old access token to be expired.'); + } - public function testAccessTokenCanBeSerialized() - { - $accessToken = new AccessToken('foo', time(), 'bar'); + public function testAccessTokenCanBeSerialized() + { + $accessToken = new AccessToken('foo', time(), 'bar'); - $newAccessToken = unserialize(serialize($accessToken)); + $newAccessToken = unserialize(serialize($accessToken)); - $this->assertEquals((string) $accessToken, (string) $newAccessToken); - $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); - } - - private function aWeekFromNow() - { - return time() + (60 * 60 * 24 * 7);//a week from now - } + $this->assertEquals((string) $accessToken, (string) $newAccessToken); + $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); + } + private function aWeekFromNow() + { + return time() + (60 * 60 * 24 * 7);//a week from now + } } diff --git a/tests/Authentication/FooFacebookClientForOAuth2Test.php b/tests/Authentication/FooFacebookClientForOAuth2Test.php new file mode 100644 index 000000000..1199b006b --- /dev/null +++ b/tests/Authentication/FooFacebookClientForOAuth2Test.php @@ -0,0 +1,58 @@ +response = '{"data":{"user_id":"444"}}'; + } + + public function setAccessTokenResponse() + { + $this->response = '{"access_token":"my_access_token","expires":"1422115200"}'; + } + + public function setCodeResponse() + { + $this->response = '{"code":"my_neat_code"}'; + } + + public function sendRequest(FacebookRequest $request) + { + return new FacebookResponse( + $request, + $this->response, + 200, + [] + ); + } +} diff --git a/tests/Authentication/OAuth2ClientTest.php b/tests/Authentication/OAuth2ClientTest.php index 6715dfd56..72a8e2a2c 100644 --- a/tests/Authentication/OAuth2ClientTest.php +++ b/tests/Authentication/OAuth2ClientTest.php @@ -26,173 +26,142 @@ use Mockery as m; use Facebook\Facebook; use Facebook\FacebookApp; -use Facebook\FacebookClient; -use Facebook\FacebookRequest; -use Facebook\FacebookResponse; use Facebook\Authentication\OAuth2Client; - -class FooFacebookClientForOAuth2Test extends FacebookClient -{ - protected $response = ''; - - public function setMetadataResponse() { - $this->response = '{"data":{"user_id":"444"}}'; - } - - public function setAccessTokenResponse() { - $this->response = '{"access_token":"my_access_token","expires":"1422115200"}'; - } - - public function setCodeResponse() { - $this->response = '{"code":"my_neat_code"}'; - } - - public function sendRequest(FacebookRequest $request) { - return new FacebookResponse( - $request, - $this->response, - 200, - [] - ); - } -} - class OAuth2ClientTest extends \PHPUnit_Framework_TestCase { - /** - * @const The foo Graph version - */ - const TESTING_GRAPH_VERSION = 'v1337'; - - /** - * @var FooFacebookClientForOAuth2Test - */ - protected $client; - - /** - * @var OAuth2Client - */ - protected $oauth; - - public function setUp() - { - $app = new FacebookApp('123', 'foo_secret'); - $this->client = new FooFacebookClientForOAuth2Test(); - $this->oauth = new OAuth2Client($app, $this->client, static::TESTING_GRAPH_VERSION); - } - - public function testCanGetMetadataFromAnAccessToken() - { - $this->client->setMetadataResponse(); - - $metadata = $this->oauth->debugToken('baz_token'); - - $this->assertInstanceOf('Facebook\Authentication\AccessTokenMetadata', $metadata); - $this->assertEquals('444', $metadata->getUserId()); - - $expectedParams = [ - 'input_token' => 'baz_token', - 'access_token' => '123|foo_secret', - 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', - ]; - - $request = $this->oauth->getLastRequest(); - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/debug_token', $request->getEndpoint()); - $this->assertEquals($expectedParams, $request->getParams()); - $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); - } - - public function testCanBuildAuthorizationUrl() - { - $scope = ['email', 'base_foo']; - $authUrl = $this->oauth->getAuthorizationUrl('https://foo.bar', $scope, 'foo_state', ['foo' => 'bar'], '*'); - - $this->assertContains('*', $authUrl); - - $expectedUrl = 'https://www.facebook.com/' . static::TESTING_GRAPH_VERSION . '/dialog/oauth?'; - $this->assertTrue(strpos($authUrl, $expectedUrl) === 0, 'Unexpected base authorization URL returned from getAuthorizationUrl().'); - - $params = [ - 'client_id' => '123', - 'redirect_uri' => 'https://foo.bar', - 'state' => 'foo_state', - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'scope' => implode(',', $scope), - 'foo' => 'bar', - ]; - foreach ($params as $key => $value) { - $this->assertContains($key . '=' . urlencode($value), $authUrl); + /** + * @const The foo Graph version + */ + const TESTING_GRAPH_VERSION = 'v1337'; + + /** + * @var FooFacebookClientForOAuth2Test + */ + protected $client; + + /** + * @var OAuth2Client + */ + protected $oauth; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_secret'); + $this->client = new FooFacebookClientForOAuth2Test(); + $this->oauth = new OAuth2Client($app, $this->client, static::TESTING_GRAPH_VERSION); } - } - - public function testCanGetAccessTokenFromCode() - { - $this->client->setAccessTokenResponse(); - - $accessToken = $this->oauth->getAccessTokenFromCode('bar_code', 'foo_uri'); - - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); - $this->assertEquals('my_access_token', $accessToken->getValue()); - - $expectedParams = [ - 'code' => 'bar_code', - 'redirect_uri' => 'foo_uri', - 'client_id' => '123', - 'client_secret' => 'foo_secret', - 'access_token' => '123|foo_secret', - 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', - ]; - - $request = $this->oauth->getLastRequest(); - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/oauth/access_token', $request->getEndpoint()); - $this->assertEquals($expectedParams, $request->getParams()); - $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); - } - - public function testCanGetLongLivedAccessToken() - { - $this->client->setAccessTokenResponse(); - - $accessToken = $this->oauth->getLongLivedAccessToken('short_token'); - - $this->assertEquals('my_access_token', $accessToken->getValue()); - - $expectedParams = [ - 'grant_type' => 'fb_exchange_token', - 'fb_exchange_token' => 'short_token', - 'client_id' => '123', - 'client_secret' => 'foo_secret', - 'access_token' => '123|foo_secret', - 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', - ]; - - $request = $this->oauth->getLastRequest(); - $this->assertEquals($expectedParams, $request->getParams()); - } - - public function testCanGetCodeFromLongLivedAccessToken() - { - $this->client->setCodeResponse(); - - $code = $this->oauth->getCodeFromLongLivedAccessToken('long_token', 'foo_uri'); - - $this->assertEquals('my_neat_code', $code); - - $expectedParams = [ - 'access_token' => 'long_token', - 'redirect_uri' => 'foo_uri', - 'client_id' => '123', - 'client_secret' => 'foo_secret', - 'appsecret_proof' => '7e91300ea91be4166282611d4fc700b473466f3ea2981dafbf492fc096995bf1', - ]; - - $request = $this->oauth->getLastRequest(); - $this->assertEquals($expectedParams, $request->getParams()); - $this->assertEquals('/oauth/client_code', $request->getEndpoint()); - } + public function testCanGetMetadataFromAnAccessToken() + { + $this->client->setMetadataResponse(); + + $metadata = $this->oauth->debugToken('baz_token'); + + $this->assertInstanceOf('Facebook\Authentication\AccessTokenMetadata', $metadata); + $this->assertEquals('444', $metadata->getUserId()); + + $expectedParams = [ + 'input_token' => 'baz_token', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/debug_token', $request->getEndpoint()); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); + } + + public function testCanBuildAuthorizationUrl() + { + $scope = ['email', 'base_foo']; + $authUrl = $this->oauth->getAuthorizationUrl('https://foo.bar', 'foo_state', $scope, ['foo' => 'bar'], '*'); + + $this->assertContains('*', $authUrl); + + $expectedUrl = 'https://www.facebook.com/' . static::TESTING_GRAPH_VERSION . '/dialog/oauth?'; + $this->assertTrue(strpos($authUrl, $expectedUrl) === 0, 'Unexpected base authorization URL returned from getAuthorizationUrl().'); + + $params = [ + 'client_id' => '123', + 'redirect_uri' => 'https://foo.bar', + 'state' => 'foo_state', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'scope' => implode(',', $scope), + 'foo' => 'bar', + ]; + foreach ($params as $key => $value) { + $this->assertContains($key . '=' . urlencode($value), $authUrl); + } + } + + public function testCanGetAccessTokenFromCode() + { + $this->client->setAccessTokenResponse(); + + $accessToken = $this->oauth->getAccessTokenFromCode('bar_code', 'foo_uri'); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('my_access_token', $accessToken->getValue()); + + $expectedParams = [ + 'code' => 'bar_code', + 'redirect_uri' => 'foo_uri', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/oauth/access_token', $request->getEndpoint()); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals(static::TESTING_GRAPH_VERSION, $request->getGraphVersion()); + } + + public function testCanGetLongLivedAccessToken() + { + $this->client->setAccessTokenResponse(); + + $accessToken = $this->oauth->getLongLivedAccessToken('short_token'); + + $this->assertEquals('my_access_token', $accessToken->getValue()); + + $expectedParams = [ + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => 'short_token', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'access_token' => '123|foo_secret', + 'appsecret_proof' => 'de753c58fd58b03afca2340bbaeb4ecf987b5de4c09e39a63c944dd25efbc234', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals($expectedParams, $request->getParams()); + } + + public function testCanGetCodeFromLongLivedAccessToken() + { + $this->client->setCodeResponse(); + + $code = $this->oauth->getCodeFromLongLivedAccessToken('long_token', 'foo_uri'); + + $this->assertEquals('my_neat_code', $code); + + $expectedParams = [ + 'access_token' => 'long_token', + 'redirect_uri' => 'foo_uri', + 'client_id' => '123', + 'client_secret' => 'foo_secret', + 'appsecret_proof' => '7e91300ea91be4166282611d4fc700b473466f3ea2981dafbf492fc096995bf1', + ]; + + $request = $this->oauth->getLastRequest(); + $this->assertEquals($expectedParams, $request->getParams()); + $this->assertEquals('/oauth/client_code', $request->getEndpoint()); + } } From 0c2600ca79b616fa29a9f164fd8f8218c271d056 Mon Sep 17 00:00:00 2001 From: Rocco Palladino Date: Mon, 9 Feb 2015 23:33:09 -0600 Subject: [PATCH 123/407] Bring Facebook\Exceptions and tests into PSR-2 compliance --- .../FacebookAuthenticationException.php | 3 +- .../FacebookAuthorizationException.php | 2 +- .../Exceptions/FacebookClientException.php | 2 +- .../Exceptions/FacebookOtherException.php | 2 +- .../Exceptions/FacebookResponseException.php | 330 +++++++------ .../Exceptions/FacebookSDKException.php | 2 +- .../Exceptions/FacebookServerException.php | 2 +- .../Exceptions/FacebookThrottleException.php | 2 +- .../FacebookResponseExceptionTest.php | 441 +++++++++--------- 9 files changed, 390 insertions(+), 396 deletions(-) diff --git a/src/Facebook/Exceptions/FacebookAuthenticationException.php b/src/Facebook/Exceptions/FacebookAuthenticationException.php index 13578f0de..e025a2771 100644 --- a/src/Facebook/Exceptions/FacebookAuthenticationException.php +++ b/src/Facebook/Exceptions/FacebookAuthenticationException.php @@ -29,5 +29,4 @@ */ class FacebookAuthenticationException extends FacebookSDKException { - -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php index a633ecbc2..4651bc4a5 100644 --- a/src/Facebook/Exceptions/FacebookAuthorizationException.php +++ b/src/Facebook/Exceptions/FacebookAuthorizationException.php @@ -30,4 +30,4 @@ class FacebookAuthorizationException extends FacebookSDKException { -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php index 650381022..45cdce3c2 100644 --- a/src/Facebook/Exceptions/FacebookClientException.php +++ b/src/Facebook/Exceptions/FacebookClientException.php @@ -30,4 +30,4 @@ class FacebookClientException extends FacebookSDKException { -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php index 34c6be5b2..226d5da17 100644 --- a/src/Facebook/Exceptions/FacebookOtherException.php +++ b/src/Facebook/Exceptions/FacebookOtherException.php @@ -30,4 +30,4 @@ class FacebookOtherException extends FacebookSDKException { -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index a22f0d453..94697cc44 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -32,182 +32,178 @@ class FacebookResponseException extends FacebookSDKException { - /** - * @var FacebookResponse The response that threw the exception. - */ - protected $response; - - /** - * @var array Decoded response. - */ - protected $responseData; - - /** - * Creates a FacebookResponseException. - * - * @param FacebookResponse $response The response that threw the exception. - * @param FacebookSDKException $previousException The more detailed exception. - */ - public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) - { - $this->response = $response; - $this->responseData = $response->getDecodedBody(); - - $errorMessage = $this->get('message', 'Unknown error from Graph.'); - $errorCode = $this->get('code', -1); - - parent::__construct($errorMessage, $errorCode, $previousException); - } - - /** - * A factory for creating the appropriate exception based on the response from Graph. - * - * @param FacebookResponse $response The response that threw the exception. - * - * @return FacebookResponseException - */ - public static function create(FacebookResponse $response) - { - $data = $response->getDecodedBody(); - - if ( ! isset($data['error']['code']) && isset($data['code'])) { - $data = ['error' => $data]; + /** + * @var FacebookResponse The response that threw the exception. + */ + protected $response; + + /** + * @var array Decoded response. + */ + protected $responseData; + + /** + * Creates a FacebookResponseException. + * + * @param FacebookResponse $response The response that threw the exception. + * @param FacebookSDKException $previousException The more detailed exception. + */ + public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) + { + $this->response = $response; + $this->responseData = $response->getDecodedBody(); + + $errorMessage = $this->get('message', 'Unknown error from Graph.'); + $errorCode = $this->get('code', -1); + + parent::__construct($errorMessage, $errorCode, $previousException); } - $code = isset($data['error']['code']) ? $data['error']['code'] : null; - $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; - - $previousException = null; - - if (isset($data['error']['error_subcode'])) { - switch ($data['error']['error_subcode']) { - // Other authentication issues - case 458: - case 459: - case 460: - case 463: - case 464: - case 467: - return new static($response, new FacebookAuthenticationException($message, $code)); - break; - } + + /** + * A factory for creating the appropriate exception based on the response from Graph. + * + * @param FacebookResponse $response The response that threw the exception. + * + * @return FacebookResponseException + */ + public static function create(FacebookResponse $response) + { + $data = $response->getDecodedBody(); + + if (! isset($data['error']['code']) && isset($data['code'])) { + $data = ['error' => $data]; + } + + $code = isset($data['error']['code']) ? $data['error']['code'] : null; + $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; + + $previousException = null; + + if (isset($data['error']['error_subcode'])) { + switch ($data['error']['error_subcode']) { + // Other authentication issues + case 458: + case 459: + case 460: + case 463: + case 464: + case 467: + return new static($response, new FacebookAuthenticationException($message, $code)); + } + } + + switch ($code) { + // Login status or token expired, revoked, or invalid + case 100: + case 102: + case 190: + return new static($response, new FacebookAuthenticationException($message, $code)); + + // Server issue, possible downtime + case 1: + case 2: + return new static($response, new FacebookServerException($message, $code)); + + // API Throttling + case 4: + case 17: + case 341: + return new static($response, new FacebookThrottleException($message, $code)); + + // Duplicate Post + case 506: + return new static($response, new FacebookClientException($message, $code)); + } + + // Missing Permissions + if ($code == 10 || ($code >= 200 && $code <= 299)) { + return new static($response, new FacebookAuthorizationException($message, $code)); + } + + // OAuth authentication error + if (isset($data['error']['type']) + && $data['error']['type'] === 'OAuthException') { + return new static($response, new FacebookAuthenticationException($message, $code)); + } + + // All others + return new static($response, new FacebookOtherException($message, $code)); + } + + /** + * Checks isset and returns that or a default value. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + private function get($key, $default = null) + { + if (isset($this->responseData['error'][$key])) { + return $this->responseData['error'][$key]; + } + + return $default; } - switch ($code) { - // Login status or token expired, revoked, or invalid - case 100: - case 102: - case 190: - return new static($response, new FacebookAuthenticationException($message, $code)); - break; - - // Server issue, possible downtime - case 1: - case 2: - return new static($response, new FacebookServerException($message, $code)); - break; - - // API Throttling - case 4: - case 17: - case 341: - return new static($response, new FacebookThrottleException($message, $code)); - break; - - // Duplicate Post - case 506: - return new static($response, new FacebookClientException($message, $code)); - break; + /** + * Returns the HTTP status code + * + * @return int + */ + public function getHttpStatusCode() + { + return $this->response->getHttpStatusCode(); } - // Missing Permissions - if ($code == 10 || ($code >= 200 && $code <= 299)) { - return new static($response, new FacebookAuthorizationException($message, $code)); + /** + * Returns the sub-error code + * + * @return int + */ + public function getSubErrorCode() + { + return $this->get('error_subcode', -1); } - // OAuth authentication error - if (isset($data['error']['type']) - && $data['error']['type'] === 'OAuthException') { - return new static($response, new FacebookAuthenticationException($message, $code)); + /** + * Returns the error type + * + * @return string + */ + public function getErrorType() + { + return $this->get('type', ''); } - // All others - return new static($response, new FacebookOtherException($message, $code)); - } - - /** - * Checks isset and returns that or a default value. - * - * @param string $key - * @param mixed $default - * - * @return mixed - */ - private function get($key, $default = null) - { - if (isset($this->responseData['error'][$key])) { - return $this->responseData['error'][$key]; + /** + * Returns the raw response used to create the exception. + * + * @return string + */ + public function getRawResponse() + { + return $this->response->getBody(); } - return $default; - } - - /** - * Returns the HTTP status code - * - * @return int - */ - public function getHttpStatusCode() - { - return $this->response->getHttpStatusCode(); - } - - /** - * Returns the sub-error code - * - * @return int - */ - public function getSubErrorCode() - { - return $this->get('error_subcode', -1); - } - - /** - * Returns the error type - * - * @return string - */ - public function getErrorType() - { - return $this->get('type', ''); - } - - /** - * Returns the raw response used to create the exception. - * - * @return string - */ - public function getRawResponse() - { - return $this->response->getBody(); - } - - /** - * Returns the decoded response used to create the exception. - * - * @return array - */ - public function getResponseData() - { - return $this->responseData; - } - - /** - * Returns the response entity used to create the exception. - * - * @return FacebookResponse - */ - public function getResponse() - { - return $this->response; - } + /** + * Returns the decoded response used to create the exception. + * + * @return array + */ + public function getResponseData() + { + return $this->responseData; + } + + /** + * Returns the response entity used to create the exception. + * + * @return FacebookResponse + */ + public function getResponse() + { + return $this->response; + } } diff --git a/src/Facebook/Exceptions/FacebookSDKException.php b/src/Facebook/Exceptions/FacebookSDKException.php index e45cdc957..603cff992 100644 --- a/src/Facebook/Exceptions/FacebookSDKException.php +++ b/src/Facebook/Exceptions/FacebookSDKException.php @@ -30,4 +30,4 @@ class FacebookSDKException extends \Exception { -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php index 962615876..a3206271a 100644 --- a/src/Facebook/Exceptions/FacebookServerException.php +++ b/src/Facebook/Exceptions/FacebookServerException.php @@ -30,4 +30,4 @@ class FacebookServerException extends FacebookSDKException { -} \ No newline at end of file +} diff --git a/src/Facebook/Exceptions/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php index 662d3bad1..72afc2045 100644 --- a/src/Facebook/Exceptions/FacebookThrottleException.php +++ b/src/Facebook/Exceptions/FacebookThrottleException.php @@ -30,4 +30,4 @@ class FacebookThrottleException extends FacebookSDKException { -} \ No newline at end of file +} diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 1947733b1..107a9b979 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -31,249 +31,248 @@ class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase { - /** - * @var FacebookRequest - */ - protected $request; + /** + * @var FacebookRequest + */ + protected $request; - public function setUp() - { - $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); - } + public function setUp() + { + $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); + } - public function testAuthenticationExceptions() - { - $params = [ - 'error' => [ - 'code' => 100, - 'message' => 'errmsg', - 'error_subcode' => 0, - 'type' => 'exception' - ], - ]; + public function testAuthenticationExceptions() + { + $params = [ + 'error' => [ + 'code' => 100, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; - $response = new FacebookResponse($this->request, json_encode($params), 401); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); - $this->assertEquals(100, $exception->getCode()); - $this->assertEquals(0, $exception->getSubErrorCode()); - $this->assertEquals('exception', $exception->getErrorType()); - $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(401, $exception->getHttpStatusCode()); + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(100, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); - $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->assertEquals(102, $exception->getCode()); + $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->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->assertEquals(190, $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->assertEquals(190, $exception->getCode()); - $params['error']['type'] = 'OAuthException'; - $params['error']['code'] = 0; - $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->assertEquals(458, $exception->getSubErrorCode()); + $params['error']['type'] = 'OAuthException'; + $params['error']['code'] = 0; + $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->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->assertEquals(460, $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->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->assertEquals(463, $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->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->assertEquals(467, $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->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->assertEquals(0, $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->assertEquals(0, $exception->getSubErrorCode()); + } - public function testServerExceptions() - { - $params = [ - 'error' => [ - 'code' => 1, - 'message' => 'errmsg', - 'error_subcode' => 0, - 'type' => 'exception' - ], - ]; + public function testServerExceptions() + { + $params = [ + 'error' => [ + 'code' => 1, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; - $response = new FacebookResponse($this->request, json_encode($params), 500); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); - $this->assertEquals(1, $exception->getCode()); - $this->assertEquals(0, $exception->getSubErrorCode()); - $this->assertEquals('exception', $exception->getErrorType()); - $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(500, $exception->getHttpStatusCode()); + $response = new FacebookResponse($this->request, json_encode($params), 500); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookServerException', $exception->getPrevious()); + $this->assertEquals(1, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(500, $exception->getHttpStatusCode()); - $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->assertEquals(2, $exception->getCode()); - } + $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->assertEquals(2, $exception->getCode()); + } - public function testThrottleExceptions() - { - $params = [ - 'error' => [ - 'code' => 4, - 'message' => 'errmsg', - 'error_subcode' => 0, - 'type' => 'exception' - ], - ]; - $response = new FacebookResponse($this->request, json_encode($params), 401); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); - $this->assertEquals(4, $exception->getCode()); - $this->assertEquals(0, $exception->getSubErrorCode()); - $this->assertEquals('exception', $exception->getErrorType()); - $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(401, $exception->getHttpStatusCode()); + public function testThrottleExceptions() + { + $params = [ + 'error' => [ + 'code' => 4, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookThrottleException', $exception->getPrevious()); + $this->assertEquals(4, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); - $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->assertEquals(17, $exception->getCode()); + $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->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->assertEquals(341, $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->assertEquals(341, $exception->getCode()); + } - public function testUserIssueExceptions() - { - $params = [ - 'error' => [ - 'code' => 230, - 'message' => 'errmsg', - 'error_subcode' => 459, - 'type' => 'exception' - ], - ]; - $response = new FacebookResponse($this->request, json_encode($params), 401); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); - $this->assertEquals(230, $exception->getCode()); - $this->assertEquals(459, $exception->getSubErrorCode()); - $this->assertEquals('exception', $exception->getErrorType()); - $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(401, $exception->getHttpStatusCode()); + public function testUserIssueExceptions() + { + $params = [ + 'error' => [ + 'code' => 230, + 'message' => 'errmsg', + 'error_subcode' => 459, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthenticationException', $exception->getPrevious()); + $this->assertEquals(230, $exception->getCode()); + $this->assertEquals(459, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); - $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->assertEquals(464, $exception->getSubErrorCode()); - } + $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->assertEquals(464, $exception->getSubErrorCode()); + } - public function testAuthorizationExceptions() - { - $params = [ - 'error' => [ - 'code' => 10, - 'message' => 'errmsg', - 'error_subcode' => 0, - 'type' => 'exception' - ], - ]; - $response = new FacebookResponse($this->request, json_encode($params), 401); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); - $this->assertEquals(10, $exception->getCode()); - $this->assertEquals(0, $exception->getSubErrorCode()); - $this->assertEquals('exception', $exception->getErrorType()); - $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(401, $exception->getHttpStatusCode()); + public function testAuthorizationExceptions() + { + $params = [ + 'error' => [ + 'code' => 10, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookAuthorizationException', $exception->getPrevious()); + $this->assertEquals(10, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); - $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->assertEquals(200, $exception->getCode()); + $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->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->assertEquals(250, $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->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->assertEquals(299, $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->assertEquals(299, $exception->getCode()); + } - public function testClientExceptions() - { - $params = [ - 'error' => [ - 'code' => 506, - 'message' => 'errmsg', - 'error_subcode' => 0, - 'type' => 'exception' - ], - ]; - $response = new FacebookResponse($this->request, json_encode($params), 401); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookClientException', $exception->getPrevious()); - $this->assertEquals(506, $exception->getCode()); - $this->assertEquals(0, $exception->getSubErrorCode()); - $this->assertEquals('exception', $exception->getErrorType()); - $this->assertEquals('errmsg', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(401, $exception->getHttpStatusCode()); - } - - public function testOtherException() - { - $params = [ - 'error' => [ - 'code' => 42, - 'message' => 'ship love', - 'error_subcode' => 0, - 'type' => 'feature' - ], - ]; - $response = new FacebookResponse($this->request, json_encode($params), 200); - $exception = FacebookResponseException::create($response); - $this->assertInstanceOf('Facebook\Exceptions\FacebookOtherException', $exception->getPrevious()); - $this->assertEquals(42, $exception->getCode()); - $this->assertEquals(0, $exception->getSubErrorCode()); - $this->assertEquals('feature', $exception->getErrorType()); - $this->assertEquals('ship love', $exception->getMessage()); - $this->assertEquals(json_encode($params), $exception->getRawResponse()); - $this->assertEquals(200, $exception->getHttpStatusCode()); - } + public function testClientExceptions() + { + $params = [ + 'error' => [ + 'code' => 506, + 'message' => 'errmsg', + 'error_subcode' => 0, + 'type' => 'exception' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 401); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookClientException', $exception->getPrevious()); + $this->assertEquals(506, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('exception', $exception->getErrorType()); + $this->assertEquals('errmsg', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(401, $exception->getHttpStatusCode()); + } + public function testOtherException() + { + $params = [ + 'error' => [ + 'code' => 42, + 'message' => 'ship love', + 'error_subcode' => 0, + 'type' => 'feature' + ], + ]; + $response = new FacebookResponse($this->request, json_encode($params), 200); + $exception = FacebookResponseException::create($response); + $this->assertInstanceOf('Facebook\Exceptions\FacebookOtherException', $exception->getPrevious()); + $this->assertEquals(42, $exception->getCode()); + $this->assertEquals(0, $exception->getSubErrorCode()); + $this->assertEquals('feature', $exception->getErrorType()); + $this->assertEquals('ship love', $exception->getMessage()); + $this->assertEquals(json_encode($params), $exception->getRawResponse()); + $this->assertEquals(200, $exception->getHttpStatusCode()); + } } From 6a3edf5b684f738f30c05beeeaf784caac4b6617 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 12 Feb 2015 01:13:37 +0100 Subject: [PATCH 124/407] Remove IDE gitignore rules --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index c4c77e40f..0c2e885a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ vendor/ composer.lock -composer.phar -.DS_Store -.idea/ tests/FacebookTestCredentials.php From 0016a8a064523fdb24daad8d5488ca9dfe5042a3 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Tue, 17 Feb 2015 23:05:27 +0100 Subject: [PATCH 125/407] PSR-2 and some extra --- src/Facebook/Authentication/AccessToken.php | 4 +- .../Authentication/AccessTokenMetadata.php | 31 +- src/Facebook/Authentication/OAuth2Client.php | 37 +- .../FacebookAuthenticationException.php | 1 + .../FacebookAuthorizationException.php | 2 +- .../Exceptions/FacebookClientException.php | 2 +- .../Exceptions/FacebookOtherException.php | 2 +- .../Exceptions/FacebookResponseException.php | 13 +- .../Exceptions/FacebookSDKException.php | 2 +- .../Exceptions/FacebookServerException.php | 2 +- .../Exceptions/FacebookThrottleException.php | 2 +- src/Facebook/Facebook.php | 1052 ++++++++--------- src/Facebook/FacebookApp.php | 128 +- src/Facebook/FacebookBatchRequest.php | 506 ++++---- src/Facebook/FacebookBatchResponse.php | 237 ++-- src/Facebook/FacebookClient.php | 407 ++++--- src/Facebook/FacebookRequest.php | 1009 ++++++++-------- src/Facebook/FacebookResponse.php | 606 +++++----- src/Facebook/FileUpload/FacebookFile.php | 179 ++- src/Facebook/FileUpload/FacebookVideo.php | 2 +- src/Facebook/FileUpload/Mimetypes.php | 17 +- src/Facebook/GraphNodes/Collection.php | 335 +++--- src/Facebook/GraphNodes/GraphAchievement.php | 7 +- src/Facebook/GraphNodes/GraphAlbum.php | 300 ++--- src/Facebook/GraphNodes/GraphApplication.php | 1 + src/Facebook/GraphNodes/GraphList.php | 388 +++--- src/Facebook/GraphNodes/GraphLocation.php | 129 +- src/Facebook/GraphNodes/GraphObject.php | 278 ++--- .../GraphNodes/GraphObjectFactory.php | 612 +++++----- src/Facebook/GraphNodes/GraphPage.php | 169 +-- src/Facebook/GraphNodes/GraphPicture.php | 3 +- src/Facebook/GraphNodes/GraphSessionInfo.php | 129 +- src/Facebook/GraphNodes/GraphUser.php | 237 ++-- src/Facebook/Helpers/FacebookCanvasHelper.php | 42 +- .../Helpers/FacebookJavaScriptHelper.php | 21 +- .../Helpers/FacebookPageTabHelper.php | 103 +- .../Helpers/FacebookRedirectLoginHelper.php | 82 +- .../FacebookSignedRequestFromInputHelper.php | 234 ++-- src/Facebook/Http/GraphRawResponse.php | 14 +- src/Facebook/Http/RequestBodyInterface.php | 10 +- src/Facebook/Http/RequestBodyMultipart.php | 13 +- src/Facebook/Http/RequestBodyUrlEncoded.php | 2 +- src/Facebook/HttpClients/FacebookCurl.php | 174 +-- .../HttpClients/FacebookCurlHttpClient.php | 328 +++-- .../HttpClients/FacebookGuzzleHttpClient.php | 109 +- .../FacebookHttpClientInterface.php | 31 +- src/Facebook/HttpClients/FacebookStream.php | 81 +- .../HttpClients/FacebookStreamHttpClient.php | 110 +- .../FacebookMemoryPersistentDataHandler.php | 1 + .../FacebookSessionPersistentDataHandler.php | 15 +- .../PersistentDataInterface.php | 3 +- .../OpenSslPseudoRandomStringGenerator.php | 19 +- .../PseudoRandomStringGeneratorInterface.php | 1 + .../PseudoRandomStringGeneratorTrait.php | 10 +- src/Facebook/SignedRequest.php | 567 +++++---- .../Url/FacebookUrlDetectionHandler.php | 19 +- src/Facebook/Url/FacebookUrlManipulator.php | 18 +- src/Facebook/Url/UrlDetectionInterface.php | 2 +- src/Facebook/autoload.php | 47 +- tests/Authentication/AccessTokenTest.php | 4 +- tests/FacebookAppTest.php | 60 +- tests/FacebookBatchRequestTest.php | 676 +++++------ tests/FacebookBatchResponseTest.php | 202 ++-- tests/FacebookClientTest.php | 487 ++++---- tests/FacebookRequestTest.php | 348 +++--- tests/FacebookResponseTest.php | 179 ++- tests/FacebookTest.php | 598 +++++----- tests/FileUpload/FacebookFileTest.php | 45 +- tests/FileUpload/MimetypesTest.php | 43 +- tests/GraphNodes/CollectionTest.php | 123 +- tests/GraphNodes/GraphAchievementTest.php | 38 +- tests/GraphNodes/GraphAlbumTest.php | 155 ++- tests/GraphNodes/GraphListTest.php | 153 +-- tests/GraphNodes/GraphNodeTest.php | 1 + tests/GraphNodes/GraphObjectFactoryTest.php | 778 ++++++------ tests/GraphNodes/GraphObjectTest.php | 218 ++-- tests/GraphNodes/GraphPageTest.php | 112 +- tests/GraphNodes/GraphSessionInfoTest.php | 64 +- tests/GraphNodes/GraphUserTest.php | 217 ++-- tests/Helpers/FacebookCanvasHelperTest.php | 36 +- .../Helpers/FacebookJavaScriptHelperTest.php | 22 +- tests/Helpers/FacebookPageTabHelperTest.php | 24 +- .../FacebookRedirectLoginHelperTest.php | 170 +-- ...cebookSignedRequestFromInputHelperTest.php | 117 +- tests/Http/RequestBodyMultipartTest.php | 15 +- tests/Http/RequestUrlEncodedTest.php | 3 +- tests/HttpClients/AbstractTestHttpClient.php | 38 +- .../FacebookCurlHttpClientTest.php | 608 +++++----- .../FacebookGuzzleHttpClientTest.php | 218 ++-- .../FacebookStreamHttpClientTest.php | 207 ++-- ...acebookMemoryPersistentDataHandlerTest.php | 28 +- ...cebookSessionPersistentDataHandlerTest.php | 66 +- .../McryptPseudoRandomStringGeneratorTest.php | 26 +- ...OpenSslPseudoRandomStringGeneratorTest.php | 26 +- .../PseudoRandomStringGeneratorTraitTest.php | 36 +- ...UrandomPseudoRandomStringGeneratorTest.php | 36 +- tests/SignedRequestTest.php | 218 ++-- tests/Url/FacebookUrlDetectionHandlerTest.php | 210 ++-- tests/Url/FacebookUrlManipulatorTest.php | 376 +++--- tests/bootstrap.php | 5 +- 100 files changed, 7848 insertions(+), 8023 deletions(-) diff --git a/src/Facebook/Authentication/AccessToken.php b/src/Facebook/Authentication/AccessToken.php index cbdb514ef..582ea6136 100644 --- a/src/Facebook/Authentication/AccessToken.php +++ b/src/Facebook/Authentication/AccessToken.php @@ -25,11 +25,11 @@ /** * Class AccessToken + * * @package Facebook */ class AccessToken { - /** * The access token value. * @@ -48,7 +48,7 @@ class AccessToken * Create a new access token entity. * * @param string $accessToken - * @param int $expiresAt + * @param int $expiresAt */ public function __construct($accessToken, $expiresAt = 0) { diff --git a/src/Facebook/Authentication/AccessTokenMetadata.php b/src/Facebook/Authentication/AccessTokenMetadata.php index bea96dd71..17e5bbf5e 100644 --- a/src/Facebook/Authentication/AccessTokenMetadata.php +++ b/src/Facebook/Authentication/AccessTokenMetadata.php @@ -27,14 +27,14 @@ /** * Class AccessTokenMetadata - * @package Facebook * * Represents metadata from an access token. - * @see https://developers.facebook.com/docs/graph-api/reference/debug_token + * + * @package Facebook + * @see https://developers.facebook.com/docs/graph-api/reference/debug_token */ class AccessTokenMetadata { - /** * The access token metadata. * @@ -56,7 +56,7 @@ class AccessTokenMetadata */ public function __construct(array $metadata) { - if (! isset($metadata['data'])) { + if (!isset($metadata['data'])) { throw new FacebookSDKException('Unexpected debug token response data.', 401); } @@ -68,8 +68,8 @@ public function __construct(array $metadata) /** * 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. + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. * * @return mixed */ @@ -86,18 +86,18 @@ public function getProperty($field, $default = null) * 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. + * @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) { - if (! isset($this->metadata[$parentField])) { + if (!isset($this->metadata[$parentField])) { return $default; } - if (! isset($this->metadata[$parentField][$field])) { + if (!isset($this->metadata[$parentField][$field])) { return $default; } @@ -107,8 +107,8 @@ public function getChildProperty($parentField, $field, $default = null) /** * Returns a value from the error metadata. * - * @param string $field The property to retrieve. - * @param mixed $default The default to return if the property doesn't exist. + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. * * @return mixed */ @@ -120,8 +120,8 @@ public function getErrorProperty($field, $default = null) /** * Returns a value from the "metadata" metadata. *Brain explodes* * - * @param string $field The property to retrieve. - * @param mixed $default The default to return if the property doesn't exist. + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. * * @return mixed */ @@ -216,6 +216,7 @@ public function getIsValid() * * Note that the issued_at field is not returned * for short-lived access tokens. + * * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug * * @return \DateTime|null @@ -335,7 +336,7 @@ public function validateUserId($userId) */ public function validateExpiration() { - if (! $this->getExpiresAt() instanceof \DateTime) { + if (!$this->getExpiresAt() instanceof \DateTime) { return; } diff --git a/src/Facebook/Authentication/OAuth2Client.php b/src/Facebook/Authentication/OAuth2Client.php index 7460c08db..8e364ec83 100644 --- a/src/Facebook/Authentication/OAuth2Client.php +++ b/src/Facebook/Authentication/OAuth2Client.php @@ -33,11 +33,11 @@ /** * Class OAuth2Client + * * @package Facebook */ class OAuth2Client { - /** * @const string The base authorization URL. */ @@ -72,9 +72,9 @@ class OAuth2Client protected $lastRequest; /** - * @param FacebookApp $app + * @param FacebookApp $app * @param FacebookClient $client - * @param string|null $graphVersion The version of the Graph API to use. + * @param string|null $graphVersion The version of the Graph API to use. */ public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) { @@ -103,10 +103,7 @@ public function getLastRequest() */ public function debugToken($accessToken) { - $accessToken = $accessToken instanceof AccessToken - ? $accessToken->getValue() - : $accessToken; - + $accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; $params = ['input_token' => $accessToken]; $this->lastRequest = new FacebookRequest( @@ -128,10 +125,10 @@ 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 array $scope An array of permissions to request. - * @param string $state The CSPRNG-generated CSRF value. - * @param array $params An array of parameters to generate URL. - * @param string $separator The separator to use in http_build_query(). + * @param array $scope An array of permissions to request. + * @param string $state The CSPRNG-generated CSRF value. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). * * @return string */ @@ -146,8 +143,7 @@ public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], arr 'scope' => implode(',', $scope) ]; - return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . - http_build_query($params, null, $separator); + return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, null, $separator); } /** @@ -181,10 +177,7 @@ public function getAccessTokenFromCode($code, $redirectUri = '') */ public function getLongLivedAccessToken($accessToken) { - $accessToken = $accessToken instanceof AccessToken - ? $accessToken->getValue() - : $accessToken; - + $accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; $params = [ 'grant_type' => 'fb_exchange_token', 'fb_exchange_token' => $accessToken, @@ -197,7 +190,7 @@ public function getLongLivedAccessToken($accessToken) * Get a valid code from an access token. * * @param AccessToken|string $accessToken - * @param string $redirectUri + * @param string $redirectUri * * @return AccessToken * @@ -212,7 +205,7 @@ public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') $response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken); $data = $response->getDecodedBody(); - if (! isset($data['code'])) { + if (!isset($data['code'])) { throw new FacebookSDKException('Code was not returned from Graph.', 401); } @@ -233,7 +226,7 @@ protected function requestAnAccessToken(array $params) $response = $this->sendRequestWithClientParams('/oauth/access_token', $params); $data = $response->getDecodedBody(); - if (! isset($data['access_token'])) { + if (!isset($data['access_token'])) { throw new FacebookSDKException('Access token was not returned from Graph.', 401); } @@ -257,8 +250,8 @@ 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 string|null $accessToken * * @return FacebookResponse diff --git a/src/Facebook/Exceptions/FacebookAuthenticationException.php b/src/Facebook/Exceptions/FacebookAuthenticationException.php index e025a2771..449cf93e6 100644 --- a/src/Facebook/Exceptions/FacebookAuthenticationException.php +++ b/src/Facebook/Exceptions/FacebookAuthenticationException.php @@ -25,6 +25,7 @@ /** * Class FacebookAuthenticationException + * * @package Facebook */ class FacebookAuthenticationException extends FacebookSDKException diff --git a/src/Facebook/Exceptions/FacebookAuthorizationException.php b/src/Facebook/Exceptions/FacebookAuthorizationException.php index 4651bc4a5..4938c42f9 100644 --- a/src/Facebook/Exceptions/FacebookAuthorizationException.php +++ b/src/Facebook/Exceptions/FacebookAuthorizationException.php @@ -25,9 +25,9 @@ /** * Class FacebookAuthorizationException + * * @package Facebook */ class FacebookAuthorizationException extends FacebookSDKException { - } diff --git a/src/Facebook/Exceptions/FacebookClientException.php b/src/Facebook/Exceptions/FacebookClientException.php index 45cdce3c2..b00628366 100644 --- a/src/Facebook/Exceptions/FacebookClientException.php +++ b/src/Facebook/Exceptions/FacebookClientException.php @@ -25,9 +25,9 @@ /** * Class FacebookClientException + * * @package Facebook */ class FacebookClientException extends FacebookSDKException { - } diff --git a/src/Facebook/Exceptions/FacebookOtherException.php b/src/Facebook/Exceptions/FacebookOtherException.php index 226d5da17..9cc94a535 100644 --- a/src/Facebook/Exceptions/FacebookOtherException.php +++ b/src/Facebook/Exceptions/FacebookOtherException.php @@ -25,9 +25,9 @@ /** * Class FacebookOtherException + * * @package Facebook */ class FacebookOtherException extends FacebookSDKException { - } diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 94697cc44..c1b19f907 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -27,11 +27,11 @@ /** * Class FacebookResponseException + * * @package Facebook */ class FacebookResponseException extends FacebookSDKException { - /** * @var FacebookResponse The response that threw the exception. */ @@ -45,7 +45,7 @@ class FacebookResponseException extends FacebookSDKException /** * Creates a FacebookResponseException. * - * @param FacebookResponse $response The response that threw the exception. + * @param FacebookResponse $response The response that threw the exception. * @param FacebookSDKException $previousException The more detailed exception. */ public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) @@ -70,7 +70,7 @@ public static function create(FacebookResponse $response) { $data = $response->getDecodedBody(); - if (! isset($data['error']['code']) && isset($data['code'])) { + if (!isset($data['error']['code']) && isset($data['code'])) { $data = ['error' => $data]; } @@ -121,8 +121,7 @@ public static function create(FacebookResponse $response) } // OAuth authentication error - if (isset($data['error']['type']) - && $data['error']['type'] === 'OAuthException') { + if (isset($data['error']['type']) && $data['error']['type'] === 'OAuthException') { return new static($response, new FacebookAuthenticationException($message, $code)); } @@ -134,7 +133,7 @@ public static function create(FacebookResponse $response) * Checks isset and returns that or a default value. * * @param string $key - * @param mixed $default + * @param mixed $default * * @return mixed */ @@ -143,7 +142,7 @@ private function get($key, $default = null) if (isset($this->responseData['error'][$key])) { return $this->responseData['error'][$key]; } - + return $default; } diff --git a/src/Facebook/Exceptions/FacebookSDKException.php b/src/Facebook/Exceptions/FacebookSDKException.php index 603cff992..03219b0ef 100644 --- a/src/Facebook/Exceptions/FacebookSDKException.php +++ b/src/Facebook/Exceptions/FacebookSDKException.php @@ -25,9 +25,9 @@ /** * Class FacebookSDKException + * * @package Facebook */ class FacebookSDKException extends \Exception { - } diff --git a/src/Facebook/Exceptions/FacebookServerException.php b/src/Facebook/Exceptions/FacebookServerException.php index a3206271a..0790b08a8 100644 --- a/src/Facebook/Exceptions/FacebookServerException.php +++ b/src/Facebook/Exceptions/FacebookServerException.php @@ -25,9 +25,9 @@ /** * Class FacebookServerException + * * @package Facebook */ class FacebookServerException extends FacebookSDKException { - } diff --git a/src/Facebook/Exceptions/FacebookThrottleException.php b/src/Facebook/Exceptions/FacebookThrottleException.php index 72afc2045..6d1e82568 100644 --- a/src/Facebook/Exceptions/FacebookThrottleException.php +++ b/src/Facebook/Exceptions/FacebookThrottleException.php @@ -25,9 +25,9 @@ /** * Class FacebookThrottleException + * * @package Facebook */ class FacebookThrottleException extends FacebookSDKException { - } diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 7e6b0d9ae..3ccdf10ba 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -49,585 +49,539 @@ /** * Class Facebook + * * @package Facebook */ class Facebook { + /** + * @const string Version number of the Facebook PHP SDK. + */ + const VERSION = '4.1.0-dev'; + + /** + * @const string Default Graph API version for requests. + */ + const DEFAULT_GRAPH_VERSION = 'v2.2'; + + /** + * @const string The name of the environment variable that contains the app ID. + */ + const APP_ID_ENV_NAME = 'FACEBOOK_APP_ID'; + + /** + * @const string The name of the environment variable that contains the app secret. + */ + const APP_SECRET_ENV_NAME = 'FACEBOOK_APP_SECRET'; + + /** + * @var FacebookApp The FacebookApp entity. + */ + protected $app; + + /** + * @var FacebookClient The Facebook client service. + */ + protected $client; + + /** + * @var OAuth2Client The OAuth 2.0 client service. + */ + protected $oAuth2Client; + + /** + * @var UrlDetectionInterface|null The URL detection handler. + */ + protected $urlDetectionHandler; + + /** + * @var PseudoRandomStringGeneratorInterface|null The cryptographically secure pseudo-random string generator. + */ + protected $pseudoRandomStringGenerator; + + /** + * @var AccessToken|null The default access token to use with requests. + */ + protected $defaultAccessToken; + + /** + * @var string|null The default Graph version we want to use. + */ + protected $defaultGraphVersion; + + /** + * @var PersistentDataInterface|null The persistent data handler. + */ + protected $persistentDataHandler; + + /** + * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. + */ + protected $lastResponse; + + /** + * Instantiates a new Facebook super-class object. + * + * @param array $config + * + * @throws FacebookSDKException + */ + public function __construct(array $config = []) + { + $appId = isset($config['app_id']) ? $config['app_id'] : getenv(static::APP_ID_ENV_NAME); + if (!$appId) { + throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"'); + } + + $appSecret = isset($config['app_secret']) ? $config['app_secret'] : getenv(static::APP_SECRET_ENV_NAME); + if (!$appSecret) { + throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"'); + } + + $this->app = new FacebookApp($appId, $appSecret); + + $httpClientHandler = null; + if (isset($config['http_client_handler'])) { + if ($config['http_client_handler'] instanceof FacebookHttpClientInterface) { + $httpClientHandler = $config['http_client_handler']; + } elseif ($config['http_client_handler'] === 'curl') { + $httpClientHandler = new FacebookCurlHttpClient(); + } elseif ($config['http_client_handler'] === 'stream') { + $httpClientHandler = new FacebookStreamHttpClient(); + } elseif ($config['http_client_handler'] === 'guzzle') { + $httpClientHandler = new FacebookGuzzleHttpClient(); + } else { + throw new \InvalidArgumentException('The http_client_handler must be set to "curl", "stream", "guzzle", or be an instance of Facebook\HttpClients\FacebookHttpClientInterface'); + } + } + + $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; + $this->client = new FacebookClient($httpClientHandler, $enableBeta); + + if (isset($config['url_detection_handler'])) { + if ($config['url_detection_handler'] instanceof UrlDetectionInterface) { + $this->urlDetectionHandler = $config['url_detection_handler']; + } else { + throw new \InvalidArgumentException('The url_detection_handler must be an instance of Facebook\Url\UrlDetectionInterface'); + } + } + + if (isset($config['pseudo_random_string_generator'])) { + if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) { + $this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator']; + } elseif ($config['pseudo_random_string_generator'] === 'mcrypt') { + $this->pseudoRandomStringGenerator = new McryptPseudoRandomStringGenerator(); + } elseif ($config['pseudo_random_string_generator'] === 'openssl') { + $this->pseudoRandomStringGenerator = new OpenSslPseudoRandomStringGenerator(); + } elseif ($config['pseudo_random_string_generator'] === 'urandom') { + $this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator(); + } else { + throw new \InvalidArgumentException('The pseudo_random_string_generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface'); + } + } + + if (isset($config['persistent_data_handler'])) { + if ($config['persistent_data_handler'] instanceof PersistentDataInterface) { + $this->persistentDataHandler = $config['persistent_data_handler']; + } elseif ($config['persistent_data_handler'] === 'session') { + $this->persistentDataHandler = new FacebookSessionPersistentDataHandler(); + } elseif ($config['persistent_data_handler'] === 'memory') { + $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); + } else { + throw new \InvalidArgumentException('The persistent_data_handler must be set to "session", "memory", or be an instance of Facebook\PersistentData\PersistentDataInterface'); + } + } + + if (isset($config['default_access_token'])) { + $this->setDefaultAccessToken($config['default_access_token']); + } + + if (isset($config['default_graph_version'])) { + $this->defaultGraphVersion = $config['default_graph_version']; + } else { + $this->defaultGraphVersion = static::DEFAULT_GRAPH_VERSION; + } + } + + /** + * Returns the FacebookApp entity. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Returns the FacebookClient service. + * + * @return FacebookClient + */ + public function getClient() + { + return $this->client; + } + + /** + * Returns the OAuth 2.0 client service. + * + * @return OAuth2Client + */ + public function getOAuth2Client() + { + if (!$this->oAuth2Client instanceof OAuth2Client) { + $app = $this->getApp(); + $client = $this->getClient(); + $this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion); + } + + return $this->oAuth2Client; + } - /** - * @const string Version number of the Facebook PHP SDK. - */ - const VERSION = '4.1.0-dev'; - - /** - * @const string Default Graph API version for requests. - */ - const DEFAULT_GRAPH_VERSION = 'v2.2'; - - /** - * @const string The name of the environment variable - * that contains the app ID. - */ - const APP_ID_ENV_NAME = 'FACEBOOK_APP_ID'; - - /** - * @const string The name of the environment variable - * that contains the app secret. - */ - const APP_SECRET_ENV_NAME = 'FACEBOOK_APP_SECRET'; - - /** - * @var FacebookApp The FacebookApp entity. - */ - protected $app; - - /** - * @var FacebookClient The Facebook client service. - */ - protected $client; - - /** - * @var OAuth2Client The OAuth 2.0 client service. - */ - protected $oAuth2Client; - - /** - * @var UrlDetectionInterface|null The URL detection handler. - */ - protected $urlDetectionHandler; - - /** - * @var PseudoRandomStringGeneratorInterface|null The cryptographically secure - * pseudo-random string generator. - */ - protected $pseudoRandomStringGenerator; - - /** - * @var AccessToken|null The default access token to use with requests. - */ - protected $defaultAccessToken; - - /** - * @var string|null The default Graph version we want to use. - */ - protected $defaultGraphVersion; - - /** - * @var PersistentDataInterface|null The persistent data handler. - */ - protected $persistentDataHandler; - - /** - * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. - */ - protected $lastResponse; - - /** - * Instantiates a new Facebook super-class object. - * - * @param array $config - * - * @throws FacebookSDKException - */ - public function __construct(array $config = []) - { - $appId = isset($config['app_id']) - ? $config['app_id'] - : getenv(static::APP_ID_ENV_NAME); - if ( ! $appId) { - throw new FacebookSDKException( - 'Required "app_id" key not supplied in config and' - . ' could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"' - ); + /** + * Returns the last response returned from Graph. + * + * @return FacebookResponse|FacebookBatchResponse|null + */ + public function getLastResponse() + { + return $this->lastResponse; } - $appSecret = isset($config['app_secret']) - ? $config['app_secret'] - : getenv(static::APP_SECRET_ENV_NAME); - if ( ! $appSecret) { - throw new FacebookSDKException( - 'Required "app_secret" key not supplied in config and' - . ' could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"' - ); + /** + * Returns the URL detection handler. + * + * @return UrlDetectionInterface + */ + public function getUrlDetectionHandler() + { + if (!$this->urlDetectionHandler instanceof UrlDetectionInterface) { + $this->urlDetectionHandler = new FacebookUrlDetectionHandler(); + } + + return $this->urlDetectionHandler; + } + + /** + * Returns the default AccessToken entity. + * + * @return AccessToken|null + */ + public function getDefaultAccessToken() + { + return $this->defaultAccessToken; + } + + /** + * Sets the default access token to use with requests. + * + * @param AccessToken|string $accessToken The access token to save. + * + * @throws \InvalidArgumentException + */ + public function setDefaultAccessToken($accessToken) + { + if (is_string($accessToken)) { + $this->defaultAccessToken = new AccessToken($accessToken); + + return; + } + + if ($accessToken instanceof AccessToken) { + $this->defaultAccessToken = $accessToken; + + return; + } + + throw new \InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken'); } - $this->app = new FacebookApp($appId, $appSecret); - - $httpClientHandler = null; - if (isset($config['http_client_handler'])) { - if ($config['http_client_handler'] instanceof FacebookHttpClientInterface) { - $httpClientHandler = $config['http_client_handler']; - } elseif ($config['http_client_handler'] === 'curl') { - $httpClientHandler = new FacebookCurlHttpClient(); - } elseif ($config['http_client_handler'] === 'stream') { - $httpClientHandler = new FacebookStreamHttpClient(); - } elseif ($config['http_client_handler'] === 'guzzle') { - $httpClientHandler = new FacebookGuzzleHttpClient(); - } else { - throw new \InvalidArgumentException( - 'The http_client_handler must be set to "curl", "stream", "guzzle", ' - . ' or be an instance of Facebook\HttpClients\FacebookHttpClientInterface' + /** + * Returns the default Graph version. + * + * @return string + */ + public function getDefaultGraphVersion() + { + return $this->defaultGraphVersion; + } + + /** + * Returns the redirect login helper. + * + * @return FacebookRedirectLoginHelper + */ + public function getRedirectLoginHelper() + { + return new FacebookRedirectLoginHelper( + $this->getOAuth2Client(), + $this->persistentDataHandler, + $this->urlDetectionHandler, + $this->pseudoRandomStringGenerator ); - } } - $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; - $this->client = new FacebookClient($httpClientHandler, $enableBeta); - - if (isset($config['url_detection_handler'])) { - if ($config['url_detection_handler'] instanceof UrlDetectionInterface) { - $this->urlDetectionHandler = $config['url_detection_handler']; - } else { - throw new \InvalidArgumentException( - 'The url_detection_handler must be an instance of Facebook\Url\UrlDetectionInterface' - ); - } + + /** + * Returns the JavaScript helper. + * + * @return FacebookJavaScriptHelper + */ + public function getJavaScriptHelper() + { + return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion); + } + + /** + * Returns the canvas helper. + * + * @return FacebookCanvasHelper + */ + public function getCanvasHelper() + { + return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion); + } + + /** + * Returns the page tab helper. + * + * @return FacebookPageTabHelper + */ + public function getPageTabHelper() + { + return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion); } - if (isset($config['pseudo_random_string_generator'])) { - if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) { - $this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator']; - } elseif ($config['pseudo_random_string_generator'] === 'mcrypt') { - $this->pseudoRandomStringGenerator = new McryptPseudoRandomStringGenerator(); - } elseif ($config['pseudo_random_string_generator'] === 'openssl') { - $this->pseudoRandomStringGenerator = new OpenSslPseudoRandomStringGenerator(); - } elseif ($config['pseudo_random_string_generator'] === 'urandom') { - $this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator(); - } else { - throw new \InvalidArgumentException( - 'The pseudo_random_string_generator must be set to "mcrypt", "openssl", or "urandom", ' - . 'or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface' + /** + * Sends a GET request to Graph and returns the result. + * + * @param string $endpoint + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function get($endpoint, $accessToken = null, $eTag = null, $graphVersion = null) + { + return $this->sendRequest( + 'GET', + $endpoint, + $params = [], + $accessToken, + $eTag, + $graphVersion ); - } } - if (isset($config['persistent_data_handler'])) { - if ( $config['persistent_data_handler'] instanceof PersistentDataInterface) { - $this->persistentDataHandler = $config['persistent_data_handler']; - } elseif ($config['persistent_data_handler'] === 'session') { - $this->persistentDataHandler = new FacebookSessionPersistentDataHandler(); - } elseif ($config['persistent_data_handler'] === 'memory') { - $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); - } else { - throw new \InvalidArgumentException( - 'The persistent_data_handler must be set to "session", "memory", ' - . 'or be an instance of Facebook\PersistentData\PersistentDataInterface' + /** + * Sends a POST request to Graph and returns the result. + * + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function post($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + { + return $this->sendRequest( + 'POST', + $endpoint, + $params, + $accessToken, + $eTag, + $graphVersion ); - } } - if (isset($config['default_access_token'])) { - $this->setDefaultAccessToken($config['default_access_token']); + /** + * Sends a DELETE request to Graph and returns the result. + * + * @param string $endpoint + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function delete($endpoint, $accessToken = null, $eTag = null, $graphVersion = null) + { + return $this->sendRequest( + 'DELETE', + $endpoint, + $params = [], + $accessToken, + $eTag, + $graphVersion + ); } - $this->defaultGraphVersion = isset($config['default_graph_version']) - ? $config['default_graph_version'] - : static::DEFAULT_GRAPH_VERSION; - } - - /** - * Returns the FacebookApp entity. - * - * @return FacebookApp - */ - public function getApp() - { - return $this->app; - } - - /** - * Returns the FacebookClient service. - * - * @return FacebookClient - */ - public function getClient() - { - return $this->client; - } - - /** - * Returns the OAuth 2.0 client service. - * - * @return OAuth2Client - */ - public function getOAuth2Client() - { - if ( ! $this->oAuth2Client instanceof OAuth2Client) { - $app = $this->getApp(); - $client = $this->getClient(); - $this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion); + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function next(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'next'); } - return $this->oAuth2Client; - } - - /** - * Returns the last response returned from Graph. - * - * @return FacebookResponse|FacebookBatchResponse|null - */ - public function getLastResponse() - { - return $this->lastResponse; - } - - /** - * Returns the URL detection handler. - * - * @return UrlDetectionInterface - */ - public function getUrlDetectionHandler() - { - if ( ! $this->urlDetectionHandler instanceof UrlDetectionInterface) { - $this->urlDetectionHandler = new FacebookUrlDetectionHandler(); + /** + * Sends a request to Graph for the previous page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function previous(GraphList $graphList) + { + return $this->getPaginationResults($graphList, 'previous'); } - return $this->urlDetectionHandler; - } - - /** - * Returns the default AccessToken entity. - * - * @return AccessToken|null - */ - public function getDefaultAccessToken() - { - return $this->defaultAccessToken; - } - - /** - * Sets the default access token to use with requests. - * - * @param AccessToken|string $accessToken The access token to save. - * - * @throws \InvalidArgumentException - */ - public function setDefaultAccessToken($accessToken) - { - if (is_string($accessToken)) { - $this->defaultAccessToken = new AccessToken($accessToken); - return; + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphList $graphList The GraphList to paginate over. + * @param string $direction The direction of the pagination: next|previous. + * + * @return GraphList|null + * + * @throws FacebookSDKException + */ + public function getPaginationResults(GraphList $graphList, $direction) + { + $paginationRequest = $graphList->getPaginationRequest($direction); + if (!$paginationRequest) { + return null; + } + + $this->lastResponse = $this->client->sendRequest($paginationRequest); + + // Keep the same GraphObject subclass + $subClassName = $graphList->getSubClassName(); + $graphList = $this->lastResponse->getGraphList($subClassName, false); + + return count($graphList) > 0 ? $graphList : null; } - if ($accessToken instanceof AccessToken) { - $this->defaultAccessToken = $accessToken; - return; + /** + * Sends a request to Graph and returns the result. + * + * @param string $method + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function sendRequest($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); + + return $this->lastResponse = $this->client->sendRequest($request); } - 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() - { - return $this->defaultGraphVersion; - } - - /** - * Returns the redirect login helper. - * - * @return FacebookRedirectLoginHelper - */ - public function getRedirectLoginHelper() - { - return new FacebookRedirectLoginHelper( - $this->getOAuth2Client(), - $this->persistentDataHandler, - $this->urlDetectionHandler, - $this->pseudoRandomStringGenerator - ); - } - - /** - * Returns the JavaScript helper. - * - * @return FacebookJavaScriptHelper - */ - public function getJavaScriptHelper() - { - return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion); - } - - /** - * Returns the canvas helper. - * - * @return FacebookCanvasHelper - */ - public function getCanvasHelper() - { - return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion); - } - - /** - * Returns the page tab helper. - * - * @return FacebookPageTabHelper - */ - public function getPageTabHelper() - { - return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion); - } - - /** - * Sends a GET request to Graph and returns the result. - * - * @param string $endpoint - * @param AccessToken|string|null $accessToken - * @param string|null $eTag - * @param string|null $graphVersion - * - * @return FacebookResponse - * - * @throws FacebookSDKException - */ - public function get( - $endpoint, - $accessToken = null, - $eTag = null, - $graphVersion = null) - { - return $this->sendRequest( - 'GET', - $endpoint, - $params = [], - $accessToken, - $eTag, - $graphVersion); - } - - /** - * Sends a POST request to Graph and returns the result. - * - * @param string $endpoint - * @param array $params - * @param AccessToken|string|null $accessToken - * @param string|null $eTag - * @param string|null $graphVersion - * - * @return FacebookResponse - * - * @throws FacebookSDKException - */ - public function post( - $endpoint, - array $params = [], - $accessToken = null, - $eTag = null, - $graphVersion = null) - { - return $this->sendRequest( - 'POST', - $endpoint, - $params, - $accessToken, - $eTag, - $graphVersion); - } - - /** - * Sends a DELETE request to Graph and returns the result. - * - * @param string $endpoint - * @param AccessToken|string|null $accessToken - * @param string|null $eTag - * @param string|null $graphVersion - * - * @return FacebookResponse - * - * @throws FacebookSDKException - */ - public function delete( - $endpoint, - $accessToken = null, - $eTag = null, - $graphVersion = null) - { - return $this->sendRequest( - 'DELETE', - $endpoint, - $params = [], - $accessToken, - $eTag, - $graphVersion); - } - - /** - * Sends a request to Graph for the next page of results. - * - * @param GraphList $graphList The GraphList to paginate over. - * - * @return GraphList|null - * - * @throws FacebookSDKException - */ - public function next(GraphList $graphList) - { - return $this->getPaginationResults($graphList, 'next'); - } - - /** - * Sends a request to Graph for the previous page of results. - * - * @param GraphList $graphList The GraphList to paginate over. - * - * @return GraphList|null - * - * @throws FacebookSDKException - */ - public function previous(GraphList $graphList) - { - return $this->getPaginationResults($graphList, 'previous'); - } - - /** - * Sends a request to Graph for the next page of results. - * - * @param GraphList $graphList The GraphList to paginate over. - * @param string $direction The direction of the pagination: next|previous. - * - * @return GraphList|null - * - * @throws FacebookSDKException - */ - public function getPaginationResults(GraphList $graphList, $direction) - { - $paginationRequest = $graphList->getPaginationRequest($direction); - if ( ! $paginationRequest) { - return null; + /** + * Sends a batched request to Graph and returns the result. + * + * @param array $requests + * @param AccessToken|string|null $accessToken + * @param string|null $graphVersion + * + * @return FacebookBatchResponse + * + * @throws FacebookSDKException + */ + public function sendBatchRequest(array $requests, $accessToken = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $batchRequest = new FacebookBatchRequest( + $this->app, + $requests, + $accessToken, + $graphVersion + ); + + return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); } - $this->lastResponse = $this->client->sendRequest($paginationRequest); - - // Keep the same GraphObject subclass - $subClassName = $graphList->getSubClassName(); - $graphList = $this->lastResponse->getGraphList($subClassName, false); - - return count($graphList) > 0 ? $graphList : null; - } - - /** - * Sends a request to Graph and returns the result. - * - * @param string $method - * @param string $endpoint - * @param array $params - * @param AccessToken|string|null $accessToken - * @param string|null $eTag - * @param string|null $graphVersion - * - * @return FacebookResponse - * - * @throws FacebookSDKException - */ - public function sendRequest( - $method, - $endpoint, - array $params = [], - $accessToken = null, - $eTag = null, - $graphVersion = null) - { - $accessToken = $accessToken ?: $this->defaultAccessToken; - $graphVersion = $graphVersion ?: $this->defaultGraphVersion; - $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); - return $this->lastResponse = $this->client->sendRequest($request); - } - - /** - * Sends a batched request to Graph and returns the result. - * - * @param array $requests - * @param AccessToken|string|null $accessToken - * @param string|null $graphVersion - * - * @return FacebookBatchResponse - * - * @throws FacebookSDKException - */ - public function sendBatchRequest( - array $requests, - $accessToken = null, - $graphVersion = null) - { - $accessToken = $accessToken ?: $this->defaultAccessToken; - $graphVersion = $graphVersion ?: $this->defaultGraphVersion; - $batchRequest = new FacebookBatchRequest( - $this->app, - $requests, - $accessToken, - $graphVersion - ); - - return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); - } - - /** - * 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) - { - $accessToken = $accessToken ?: $this->defaultAccessToken; - $graphVersion = $graphVersion ?: $this->defaultGraphVersion; - return new FacebookRequest( - $this->app, - $accessToken, - $method, - $endpoint, - $params, - $eTag, - $graphVersion - ); - } - - /** - * Factory to create FacebookFile's. - * - * @param string $pathToFile - * - * @return FacebookFile - * - * @throws FacebookSDKException - */ - public function fileToUpload($pathToFile) - { - return new FacebookFile($pathToFile); - } - - /** - * Factory to create FacebookVideo's. - * - * @param string $pathToFile - * - * @return FacebookVideo - * - * @throws FacebookSDKException - */ - public function videoToUpload($pathToFile) - { - return new FacebookVideo($pathToFile); - } + /** + * 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) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + + return new FacebookRequest( + $this->app, + $accessToken, + $method, + $endpoint, + $params, + $eTag, + $graphVersion + ); + } + /** + * Factory to create FacebookFile's. + * + * @param string $pathToFile + * + * @return FacebookFile + * + * @throws FacebookSDKException + */ + public function fileToUpload($pathToFile) + { + return new FacebookFile($pathToFile); + } + + /** + * Factory to create FacebookVideo's. + * + * @param string $pathToFile + * + * @return FacebookVideo + * + * @throws FacebookSDKException + */ + public function videoToUpload($pathToFile) + { + return new FacebookVideo($pathToFile); + } } diff --git a/src/Facebook/FacebookApp.php b/src/Facebook/FacebookApp.php index cc21a8d6c..84956ce98 100644 --- a/src/Facebook/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -27,77 +27,75 @@ class FacebookApp implements \Serializable { + /** + * @var string The app ID. + */ + protected $id; - /** - * @var string The app ID. - */ - protected $id; + /** + * @var string The app secret. + */ + protected $secret; - /** - * @var string The app secret. - */ - protected $secret; + /** + * @param string $id + * @param string $secret + */ + public function __construct($id, $secret) + { + $this->id = $id; + $this->secret = $secret; + } - /** - * @param string $id - * @param string $secret - */ - public function __construct($id, $secret) - { - $this->id = $id; - $this->secret = $secret; - } + /** + * Returns the app ID. + * + * @return string + */ + public function getId() + { + return $this->id; + } - /** - * Returns the app ID. - * - * @return string - */ - public function getId() - { - return $this->id; - } + /** + * Returns the app secret. + * + * @return string + */ + public function getSecret() + { + return $this->secret; + } - /** - * Returns the app secret. - * - * @return string - */ - public function getSecret() - { - return $this->secret; - } + /** + * Returns an app access token. + * + * @return AccessToken + */ + public function getAccessToken() + { + return new AccessToken($this->id . '|' . $this->secret); + } - /** - * Returns an app access token. - * - * @return AccessToken - */ - public function getAccessToken() - { - return new AccessToken($this->id . '|' . $this->secret); - } + /** + * Serializes the FacebookApp entity as a string. + * + * @return string + */ + public function serialize() + { + return serialize([$this->id, $this->secret]); + } - /** - * Serializes the FacebookApp entity as a string. - * - * @return string - */ - public function serialize() - { - return serialize([$this->id, $this->secret]); - } - - /** - * Unserializes a string as a FacebookApp entity. - * - * @param string $serialized - */ - public function unserialize($serialized) - { - list($id, $secret) = unserialize($serialized); - - $this->__construct($id, $secret); - } + /** + * Unserializes a string as a FacebookApp entity. + * + * @param string $serialized + */ + public function unserialize($serialized) + { + list($id, $secret) = unserialize($serialized); + $this->__construct($id, $secret); + } } diff --git a/src/Facebook/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php index 0e409d722..33c489cf8 100755 --- a/src/Facebook/FacebookBatchRequest.php +++ b/src/Facebook/FacebookBatchRequest.php @@ -26,290 +26,278 @@ use ArrayIterator; use IteratorAggregate; use ArrayAccess; +use Facebook\Authentication\AccessToken; use Facebook\Exceptions\FacebookSDKException; /** * Class BatchRequest + * * @package Facebook */ class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, ArrayAccess { + /** + * @var array An array of FacebookRequest entities to send. + */ + protected $requests; + + /** + * @var array An array of files to upload. + */ + protected $attachedFiles; + + /** + * Creates a new Request entity. + * + * @param FacebookApp|null $app + * @param array $requests + * @param AccessToken|string|null $accessToken + * @param string|null $graphVersion + */ + public function __construct(FacebookApp $app = null, array $requests = [], $accessToken = null, $graphVersion = null) + { + parent::__construct($app, $accessToken, 'POST', '', [], null, $graphVersion); + + $this->add($requests); + } - /** - * @var array An array of FacebookRequest entities to send. - */ - protected $requests; - - /** - * @var array An array of files to upload. - */ - protected $attachedFiles; - - /** - * Creates a new Request entity. - * - * @param FacebookApp|null $app - * @param array $requests - * @param AccessToken|string|null $accessToken - * @param string|null $graphVersion - */ - public function __construct( - FacebookApp $app = null, - array $requests = [], - $accessToken = null, - $graphVersion = null - ) - { - parent::__construct($app, $accessToken, 'POST', '', [], null, $graphVersion); - - $this->add($requests); - } - - /** - * A a new request to the array. - * - * @param FacebookRequest|array $request - * @param string|null $name - * - * @return FacebookBatchRequest - * - * @throws \InvalidArgumentException - */ - public function add($request, $name = null) - { - if (is_array($request)) { - foreach ($request as $key => $req) { - $this->add($req, $key); - } - return $this; - } elseif ($request instanceof FacebookRequest) { - $this->addFallbackDefaults($request); - $requestToAdd = [ - 'name' => $name, - 'request' => $request, - ]; - - // File uploads - $attachedFiles = $this->extractFileAttachments($request); - if ($attachedFiles) { - $requestToAdd['attached_files'] = $attachedFiles; - } - $this->requests[] = $requestToAdd; - - return $this; + /** + * A a new request to the array. + * + * @param FacebookRequest|array $request + * @param string|null $name + * + * @return FacebookBatchRequest + * + * @throws \InvalidArgumentException + */ + public function add($request, $name = null) + { + if (is_array($request)) { + foreach ($request as $key => $req) { + $this->add($req, $key); + } + + return $this; + } + + if (!$request instanceof FacebookRequest) { + throw new \InvalidArgumentException('Argument for add() must be of type array or FacebookRequest.'); + } + + $this->addFallbackDefaults($request); + $requestToAdd = [ + 'name' => $name, + 'request' => $request, + ]; + + // File uploads + $attachedFiles = $this->extractFileAttachments($request); + if ($attachedFiles) { + $requestToAdd['attached_files'] = $attachedFiles; + } + $this->requests[] = $requestToAdd; + + return $this; } - throw new \InvalidArgumentException( - 'Argument for add() must be of type array or FacebookRequest.' - ); - } - - /** - * Ensures that the FacebookApp and access token fall back when missing. - * - * @param FacebookRequest $request - * - * @throws FacebookSDKException - */ - public function addFallbackDefaults(FacebookRequest $request) - { - if (!$request->getApp()) { - $app = $this->getApp(); - if (!$app) { - throw new FacebookSDKException( - 'Missing FacebookApp on FacebookRequest and no fallback detected on FacebookBatchRequest.' - ); - } - $request->setApp($app); + + /** + * Ensures that the FacebookApp and access token fall back when missing. + * + * @param FacebookRequest $request + * + * @throws FacebookSDKException + */ + public function addFallbackDefaults(FacebookRequest $request) + { + if (!$request->getApp()) { + $app = $this->getApp(); + if (!$app) { + throw new FacebookSDKException('Missing FacebookApp on FacebookRequest and no fallback detected on FacebookBatchRequest.'); + } + $request->setApp($app); + } + + if (!$request->getAccessToken()) { + $accessToken = $this->getAccessToken(); + if (!$accessToken) { + throw new FacebookSDKException('Missing access token on FacebookRequest and no fallback detected on FacebookBatchRequest.'); + } + $request->setAccessToken($accessToken); + } } - if (!$request->getAccessToken()) { - $accessToken = $this->getAccessToken(); - if (!$accessToken) { - throw new FacebookSDKException( - 'Missing access token on FacebookRequest and no fallback detected on FacebookBatchRequest.' - ); - } - $request->setAccessToken($accessToken); + + /** + * Extracts the files from a request. + * + * @param FacebookRequest $request + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function extractFileAttachments(FacebookRequest $request) + { + if (!$request->containsFileUploads()) { + return null; + } + + $files = $request->getFiles(); + $fileNames = []; + foreach ($files as $file) { + $fileName = uniqid(); + $this->addFile($fileName, $file); + $fileNames[] = $fileName; + } + + $request->resetFiles(); + + // @TODO Does Graph support multiple uploads on one endpoint? + return implode(',', $fileNames); } - } - - /** - * Extracts the files from a request. - * - * @param FacebookRequest $request - * - * @return string|null - * - * @throws FacebookSDKException - */ - public function extractFileAttachments(FacebookRequest $request) - { - if ( ! $request->containsFileUploads()) { - return null; + + /** + * Return the FacebookRequest entities. + * + * @return array + */ + public function getRequests() + { + return $this->requests; } - $files = $request->getFiles(); - $fileNames = []; - foreach ($files as $file) { - $fileName = uniqid(); - $this->addFile($fileName, $file); - $fileNames[] = $fileName; + + /** + * Prepares the requests to be sent as a batch request. + * + * @return string + */ + public function prepareRequestsForBatch() + { + $this->validateBatchRequestCount(); + + $params = [ + 'batch' => $this->convertRequestsToJson(), + 'include_headers' => true, + ]; + $this->setParams($params); } - $request->resetFiles(); - - // @TODO Does Graph support multiple uploads on one endpoint? - return implode(',', $fileNames); - } - - /** - * Return the FacebookRequest entities. - * - * @return array - */ - public function getRequests() - { - return $this->requests; - } - - /** - * Prepares the requests to be sent as a batch request. - * - * @return string - */ - public function prepareRequestsForBatch() - { - $this->validateBatchRequestCount(); - - $params = [ - 'batch' => $this->convertRequestsToJson(), - 'include_headers' => true, - ]; - $this->setParams($params); - } - - /** - * Converts the requests into a JSON(P) string. - * - * @return string - */ - public function convertRequestsToJson() - { - $requests = []; - foreach ($this->requests as $request) { - $attachedFiles = isset($request['attached_files']) ? $request['attached_files'] : null; - $requests[] = $this->requestEntityToBatchArray($request['request'], $request['name'], $attachedFiles); + /** + * Converts the requests into a JSON(P) string. + * + * @return string + */ + public function convertRequestsToJson() + { + $requests = []; + foreach ($this->requests as $request) { + $attachedFiles = isset($request['attached_files']) ? $request['attached_files'] : null; + $requests[] = $this->requestEntityToBatchArray($request['request'], $request['name'], $attachedFiles); + } + + return json_encode($requests); } - return json_encode($requests); - } - - /** - * Validate the request count before sending them as a batch. - * - * @throws FacebookSDKException - */ - public function validateBatchRequestCount() - { - $batchCount = count($this->requests); - if ($batchCount === 0) { - throw new FacebookSDKException( - 'There are no batch requests to send.' - ); - } elseif ($batchCount > 50) { - // Per: https://developers.facebook.com/docs/graph-api/making-multiple-requests#limits - throw new FacebookSDKException( - 'You cannot send more than 50 batch requests at a time.' - ); + /** + * Validate the request count before sending them as a batch. + * + * @throws FacebookSDKException + */ + public function validateBatchRequestCount() + { + $batchCount = count($this->requests); + if ($batchCount === 0) { + throw new FacebookSDKException('There are no batch requests to send.'); + } elseif ($batchCount > 50) { + // Per: https://developers.facebook.com/docs/graph-api/making-multiple-requests#limits + throw new FacebookSDKException('You cannot send more than 50 batch requests at a time.'); + } } - } - - /** - * Converts a Request entity into an array that is batch-friendly. - * - * @param FacebookRequest $request The request entity to convert. - * @param string|null $requestName The name of the request. - * @param string|null $attachedFiles Names of files associated with the request. - * - * @return array - */ - public function requestEntityToBatchArray( - FacebookRequest $request, - $requestName = null, - $attachedFiles = null) - { - $compiledHeaders = []; - $headers = $request->getHeaders(); - foreach ($headers as $name => $value) { - $compiledHeaders[] = $name . ': ' . $value; + + /** + * Converts a Request entity into an array that is batch-friendly. + * + * @param FacebookRequest $request The request entity to convert. + * @param string|null $requestName The name of the request. + * @param string|null $attachedFiles Names of files associated with the request. + * + * @return array + */ + public function requestEntityToBatchArray(FacebookRequest $request, $requestName = null, $attachedFiles = null) + { + $compiledHeaders = []; + $headers = $request->getHeaders(); + foreach ($headers as $name => $value) { + $compiledHeaders[] = $name . ': ' . $value; + } + + $batch = [ + 'headers' => $compiledHeaders, + 'method' => $request->getMethod(), + 'relative_url' => $request->getUrl(), + ]; + + // Since file uploads are moved to the root request of a batch request, + // the child requests will always be URL-encoded. + $body = $request->getUrlEncodedBody()->getBody(); + if ($body) { + $batch['body'] = $body; + } + + if (isset($requestName)) { + $batch['name'] = $requestName; + } + + if (isset($attachedFiles)) { + $batch['attached_files'] = $attachedFiles; + } + + // @TODO Add support for "omit_response_on_success" + // @TODO Add support for "depends_on" + // @TODO Add support for JSONP with "callback" + + return $batch; } - $batch = [ - 'headers' => $compiledHeaders, - 'method' => $request->getMethod(), - 'relative_url' => $request->getUrl(), - ]; - - // Since file uploads are moved to the root request of a batch request, - // the child requests will always be URL-encoded. - $body = $request->getUrlEncodedBody()->getBody(); - if ($body) { - $batch['body'] = $body; + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->requests); } - if (isset($requestName)) { - $batch['name'] = $requestName; + /** + * @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->add($value, $offset); } - if (isset($attachedFiles)) { - $batch['attached_files'] = $attachedFiles; + /** + * @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->requests[$offset]); } - // @TODO Add support for "omit_response_on_success" - // @TODO Add support for "depends_on" - // @TODO Add support for JSONP with "callback" - - return $batch; - } - - /** - * Get an iterator for the items. - * - * @return ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->requests); - } - - /** - * @inheritdoc - */ - public function offsetSet($offset, $value) - { - $this->add($value, $offset); - } - - /** - * @inheritdoc - */ - public function offsetExists($offset) - { - return isset($this->requests[$offset]); - } - - /** - * @inheritdoc - */ - public function offsetUnset($offset) - { - unset($this->requests[$offset]); - } - - /** - * @inheritdoc - */ - public function offsetGet($offset) - { - return isset($this->requests[$offset]) ? $this->requests[$offset] : null; - } + /** + * @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->requests[$offset]); + } + /** + * @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->requests[$offset]) ? $this->requests[$offset] : null; + } } diff --git a/src/Facebook/FacebookBatchResponse.php b/src/Facebook/FacebookBatchResponse.php index c0e47f7b4..5ea765e30 100755 --- a/src/Facebook/FacebookBatchResponse.php +++ b/src/Facebook/FacebookBatchResponse.php @@ -29,133 +29,126 @@ /** * Class FacebookBatchResponse + * * @package Facebook */ class FacebookBatchResponse extends FacebookResponse implements IteratorAggregate, ArrayAccess { + /** + * @var FacebookBatchRequest The original entity that made the batch request. + */ + protected $batchRequest; + + /** + * @var array An array of FacebookResponse entities. + */ + protected $responses = []; + + /** + * Creates a new Response entity. + * + * @param FacebookBatchRequest $batchRequest + * @param FacebookResponse $response + */ + public function __construct(FacebookBatchRequest $batchRequest, FacebookResponse $response) + { + $this->batchRequest = $batchRequest; + + $request = $response->getRequest(); + $body = $response->getBody(); + $httpStatusCode = $response->getHttpStatusCode(); + $headers = $response->getHeaders(); + parent::__construct($request, $body, $httpStatusCode, $headers); + + $responses = $response->getDecodedBody(); + $this->setResponses($responses); + } + + /** + * Returns an array of FacebookResponse entities. + * + * @return array + */ + public function getResponses() + { + return $this->responses; + } + + /** + * 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) + { + $this->responses = []; + + foreach ($responses as $key => $graphResponse) { + $this->addResponse($key, $graphResponse); + } + } + + /** + * Add a response to the list. + * + * @param int $key + * @param array|null $response + */ + public function addResponse($key, $response) + { + $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; + $httpResponseHeaders = isset($response['headers']) ? $response['headers'] : []; + + $this->responses[$originalRequestName] = new FacebookResponse( + $originalRequest, + $httpResponseBody, + $httpResponseCode, + $httpResponseHeaders + ); + } - /** - * @var FacebookBatchRequest The original entity that made the batch request. - */ - protected $batchRequest; - - /** - * @var array An array of FacebookResponse entities. - */ - protected $responses = []; - - /** - * Creates a new Response entity. - * - * @param FacebookBatchRequest $batchRequest - * @param FacebookResponse $response - */ - public function __construct( - FacebookBatchRequest $batchRequest, - FacebookResponse $response - ) - { - $this->batchRequest = $batchRequest; - - $request = $response->getRequest(); - $body = $response->getBody(); - $httpStatusCode = $response->getHttpStatusCode(); - $headers = $response->getHeaders(); - parent::__construct($request, $body, $httpStatusCode, $headers); - - $responses = $response->getDecodedBody(); - $this->setResponses($responses); - } - - /** - * Returns an array of FacebookResponse entities. - * - * @return array - */ - public function getResponses() - { - return $this->responses; - } - - /** - * 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) - { - $this->responses = []; - - foreach ($responses as $key => $graphResponse) { - $this->addResponse($key, $graphResponse); + /** + * @inheritdoc + */ + public function getIterator() + { + return new ArrayIterator($this->responses); } - } - - /** - * Add a response to the list. - * - * @param int $key - * @param array|null $response - */ - public function addResponse($key, $response) - { - $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; - $httpResponseHeaders = isset($response['headers']) ? $response['headers'] : []; - - $this->responses[$originalRequestName] = new FacebookResponse( - $originalRequest, - $httpResponseBody, - $httpResponseCode, - $httpResponseHeaders); - } - - /** - * @inheritdoc - */ - public function getIterator() - { - return new ArrayIterator($this->responses); - } - - /** - * @inheritdoc - */ - public function offsetSet($offset, $value) - { - $this->addResponse($offset, $value); - } - - /** - * @inheritdoc - */ - public function offsetExists($offset) - { - return isset($this->responses[$offset]); - } - - /** - * @inheritdoc - */ - public function offsetUnset($offset) - { - unset($this->responses[$offset]); - } - - /** - * @inheritdoc - */ - public function offsetGet($offset) - { - return isset($this->responses[$offset]) ? $this->responses[$offset] : null; - } + /** + * @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->addResponse($offset, $value); + } + + /** + * @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->responses[$offset]); + } + + /** + * @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->responses[$offset]); + } + + /** + * @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->responses[$offset]) ? $this->responses[$offset] : null; + } } diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index caf6c33fb..b10762f1b 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -30,226 +30,221 @@ /** * Class FacebookClient + * * @package Facebook */ class FacebookClient { - - /** - * @const string Production Graph API URL. - */ - const BASE_GRAPH_URL = 'https://graph.facebook.com'; - - /** - * @const string Graph API URL for video uploads. - */ - const BASE_GRAPH_VIDEO_URL = 'https://graph-video.facebook.com'; - - /** - * @const string Beta Graph API URL. - */ - const BASE_GRAPH_URL_BETA = 'https://graph.beta.facebook.com'; - - /** - * @const string Beta Graph API URL for video uploads. - */ - const BASE_GRAPH_VIDEO_URL_BETA = 'https://graph-video.beta.facebook.com'; - - /** - * @const int The timeout in seconds for a normal request. - */ - const DEFAULT_REQUEST_TIMEOUT = 60; - - /** - * @const int The timeout in seconds for a request that contains file uploads. - */ - const DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT = 3600; - - /** - * @const int The timeout in seconds for a request that contains video uploads. - */ - const DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT = 7200; - - /** - * @var bool Toggle to use Graph beta url. - */ - protected $enableBetaMode = false; - - /** - * @var FacebookHttpClientInterface HTTP client handler. - */ - protected $httpClientHandler; - - /** - * @var int The number of calls that have been made to Graph. - */ - public static $requestCount = 0; - - /** - * Instantiates a new FacebookClient object. - * - * @param FacebookHttpClientInterface|null $httpClientHandler - * @param boolean $enableBeta - */ - public function __construct( - FacebookHttpClientInterface $httpClientHandler = null, - $enableBeta = false - ) - { - $this->httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler(); - $this->enableBetaMode = $enableBeta; - } - - /** - * Sets the HTTP client handler. - * - * @param FacebookHttpClientInterface $httpClientHandler - */ - public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler) - { - $this->httpClientHandler = $httpClientHandler; - } - - /** - * Returns the HTTP client handler. - * - * @return FacebookHttpClientInterface - */ - public function getHttpClientHandler() - { - return $this->httpClientHandler; - } - - /** - * Detects which HTTP client handler to use. - * - * @return FacebookHttpClientInterface - */ - public function detectHttpClientHandler() - { - return function_exists('curl_init') - ? new FacebookCurlHttpClient() - : new FacebookStreamHttpClient(); - } - - /** - * Toggle beta mode. - * - * @param boolean $betaMode - */ - public function enableBetaMode($betaMode = true) - { - $this->enableBetaMode = $betaMode; - } - - /** - * 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) - { - if ($postToVideoUrl) { - return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL; - } - return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL; - } - - /** - * Prepares the request for sending to the client handler. - * - * @param FacebookRequest $request - * - * @return array - */ - public function prepareRequestMessage(FacebookRequest $request) - { - $postToVideoUrl = $request->containsVideoUploads(); - $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl(); - - // If we're sending files they should be sent as multipart/form-data - if($request->containsFileUploads()) { - $requestBody = $request->getMultipartBody(); - $request->setHeaders( - ['Content-Type' => 'multipart/form-data; boundary=' . $requestBody->getBoundary()] - ); - } else { - $requestBody = $request->getUrlEncodedBody(); - $request->setHeaders( - ['Content-Type' => 'application/x-www-form-urlencoded'] - ); + /** + * @const string Production Graph API URL. + */ + const BASE_GRAPH_URL = 'https://graph.facebook.com'; + + /** + * @const string Graph API URL for video uploads. + */ + const BASE_GRAPH_VIDEO_URL = 'https://graph-video.facebook.com'; + + /** + * @const string Beta Graph API URL. + */ + const BASE_GRAPH_URL_BETA = 'https://graph.beta.facebook.com'; + + /** + * @const string Beta Graph API URL for video uploads. + */ + const BASE_GRAPH_VIDEO_URL_BETA = 'https://graph-video.beta.facebook.com'; + + /** + * @const int The timeout in seconds for a normal request. + */ + const DEFAULT_REQUEST_TIMEOUT = 60; + + /** + * @const int The timeout in seconds for a request that contains file uploads. + */ + const DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT = 3600; + + /** + * @const int The timeout in seconds for a request that contains video uploads. + */ + const DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT = 7200; + + /** + * @var bool Toggle to use Graph beta url. + */ + protected $enableBetaMode = false; + + /** + * @var FacebookHttpClientInterface HTTP client handler. + */ + protected $httpClientHandler; + + /** + * @var int The number of calls that have been made to Graph. + */ + public static $requestCount = 0; + + /** + * Instantiates a new FacebookClient object. + * + * @param FacebookHttpClientInterface|null $httpClientHandler + * @param boolean $enableBeta + */ + public function __construct(FacebookHttpClientInterface $httpClientHandler = null, $enableBeta = false) + { + $this->httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler(); + $this->enableBetaMode = $enableBeta; } - return [ - $url, - $request->getMethod(), - $request->getHeaders(), - $requestBody->getBody(), - ]; - } - - /** - * Makes the request to Graph and returns the result. - * - * @param FacebookRequest $request - * - * @return FacebookResponse - * - * @throws FacebookSDKException - */ - public function sendRequest(FacebookRequest $request) - { - if (get_class($request) === 'FacebookRequest') { - $request->validateAccessToken(); + /** + * Sets the HTTP client handler. + * + * @param FacebookHttpClientInterface $httpClientHandler + */ + public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler) + { + $this->httpClientHandler = $httpClientHandler; } - list($url, $method, $headers, $body) = $this->prepareRequestMessage($request); - - // Since file uploads can take a while, we need to give more time for uploads - $timeOut = static::DEFAULT_REQUEST_TIMEOUT; - if ($request->containsFileUploads()) { - $timeOut = static::DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT; - } elseif ($request->containsVideoUploads()) { - $timeOut = static::DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT; + /** + * Returns the HTTP client handler. + * + * @return FacebookHttpClientInterface + */ + public function getHttpClientHandler() + { + return $this->httpClientHandler; } - // Should throw `FacebookSDKException` exception on HTTP client error. - // Don't catch to allow it to bubble up. - $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers, $timeOut); + /** + * Detects which HTTP client handler to use. + * + * @return FacebookHttpClientInterface + */ + public function detectHttpClientHandler() + { + return function_exists('curl_init') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient(); + } - static::$requestCount++; + /** + * Toggle beta mode. + * + * @param boolean $betaMode + */ + public function enableBetaMode($betaMode = true) + { + $this->enableBetaMode = $betaMode; + } - $returnResponse = new FacebookResponse( - $request, - $rawResponse->getBody(), - $rawResponse->getHttpResponseCode(), - $rawResponse->getHeaders() - ); + /** + * 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) + { + if ($postToVideoUrl) { + return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL; + } + + return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL; + } - if ($returnResponse->isError()) { - throw $returnResponse->getThrownException(); + /** + * Prepares the request for sending to the client handler. + * + * @param FacebookRequest $request + * + * @return array + */ + public function prepareRequestMessage(FacebookRequest $request) + { + $postToVideoUrl = $request->containsVideoUploads(); + $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl(); + + // If we're sending files they should be sent as multipart/form-data + if ($request->containsFileUploads()) { + $requestBody = $request->getMultipartBody(); + $request->setHeaders([ + 'Content-Type' => 'multipart/form-data; boundary=' . $requestBody->getBoundary(), + ]); + } else { + $requestBody = $request->getUrlEncodedBody(); + $request->setHeaders([ + 'Content-Type' => 'application/x-www-form-urlencoded', + ]); + } + + return [ + $url, + $request->getMethod(), + $request->getHeaders(), + $requestBody->getBody(), + ]; } - return $returnResponse; - } - - /** - * Makes a batched request to Graph and returns the result. - * - * @param FacebookBatchRequest $request - * - * @return FacebookBatchResponse - * - * @throws FacebookSDKException - */ - public function sendBatchRequest(FacebookBatchRequest $request) - { - $request->prepareRequestsForBatch(); - $facebookResponse = $this->sendRequest($request); - - return new FacebookBatchResponse($request, $facebookResponse); - } + /** + * Makes the request to Graph and returns the result. + * + * @param FacebookRequest $request + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function sendRequest(FacebookRequest $request) + { + if (get_class($request) === 'FacebookRequest') { + $request->validateAccessToken(); + } + + list($url, $method, $headers, $body) = $this->prepareRequestMessage($request); + + // Since file uploads can take a while, we need to give more time for uploads + $timeOut = static::DEFAULT_REQUEST_TIMEOUT; + if ($request->containsFileUploads()) { + $timeOut = static::DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT; + } elseif ($request->containsVideoUploads()) { + $timeOut = static::DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT; + } + + // Should throw `FacebookSDKException` exception on HTTP client error. + // Don't catch to allow it to bubble up. + $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers, $timeOut); + + static::$requestCount++; + + $returnResponse = new FacebookResponse( + $request, + $rawResponse->getBody(), + $rawResponse->getHttpResponseCode(), + $rawResponse->getHeaders() + ); + + if ($returnResponse->isError()) { + throw $returnResponse->getThrownException(); + } + + return $returnResponse; + } + /** + * Makes a batched request to Graph and returns the result. + * + * @param FacebookBatchRequest $request + * + * @return FacebookBatchResponse + * + * @throws FacebookSDKException + */ + public function sendBatchRequest(FacebookBatchRequest $request) + { + $request->prepareRequestsForBatch(); + $facebookResponse = $this->sendRequest($request); + + return new FacebookBatchResponse($request, $facebookResponse); + } } diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index eb1953d8b..5e4083f8a 100755 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -33,525 +33,504 @@ /** * Class Request + * * @package Facebook */ class FacebookRequest { + /** + * @var FacebookApp The Facebook app entity. + */ + protected $app; + + /** + * @var string|null The access token to use for this request. + */ + protected $accessToken; + + /** + * @var string The HTTP method for this request. + */ + protected $method; + + /** + * @var string The Graph endpoint for this request. + */ + protected $endpoint; + + /** + * @var array The headers to send with this request. + */ + protected $headers = []; + + /** + * @var array The parameters to send with this request. + */ + protected $params = []; + + /** + * @var array The files to send with this request. + */ + protected $files = []; + + /** + * @var string ETag to send with this request. + */ + protected $eTag; + + /** + * @var string Graph version to use for this request. + */ + protected $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 + */ + public function __construct(FacebookApp $app = null, $accessToken = null, $method = null, $endpoint = null, array $params = [], $eTag = null, $graphVersion = null) + { + $this->setApp($app); + $this->setAccessToken($accessToken); + $this->setMethod($method); + $this->setEndpoint($endpoint); + $this->setParams($params); + $this->setETag($eTag); + $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + } + + /** + * Set the access token for this request. + * + * @param AccessToken|string + * + * @return FacebookRequest + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + if ($accessToken instanceof AccessToken) { + $this->accessToken = $accessToken->getValue(); + } + + return $this; + } + + /** + * Sets the access token with one harvested from a URL or POST params. + * + * @param string $accessToken The access token. + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setAccessTokenFromParams($accessToken) + { + $existingAccessToken = $this->getAccessToken(); + if (!$existingAccessToken) { + $this->setAccessToken($accessToken); + } elseif ($accessToken !== $existingAccessToken) { + throw new FacebookSDKException('Access token mismatch. The access token provided in the FacebookRequest and the one provided in the URL or POST params do not match.'); + } + + return $this; + } + + /** + * Return the access token for this request. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * Return the access token for this request an an AccessToken entity. + * + * @return AccessToken|null + */ + public function getAccessTokenEntity() + { + return $this->accessToken ? new AccessToken($this->accessToken) : null; + } + + /** + * Set the FacebookApp entity used for this request. + * + * @param FacebookApp|null $app + */ + public function setApp(FacebookApp $app = null) + { + $this->app = $app; + } + + /** + * Return the FacebookApp entity used for this request. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Generate an app secret proof to sign this request. + * + * @return string|null + */ + public function getAppSecretProof() + { + if (!$accessTokenEntity = $this->getAccessTokenEntity()) { + return null; + } + + return $accessTokenEntity->getAppSecretProof($this->app->getSecret()); + } + + /** + * Validate that an access token exists for this request. + * + * @throws FacebookSDKException + */ + public function validateAccessToken() + { + $accessToken = $this->getAccessToken(); + if (!$accessToken) { + throw new FacebookSDKException('You must provide an access token.'); + } + } + + /** + * Set the HTTP method for this request. + * + * @param string + * + * @return FacebookRequest + */ + public function setMethod($method) + { + $this->method = strtoupper($method); + } + + /** + * Return the HTTP method for this request. + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Validate that the HTTP method is set. + * + * @throws FacebookSDKException + */ + public function validateMethod() + { + if (!$this->method) { + throw new FacebookSDKException('HTTP method not specified.'); + } + + if (!in_array($this->method, ['GET', 'POST', 'DELETE'])) { + throw new FacebookSDKException('Invalid HTTP method specified.'); + } + } + + /** + * Set the endpoint for this request. + * + * @param string + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setEndpoint($endpoint) + { + // Harvest the access token from the endpoint to keep things in sync + $params = FacebookUrlManipulator::getParamsAsArray($endpoint); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Clean the token & app secret proof from the endpoint. + $filterParams = ['access_token', 'appsecret_proof']; + $this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams); + + return $this; + } + + /** + * Return the HTTP method for this request. + * + * @return string + */ + public function getEndpoint() + { + // For batch requests, this will be empty + return $this->endpoint; + } + + /** + * Generate and return the headers for this request. + * + * @return array + */ + public function getHeaders() + { + $headers = static::getDefaultHeaders(); + + if ($this->eTag) { + $headers['If-None-Match'] = $this->eTag; + } + + return array_merge($this->headers, $headers); + } + + /** + * Set the headers for this request. + * + * @param array $headers + */ + public function setHeaders(array $headers) + { + $this->headers = array_merge($this->headers, $headers); + } + + /** + * Sets the eTag value. + * + * @param string $eTag + */ + public function setETag($eTag) + { + $this->eTag = $eTag; + } + + /** + * Set the params for this request. + * + * @param array $params + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setParams(array $params = []) + { + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Don't let these buggers slip in. + unset($params['access_token'], $params['appsecret_proof']); + + // @TODO Refactor code above with this + //$params = $this->sanitizeAuthenticationParams($params); + $params = $this->sanitizeFileParams($params); + $this->dangerouslySetParams($params); + + return $this; + } + + /** + * Set the params for this request without filtering them first. + * + * @param array $params + * + * @return FacebookRequest + */ + public function dangerouslySetParams(array $params = []) + { + $this->params = array_merge($this->params, $params); + + return $this; + } + + /** + * Iterate over the params and pull out the file uploads. + * + * @param array $params + * + * @return array + */ + public function sanitizeFileParams(array $params) + { + foreach ($params as $key => $value) { + if ($value instanceof FacebookFile) { + $this->addFile($key, $value); + unset($params[$key]); + } + } + + return $params; + } + + /** + * Add a file to be uploaded. + * + * @param string $key + * @param FacebookFile $file + */ + public function addFile($key, FacebookFile $file) + { + $this->files[$key] = $file; + } - /** - * @var FacebookApp The Facebook app entity. - */ - protected $app; - - /** - * @var string|null The access token to use for this request. - */ - protected $accessToken; - - /** - * @var string The HTTP method for this request. - */ - protected $method; - - /** - * @var string The Graph endpoint for this request. - */ - protected $endpoint; - - /** - * @var array The headers to send with this request. - */ - protected $headers = []; - - /** - * @var array The parameters to send with this request. - */ - protected $params = []; - - /** - * @var array The files to send with this request. - */ - protected $files = []; - - /** - * @var string ETag to send with this request. - */ - protected $eTag; - - /** - * @var string Graph version to use for this request. - */ - protected $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 - */ - public function __construct( - FacebookApp $app = null, - $accessToken = null, - $method = null, - $endpoint = null, - array $params = [], - $eTag = null, - $graphVersion = null - ) - { - $this->setApp($app); - $this->setAccessToken($accessToken); - $this->setMethod($method); - $this->setEndpoint($endpoint); - $this->setParams($params); - $this->setETag($eTag); - $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; - } - - /** - * Set the access token for this request. - * - * @param AccessToken|string - * - * @return FacebookRequest - */ - public function setAccessToken($accessToken) - { - $this->accessToken = $accessToken instanceof AccessToken - ? $accessToken->getValue() - : $accessToken; - - return $this; - } - - /** - * Sets the access token with one harvested from a URL or POST params. - * - * @param string $accessToken The access token. - * - * @return FacebookRequest - * - * @throws FacebookSDKException - */ - public function setAccessTokenFromParams($accessToken) - { - $existingAccessToken = $this->getAccessToken(); - if ( ! $existingAccessToken) { - $this->setAccessToken($accessToken); - } elseif ($accessToken !== $existingAccessToken) { - throw new FacebookSDKException( - 'Access token mismatch. The access token provided in the FacebookRequest ' . - 'and the one provided in the URL or POST params do not match.' - ); - } - - return $this; - } - - /** - * Return the access token for this request. - * - * @return string|null - */ - public function getAccessToken() - { - return $this->accessToken; - } - - /** - * Return the access token for this request an an AccessToken entity. - * - * @return AccessToken|null - */ - public function getAccessTokenEntity() - { - return $this->accessToken ? new AccessToken($this->accessToken) : null; - } - - /** - * Set the FacebookApp entity used for this request. - * - * @param FacebookApp|null $app - */ - public function setApp(FacebookApp $app = null) - { - $this->app = $app; - } - - /** - * Return the FacebookApp entity used for this request. - * - * @return FacebookApp - */ - public function getApp() - { - return $this->app; - } - - /** - * Generate an app secret proof to sign this request. - * - * @return string|null - */ - public function getAppSecretProof() - { - if ( ! $accessTokenEntity = $this->getAccessTokenEntity()) { - return null; - } - - return $accessTokenEntity->getAppSecretProof($this->app->getSecret()); - } - - /** - * Validate that an access token exists for this request. - * - * @throws FacebookSDKException - */ - public function validateAccessToken() - { - $accessToken = $this->getAccessToken(); - if (!$accessToken) { - throw new FacebookSDKException( - 'You must provide an access token.' - ); - } - } - - /** - * Set the HTTP method for this request. - * - * @param string - * - * @return FacebookRequest - */ - public function setMethod($method) - { - $this->method = strtoupper($method); - } - - /** - * Return the HTTP method for this request. - * - * @return string - */ - public function getMethod() - { - return $this->method; - } - - /** - * Validate that the HTTP method is set. - * - * @throws FacebookSDKException - */ - public function validateMethod() - { - if (!$this->method) { - throw new FacebookSDKException( - 'HTTP method not specified.' - ); - } - switch ($this->method) { - case 'GET': - case 'POST': - case 'DELETE': - return; - break; - } - throw new FacebookSDKException( - 'Invalid HTTP method specified.' - ); - } - - /** - * Set the endpoint for this request. - * - * @param string - * - * @return FacebookRequest - * - * @throws FacebookSDKException - */ - public function setEndpoint($endpoint) - { - // Harvest the access token from the endpoint to keep things in sync - $params = FacebookUrlManipulator::getParamsAsArray($endpoint); - if (isset($params['access_token'])) { - $this->setAccessTokenFromParams($params['access_token']); - } - - // Clean the token & app secret proof from the endpoint. - $filterParams = ['access_token', 'appsecret_proof']; - $this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams); - - return $this; - } - - /** - * Return the HTTP method for this request. - * - * @return string - */ - public function getEndpoint() - { - // For batch requests, this will be empty - return $this->endpoint; - } - - /** - * Generate and return the headers for this request. - * - * @return array - */ - public function getHeaders() - { - $headers = static::getDefaultHeaders(); - - if ($this->eTag) { - $headers['If-None-Match'] = $this->eTag; - } - - return array_merge($this->headers, $headers); - } - - /** - * Set the headers for this request. - * - * @param array $headers - */ - public function setHeaders(array $headers) - { - $this->headers = array_merge($this->headers, $headers); - } - - /** - * Sets the eTag value. - * - * @param string $eTag - */ - public function setETag($eTag) - { - $this->eTag = $eTag; - } - - /** - * Set the params for this request. - * - * @param array $params - * - * @return FacebookRequest - * - * @throws FacebookSDKException - */ - public function setParams(array $params = []) - { - if (isset($params['access_token'])) { - $this->setAccessTokenFromParams($params['access_token']); - } - - // Don't let these buggers slip in. - unset($params['access_token'], $params['appsecret_proof']); - - // @TODO Refactor code above with this - //$params = $this->sanitizeAuthenticationParams($params); - $params = $this->sanitizeFileParams($params); - $this->dangerouslySetParams($params); - - return $this; - } - - /** - * Set the params for this request without filtering them first. - * - * @param array $params - * - * @return FacebookRequest - */ - public function dangerouslySetParams(array $params = []) - { - $this->params = array_merge($this->params, $params); - - return $this; - } - - /** - * Iterate over the params and pull out the file uploads. - * - * @param array $params - * - * @return array - */ - public function sanitizeFileParams(array $params) - { - foreach ($params as $key => $value) { - if ($value instanceOf FacebookFile) { - $this->addFile($key, $value); - unset($params[$key]); - } - } - - return $params; - } - - /** - * Add a file to be uploaded. - * - * @param string $key - * @param FacebookFile $file - */ - public function addFile($key, FacebookFile $file) - { - $this->files[$key] = $file; - } - - /** - * Removes all the files from the upload queue. - */ - public function resetFiles() - { - $this->files = []; - } - - /** - * Get the list of files to be uploaded. - * - * @return array - */ - public function getFiles() - { - return $this->files; - } - - /** - * Let's us know if there is a file upload with this request. - * - * @return boolean - */ - public function containsFileUploads() - { - return ! empty($this->files); - } - - /** - * Let's us know if there is a video upload with this request. - * - * @return boolean - */ - public function containsVideoUploads() - { - foreach ($this->files as $file) { - if ($file instanceOf FacebookVideo) { - return true; - } - } - - return false; - } - - /** - * Returns the body of the request as multipart/form-data. - * - * @return RequestBodyMultipart - */ - public function getMultipartBody() - { - $params = $this->getPostParams(); - - return new RequestBodyMultipart($params, $this->files); - } - - /** - * Returns the body of the request as URL-encoded. - * - * @return RequestBodyUrlEncoded - */ - public function getUrlEncodedBody() - { - $params = $this->getPostParams(); - - return new RequestBodyUrlEncoded($params); - } - - /** - * Generate and return the params for this request. - * - * @return array - */ - public function getParams() - { - $params = $this->params; - - $accessToken = $this->getAccessToken(); - if ($accessToken) { - $params['access_token'] = $accessToken; - $params['appsecret_proof'] = $this->getAppSecretProof(); - } - - return $params; - } - - /** - * Only return params on POST requests. - * - * @return array - */ - public function getPostParams() - { - if ($this->getMethod() === 'POST') { - return $this->getParams(); - } - - return []; - } - - /** - * The graph version used for this request. - * - * @return string - */ - public function getGraphVersion() - { - return $this->graphVersion; - } - - /** - * Generate and return the URL for this request. - * - * @return string - */ - public function getUrl() - { - $this->validateMethod(); - - $graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion); - $endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint()); - - $url = $graphVersion.$endpoint; - - if ($this->getMethod() !== 'POST') { - $params = $this->getParams(); - $url = FacebookUrlManipulator::appendParamsToUrl($url, $params); - } - - return $url; - } - - /** - * Return the default headers that every request should use. - * - * @return array - */ - public static function getDefaultHeaders() - { - return [ - 'User-Agent' => 'fb-php-' . Facebook::VERSION, - 'Accept-Encoding' => '*', - ]; - } + /** + * Removes all the files from the upload queue. + */ + public function resetFiles() + { + $this->files = []; + } + + /** + * Get the list of files to be uploaded. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * Let's us know if there is a file upload with this request. + * + * @return boolean + */ + public function containsFileUploads() + { + return !empty($this->files); + } + /** + * Let's us know if there is a video upload with this request. + * + * @return boolean + */ + public function containsVideoUploads() + { + foreach ($this->files as $file) { + if ($file instanceof FacebookVideo) { + return true; + } + } + + return false; + } + + /** + * Returns the body of the request as multipart/form-data. + * + * @return RequestBodyMultipart + */ + public function getMultipartBody() + { + $params = $this->getPostParams(); + + return new RequestBodyMultipart($params, $this->files); + } + + /** + * Returns the body of the request as URL-encoded. + * + * @return RequestBodyUrlEncoded + */ + public function getUrlEncodedBody() + { + $params = $this->getPostParams(); + + return new RequestBodyUrlEncoded($params); + } + + /** + * Generate and return the params for this request. + * + * @return array + */ + public function getParams() + { + $params = $this->params; + + $accessToken = $this->getAccessToken(); + if ($accessToken) { + $params['access_token'] = $accessToken; + $params['appsecret_proof'] = $this->getAppSecretProof(); + } + + return $params; + } + + /** + * Only return params on POST requests. + * + * @return array + */ + public function getPostParams() + { + if ($this->getMethod() === 'POST') { + return $this->getParams(); + } + + return []; + } + + /** + * The graph version used for this request. + * + * @return string + */ + public function getGraphVersion() + { + return $this->graphVersion; + } + + /** + * Generate and return the URL for this request. + * + * @return string + */ + public function getUrl() + { + $this->validateMethod(); + + $graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion); + $endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint()); + + $url = $graphVersion . $endpoint; + + if ($this->getMethod() !== 'POST') { + $params = $this->getParams(); + $url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + } + + return $url; + } + + /** + * Return the default headers that every request should use. + * + * @return array + */ + public static function getDefaultHeaders() + { + return [ + 'User-Agent' => 'fb-php-' . Facebook::VERSION, + 'Accept-Encoding' => '*', + ]; + } } diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 74fa38256..344f0af88 100755 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -29,321 +29,319 @@ /** * Class FacebookResponse + * * @package Facebook */ class FacebookResponse { + /** + * @var int The HTTP status code response from Graph. + */ + protected $httpStatusCode; + + /** + * @var array The headers returned from Graph. + */ + protected $headers; + + /** + * @var string The raw body of the response from Graph. + */ + protected $body; + + /** + * @var array The decoded body of the Graph response. + */ + protected $decodedBody = []; + + /** + * @var FacebookRequest The original request that returned this response. + */ + protected $request; + + /** + * @var FacebookSDKException The exception thrown by this request. + */ + protected $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 = []) + { + $this->request = $request; + $this->body = $body; + $this->httpStatusCode = $httpStatusCode; + $this->headers = $headers; + + $this->decodeBody(); + } + + /** + * Return the original request that returned this response. + * + * @return FacebookRequest + */ + public function getRequest() + { + return $this->request; + } + + /** + * Return the FacebookApp entity used for this response. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->request->getApp(); + } + + /** + * Return the access token that was used for this response. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->request->getAccessToken(); + } + + /** + * Return the HTTP status code for this response. + * + * @return int + */ + public function getHttpStatusCode() + { + return $this->httpStatusCode; + } + + /** + * Return the HTTP headers for this response. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Return the raw body response. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Return the decoded body response. + * + * @return array + */ + public function getDecodedBody() + { + return $this->decodedBody; + } + + /** + * Get the app secret proof that was used for this response. + * + * @return string|null + */ + public function getAppSecretProof() + { + return $this->request->getAppSecretProof(); + } - /** - * @var int The HTTP status code response from Graph. - */ - protected $httpStatusCode; - - /** - * @var array The headers returned from Graph. - */ - protected $headers; - - /** - * @var string The raw body of the response from Graph. - */ - protected $body; - - /** - * @var array The decoded body of the Graph response. - */ - protected $decodedBody = []; - - /** - * @var FacebookRequest The original request that returned this response. - */ - protected $request; - - /** - * @var FacebookSDKException The exception thrown by this request. - */ - protected $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 = [] - ) - { - $this->request = $request; - $this->body = $body; - $this->httpStatusCode = $httpStatusCode; - $this->headers = $headers; - - $this->decodeBody(); - } - - /** - * Return the original request that returned this response. - * - * @return FacebookRequest - */ - public function getRequest() - { - return $this->request; - } - - /** - * Return the FacebookApp entity used for this response. - * - * @return FacebookApp - */ - public function getApp() - { - return $this->request->getApp(); - } - - /** - * Return the access token that was used for this response. - * - * @return string|null - */ - public function getAccessToken() - { - return $this->request->getAccessToken(); - } - - /** - * Return the HTTP status code for this response. - * - * @return int - */ - public function getHttpStatusCode() - { - return $this->httpStatusCode; - } - - /** - * Return the HTTP headers for this response. - * - * @return array - */ - public function getHeaders() - { - return $this->headers; - } - - /** - * Return the raw body response. - * - * @return string - */ - public function getBody() - { - return $this->body; - } - - /** - * Return the decoded body response. - * - * @return array - */ - public function getDecodedBody() - { - return $this->decodedBody; - } - - /** - * Get the app secret proof that was used for this response. - * - * @return string|null - */ - public function getAppSecretProof() - { - return $this->request->getAppSecretProof(); - } - - /** - * Get the ETag associated with the response. - * - * @return string|null - */ - public function getETag() - { - return isset($this->headers['ETag']) ? $this->headers['ETag'] : null; - } - - /** - * Get the version of Graph that returned this response. - * - * @return string|null - */ - public function getGraphVersion() - { - return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null; - } - - /** - * Returns true if Graph returned an error message. - * - * @return boolean - */ - public function isError() - { - return isset($this->decodedBody['error']); - } - - /** - * Throws the exception. - * - * @throws FacebookSDKException - */ - public function throwException() - { - throw $this->thrownException; - } - - /** - * Instantiates an exception to be thrown later. - */ - public function makeException() - { - $this->thrownException = FacebookResponseException::create($this); - } - - /** - * Returns the exception that was thrown for this request. - * - * @return FacebookSDKException|null - */ - public function getThrownException() - { - return $this->thrownException; - } - - /** - * Convert the raw response into an array if possible. - * - * Graph will return 2 types of responses: - * - JSON(P) - * Most responses from Grpah are JSON(P) - * - application/x-www-form-urlencoded key/value pairs - * Happens on the `/oauth/access_token` endpoint when exchanging - * a short-lived access token for a long-lived access token - * - And sometimes nothing :/ but that'd be a bug. - */ - public function decodeBody() - { - $this->decodedBody = json_decode($this->body, true); - - if ($this->decodedBody === null) { - $this->decodedBody = []; - parse_str($this->body, $this->decodedBody); + /** + * Get the ETag associated with the response. + * + * @return string|null + */ + public function getETag() + { + return isset($this->headers['ETag']) ? $this->headers['ETag'] : null; } - // Backwards compatibility for Graph < 2.1. - // Mimics 2.1 responses. - // @TODO Remove this after Graph 2.0 is no longer supported - elseif (is_bool($this->decodedBody)) { - $this->decodedBody = ['success' => $this->decodedBody]; - } elseif (is_numeric($this->decodedBody)) { - $this->decodedBody = ['id' => $this->decodedBody]; + /** + * Get the version of Graph that returned this response. + * + * @return string|null + */ + public function getGraphVersion() + { + return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null; } - if ( ! is_array($this->decodedBody)) { - $this->decodedBody = []; + /** + * Returns true if Graph returned an error message. + * + * @return boolean + */ + public function isError() + { + return isset($this->decodedBody['error']); } - if ($this->isError()) { - $this->makeException(); + /** + * Throws the exception. + * + * @throws FacebookSDKException + */ + public function throwException() + { + throw $this->thrownException; } - } - - /** - * Instantiate a new GraphObject from response. - * - * @param string|null $subclassName The GraphObject sub class to cast to. - * - * @return \Facebook\GraphNodes\GraphObject - * - * @throws FacebookSDKException - */ - public function getGraphObject($subclassName = null) - { - $factory = new GraphObjectFactory($this); - return $factory->makeGraphObject($subclassName); - } - - /** - * Convenience method for creating a GraphAlbum collection. - * - * @return \Facebook\GraphNodes\GraphAlbum - * - * @throws FacebookSDKException - */ - public function getGraphAlbum() - { - $factory = new GraphObjectFactory($this); - return $factory->makeGraphAlbum(); - } - - /** - * Convenience method for creating a GraphPage collection. - * - * @return \Facebook\GraphNodes\GraphPage - * - * @throws FacebookSDKException - */ - public function getGraphPage() - { - $factory = new GraphObjectFactory($this); - return $factory->makeGraphPage(); - } - - /** - * Convenience method for creating a GraphSessionInfo collection. - * - * @return \Facebook\GraphNodes\GraphSessionInfo - * - * @throws FacebookSDKException - */ - public function getGraphSessionInfo() - { - $factory = new GraphObjectFactory($this); - return $factory->makeGraphSessionInfo(); - } - - /** - * Convenience method for creating a GraphUser collection. - * - * @return \Facebook\GraphNodes\GraphUser - * - * @throws FacebookSDKException - */ - public function getGraphUser() - { - $factory = new GraphObjectFactory($this); - return $factory->makeGraphUser(); - } - - /** - * Instantiate a new GraphList from response. - * - * @param string|null $subclassName The GraphObject sub class to cast list items to. - * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. - * - * @return \Facebook\GraphNodes\GraphList - * - * @throws FacebookSDKException - */ - public function getGraphList($subclassName = null, $auto_prefix = true) - { - $factory = new GraphObjectFactory($this); - return $factory->makeGraphList($subclassName, $auto_prefix); - } + /** + * Instantiates an exception to be thrown later. + */ + public function makeException() + { + $this->thrownException = FacebookResponseException::create($this); + } + + /** + * Returns the exception that was thrown for this request. + * + * @return FacebookSDKException|null + */ + public function getThrownException() + { + return $this->thrownException; + } + + /** + * Convert the raw response into an array if possible. + * + * Graph will return 2 types of responses: + * - JSON(P) + * Most responses from Grpah are JSON(P) + * - application/x-www-form-urlencoded key/value pairs + * Happens on the `/oauth/access_token` endpoint when exchanging + * a short-lived access token for a long-lived access token + * - And sometimes nothing :/ but that'd be a bug. + */ + public function decodeBody() + { + $this->decodedBody = json_decode($this->body, true); + + if ($this->decodedBody === 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)) { + $this->decodedBody = ['id' => $this->decodedBody]; + } + + if (!is_array($this->decodedBody)) { + $this->decodedBody = []; + } + + if ($this->isError()) { + $this->makeException(); + } + } + + /** + * Instantiate a new GraphObject from response. + * + * @param string|null $subclassName The GraphObject sub class to cast to. + * + * @return \Facebook\GraphNodes\GraphObject + * + * @throws FacebookSDKException + */ + public function getGraphObject($subclassName = null) + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphObject($subclassName); + } + + /** + * Convenience method for creating a GraphAlbum collection. + * + * @return \Facebook\GraphNodes\GraphAlbum + * + * @throws FacebookSDKException + */ + public function getGraphAlbum() + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphAlbum(); + } + + /** + * Convenience method for creating a GraphPage collection. + * + * @return \Facebook\GraphNodes\GraphPage + * + * @throws FacebookSDKException + */ + public function getGraphPage() + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphPage(); + } + + /** + * Convenience method for creating a GraphSessionInfo collection. + * + * @return \Facebook\GraphNodes\GraphSessionInfo + * + * @throws FacebookSDKException + */ + public function getGraphSessionInfo() + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphSessionInfo(); + } + + /** + * Convenience method for creating a GraphUser collection. + * + * @return \Facebook\GraphNodes\GraphUser + * + * @throws FacebookSDKException + */ + public function getGraphUser() + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphUser(); + } + + /** + * Instantiate a new GraphList from response. + * + * @param string|null $subclassName The GraphObject sub class to cast list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return \Facebook\GraphNodes\GraphList + * + * @throws FacebookSDKException + */ + public function getGraphList($subclassName = null, $auto_prefix = true) + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphList($subclassName, $auto_prefix); + } } diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php index 783cc9ea0..f8b990548 100755 --- a/src/Facebook/FileUpload/FacebookFile.php +++ b/src/Facebook/FileUpload/FacebookFile.php @@ -27,112 +27,109 @@ /** * Class FacebookFile + * * @package Facebook */ class FacebookFile { + /** + * @var string The path to the file on the system. + */ + protected $path; - /** - * @var string The path to the file on the system. - */ - protected $path; + /** + * @var resource The stream pointing to the file. + */ + protected $stream; - /** - * @var resource The stream pointing to the file. - */ - protected $stream; + /** + * Creates a new FacebookFile entity. + * + * @param string $filePath + * + * @throws FacebookSDKException + */ + public function __construct($filePath) + { + $this->path = $filePath; + $this->open(); + } - /** - * Creates a new FacebookFile entity. - * - * @param string $filePath - * - * @throws FacebookSDKException - */ - public function __construct($filePath) - { - $this->path = $filePath; - $this->open(); - } + /** + * Closes the stream when destructed. + */ + public function __destruct() + { + $this->close(); + } - /** - * Closes the stream when destructed. - */ - public function __destruct() - { - $this->close(); - } + /** + * Opens a stream for the file. + * + * @throws FacebookSDKException + */ + public function open() + { + if (!$this->isRemoteFile($this->path) && !is_readable($this->path)) { + throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to read resource: ' . $this->path . '.'); + } - /** - * Opens a stream for the file. - * - * @throws FacebookSDKException - */ - public function open() - { - if ( ! $this->isRemoteFile($this->path) - && ! is_readable($this->path) ) { - throw new FacebookSDKException('Failed to create FacebookFile entity. ' - . 'Unable to read resource: ' . $this->path . '.'); - } - $this->stream = fopen($this->path, 'r'); + $this->stream = fopen($this->path, 'r'); - if ( ! $this->stream) { - throw new FacebookSDKException('Failed to create FacebookFile entity. ' - . 'Unable to open resource: ' . $this->path . '.'); + if (!$this->stream) { + throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to open resource: ' . $this->path . '.'); + } } - } - /** - * Stops the file stream. - */ - public function close() - { - if (is_resource($this->stream)) { - fclose($this->stream); + /** + * Stops the file stream. + */ + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } } - } - - /** - * Return the contents of the file. - * - * @return string - */ - public function getContents() - { - return stream_get_contents($this->stream); - } - /** - * Return the name of the file. - * - * @return string - */ - public function getFileName() - { - return basename($this->path); - } + /** + * Return the contents of the file. + * + * @return string + */ + public function getContents() + { + return stream_get_contents($this->stream); + } - /** - * Return the mimetype of the file. - * - * @return string - */ - public function getMimetype() - { - return Mimetypes::getInstance()->fromFilename($this->path) ?: 'text/plain'; - } + /** + * Return the name of the file. + * + * @return string + */ + public function getFileName() + { + return basename($this->path); + } - /** - * Returns true if the path to the file is remote. - * - * @param string $pathToFile - * - * @return boolean - */ - protected function isRemoteFile($pathToFile) - { - return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1; - } + /** + * Return the mimetype of the file. + * + * @return string + */ + public function getMimetype() + { + 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) + { + return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1; + } } diff --git a/src/Facebook/FileUpload/FacebookVideo.php b/src/Facebook/FileUpload/FacebookVideo.php index 002578b4d..1e8c55aa8 100755 --- a/src/Facebook/FileUpload/FacebookVideo.php +++ b/src/Facebook/FileUpload/FacebookVideo.php @@ -25,9 +25,9 @@ /** * Class FacebookVideo + * * @package Facebook */ class FacebookVideo extends FacebookFile { - // The class left intentionally blank. } diff --git a/src/Facebook/FileUpload/Mimetypes.php b/src/Facebook/FileUpload/Mimetypes.php index d4547eb6b..f8b7e36d1 100644 --- a/src/Facebook/FileUpload/Mimetypes.php +++ b/src/Facebook/FileUpload/Mimetypes.php @@ -24,12 +24,12 @@ namespace Facebook\FileUpload; /** + * Provides mappings of file extensions to mimetypes + * * Taken from Guzzle + * * @see https://github.com/guzzle/guzzle/blob/master/src/Mimetypes.php - */ - -/** - * Provides mappings of file extensions to mimetypes + * * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types */ class Mimetypes @@ -38,7 +38,7 @@ class Mimetypes protected static $instance; /** @var array Mapping of extension to mimetype */ - protected $mimetypes = array( + protected $mimetypes = [ '3dml' => 'text/vnd.in3d.3dml', '3g2' => 'video/3gpp2', '3gp' => 'video/3gpp', @@ -942,7 +942,7 @@ class Mimetypes 'zir' => 'application/vnd.zul', 'zirz' => 'application/vnd.zul', 'zmm' => 'application/vnd.handheld-entertainment+xml' - ); + ]; /** * Get a singleton instance of the class @@ -965,15 +965,12 @@ public static function getInstance() * @param string $extension File extension * * @return string|null - * */ public function fromExtension($extension) { $extension = strtolower($extension); - return isset($this->mimetypes[$extension]) - ? $this->mimetypes[$extension] - : null; + return isset($this->mimetypes[$extension]) ? $this->mimetypes[$extension] : null; } /** diff --git a/src/Facebook/GraphNodes/Collection.php b/src/Facebook/GraphNodes/Collection.php index f737bd975..620b9a1dc 100644 --- a/src/Facebook/GraphNodes/Collection.php +++ b/src/Facebook/GraphNodes/Collection.php @@ -25,7 +25,9 @@ /** * Class Collection + * * Modified version of Collection in "illuminate/support" by Taylor Otwell + * * @package Facebook */ @@ -36,173 +38,176 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate { + /** + * The items contained in the collection. + * + * @var array + */ + protected $items = []; + + /** + * Create a new collection. + * + * @param array $items + */ + public function __construct(array $items = []) + { + $this->items = $items; + } - /** - * The items contained in the collection. - * - * @var array - */ - protected $items = []; - - /** - * Create a new collection. - * - * @param array $items - */ - public function __construct(array $items = []) - { - $this->items = $items; - } - - /** - * 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 - */ - public function getProperty($name, $default = null) - { - if (isset($this->items[$name])) { - return $this->items[$name]; + /** + * 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 + */ + public function getProperty($name, $default = null) + { + if (isset($this->items[$name])) { + return $this->items[$name]; + } + + return $default ?: null; } - return $default ?: null; - } - - /** - * Returns a list of all properties set on the object. - * - * @return array - */ - public function getPropertyNames() - { - return array_keys($this->items); - } - - /** - * Get all of the items in the collection. - * - * @return array - */ - public function all() - { - return $this->items; - } - - /** - * Get the collection of items as a plain array. - * - * @return array - */ - public function asArray() - { - return array_map(function($value) - { - return $value instanceof Collection ? $value->asArray() : $value; - - }, $this->items); - } - - /** - * Run a map over each of the items. - * - * @param \Closure $callback - * @return static - */ - public function map(\Closure $callback) - { - 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) - { - return json_encode($this->asArray(), $options); - } - - /** - * Count the number of items in the collection. - * - * @return int - */ - public function count() - { - return count($this->items); - } - - /** - * Get an iterator for the items. - * - * @return ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->items); - } - - /** - * Determine if an item exists at an offset. - * - * @param mixed $key - * @return bool - */ - public function offsetExists($key) - { - return array_key_exists($key, $this->items); - } - - /** - * Get an item at a given offset. - * - * @param mixed $key - * @return mixed - */ - public function offsetGet($key) - { - return $this->items[$key]; - } - - /** - * Set the item at a given offset. - * - * @param mixed $key - * @param mixed $value - * @return void - */ - public function offsetSet($key, $value) - { - if (is_null($key)) { - $this->items[] = $value; - } else { - $this->items[$key] = $value; + + /** + * Returns a list of all properties set on the object. + * + * @return array + */ + public function getPropertyNames() + { + return array_keys($this->items); } - } - - /** - * Unset the item at a given offset. - * - * @param string $key - * @return void - */ - public function offsetUnset($key) - { - unset($this->items[$key]); - } - - /** - * Convert the collection to its string representation. - * - * @return string - */ - public function __toString() - { - return $this->asJson(); - } + /** + * Get all of the items in the collection. + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function asArray() + { + return array_map(function ($value) { + return $value instanceof Collection ? $value->asArray() : $value; + }, $this->items); + } + + /** + * Run a map over each of the items. + * + * @param \Closure $callback + * + * @return static + */ + public function map(\Closure $callback) + { + 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) + { + return json_encode($this->asArray(), $options); + } + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count() + { + return count($this->items); + } + + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->items); + } + + /** + * Determine if an item exists at an offset. + * + * @param mixed $key + * + * @return bool + */ + public function offsetExists($key) + { + return array_key_exists($key, $this->items); + } + + /** + * Get an item at a given offset. + * + * @param mixed $key + * + * @return mixed + */ + public function offsetGet($key) + { + return $this->items[$key]; + } + + /** + * Set the item at a given offset. + * + * @param mixed $key + * @param mixed $value + * + * @return void + */ + public function offsetSet($key, $value) + { + if (is_null($key)) { + $this->items[] = $value; + } else { + $this->items[$key] = $value; + } + } + + /** + * Unset the item at a given offset. + * + * @param string $key + * + * @return void + */ + public function offsetUnset($key) + { + unset($this->items[$key]); + } + + /** + * Convert the collection to its string representation. + * + * @return string + */ + public function __toString() + { + return $this->asJson(); + } } diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php index 2bc3afb73..ad8afe248 100644 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -25,6 +25,7 @@ /** * Class GraphAchievement + * * @package Facebook */ @@ -79,8 +80,7 @@ public function getApplication() } /** - * Returns information about the achievement type this instance is - * connected with. + * Returns information about the achievement type this instance is connected with. * * @return array|null */ @@ -102,8 +102,7 @@ public function getType() } /** - * Indicates whether gaining the achievement published a feed story for - * the user. + * Indicates whether gaining the achievement published a feed story for the user. * * @return boolean|null */ diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index 0e9421676..f2de63199 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -25,159 +25,159 @@ /** * Class GraphAlbum + * * @package Facebook - * @author Daniele Grosso */ class GraphAlbum extends GraphObject { - /** - * @var array Maps object key names to Graph object types. - */ - protected static $graphObjectMap = [ - 'from' => '\Facebook\GraphNodes\GraphUser', - 'place' => '\Facebook\GraphNodes\GraphPage', - ]; - - /** - * Returns the ID for the album. - * - * @return string|null - */ - public function getId() - { - return $this->getProperty('id'); - } - - /** - * Returns whether the viewer can upload photos to this album. - * - * @return boolean|null - */ - public function getCanUpload() - { - return $this->getProperty('can_upload'); - } - - /** - * Returns the number of photos in this album. - * - * @return int|null - */ - public function getCount() - { - return $this->getProperty('count'); - } - - /** - * Returns the ID of the album's cover photo. - * - * @return string|null - */ - public function getCoverPhoto() - { - return $this->getProperty('cover_photo'); - } - - /** - * Returns the time the album was initially created. - * - * @return \DateTime|null - */ - public function getCreatedTime() - { - return $this->getProperty('created_time'); - } - - /** - * Returns the time the album was updated. - * - * @return \DateTime|null - */ - public function getUpdatedTime() - { - return $this->getProperty('updated_time'); - } - - /** - * Returns the description of the album. - * - * @return string|null - */ - public function getDescription() - { - return $this->getProperty('description'); - } - - /** - * Returns profile that created the album. - * - * @return GraphUser|null - */ - public function getFrom() - { - return $this->getProperty('from'); - } - - /** - * Returns profile that created the album. - * - * @return GraphPage|null - */ - public function getPlace() - { - return $this->getProperty('place'); - } - - /** - * Returns a link to this album on Facebook. - * - * @return string|null - */ - public function getLink() - { - return $this->getProperty('link'); - } - - /** - * Returns the textual location of the album. - * - * @return string|null - */ - public function getLocation() - { - return $this->getProperty('location'); - } - - /** - * Returns the title of the album. - * - * @return string|null - */ - public function getName() - { - return $this->getProperty('name'); - } - - /** - * Returns the privacy settings for the album. - * - * @return string|null - */ - public function getPrivacy() - { - return $this->getProperty('privacy'); - } - - /** - * Returns the type of the album. - * enum{ profile, mobile, wall, normal, album } - * - * @return string|null - */ - public function getType() - { - return $this->getProperty('type'); - } - + /** + * @var array Maps object key names to Graph object types. + */ + protected static $graphObjectMap = [ + 'from' => '\Facebook\GraphNodes\GraphUser', + 'place' => '\Facebook\GraphNodes\GraphPage', + ]; + + /** + * Returns the ID for the album. + * + * @return string|null + */ + public function getId() + { + return $this->getProperty('id'); + } + + /** + * Returns whether the viewer can upload photos to this album. + * + * @return boolean|null + */ + public function getCanUpload() + { + return $this->getProperty('can_upload'); + } + + /** + * Returns the number of photos in this album. + * + * @return int|null + */ + public function getCount() + { + return $this->getProperty('count'); + } + + /** + * Returns the ID of the album's cover photo. + * + * @return string|null + */ + public function getCoverPhoto() + { + return $this->getProperty('cover_photo'); + } + + /** + * Returns the time the album was initially created. + * + * @return \DateTime|null + */ + public function getCreatedTime() + { + return $this->getProperty('created_time'); + } + + /** + * Returns the time the album was updated. + * + * @return \DateTime|null + */ + public function getUpdatedTime() + { + return $this->getProperty('updated_time'); + } + + /** + * Returns the description of the album. + * + * @return string|null + */ + public function getDescription() + { + return $this->getProperty('description'); + } + + /** + * Returns profile that created the album. + * + * @return GraphUser|null + */ + public function getFrom() + { + return $this->getProperty('from'); + } + + /** + * Returns profile that created the album. + * + * @return GraphPage|null + */ + public function getPlace() + { + return $this->getProperty('place'); + } + + /** + * Returns a link to this album on Facebook. + * + * @return string|null + */ + public function getLink() + { + return $this->getProperty('link'); + } + + /** + * Returns the textual location of the album. + * + * @return string|null + */ + public function getLocation() + { + return $this->getProperty('location'); + } + + /** + * Returns the title of the album. + * + * @return string|null + */ + public function getName() + { + return $this->getProperty('name'); + } + + /** + * Returns the privacy settings for the album. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getProperty('privacy'); + } + + /** + * Returns the type of the album. + * + * enum{ profile, mobile, wall, normal, album } + * + * @return string|null + */ + public function getType() + { + return $this->getProperty('type'); + } } diff --git a/src/Facebook/GraphNodes/GraphApplication.php b/src/Facebook/GraphNodes/GraphApplication.php index b2c3e79ae..d22002073 100644 --- a/src/Facebook/GraphNodes/GraphApplication.php +++ b/src/Facebook/GraphNodes/GraphApplication.php @@ -25,6 +25,7 @@ /** * Class GraphApplication + * * @package Facebook */ diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php index 684bad38b..8bc2b15db 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphList.php @@ -29,228 +29,232 @@ /** * Class GraphList + * * @package Facebook */ class GraphList extends Collection { + /** + * @var FacebookRequest The original request that generated this data. + */ + protected $request; - /** - * @var FacebookRequest The original request that generated this data. - */ - protected $request; + /** + * @var array An array of Graph meta data like pagination, etc. + */ + protected $metaData = []; - /** - * @var array An array of Graph meta data like pagination, etc. - */ - protected $metaData = []; + /** + * @var string|null The parent Graph edge endpoint that generated the list. + */ + protected $parentEdgeEndpoint; - /** - * @var string|null The parent Graph edge endpoint that generated the list. - */ - protected $parentEdgeEndpoint; + /** + * @var string|null The subclass of the child GraphObject's. + */ + protected $subclassName; - /** - * @var string|null The subclass of the child GraphObject's. - */ - protected $subclassName; + /** + * Init this collection of GraphObject's. + * + * @param FacebookRequest $request The original request that generated this data. + * @param array $data An array of GraphObject's. + * @param array $metaData An array of Graph meta data like pagination, etc. + * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. + * @param string|null $subclassName The subclass of the child GraphObject's. + */ + public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) + { + $this->request = $request; + $this->metaData = $metaData; + $this->parentEdgeEndpoint = $parentEdgeEndpoint; + $this->subclassName = $subclassName; - /** - * Init this collection of GraphObject's. - * - * @param FacebookRequest $request The original request that generated this data. - * @param array $data An array of GraphObject's. - * @param array $metaData An array of Graph meta data like pagination, etc. - * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. - * @param string|null $subclassName The subclass of the child GraphObject's. - */ - public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) - { - $this->request = $request; - $this->metaData = $metaData; - $this->parentEdgeEndpoint = $parentEdgeEndpoint; - $this->subclassName = $subclassName; + parent::__construct($data); + } - parent::__construct($data); - } + /** + * Gets the parent Graph edge endpoint that generated the list. + * + * @return string|null + */ + public function getParentGraphEdge() + { + return $this->parentEdgeEndpoint; + } - /** - * Gets the parent Graph edge endpoint that generated the list. - * - * @return string|null - */ - public function getParentGraphEdge() - { - return $this->parentEdgeEndpoint; - } + /** + * Gets the subclass name that the child GraphObject's are cast as. + * + * @return string|null + */ + public function getSubClassName() + { + return $this->subclassName; + } - /** - * Gets the subclass name that the child GraphObject's are cast as. - * - * @return string|null - */ - public function getSubClassName() - { - return $this->subclassName; - } + /** + * Returns the raw meta data associated with this GraphList. + * + * @return array + */ + public function getMetaData() + { + return $this->metaData; + } - /** - * Returns the raw meta data associated with this GraphList. - * - * @return array - */ - public function getMetaData() - { - return $this->metaData; - } + /** + * Returns the next cursor if it exists. + * + * @return string|null + */ + public function getNextCursor() + { + return $this->getCursor('after'); + } - /** - * Returns the next cursor if it exists. - * - * @return string|null - */ - public function getNextCursor() - { - return $this->getCursor('after'); - } + /** + * Returns the previous cursor if it exists. + * + * @return string|null + */ + public function getPreviousCursor() + { + return $this->getCursor('before'); + } - /** - * Returns the previous cursor if it exists. - * - * @return string|null - */ - public function getPreviousCursor() - { - return $this->getCursor('before'); - } + /** + * Returns the cursor for a specific direction if it exists. + * + * @param string $direction The direction of the page: after|before + * + * @return string|null + */ + public function getCursor($direction) + { + if (isset($this->metaData['paging']['cursors'][$direction])) { + return $this->metaData['paging']['cursors'][$direction]; + } - /** - * Returns the cursor for a specific direction if it exists. - * - * @param string $direction The direction of the page: after|before - * - * @return string|null - */ - public function getCursor($direction) - { - return isset($this->metaData['paging']['cursors'][$direction]) - ? $this->metaData['paging']['cursors'][$direction] - : null; - } + return null; + } - /** - * Generates a pagination URL based on a cursor. - * - * @param string $direction The direction of the page: next|previous - * - * @return string|null - * - * @throws FacebookSDKException - */ - public function getPaginationUrl($direction) - { - $this->validateForPagination(); + /** + * Generates a pagination URL based on a cursor. + * + * @param string $direction The direction of the page: next|previous + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function getPaginationUrl($direction) + { + $this->validateForPagination(); - // Do we have a paging URL? - if (isset($this->metaData['paging'][$direction])) { - // Graph returns the full URL with all the original params. - // We just want the endpoint though. - $pageUrl = $this->metaData['paging'][$direction]; - return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); - } + // Do we have a paging URL? + if (isset($this->metaData['paging'][$direction])) { + // Graph returns the full URL with all the original params. + // We just want the endpoint though. + $pageUrl = $this->metaData['paging'][$direction]; - // Do we have a cursor to work with? - $cursorDirection = $direction === 'next' ? 'after' : 'before'; - $cursor = $this->getCursor($cursorDirection); - if ( ! $cursor) { - return null; - } + return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); + } - // If we don't know the ID of the parent node, this ain't gonna work. - if ( ! $this->parentEdgeEndpoint) { - return null; - } + // Do we have a cursor to work with? + $cursorDirection = $direction === 'next' ? 'after' : 'before'; + $cursor = $this->getCursor($cursorDirection); + if (!$cursor) { + return null; + } - // We have the parent node ID, paging cursor & original request. - // These were the ingredients chosen to create the perfect little URL. - $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); + // If we don't know the ID of the parent node, this ain't gonna work. + if (!$this->parentEdgeEndpoint) { + return null; + } - // Pull in the original params - $originalUrl = $this->request->getUrl(); - $pageUrl = FacebookUrlManipulator::mergeUrlParams($originalUrl, $pageUrl); + // We have the parent node ID, paging cursor & original request. + // These were the ingredients chosen to create the perfect little URL. + $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); - return FacebookUrlManipulator::forceSlashPrefix($pageUrl); - } + // Pull in the original params + $originalUrl = $this->request->getUrl(); + $pageUrl = FacebookUrlManipulator::mergeUrlParams($originalUrl, $pageUrl); - /** - * Validates whether or not we can paginate on this request. - * - * @throws FacebookSDKException - */ - public function validateForPagination() - { - if ($this->request->getMethod() !== 'GET') { - throw new FacebookSDKException( - 'You can only paginate on a GET request.', 720 - ); + return FacebookUrlManipulator::forceSlashPrefix($pageUrl); } - } - /** - * Gets the request object needed to make a next|previous page request. - * - * @param string $direction The direction of the page: next|previous - * - * @return FacebookRequest|null - * - * @throws FacebookSDKException - */ - public function getPaginationRequest($direction) - { - $pageUrl = $this->getPaginationUrl($direction); - if ( ! $pageUrl) { - return null; + /** + * Validates whether or not we can paginate on this request. + * + * @throws FacebookSDKException + */ + public function validateForPagination() + { + if ($this->request->getMethod() !== 'GET') { + throw new FacebookSDKException('You can only paginate on a GET request.', 720); + } } - $newRequest = clone $this->request; - $newRequest->setEndpoint($pageUrl); - return $newRequest; - } + /** + * Gets the request object needed to make a next|previous page request. + * + * @param string $direction The direction of the page: next|previous + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPaginationRequest($direction) + { + $pageUrl = $this->getPaginationUrl($direction); + if (!$pageUrl) { + return null; + } + + $newRequest = clone $this->request; + $newRequest->setEndpoint($pageUrl); + + return $newRequest; + } - /** - * Gets the request object needed to make a "next" page request. - * - * @return FacebookRequest|null - * - * @throws FacebookSDKException - */ - public function getNextPageRequest() - { - return $this->getPaginationRequest('next'); - } + /** + * Gets the request object needed to make a "next" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getNextPageRequest() + { + return $this->getPaginationRequest('next'); + } - /** - * Gets the request object needed to make a "previous" page request. - * - * @return FacebookRequest|null - * - * @throws FacebookSDKException - */ - public function getPreviousPageRequest() - { - return $this->getPaginationRequest('previous'); - } + /** + * Gets the request object needed to make a "previous" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPreviousPageRequest() + { + return $this->getPaginationRequest('previous'); + } - /** - * 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() - { - return isset($this->metaData['summary']['total_count']) - ? $this->metaData['summary']['total_count'] - : null; - } + /** + * 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() + { + if (isset($this->metaData['summary']['total_count'])) { + return $this->metaData['summary']['total_count']; + } + return null; + } } diff --git a/src/Facebook/GraphNodes/GraphLocation.php b/src/Facebook/GraphNodes/GraphLocation.php index feff80f48..45f6d7763 100644 --- a/src/Facebook/GraphNodes/GraphLocation.php +++ b/src/Facebook/GraphNodes/GraphLocation.php @@ -25,79 +25,78 @@ /** * Class GraphLocation + * * @package Facebook */ class GraphLocation extends GraphObject { + /** + * Returns the street component of the location + * + * @return string|null + */ + public function getStreet() + { + return $this->getProperty('street'); + } - /** - * Returns the street component of the location - * - * @return string|null - */ - public function getStreet() - { - return $this->getProperty('street'); - } - - /** - * Returns the city component of the location - * - * @return string|null - */ - public function getCity() - { - return $this->getProperty('city'); - } - - /** - * Returns the state component of the location - * - * @return string|null - */ - public function getState() - { - return $this->getProperty('state'); - } + /** + * Returns the city component of the location + * + * @return string|null + */ + public function getCity() + { + return $this->getProperty('city'); + } - /** - * Returns the country component of the location - * - * @return string|null - */ - public function getCountry() - { - return $this->getProperty('country'); - } + /** + * Returns the state component of the location + * + * @return string|null + */ + public function getState() + { + return $this->getProperty('state'); + } - /** - * Returns the zipcode component of the location - * - * @return string|null - */ - public function getZip() - { - return $this->getProperty('zip'); - } + /** + * Returns the country component of the location + * + * @return string|null + */ + public function getCountry() + { + return $this->getProperty('country'); + } - /** - * Returns the latitude component of the location - * - * @return float|null - */ - public function getLatitude() - { - return $this->getProperty('latitude'); - } + /** + * Returns the zipcode component of the location + * + * @return string|null + */ + public function getZip() + { + return $this->getProperty('zip'); + } - /** - * Returns the street component of the location - * - * @return float|null - */ - public function getLongitude() - { - return $this->getProperty('longitude'); - } + /** + * Returns the latitude component of the location + * + * @return float|null + */ + public function getLatitude() + { + return $this->getProperty('latitude'); + } + /** + * Returns the street component of the location + * + * @return float|null + */ + public function getLongitude() + { + return $this->getProperty('longitude'); + } } diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php index 86860e3c6..923b06c90 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -25,161 +25,161 @@ /** * Class GraphObject + * * @package Facebook */ class GraphObject extends Collection { + /** + * @var array Maps object key names to Graph object types. + */ + protected static $graphObjectMap = []; - /** - * @var array Maps object key names to Graph object types. - */ - protected static $graphObjectMap = []; + /** + * Init this Graph object. + * + * @param array $data + */ + public function __construct(array $data = []) + { + parent::__construct($this->castItems($data)); + } - /** - * Init this Graph object. - * - * @param array $data - */ - public function __construct(array $data = []) - { - $items = $this->castItems($data); - parent::__construct($items); - } + /** + * Iterates over an array and detects the types each node + * should be cast to and returns all the items as an array. + * + * @TODO Add auto-casting to AccessToken entities. + * + * @param array $data The array to iterate over. + * + * @return array + */ + public function castItems(array $data) + { + $items = []; - /** - * Iterates over an array and detects the types each node - * should be cast to and returns all the items as an array. - * - * @TODO Add auto-casting to AccessToken entities. - * - * @param array $data The array to iterate over. - * - * @return array - */ - public function castItems(array $data) - { - $items = []; + foreach ($data as $k => $v) { + if ($this->shouldCastAsDateTime($k) + && (is_numeric($v) + || $k === 'birthday' + || $this->isIso8601DateString($v)) + ) { + $items[$k] = $this->castToDateTime($v); + } else { + $items[$k] = $v; + } + } - foreach ($data as $k => $v) { - if ( - $this->shouldCastAsDateTime($k) - && (is_numeric($v) - || $k === 'birthday' - || $this->isIso8601DateString($v)) - ) { - $items[$k] = $this->castToDateTime($v); - } else { - $items[$k] = $v; - } + return $items; } - return $items; - } + /** + * Uncasts any auto-casted datatypes. + * Basically the reverse of castItems(). + * + * @return array + */ + public function uncastItems() + { + $items = $this->asArray(); - /** - * Uncasts any auto-casted datatypes. - * Basically the reverse of castItems(). - * - * @return array - */ - public function uncastItems() - { - $items = $this->asArray(); - return array_map(function ($v) { - $returnVal = $v; - if ($v instanceof \DateTime) { - $returnVal = $v->format(\DateTime::ISO8601); - } - return $returnVal; - }, $items); - } + return array_map(function ($v) { + if ($v instanceof \DateTime) { + return $v->format(\DateTime::ISO8601); + } + + return $v; + }, $items); + } - /** - * Get the collection of items as JSON. - * - * @param int $options - * @return string - */ - public function asJson($options = 0) - { - $items = $this->uncastItems(); - return json_encode($items, $options); - } + /** + * Get the collection of items as JSON. + * + * @param int $options + * + * @return string + */ + public function asJson($options = 0) + { + return json_encode($this->uncastItems(), $options); + } - /** - * Detects an ISO 8601 formatted string. - * - * @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 - * - * @param string $string - * - * @return boolean - */ - 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; - } + /** + * 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)?)?)?)?$/'; - /** - * Determines if a value from Graph should be cast to DateTime. - * - * @param string $key - * - * @return boolean - */ - public function shouldCastAsDateTime($key) - { - return in_array($key, [ - 'created_time', - 'updated_time', - 'start_time', - 'end_time', - 'backdated_time', - 'issued_at', - 'expires_at', - 'birthday', - 'publish_time' - ], true); - } + return preg_match($crazyInsaneRegexThatSomehowDetectsIso8601, $string) === 1; + } - /** - * Casts a date value from Graph to DateTime. - * - * @param int|string $value - * - * @return \DateTime - */ - public function castToDateTime($value) - { - if (is_int($value)) { - $dt = new \DateTime(); - $dt->setTimestamp($value); - } else { - $dt = new \DateTime($value); + /** + * Determines if a value from Graph should be cast to DateTime. + * + * @param string $key + * + * @return boolean + */ + public function shouldCastAsDateTime($key) + { + return in_array($key, [ + 'created_time', + 'updated_time', + 'start_time', + 'end_time', + 'backdated_time', + 'issued_at', + 'expires_at', + 'birthday', + 'publish_time' + ], true); } - return $dt; - } - /** - * Getter for $graphObjectMap. - * - * @return array - */ - public static function getObjectMap() - { - return static::$graphObjectMap; - } + /** + * Casts a date value from Graph to DateTime. + * + * @param int|string $value + * + * @return \DateTime + */ + public function castToDateTime($value) + { + if (is_int($value)) { + $dt = new \DateTime(); + $dt->setTimestamp($value); + } else { + $dt = new \DateTime($value); + } + + return $dt; + } + /** + * Getter for $graphObjectMap. + * + * @return array + */ + public static function getObjectMap() + { + return static::$graphObjectMap; + } } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 6e534cd14..fa3a143cf 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -43,333 +43,321 @@ class GraphObjectFactory { - /** - * @const string The base graph object class. - */ - const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; - - /** - * @const string The graph object prefix. - */ - const BASE_GRAPH_OBJECT_PREFIX = '\Facebook\GraphNodes\\'; - - /** - * @var FacebookResponse The response entity from Graph. - */ - protected $response; - - /** - * @var array The decoded body of the FacebookResponse entity from Graph. - */ - protected $decodedBody; - - /** - * Init this Graph object. - * - * @param FacebookResponse $response The response entity from Graph. - */ - public function __construct(FacebookResponse $response) - { - $this->response = $response; - $this->decodedBody = $response->getDecodedBody(); - } - - /** - * Tries to convert a FacebookResponse entity into a GraphObject. - * - * @param string|null $subclassName The GraphObject sub class to cast to. - * - * @return GraphObject - * - * @throws FacebookSDKException - */ - public function makeGraphObject($subclassName = null) - { - $this->validateResponseAsArray(); - $this->validateResponseCastableAsGraphObject(); - - return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); - } - - /** - * Convenience method for creating a GraphAchievement collection. - * - * @return GraphAchievement - * - * @throws FacebookSDKException - */ - public function makeGraphAchievement() - { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); - } - - /** - * Convenience method for creating a GraphAlbum collection. - * - * @return GraphAlbum - * - * @throws FacebookSDKException - */ - public function makeGraphAlbum() - { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); - } - - /** - * Convenience method for creating a GraphPage collection. - * - * @return GraphPage - * - * @throws FacebookSDKException - */ - public function makeGraphPage() - { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); - } - - /** - * Convenience method for creating a GraphSessionInfo collection. - * - * @return GraphSessionInfo - * - * @throws FacebookSDKException - */ - public function makeGraphSessionInfo() - { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); - } - - /** - * Convenience method for creating a GraphUser collection. - * - * @return GraphUser - * - * @throws FacebookSDKException - */ - public function makeGraphUser() - { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); - } - - /** - * Tries to convert a FacebookResponse entity into a GraphList. - * - * @param string|null $subclassName The GraphObject sub class to cast the list items to. - * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. - * - * @return GraphList - * - * @throws FacebookSDKException - */ - public function makeGraphList($subclassName = null, $auto_prefix = true) - { - $this->validateResponseAsArray(); - $this->validateResponseCastableAsGraphList(); - - if ($subclassName && $auto_prefix) { - $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; + /** + * @const string The base graph object class. + */ + const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; + + /** + * @const string The graph object prefix. + */ + const BASE_GRAPH_OBJECT_PREFIX = '\Facebook\GraphNodes\\'; + + /** + * @var FacebookResponse The response entity from Graph. + */ + protected $response; + + /** + * @var array The decoded body of the FacebookResponse entity from Graph. + */ + protected $decodedBody; + + /** + * Init this Graph object. + * + * @param FacebookResponse $response The response entity from Graph. + */ + public function __construct(FacebookResponse $response) + { + $this->response = $response; + $this->decodedBody = $response->getDecodedBody(); } - return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); - } - - /** - * Validates the decoded body. - * - * @throws FacebookSDKException - */ - public function validateResponseAsArray() - { - if ( ! is_array($this->decodedBody)) { - throw new FacebookSDKException( - 'Unable to get response from Graph as array.', 620 - ); + /** + * Tries to convert a FacebookResponse entity into a GraphObject. + * + * @param string|null $subclassName The GraphObject sub class to cast to. + * + * @return GraphObject + * + * @throws FacebookSDKException + */ + public function makeGraphObject($subclassName = null) + { + $this->validateResponseAsArray(); + $this->validateResponseCastableAsGraphObject(); + + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } - } - - /** - * Validates that the return data can be cast as a GraphObject. - * - * @throws FacebookSDKException - */ - public function validateResponseCastableAsGraphObject() - { - if (isset($this->decodedBody['data']) - && static::isCastableAsGraphList($this->decodedBody['data'])) { - throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphObject ' . - 'because the response looks like a GraphList. ' . - 'Try using GraphObjectFactory::makeGraphList() instead.', 620 - ); + + /** + * Convenience method for creating a GraphAchievement collection. + * + * @return GraphAchievement + * + * @throws FacebookSDKException + */ + public function makeGraphAchievement() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); + } + + /** + * Convenience method for creating a GraphAlbum collection. + * + * @return GraphAlbum + * + * @throws FacebookSDKException + */ + public function makeGraphAlbum() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); + } + + /** + * Convenience method for creating a GraphPage collection. + * + * @return GraphPage + * + * @throws FacebookSDKException + */ + public function makeGraphPage() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); + } + + /** + * Convenience method for creating a GraphSessionInfo collection. + * + * @return GraphSessionInfo + * + * @throws FacebookSDKException + */ + public function makeGraphSessionInfo() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); + } + + /** + * Convenience method for creating a GraphUser collection. + * + * @return GraphUser + * + * @throws FacebookSDKException + */ + public function makeGraphUser() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); + } + + /** + * Tries to convert a FacebookResponse entity into a GraphList. + * + * @param string|null $subclassName The GraphObject sub class to cast the list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return GraphList + * + * @throws FacebookSDKException + */ + public function makeGraphList($subclassName = null, $auto_prefix = true) + { + $this->validateResponseAsArray(); + $this->validateResponseCastableAsGraphList(); + + if ($subclassName && $auto_prefix) { + $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; + } + + return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); } - } - - /** - * Validates that the return data can be cast as a GraphList. - * - * @throws FacebookSDKException - */ - public function validateResponseCastableAsGraphList() - { - if ( ! (isset($this->decodedBody['data']) - && static::isCastableAsGraphList($this->decodedBody['data']) ) ) { - throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphList ' . - 'because the response does not look like a GraphList. ' . - 'Try using GraphObjectFactory::makeGraphObject() instead.', 620 - ); + + /** + * Validates the decoded body. + * + * @throws FacebookSDKException + */ + public function validateResponseAsArray() + { + if (!is_array($this->decodedBody)) { + throw new FacebookSDKException('Unable to get response from Graph as array.', 620); + } } - } - - /** - * Safely instantiates a GraphObject of $subclassName. - * - * @param array $data The array of data to iterate over. - * @param string|null $subclassName The subclass to cast this collection to. - * - * @return GraphObject - * - * @throws FacebookSDKException - */ - public function safelyMakeGraphObject(array $data, $subclassName = null) - { - $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; - static::validateSubclass($subclassName); - - // Remember the parent node ID - $parentNodeId = isset($data['id']) ? $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 GraphObject 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 GraphList or GraphObject - $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); - } else { - $items[$k] = $v; - } + + /** + * Validates that the return data can be cast as a GraphObject. + * + * @throws FacebookSDKException + */ + public function validateResponseCastableAsGraphObject() + { + if (isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data'])) { + throw new FacebookSDKException( + 'Unable to convert response from Graph to a GraphObject because the response looks like a GraphList. Try using GraphObjectFactory::makeGraphList() instead.', + 620 + ); + } } - return new $subclassName($items); - } - - /** - * Takes an array of values and determines how to cast each node. - * - * @param array $data The array of data to iterate over. - * @param string|null $subclassName The subclass to cast this collection to. - * @param string|null $parentKey The key of this data (Graph edge). - * @param string|null $parentNodeId The parent Graph node ID. - * - * @return GraphObject|GraphList - * - * @throws FacebookSDKException - */ - public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) - { - if (isset($data['data'])) { - // Create GraphList - if (static::isCastableAsGraphList($data['data'])) { - return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); - } - // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key - $data = $data['data']; + /** + * Validates that the return data can be cast as a GraphList. + * + * @throws FacebookSDKException + */ + public function validateResponseCastableAsGraphList() + { + if (!(isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data']))) { + throw new FacebookSDKException( + 'Unable to convert response from Graph to a GraphList because the response does not look like a GraphList. Try using GraphObjectFactory::makeGraphObject() instead.', + 620 + ); + } } - // Create GraphObject - return $this->safelyMakeGraphObject($data, $subclassName); - } - - /** - * Return an array of GraphObject's. - * - * @param array $data The array of data to iterate over. - * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. - * @param string|null $parentKey The key of this data (Graph edge). - * @param string|null $parentNodeId The parent Graph node ID. - * - * @return GraphList - * - * @throws FacebookSDKException - */ - public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) - { - if ( ! isset($data['data'])) { - throw new FacebookSDKException( - 'Cannot cast data to GraphList. Expected a "data" key.', 620 - ); + /** + * Safely instantiates a GraphObject of $subclassName. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The subclass to cast this collection to. + * + * @return GraphObject + * + * @throws FacebookSDKException + */ + public function safelyMakeGraphObject(array $data, $subclassName = null) + { + $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; + static::validateSubclass($subclassName); + + // Remember the parent node ID + $parentNodeId = isset($data['id']) ? $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 GraphObject 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 GraphList or GraphObject + $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); + } else { + $items[$k] = $v; + } + } + + return new $subclassName($items); } - $dataList = []; - foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName, $parentKey, $parentNodeId); + /** + * Takes an array of values and determines how to cast each node. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The subclass to cast this collection to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. + * + * @return GraphObject|GraphList + * + * @throws FacebookSDKException + */ + public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + { + if (isset($data['data'])) { + // Create GraphList + if (static::isCastableAsGraphList($data['data'])) { + return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); + } + // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key + $data = $data['data']; + } + + // Create GraphObject + return $this->safelyMakeGraphObject($data, $subclassName); } - $metaData = $this->getMetaData($data); - - // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) - $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; - - return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); - } - - /** - * Get the meta data from a list in a Graph response. - * - * @param array $data The Graph response. - * - * @return array - */ - public function getMetaData(array $data) - { - unset($data['data']); - - return $data; - } - - /** - * Determines whether or not the data should be cast as a GraphList. - * - * @param array $data - * - * @return boolean - */ - public static function isCastableAsGraphList(array $data) - { - if ($data === []) { - return true; + /** + * Return an array of GraphObject's. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. + * + * @return GraphList + * + * @throws FacebookSDKException + */ + public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + { + if (!isset($data['data'])) { + throw new FacebookSDKException('Cannot cast data to GraphList. Expected a "data" key.', 620); + } + + $dataList = []; + foreach ($data['data'] as $graphNode) { + $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName, $parentKey, $parentNodeId); + } + + $metaData = $this->getMetaData($data); + + // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) + $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; + + return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); } - // Checks for a sequential numeric array which would be a GraphList - return array_keys($data) === range(0, count($data) - 1); - } - - /** - * Ensures that the subclass in question is valid. - * - * @param string $subclassName The GraphObject subclass to validate. - * - * @throws FacebookSDKException - */ - public static function validateSubclass($subclassName) - { - if ($subclassName == static::BASE_GRAPH_OBJECT_CLASS - || is_subclass_of($subclassName, static::BASE_GRAPH_OBJECT_CLASS)) { - return; + + /** + * Get the meta data from a list in a Graph response. + * + * @param array $data The Graph response. + * + * @return array + */ + public function getMetaData(array $data) + { + unset($data['data']); + + return $data; } - throw new FacebookSDKException( - 'The given subclass "' . $subclassName . '" is not valid. ' - . 'Cannot cast to an object that is not a GraphObject subclass.', 620 - ); - } + /** + * Determines whether or not the data should be cast as a GraphList. + * + * @param array $data + * + * @return boolean + */ + public static function isCastableAsGraphList(array $data) + { + if ($data === []) { + return true; + } + + // Checks for a sequential numeric array which would be a GraphList + return array_keys($data) === range(0, count($data) - 1); + } + /** + * Ensures that the subclass in question is valid. + * + * @param string $subclassName The GraphObject subclass to validate. + * + * @throws FacebookSDKException + */ + public static function validateSubclass($subclassName) + { + if ($subclassName == static::BASE_GRAPH_OBJECT_CLASS || is_subclass_of($subclassName, static::BASE_GRAPH_OBJECT_CLASS)) { + return; + } + + throw new FacebookSDKException('The given subclass "' . $subclassName . '" is not valid. Cannot cast to an object that is not a GraphObject subclass.', 620); + } } diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index 8950128fb..4c709a0f2 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -25,100 +25,101 @@ /** * Class GraphPage + * * @package Facebook - * @author Artur Luiz */ class GraphPage extends GraphObject { - /** - * @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', - ]; - - /** - * Returns the ID for the user's page as a string if present. - * - * @return string|null - */ - public function getId() - { - return $this->getProperty('id'); - } + /** + * @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', + ]; - /** - * Returns the Category for the user's page as a string if present. - * - * @return string|null - */ - public function getCategory() - { - return $this->getProperty('category'); - } + /** + * Returns the ID for the user's page as a string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getProperty('id'); + } - /** - * Returns the Name of the user's page as a string if present. - * - * @return string|null - */ - public function getName() - { - return $this->getProperty('name'); - } + /** + * Returns the Category for the user's page as a string if present. + * + * @return string|null + */ + public function getCategory() + { + return $this->getProperty('category'); + } - /** - * Returns the best available Page on Facebook. - * - * @return GraphPage|null - */ - public function getBestPage() - { - return $this->getProperty('best_page'); - } + /** + * Returns the Name of the user's page as a string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getProperty('name'); + } - /** - * Returns the brand's global (parent) Page. - * - * @return GraphPage|null - */ - public function getGlobalBrandParentPage() - { - return $this->getProperty('global_brand_parent_page'); - } + /** + * Returns the best available Page on Facebook. + * + * @return GraphPage|null + */ + public function getBestPage() + { + return $this->getProperty('best_page'); + } - /** - * Returns the location of this place. - * - * @return GraphLocation|null - */ - public function getLocation() - { - return $this->getProperty('location'); - } + /** + * Returns the brand's global (parent) Page. + * + * @return GraphPage|null + */ + public function getGlobalBrandParentPage() + { + return $this->getProperty('global_brand_parent_page'); + } - /** - * Returns the page access token for the admin user. - * Only available in the `/me/accounts` context. - * - * @return string|null - */ - public function getAccessToken() - { - return $this->getProperty('access_token'); - } + /** + * Returns the location of this place. + * + * @return GraphLocation|null + */ + public function getLocation() + { + return $this->getProperty('location'); + } - /** - * Returns the roles of the page admin user. - * Only available in the `/me/accounts` context. - * - * @return array|null - */ - public function getPerms() - { - return $this->getProperty('perms'); - } + /** + * Returns the page access token for the admin user. + * + * Only available in the `/me/accounts` context. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->getProperty('access_token'); + } + /** + * Returns the roles of the page admin user. + * + * Only available in the `/me/accounts` context. + * + * @return array|null + */ + public function getPerms() + { + return $this->getProperty('perms'); + } } diff --git a/src/Facebook/GraphNodes/GraphPicture.php b/src/Facebook/GraphNodes/GraphPicture.php index 711bb04a2..22a66ca76 100644 --- a/src/Facebook/GraphNodes/GraphPicture.php +++ b/src/Facebook/GraphNodes/GraphPicture.php @@ -25,11 +25,11 @@ /** * Class GraphPicture + * * @package Facebook */ class GraphPicture extends GraphObject { - /** * Returns true if user picture is silhouette. * @@ -69,5 +69,4 @@ public function getHeight() { return $this->getProperty('height'); } - } diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index 86cf648cf..976d0ab9a 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -25,79 +25,78 @@ /** * Class GraphSessionInfo + * * @package Facebook */ class GraphSessionInfo extends GraphObject { + /** + * Returns the application id the token was issued for. + * + * @return string|null + */ + public function getAppId() + { + return $this->getProperty('app_id'); + } - /** - * Returns the application id the token was issued for. - * - * @return string|null - */ - public function getAppId() - { - return $this->getProperty('app_id'); - } - - /** - * Returns the application name the token was issued for. - * - * @return string|null - */ - public function getApplication() - { - return $this->getProperty('application'); - } - - /** - * Returns the date & time that the token expires. - * - * @return \DateTime|null - */ - public function getExpiresAt() - { - return $this->getProperty('expires_at'); - } + /** + * Returns the application name the token was issued for. + * + * @return string|null + */ + public function getApplication() + { + return $this->getProperty('application'); + } - /** - * Returns whether the token is valid. - * - * @return boolean - */ - public function getIsValid() - { - return $this->getProperty('is_valid'); - } + /** + * Returns the date & time that the token expires. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->getProperty('expires_at'); + } - /** - * Returns the date & time the token was issued at. - * - * @return \DateTime|null - */ - public function getIssuedAt() - { - return $this->getProperty('issued_at'); - } + /** + * Returns whether the token is valid. + * + * @return boolean + */ + public function getIsValid() + { + return $this->getProperty('is_valid'); + } - /** - * Returns the scope permissions associated with the token. - * - * @return array - */ - public function getScopes() - { - return $this->getProperty('scopes'); - } + /** + * Returns the date & time the token was issued at. + * + * @return \DateTime|null + */ + public function getIssuedAt() + { + return $this->getProperty('issued_at'); + } - /** - * Returns the login id of the user associated with the token. - * - * @return string|null - */ - public function getUserId() - { - return $this->getProperty('user_id'); - } + /** + * Returns the scope permissions associated with the token. + * + * @return array + */ + public function getScopes() + { + return $this->getProperty('scopes'); + } + /** + * Returns the login id of the user associated with the token. + * + * @return string|null + */ + public function getUserId() + { + return $this->getProperty('user_id'); + } } diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 167af81bd..3bab2a3c7 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -25,139 +25,138 @@ /** * Class GraphUser + * * @package Facebook */ class GraphUser extends GraphObject { + /** + * @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', + ]; - /** - * @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', - ]; - - /** - * Returns the ID for the user as a string if present. - * - * @return string|null - */ - public function getId() - { - return $this->getProperty('id'); - } - - /** - * Returns the name for the user as a string if present. - * - * @return string|null - */ - public function getName() - { - return $this->getProperty('name'); - } + /** + * Returns the ID for the user as a string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getProperty('id'); + } - /** - * Returns the first name for the user as a string if present. - * - * @return string|null - */ - public function getFirstName() - { - return $this->getProperty('first_name'); - } + /** + * Returns the name for the user as a string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getProperty('name'); + } - /** - * Returns the middle name for the user as a string if present. - * - * @return string|null - */ - public function getMiddleName() - { - return $this->getProperty('middle_name'); - } + /** + * Returns the first name for the user as a string if present. + * + * @return string|null + */ + public function getFirstName() + { + return $this->getProperty('first_name'); + } - /** - * Returns the last name for the user as a string if present. - * - * @return string|null - */ - public function getLastName() - { - return $this->getProperty('last_name'); - } + /** + * Returns the middle name for the user as a string if present. + * + * @return string|null + */ + public function getMiddleName() + { + return $this->getProperty('middle_name'); + } - /** - * Returns the gender for the user as a string if present. - * - * @return string|null - */ - public function getGender() - { - return $this->getProperty('gender'); - } + /** + * Returns the last name for the user as a string if present. + * + * @return string|null + */ + public function getLastName() + { + return $this->getProperty('last_name'); + } - /** - * Returns the Facebook URL for the user as a string if available. - * - * @return string|null - */ - public function getLink() - { - return $this->getProperty('link'); - } + /** + * Returns the gender for the user as a string if present. + * + * @return string|null + */ + public function getGender() + { + return $this->getProperty('gender'); + } - /** - * Returns the users birthday, if available. - * - * @return \DateTime|null - */ - public function getBirthday() - { - return $this->getProperty('birthday'); - } + /** + * Returns the Facebook URL for the user as a string if available. + * + * @return string|null + */ + public function getLink() + { + return $this->getProperty('link'); + } - /** - * Returns the current location of the user as a GraphPage. - * - * @return GraphPage|null - */ - public function getLocation() - { - return $this->getProperty('location'); - } + /** + * Returns the users birthday, if available. + * + * @return \DateTime|null + */ + public function getBirthday() + { + return $this->getProperty('birthday'); + } - /** - * Returns the current location of the user as a GraphPage. - * - * @return GraphPage|null - */ - public function getHometown() - { - return $this->getProperty('hometown'); - } + /** + * Returns the current location of the user as a GraphPage. + * + * @return GraphPage|null + */ + public function getLocation() + { + return $this->getProperty('location'); + } - /** - * Returns the current location of the user as a GraphUser. - * - * @return GraphUser|null - */ - public function getSignificantOther() - { - return $this->getProperty('significant_other'); - } + /** + * Returns the current location of the user as a GraphPage. + * + * @return GraphPage|null + */ + public function getHometown() + { + return $this->getProperty('hometown'); + } - /** - * Returns the picture of the user as a GraphPicture - * - * @return GraphPicture|null - */ - public function getPicture() - { - return $this->getProperty('picture'); - } + /** + * Returns the current location of the user as a GraphUser. + * + * @return GraphUser|null + */ + public function getSignificantOther() + { + return $this->getProperty('significant_other'); + } + /** + * Returns the picture of the user as a GraphPicture + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getProperty('picture'); + } } diff --git a/src/Facebook/Helpers/FacebookCanvasHelper.php b/src/Facebook/Helpers/FacebookCanvasHelper.php index b3a8ee16f..8068526ad 100644 --- a/src/Facebook/Helpers/FacebookCanvasHelper.php +++ b/src/Facebook/Helpers/FacebookCanvasHelper.php @@ -25,34 +25,28 @@ /** * Class FacebookCanvasLoginHelper + * * @package Facebook */ class FacebookCanvasHelper extends FacebookSignedRequestFromInputHelper { - - /** - * Returns the app data value. - * - * @return mixed|null - */ - public function getAppData() - { - return $this->signedRequest ? $this->signedRequest->get('app_data') : null; - } - - /** - * Get raw signed request from POST. - * - * @return string|null - */ - public function getRawSignedRequest() - { - $rawSignedRequest = $this->getRawSignedRequestFromPost(); - if ($rawSignedRequest) { - return $rawSignedRequest; + /** + * Returns the app data value. + * + * @return mixed|null + */ + public function getAppData() + { + return $this->signedRequest ? $this->signedRequest->get('app_data') : null; } - return null; - } - + /** + * Get raw signed request from POST. + * + * @return string|null + */ + public function getRawSignedRequest() + { + return $this->getRawSignedRequestFromPost() ?: null; + } } diff --git a/src/Facebook/Helpers/FacebookJavaScriptHelper.php b/src/Facebook/Helpers/FacebookJavaScriptHelper.php index bd8d077b8..5d406b539 100644 --- a/src/Facebook/Helpers/FacebookJavaScriptHelper.php +++ b/src/Facebook/Helpers/FacebookJavaScriptHelper.php @@ -25,19 +25,18 @@ /** * Class FacebookJavaScriptLoginHelper + * * @package Facebook */ class FacebookJavaScriptHelper extends FacebookSignedRequestFromInputHelper { - - /** - * Get raw signed request from the cookie. - * - * @return string|null - */ - public function getRawSignedRequest() - { - return $this->getRawSignedRequestFromCookie(); - } - + /** + * Get raw signed request from the cookie. + * + * @return string|null + */ + public function getRawSignedRequest() + { + return $this->getRawSignedRequestFromCookie(); + } } diff --git a/src/Facebook/Helpers/FacebookPageTabHelper.php b/src/Facebook/Helpers/FacebookPageTabHelper.php index 4f0adb891..ee43f5e89 100644 --- a/src/Facebook/Helpers/FacebookPageTabHelper.php +++ b/src/Facebook/Helpers/FacebookPageTabHelper.php @@ -28,69 +28,68 @@ /** * Class FacebookPageTabHelper + * * @package Facebook - * @author Fosco Marotto */ class FacebookPageTabHelper extends FacebookCanvasHelper { + /** + * @var array|null + */ + protected $pageData; - /** - * @var array|null - */ - protected $pageData; + /** + * Initialize the helper and process available signed request data. + * + * @param FacebookApp $app The FacebookApp entity. + * @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) + { + parent::__construct($app, $client, $graphVersion); - /** - * Initialize the helper and process available signed request data. - * - * @param FacebookApp $app The FacebookApp entity. - * @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) - { - parent::__construct($app, $client, $graphVersion); + if (!$this->signedRequest) { + return; + } - if ( ! $this->signedRequest) { - return; + $this->pageData = $this->signedRequest->get('page'); } - $this->pageData = $this->signedRequest->get('page'); - } + /** + * Returns a value from the page data. + * + * @param string $key + * @param mixed|null $default + * + * @return mixed|null + */ + public function getPageData($key, $default = null) + { + if (isset($this->pageData[$key])) { + return $this->pageData[$key]; + } - /** - * Returns a value from the page data. - * - * @param string $key - * @param mixed|null $default - * - * @return mixed|null - */ - public function getPageData($key, $default = null) - { - if (isset($this->pageData[$key])) { - return $this->pageData[$key]; + return $default; } - return $default; - } - - /** - * Returns true if the user is an admin. - * - * @return boolean - */ - public function isAdmin() - { - return $this->getPageData('admin') === true; - } - /** - * Returns the page id if available. - * - * @return string|null - */ - public function getPageId() - { - return $this->getPageData('id'); - } + /** + * Returns true if the user is an admin. + * + * @return boolean + */ + public function isAdmin() + { + return $this->getPageData('admin') === true; + } + /** + * Returns the page id if available. + * + * @return string|null + */ + public function getPageId() + { + return $this->getPageData('id'); + } } diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 0a32750bd..d22c8b740 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -38,11 +38,11 @@ /** * Class FacebookRedirectLoginHelper + * * @package Facebook */ class FacebookRedirectLoginHelper { - /** * @const int The length of CSRF string to validate the login link. */ @@ -64,17 +64,15 @@ class FacebookRedirectLoginHelper protected $persistentDataHandler; /** - * @var PseudoRandomStringGeneratorInterface The cryptographically secure - * pseudo-random string generator. + * @var PseudoRandomStringGeneratorInterface The cryptographically secure pseudo-random string generator. */ protected $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) { @@ -133,24 +131,20 @@ public function detectPseudoRandomStringGenerator() return new OpenSslPseudoRandomStringGenerator(); } - if (! ini_get('open_basedir') && is_readable('/dev/urandom')) { + if (!ini_get('open_basedir') && is_readable('/dev/urandom')) { return new UrandomPseudoRandomStringGenerator(); } - throw new FacebookSDKException( - 'Unable to detect a cryptographically secure pseudo-random string generator.' - ); + throw new FacebookSDKException('Unable to detect a cryptographically secure pseudo-random string generator.'); } /** - * Stores CSRF state and returns a URL to which the user should be sent to - * in order to continue the login process with Facebook. + * 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 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(). * * @return string */ @@ -165,10 +159,9 @@ 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(). + * @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 */ @@ -181,9 +174,8 @@ 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(). + * @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 * @@ -191,7 +183,7 @@ public function getLoginUrl($redirectUrl, array $scope = [], $separator = '&') */ public function getLogoutUrl($accessToken, $next, $separator = '&') { - if (! $accessToken instanceof AccessToken) { + if (!$accessToken instanceof AccessToken) { $accessToken = new AccessToken($accessToken); } @@ -208,13 +200,11 @@ 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. + * 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(). + * @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 */ @@ -226,13 +216,11 @@ 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. + * 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(). + * @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 */ @@ -254,7 +242,7 @@ public function getReAuthenticationUrl($redirectUrl, array $scope = [], $separat */ public function getAccessToken($redirectUrl = null) { - if (! $code = $this->getCode()) { + if (!$code = $this->getCode()) { return null; } @@ -277,18 +265,12 @@ protected function validateCsrf() $state = $this->getState(); $savedState = $this->persistentDataHandler->get('state'); - if (! $state || ! $savedState) { - throw new FacebookSDKException( - 'Cross-site request forgery validation failed. ' . - 'Required param "state" missing.' - ); + if (!$state || !$savedState) { + throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.'); } - + if ($state !== $savedState) { - throw new FacebookSDKException( - 'Cross-site request forgery validation failed. ' . - 'The "state" param from the URL and session do not match.' - ); + throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } } diff --git a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php index ae529229e..aafa24645 100644 --- a/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php +++ b/src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -32,135 +32,135 @@ /** * Class FacebookSignedRequestFromInputHelper + * * @package Facebook */ abstract class FacebookSignedRequestFromInputHelper { + /** + * @var SignedRequest|null The SignedRequest entity. + */ + protected $signedRequest; + + /** + * @var FacebookApp The FacebookApp entity. + */ + protected $app; + + /** + * @var OAuth2Client The OAuth 2.0 client service. + */ + protected $oAuth2Client; + + /** + * Initialize the helper and process available signed request data. + * + * @param FacebookApp $app The FacebookApp entity. + * @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) + { + $this->app = $app; + $graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + $this->oAuth2Client = new OAuth2Client($this->app, $client, $graphVersion); + + $this->instantiateSignedRequest(); + } + + /** + * Instantiates a new SignedRequest entity. + * + * @param string|null + */ + public function instantiateSignedRequest($rawSignedRequest = null) + { + $rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); - /** - * @var SignedRequest|null The SignedRequest entity. - */ - protected $signedRequest; - - /** - * @var FacebookApp The FacebookApp entity. - */ - protected $app; - - /** - * @var OAuth2Client The OAuth 2.0 client service. - */ - protected $oAuth2Client; - - /** - * Initialize the helper and process available signed request data. - * - * @param FacebookApp $app The FacebookApp entity. - * @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) - { - $this->app = $app; - $graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; - $this->oAuth2Client = new OAuth2Client($this->app, $client, $graphVersion); - - $this->instantiateSignedRequest(); - } - - /** - * Instantiates a new SignedRequest entity. - * - * @param string|null - */ - public function instantiateSignedRequest($rawSignedRequest = null) - { - $rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); - - if ( ! $rawSignedRequest) { - return; + if (!$rawSignedRequest) { + return; + } + + $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest); } - $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest); - } - - /** - * Returns an AccessToken entity from the signed request. - * - * @return AccessToken|null - * - * @throws \Facebook\Exceptions\FacebookSDKException - */ - public function getAccessToken() - { - if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { - $code = $this->signedRequest->get('code'); - $accessToken = $this->signedRequest->get('oauth_token'); - - if ($code && ! $accessToken) { - return $this->oAuth2Client->getAccessTokenFromCode($code); - } - - $expiresAt = $this->signedRequest->get('expires', 0); - return new AccessToken($accessToken, $expiresAt); + /** + * Returns an AccessToken entity from the signed request. + * + * @return AccessToken|null + * + * @throws \Facebook\Exceptions\FacebookSDKException + */ + public function getAccessToken() + { + if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { + $code = $this->signedRequest->get('code'); + $accessToken = $this->signedRequest->get('oauth_token'); + + if ($code && !$accessToken) { + return $this->oAuth2Client->getAccessTokenFromCode($code); + } + + $expiresAt = $this->signedRequest->get('expires', 0); + + return new AccessToken($accessToken, $expiresAt); + } + + return null; } - return null; - } - - /** - * Returns the SignedRequest entity. - * - * @return SignedRequest|null - */ - public function getSignedRequest() - { - return $this->signedRequest; - } - - /** - * Returns the user_id if available. - * - * @return string|null - */ - public function getUserId() - { - return $this->signedRequest ? $this->signedRequest->getUserId() : null; - } - - /** - * Get raw signed request from input. - * - * @return string|null - */ - abstract public function getRawSignedRequest(); - - /** - * Get raw signed request from POST input. - * - * @return string|null - */ - public function getRawSignedRequestFromPost() - { - if (isset($_POST['signed_request'])) { - return $_POST['signed_request']; + /** + * Returns the SignedRequest entity. + * + * @return SignedRequest|null + */ + public function getSignedRequest() + { + return $this->signedRequest; } - return null; - } - - /** - * Get raw signed request from cookie set from the Javascript SDK. - * - * @return string|null - */ - public function getRawSignedRequestFromCookie() - { - if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { - return $_COOKIE['fbsr_' . $this->app->getId()]; + /** + * Returns the user_id if available. + * + * @return string|null + */ + public function getUserId() + { + return $this->signedRequest ? $this->signedRequest->getUserId() : null; } - return null; - } + /** + * Get raw signed request from input. + * + * @return string|null + */ + abstract public function getRawSignedRequest(); + + /** + * Get raw signed request from POST input. + * + * @return string|null + */ + public function getRawSignedRequestFromPost() + { + if (isset($_POST['signed_request'])) { + return $_POST['signed_request']; + } + + return null; + } + /** + * Get raw signed request from cookie set from the Javascript SDK. + * + * @return string|null + */ + public function getRawSignedRequestFromCookie() + { + if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { + return $_COOKIE['fbsr_' . $this->app->getId()]; + } + + return null; + } } diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php index 82f8a42b8..583d3033c 100755 --- a/src/Facebook/Http/GraphRawResponse.php +++ b/src/Facebook/Http/GraphRawResponse.php @@ -25,11 +25,11 @@ /** * Class GraphRawResponse + * * @package Facebook */ class GraphRawResponse { - /** * @var array The response headers in the form of an associative array. */ @@ -48,14 +48,14 @@ class GraphRawResponse /** * 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 $body The raw response body. + * @param int $httpStatusCode The HTTP response code (if sending headers as parsed array). */ public function __construct($headers, $body, $httpStatusCode = null) { if (is_numeric($httpStatusCode)) { - $this->httpResponseCode = (int) $httpStatusCode; + $this->httpResponseCode = (int)$httpStatusCode; } if (is_array($headers)) { @@ -105,7 +105,7 @@ public function getHttpResponseCode() public function setHttpResponseCodeFromHeader($rawResponseHeader) { preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $rawResponseHeader, $match); - $this->httpResponseCode = (int) $match[1]; + $this->httpResponseCode = (int)$match[1]; } /** @@ -129,7 +129,7 @@ protected function setHeadersFromString($rawHeaders) if (strpos($line, ': ') === false) { $this->setHttpResponseCodeFromHeader($line); } else { - list ($key, $value) = explode(': ', $line); + list($key, $value) = explode(': ', $line); $this->headers[$key] = $value; } } diff --git a/src/Facebook/Http/RequestBodyInterface.php b/src/Facebook/Http/RequestBodyInterface.php index 0da6a8821..97e0a2e87 100755 --- a/src/Facebook/Http/RequestBodyInterface.php +++ b/src/Facebook/Http/RequestBodyInterface.php @@ -25,15 +25,15 @@ /** * Interface + * * @package Facebook */ interface RequestBodyInterface { - /** - * Get the body of the request to send to Graph. - * - * @return string - */ + * Get the body of the request to send to Graph. + * + * @return string + */ public function getBody(); } diff --git a/src/Facebook/Http/RequestBodyMultipart.php b/src/Facebook/Http/RequestBodyMultipart.php index fad4c28ab..34152bf59 100644 --- a/src/Facebook/Http/RequestBodyMultipart.php +++ b/src/Facebook/Http/RequestBodyMultipart.php @@ -25,18 +25,17 @@ use Facebook\FileUpload\FacebookFile; -/** - * Some things copied from Guzzle - * @see https://github.com/guzzle/guzzle/blob/master/src/Post/MultipartBody.php - */ - /** * Class RequestBodyMultipartt + * + * Some things copied from Guzzle + * * @package Facebook + * + * @see https://github.com/guzzle/guzzle/blob/master/src/Post/MultipartBody.php */ class RequestBodyMultipart implements RequestBodyInterface { - /** * @var string The boundary. */ @@ -100,7 +99,7 @@ public function getBoundary() /** * Get the string needed to transfer a file. * - * @param string $name + * @param string $name * @param FacebookFile $file * * @return string diff --git a/src/Facebook/Http/RequestBodyUrlEncoded.php b/src/Facebook/Http/RequestBodyUrlEncoded.php index 8e6c5e651..77c2b6492 100644 --- a/src/Facebook/Http/RequestBodyUrlEncoded.php +++ b/src/Facebook/Http/RequestBodyUrlEncoded.php @@ -25,11 +25,11 @@ /** * Class RequestBodyUrlEncoded + * * @package Facebook */ class RequestBodyUrlEncoded implements RequestBodyInterface { - /** * @var array The parameters to send with this request. */ diff --git a/src/Facebook/HttpClients/FacebookCurl.php b/src/Facebook/HttpClients/FacebookCurl.php index 5b20e92db..e5d124ac4 100644 --- a/src/Facebook/HttpClients/FacebookCurl.php +++ b/src/Facebook/HttpClients/FacebookCurl.php @@ -25,105 +25,105 @@ /** * Class FacebookCurl - * Abstraction for the procedural curl elements so that curl can be mocked - * and the implementation can be tested. + * + * Abstraction for the procedural curl elements so that curl can be mocked and the implementation can be tested. + * * @package Facebook */ class FacebookCurl { - /** - * @var resource Curl resource instance - */ - protected $curl; - - /** - * Make a new curl reference instance - */ - public function init() - { - $this->curl = curl_init(); - } + /** + * @var resource Curl resource instance + */ + protected $curl; - /** - * Set a curl option - * - * @param $key - * @param $value - */ - public function setopt($key, $value) - { - curl_setopt($this->curl, $key, $value); - } + /** + * Make a new curl reference instance + */ + public function init() + { + $this->curl = curl_init(); + } - /** - * Set an array of options to a curl resource - * - * @param array $options - */ - public function setopt_array(array $options) - { - curl_setopt_array($this->curl, $options); - } + /** + * Set a curl option + * + * @param $key + * @param $value + */ + public function setopt($key, $value) + { + curl_setopt($this->curl, $key, $value); + } - /** - * Send a curl request - * - * @return mixed - */ - public function exec() - { - return curl_exec($this->curl); - } + /** + * Set an array of options to a curl resource + * + * @param array $options + */ + public function setoptArray(array $options) + { + curl_setopt_array($this->curl, $options); + } - /** - * Return the curl error number - * - * @return int - */ - public function errno() - { - return curl_errno($this->curl); - } + /** + * Send a curl request + * + * @return mixed + */ + public function exec() + { + return curl_exec($this->curl); + } - /** - * Return the curl error message - * - * @return string - */ - public function error() - { - return curl_error($this->curl); - } + /** + * Return the curl error number + * + * @return int + */ + public function errno() + { + return curl_errno($this->curl); + } - /** - * Get info from a curl reference - * - * @param $type - * - * @return mixed - */ - public function getinfo($type) - { - return curl_getinfo($this->curl, $type); - } + /** + * Return the curl error message + * + * @return string + */ + public function error() + { + return curl_error($this->curl); + } - /** - * Get the currently installed curl version - * - * @return array - */ - public function version() - { - return curl_version(); - } + /** + * Get info from a curl reference + * + * @param $type + * + * @return mixed + */ + public function getinfo($type) + { + return curl_getinfo($this->curl, $type); + } - /** - * Close the resource connection to curl - */ - public function close() - { - curl_close($this->curl); - } + /** + * Get the currently installed curl version + * + * @return array + */ + public function version() + { + return curl_version(); + } + /** + * Close the resource connection to curl + */ + public function close() + { + curl_close($this->curl); + } } diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 56e66c9ed..955ac0622 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -28,185 +28,183 @@ /** * Class FacebookCurlHttpClient + * * @package Facebook */ 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; + + /** + * @var FacebookCurl Procedural curl as object + */ + protected $facebookCurl; + + /** + * @const Curl Version which is unaffected by the proxy header length error. + */ + const CURL_PROXY_QUIRK_VER = 0x071E00; + + /** + * @const "Connection Established" header text + */ + const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n"; + + /** + * @param FacebookCurl|null Procedural curl as object + */ + public function __construct(FacebookCurl $facebookCurl = null) + { + $this->facebookCurl = $facebookCurl ?: new FacebookCurl(); + } + + /** + * @inheritdoc + */ + public function send($url, $method, $body, array $headers, $timeOut) + { + $this->openConnection($url, $method, $body, $headers, $timeOut); + $this->sendRequest(); + + if ($curlErrorCode = $this->facebookCurl->errno()) { + throw new FacebookSDKException($this->facebookCurl->error(), $curlErrorCode); + } + + // Separate the raw headers from the raw body + list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody(); + + $this->closeConnection(); - /** - * @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; - - /** - * @var FacebookCurl Procedural curl as object - */ - protected $facebookCurl; - - /** - * @const Curl Version which is unaffected by the proxy header length error. - */ - const CURL_PROXY_QUIRK_VER = 0x071E00; - - /** - * @const "Connection Established" header text - */ - const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n"; - - /** - * @param FacebookCurl|null Procedural curl as object - */ - public function __construct(FacebookCurl $facebookCurl = null) - { - $this->facebookCurl = $facebookCurl ?: new FacebookCurl(); - } - - /** - * @inheritdoc - */ - public function send($url, $method, $body, array $headers, $timeOut) - { - $this->openConnection($url, $method, $body, $headers, $timeOut); - $this->sendRequest(); - - if ($curlErrorCode = $this->facebookCurl->errno()) { - $curlErrorMessage = $this->facebookCurl->error(); - throw new FacebookSDKException($curlErrorMessage, $curlErrorCode); + return new GraphRawResponse($rawHeaders, $rawBody); } - // Separate the raw headers from the raw body - list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody(); - - $this->closeConnection(); - - return new GraphRawResponse($rawHeaders, $rawBody); - } - - /** - * 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. - */ - public function openConnection($url, $method, $body, array $headers, $timeOut) - { - $options = [ - CURLOPT_CUSTOMREQUEST => $method, - CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers), - CURLOPT_URL => $url, - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => $timeOut, - CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects - CURLOPT_HEADER => true, // Enable header processing - CURLOPT_SSL_VERIFYHOST => 2, - CURLOPT_SSL_VERIFYPEER => true, - CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', - ]; - - if ($method !== "GET") { - $options[CURLOPT_POSTFIELDS] = $body; + /** + * 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. + */ + public function openConnection($url, $method, $body, array $headers, $timeOut) + { + $options = [ + CURLOPT_CUSTOMREQUEST => $method, + CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers), + CURLOPT_URL => $url, + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => $timeOut, + CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects + CURLOPT_HEADER => true, // Enable header processing + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', + ]; + + if ($method !== "GET") { + $options[CURLOPT_POSTFIELDS] = $body; + } + + $this->facebookCurl->init(); + $this->facebookCurl->setoptArray($options); } - $this->facebookCurl->init(); - $this->facebookCurl->setopt_array($options); - } - - /** - * Closes an existing curl connection - */ - public function closeConnection() - { - $this->facebookCurl->close(); - } - - /** - * Send the request and get the raw response from curl - */ - public function sendRequest() - { - $this->rawResponse = $this->facebookCurl->exec(); - } - - /** - * Compiles the request headers into a curl-friendly format. - * - * @param array $headers The request headers. - * - * @return array - */ - public function compileRequestHeaders(array $headers) - { - $return = []; - - foreach ($headers as $key => $value) { - $return[] = $key . ': ' . $value; + /** + * Closes an existing curl connection + */ + public function closeConnection() + { + $this->facebookCurl->close(); } - return $return; - } - - /** - * Extracts the headers and the body into a two-part array - * - * @return array - */ - public function extractResponseHeadersAndBody() - { - $headerSize = $this->getHeaderSize(); - - $rawHeaders = mb_substr($this->rawResponse, 0, $headerSize); - $rawBody = mb_substr($this->rawResponse, $headerSize); - - return array(trim($rawHeaders), trim($rawBody)); - } - - /** - * Return proper header size - * - * @return integer - */ - private function getHeaderSize() - { - $headerSize = $this->facebookCurl->getinfo(CURLINFO_HEADER_SIZE); - // This corrects a Curl bug where header size does not account - // for additional Proxy headers. - if ( $this->needsCurlProxyFix() ) { - // Additional way to calculate the request body size. - if (preg_match('/Content-Length: (\d+)/', $this->rawResponse, $m)) { - $headerSize = mb_strlen($this->rawResponse) - $m[1]; - } elseif (stripos($this->rawResponse, self::CONNECTION_ESTABLISHED) !== false) { - $headerSize += mb_strlen(self::CONNECTION_ESTABLISHED); - } + /** + * Send the request and get the raw response from curl + */ + public function sendRequest() + { + $this->rawResponse = $this->facebookCurl->exec(); } - return $headerSize; - } + /** + * Compiles the request headers into a curl-friendly format. + * + * @param array $headers The request headers. + * + * @return array + */ + public function compileRequestHeaders(array $headers) + { + $return = []; + + foreach ($headers as $key => $value) { + $return[] = $key . ': ' . $value; + } + + return $return; + } + + /** + * Extracts the headers and the body into a two-part array + * + * @return array + */ + public function extractResponseHeadersAndBody() + { + $headerSize = $this->getHeaderSize(); + + $rawHeaders = mb_substr($this->rawResponse, 0, $headerSize); + $rawBody = mb_substr($this->rawResponse, $headerSize); - /** - * Detect versions of Curl which report incorrect header lengths when - * using Proxies. - * - * @return boolean - */ - private function needsCurlProxyFix() - { - $ver = $this->facebookCurl->version(); - $version = $ver['version_number']; + return [trim($rawHeaders), trim($rawBody)]; + } - return $version < self::CURL_PROXY_QUIRK_VER; - } + /** + * Return proper header size + * + * @return integer + */ + private function getHeaderSize() + { + $headerSize = $this->facebookCurl->getinfo(CURLINFO_HEADER_SIZE); + // This corrects a Curl bug where header size does not account + // for additional Proxy headers. + if ($this->needsCurlProxyFix()) { + // Additional way to calculate the request body size. + if (preg_match('/Content-Length: (\d+)/', $this->rawResponse, $m)) { + $headerSize = mb_strlen($this->rawResponse) - $m[1]; + } elseif (stripos($this->rawResponse, self::CONNECTION_ESTABLISHED) !== false) { + $headerSize += mb_strlen(self::CONNECTION_ESTABLISHED); + } + } + + return $headerSize; + } + /** + * Detect versions of Curl which report incorrect header lengths when + * using Proxies. + * + * @return boolean + */ + private function needsCurlProxyFix() + { + $ver = $this->facebookCurl->version(); + $version = $ver['version_number']; + + return $version < self::CURL_PROXY_QUIRK_VER; + } } diff --git a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php index 6f1c822a3..6f2a1c6f2 100644 --- a/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php +++ b/src/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -33,70 +33,65 @@ class FacebookGuzzleHttpClient implements FacebookHttpClientInterface { + /** + * @var \GuzzleHttp\Client The Guzzle client. + */ + protected $guzzleClient; - /** - * @var \GuzzleHttp\Client The Guzzle client. - */ - protected $guzzleClient; - - /** - * @param \GuzzleHttp\Client|null The Guzzle client. - */ - public function __construct(Client $guzzleClient = null) - { - $this->guzzleClient = $guzzleClient ?: new Client(); - } + /** + * @param \GuzzleHttp\Client|null The Guzzle client. + */ + public function __construct(Client $guzzleClient = null) + { + $this->guzzleClient = $guzzleClient ?: new Client(); + } - /** - * @inheritdoc - */ - public function send($url, $method, $body, array $headers, $timeOut) - { - $options = [ - 'headers' => $headers, - 'body' => $body, - 'timeout' => $timeOut, - 'connect_timeout' => 10, - 'verify' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', - ]; - $request = $this->guzzleClient->createRequest($method, $url, $options); + /** + * @inheritdoc + */ + public function send($url, $method, $body, array $headers, $timeOut) + { + $options = [ + 'headers' => $headers, + 'body' => $body, + 'timeout' => $timeOut, + 'connect_timeout' => 10, + 'verify' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', + ]; + $request = $this->guzzleClient->createRequest($method, $url, $options); - try { - $rawResponse = $this->guzzleClient->send($request); - } catch (RequestException $e) { - $rawResponse = $e->getResponse(); + try { + $rawResponse = $this->guzzleClient->send($request); + } catch (RequestException $e) { + $rawResponse = $e->getResponse(); - if ( - $e->getPrevious() instanceof RingException - || ! $rawResponse instanceof ResponseInterface - ) { - throw new FacebookSDKException($e->getMessage(), $e->getCode()); - } - } + if ($e->getPrevious() instanceof RingException || !$rawResponse instanceof ResponseInterface) { + throw new FacebookSDKException($e->getMessage(), $e->getCode()); + } + } - $rawHeaders = $this->getHeadersAsString($rawResponse); - $rawBody = $rawResponse->getBody(); - $httpStatusCode = $rawResponse->getStatusCode(); + $rawHeaders = $this->getHeadersAsString($rawResponse); + $rawBody = $rawResponse->getBody(); + $httpStatusCode = $rawResponse->getStatusCode(); - return new GraphRawResponse($rawHeaders, $rawBody, $httpStatusCode); - } - - /** - * Returns the Guzzle array of headers as a string. - * - * @param ResponseInterface $response The Guzzle response. - * - * @return string - */ - public function getHeadersAsString(ResponseInterface $response) - { - $headers = $response->getHeaders(); - $rawHeaders = []; - foreach ($headers as $name => $values) { - $rawHeaders[] = $name . ": " . implode(", ", $values); + return new GraphRawResponse($rawHeaders, $rawBody, $httpStatusCode); } - return implode("\r\n", $rawHeaders); - } + /** + * Returns the Guzzle array of headers as a string. + * + * @param ResponseInterface $response The Guzzle response. + * + * @return string + */ + public function getHeadersAsString(ResponseInterface $response) + { + $headers = $response->getHeaders(); + $rawHeaders = []; + foreach ($headers as $name => $values) { + $rawHeaders[] = $name . ": " . implode(", ", $values); + } + return implode("\r\n", $rawHeaders); + } } diff --git a/src/Facebook/HttpClients/FacebookHttpClientInterface.php b/src/Facebook/HttpClients/FacebookHttpClientInterface.php index 389b0cc8c..0029bc022 100644 --- a/src/Facebook/HttpClients/FacebookHttpClientInterface.php +++ b/src/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -25,24 +25,23 @@ /** * Interface FacebookHttpClientInterface + * * @package Facebook */ 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. - * - * @return \Facebook\Http\GraphRawResponse Raw response from the server. - * - * @throws \Facebook\Exceptions\FacebookSDKException - */ - public function send($url, $method, $body, array $headers, $timeOut); - + /** + * 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. + * + * @return \Facebook\Http\GraphRawResponse Raw response from the server. + * + * @throws \Facebook\Exceptions\FacebookSDKException + */ + public function send($url, $method, $body, array $headers, $timeOut); } diff --git a/src/Facebook/HttpClients/FacebookStream.php b/src/Facebook/HttpClients/FacebookStream.php index 8577e1ae9..95aa22e7a 100644 --- a/src/Facebook/HttpClients/FacebookStream.php +++ b/src/Facebook/HttpClients/FacebookStream.php @@ -25,55 +25,56 @@ /** * Class FacebookStream + * * Abstraction for the procedural stream elements so that the functions can be * mocked and the implementation can be tested. + * * @package Facebook */ class FacebookStream { + /** + * @var resource Context stream resource instance + */ + protected $stream; - /** - * @var resource Context stream resource instance - */ - protected $stream; - - /** - * @var array Response headers from the stream wrapper - */ - protected $responseHeaders; + /** + * @var array Response headers from the stream wrapper + */ + protected $responseHeaders; - /** - * Make a new context stream reference instance - * - * @param array $options - */ - public function streamContextCreate(array $options) - { - $this->stream = stream_context_create($options); - } + /** + * Make a new context stream reference instance + * + * @param array $options + */ + public function streamContextCreate(array $options) + { + $this->stream = stream_context_create($options); + } - /** - * The response headers from the stream wrapper - * - * @return array|null - */ - public function getResponseHeaders() - { - return $this->responseHeaders; - } + /** + * The response headers from the stream wrapper + * + * @return array|null + */ + public function getResponseHeaders() + { + return $this->responseHeaders; + } - /** - * Send a stream wrapped request - * - * @param string $url - * - * @return mixed - */ - public function fileGetContents($url) - { - $rawResponse = file_get_contents($url, false, $this->stream); - $this->responseHeaders = $http_response_header; - return $rawResponse; - } + /** + * Send a stream wrapped request + * + * @param string $url + * + * @return mixed + */ + public function fileGetContents($url) + { + $rawResponse = file_get_contents($url, false, $this->stream); + $this->responseHeaders = $http_response_header; + return $rawResponse; + } } diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index 4f450b9b3..b15751431 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -28,69 +28,67 @@ class FacebookStreamHttpClient implements FacebookHttpClientInterface { + /** + * @var FacebookStream Procedural stream wrapper as object. + */ + protected $facebookStream; - /** - * @var FacebookStream Procedural stream wrapper as object. - */ - protected $facebookStream; - - /** - * @param FacebookStream|null Procedural stream wrapper as object. - */ - public function __construct(FacebookStream $facebookStream = null) - { - $this->facebookStream = $facebookStream ?: new FacebookStream(); - } + /** + * @param FacebookStream|null Procedural stream wrapper as object. + */ + public function __construct(FacebookStream $facebookStream = null) + { + $this->facebookStream = $facebookStream ?: new FacebookStream(); + } - /** - * @inheritdoc - */ - public function send($url, $method, $body, array $headers, $timeOut) - { - $options = [ - 'http' => [ - 'method' => $method, - 'header' => $this->compileHeader($headers), - 'content' => $body, - 'timeout' => $timeOut, - 'ignore_errors' => true - ], - 'ssl' => [ - 'verify_peer' => true, - 'verify_peer_name' => true, - 'allow_self_signed' => true, // All root certificates are self-signed - 'cafile' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', - ], - ]; + /** + * @inheritdoc + */ + public function send($url, $method, $body, array $headers, $timeOut) + { + $options = [ + 'http' => [ + 'method' => $method, + 'header' => $this->compileHeader($headers), + 'content' => $body, + 'timeout' => $timeOut, + 'ignore_errors' => true + ], + 'ssl' => [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, // All root certificates are self-signed + 'cafile' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', + ], + ]; - $this->facebookStream->streamContextCreate($options); - $rawBody = $this->facebookStream->fileGetContents($url); - $rawHeaders = $this->facebookStream->getResponseHeaders(); + $this->facebookStream->streamContextCreate($options); + $rawBody = $this->facebookStream->fileGetContents($url); + $rawHeaders = $this->facebookStream->getResponseHeaders(); - if ($rawBody === false || !$rawHeaders) { - throw new FacebookSDKException('Stream returned an empty response', 660); - } + if ($rawBody === false || !$rawHeaders) { + throw new FacebookSDKException('Stream returned an empty response', 660); + } - $rawHeaders = implode("\r\n", $rawHeaders); + $rawHeaders = implode("\r\n", $rawHeaders); - return new GraphRawResponse($rawHeaders, $rawBody); - } - - /** - * Formats the headers for use in the stream wrapper. - * - * @param array $headers The request headers. - * - * @return string - */ - public function compileHeader(array $headers) - { - $header = []; - foreach($headers as $k => $v) { - $header[] = $k . ': ' . $v; + return new GraphRawResponse($rawHeaders, $rawBody); } - return implode("\r\n", $header); - } + /** + * Formats the headers for use in the stream wrapper. + * + * @param array $headers The request headers. + * + * @return string + */ + public function compileHeader(array $headers) + { + $header = []; + foreach ($headers as $k => $v) { + $header[] = $k . ': ' . $v; + } + return implode("\r\n", $header); + } } diff --git a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php index 2d1682dd9..93a668615 100644 --- a/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookMemoryPersistentDataHandler.php @@ -25,6 +25,7 @@ /** * Class FacebookMemoryPersistentDataHandler + * * @package Facebook */ class FacebookMemoryPersistentDataHandler implements PersistentDataInterface diff --git a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php index 40c2d5e81..698bfd046 100644 --- a/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php +++ b/src/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php @@ -27,6 +27,7 @@ /** * Class FacebookSessionPersistentDataHandler + * * @package Facebook */ class FacebookSessionPersistentDataHandler implements PersistentDataInterface @@ -45,11 +46,9 @@ class FacebookSessionPersistentDataHandler implements PersistentDataInterface */ public function __construct($enableSessionCheck = true) { - if ($enableSessionCheck - && session_status() !== PHP_SESSION_ACTIVE) { + if ($enableSessionCheck && session_status() !== PHP_SESSION_ACTIVE) { throw new FacebookSDKException( - 'Sessions are not active. Please make sure session_start() is '. - ' at the top of your script.', + 'Sessions are not active. Please make sure session_start() is at the top of your script.', 720 ); } @@ -60,9 +59,11 @@ public function __construct($enableSessionCheck = true) */ public function get($key) { - return isset($_SESSION[$this->sessionPrefix . $key]) - ? $_SESSION[$this->sessionPrefix . $key] - : null; + if (isset($_SESSION[$this->sessionPrefix . $key])) { + return $_SESSION[$this->sessionPrefix . $key]; + } + + return null; } /** diff --git a/src/Facebook/PersistentData/PersistentDataInterface.php b/src/Facebook/PersistentData/PersistentDataInterface.php index 942f25008..bd7e072a8 100644 --- a/src/Facebook/PersistentData/PersistentDataInterface.php +++ b/src/Facebook/PersistentData/PersistentDataInterface.php @@ -25,6 +25,7 @@ /** * Interface PersistentDataInterface + * * @package Facebook */ interface PersistentDataInterface @@ -42,7 +43,7 @@ public function get($key); * Set a value in the persistent data store. * * @param string $key - * @param mixed $value + * @param mixed $value */ public function set($key, $value); } diff --git a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php index 983ca6a6c..f4ea6b870 100644 --- a/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php @@ -32,8 +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(). '; + const ERROR_MESSAGE = 'Unable to generate a cryptographically secure pseudo-random string from openssl_random_pseudo_bytes().'; /** * @throws FacebookSDKException @@ -41,10 +40,7 @@ class OpenSslPseudoRandomStringGenerator implements PseudoRandomStringGeneratorI public function __construct() { if (!function_exists('openssl_random_pseudo_bytes')) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'The function openssl_random_pseudo_bytes() does not exist.' - ); + throw new FacebookSDKException(static::ERROR_MESSAGE . 'The function openssl_random_pseudo_bytes() does not exist.'); } } @@ -59,18 +55,11 @@ public function getPseudoRandomString($length) $binaryString = openssl_random_pseudo_bytes($length, $wasCryptographicallyStrong); if ($binaryString === false) { - throw new FacebookSDKException( - static::ERROR_MESSAGE . - 'openssl_random_pseudo_bytes() returned an unknown error.' - ); + throw new FacebookSDKException(static::ERROR_MESSAGE . 'openssl_random_pseudo_bytes() returned an unknown error.'); } if ($wasCryptographicallyStrong !== true) { - 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.' - ); + 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.'); } return $this->binToHex($binaryString, $length); diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php index fd27510ab..970330c85 100755 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php @@ -25,6 +25,7 @@ /** * Interface + * * @package Facebook */ interface PseudoRandomStringGeneratorInterface diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index dbcf78e0d..a41ce5985 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -35,15 +35,11 @@ trait PseudoRandomStringGeneratorTrait public function validateLength($length) { if (!is_int($length)) { - throw new \InvalidArgumentException( - 'getPseudoRandomString() expects an integer for the string 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' - ); + throw new \InvalidArgumentException('getPseudoRandomString() expects a length greater than 1'); } } @@ -51,7 +47,7 @@ public function validateLength($length) * 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 */ diff --git a/src/Facebook/SignedRequest.php b/src/Facebook/SignedRequest.php index f93c355d6..77099a346 100644 --- a/src/Facebook/SignedRequest.php +++ b/src/Facebook/SignedRequest.php @@ -27,321 +27,306 @@ /** * Class SignedRequest + * * @package Facebook */ class SignedRequest { + /** + * @var FacebookApp The FacebookApp entity. + */ + protected $app; + + /** + * @var string The raw encrypted signed request. + */ + protected $rawSignedRequest; + + /** + * @var array The payload from the decrypted signed request. + */ + protected $payload; + + /** + * Instantiate a new SignedRequest entity. + * + * @param FacebookApp $facebookApp The FacebookApp entity. + * @param string|null $rawSignedRequest The raw signed request. + */ + public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null) + { + $this->app = $facebookApp; + + if (!$rawSignedRequest) { + return; + } + + $this->rawSignedRequest = $rawSignedRequest; + + $this->parse(); + } + + /** + * Returns the raw signed request data. + * + * @return string|null + */ + public function getRawSignedRequest() + { + return $this->rawSignedRequest; + } - /** - * @var FacebookApp The FacebookApp entity. - */ - protected $app; - - /** - * @var string The raw encrypted signed request. - */ - protected $rawSignedRequest; - - /** - * @var array The payload from the decrypted signed request. - */ - protected $payload; - - /** - * Instantiate a new SignedRequest entity. - * - * @param FacebookApp $facebookApp The FacebookApp entity. - * @param string|null $rawSignedRequest The raw signed request. - */ - public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null) - { - $this->app = $facebookApp; - - if ( ! $rawSignedRequest) { - return; + /** + * Returns the parsed signed request data. + * + * @return array|null + */ + public function getPayload() + { + return $this->payload; } - $this->rawSignedRequest = $rawSignedRequest; - - $this->parse(); - } - - /** - * Returns the raw signed request data. - * - * @return string|null - */ - public function getRawSignedRequest() - { - return $this->rawSignedRequest; - } - - /** - * Returns the parsed signed request data. - * - * @return array|null - */ - public function getPayload() - { - 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) - { - if (isset($this->payload[$key])) { - return $this->payload[$key]; + /** + * 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) + { + if (isset($this->payload[$key])) { + return $this->payload[$key]; + } + + return $default; } - return $default; - } - - /** - * Returns user_id from signed request data if available. - * - * @return string|null - */ - public function getUserId() - { - return $this->get('user_id'); - } - - /** - * Checks for OAuth data in the payload. - * - * @return boolean - */ - public function hasOAuthData() - { - 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) - { - $payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-SHA256'; - $payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time(); - $encodedPayload = $this->base64UrlEncode(json_encode($payload)); - - $hashedSig = $this->hashSignature($encodedPayload); - $encodedSig = $this->base64UrlEncode($hashedSig); - - return $encodedSig . '.' . $encodedPayload; - } - - /** - * Validates and decodes a signed request and saves - * the payload to an array. - */ - protected function parse() - { - list($encodedSig, $encodedPayload) = $this->split(); - - // Signature validation - $sig = $this->decodeSignature($encodedSig); - $hashedSig = $this->hashSignature($encodedPayload); - $this->validateSignature($hashedSig, $sig); - - $this->payload = $this->decodePayload($encodedPayload); - - // Payload validation - $this->validateAlgorithm(); - } - - /** - * Splits a raw signed request into signature and payload. - * - * @returns array - * - * @throws FacebookSDKException - */ - protected function split() - { - if (strpos($this->rawSignedRequest, '.') === false) { - throw new FacebookSDKException( - 'Malformed signed request.', 606 - ); + /** + * Returns user_id from signed request data if available. + * + * @return string|null + */ + public function getUserId() + { + return $this->get('user_id'); } - return explode('.', $this->rawSignedRequest, 2); - } - - /** - * Decodes the raw signature from a signed request. - * - * @param string $encodedSig - * - * @returns string - * - * @throws FacebookSDKException - */ - protected function decodeSignature($encodedSig) - { - $sig = $this->base64UrlDecode($encodedSig); - - if ($sig) { - return $sig; + /** + * Checks for OAuth data in the payload. + * + * @return boolean + */ + public function hasOAuthData() + { + return $this->get('oauth_token') || $this->get('code'); } - throw new FacebookSDKException( - 'Signed request has malformed encoded signature data.', 607 - ); - } - - /** - * Decodes the raw payload from a signed request. - * - * @param string $encodedPayload - * - * @returns array - * - * @throws FacebookSDKException - */ - protected function decodePayload($encodedPayload) - { - $payload = $this->base64UrlDecode($encodedPayload); - - if ($payload) { - $payload = json_decode($payload, true); + /** + * Creates a signed request from an array of data. + * + * @param array $payload + * + * @return string + */ + public function make(array $payload) + { + $payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-SHA256'; + $payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time(); + $encodedPayload = $this->base64UrlEncode(json_encode($payload)); + + $hashedSig = $this->hashSignature($encodedPayload); + $encodedSig = $this->base64UrlEncode($hashedSig); + + return $encodedSig . '.' . $encodedPayload; } - if (is_array($payload)) { - return $payload; + /** + * Validates and decodes a signed request and saves + * the payload to an array. + */ + protected function parse() + { + list($encodedSig, $encodedPayload) = $this->split(); + + // Signature validation + $sig = $this->decodeSignature($encodedSig); + $hashedSig = $this->hashSignature($encodedPayload); + $this->validateSignature($hashedSig, $sig); + + $this->payload = $this->decodePayload($encodedPayload); + + // Payload validation + $this->validateAlgorithm(); } - throw new FacebookSDKException( - 'Signed request has malformed encoded payload data.', 607 - ); - } - - /** - * Validates the algorithm used in a signed request. - * - * @throws FacebookSDKException - */ - protected function validateAlgorithm() - { - if ($this->get('algorithm') === 'HMAC-SHA256') { - return; + /** + * Splits a raw signed request into signature and payload. + * + * @returns array + * + * @throws FacebookSDKException + */ + protected function split() + { + if (strpos($this->rawSignedRequest, '.') === false) { + throw new FacebookSDKException('Malformed signed request.', 606); + } + + return explode('.', $this->rawSignedRequest, 2); } - throw new FacebookSDKException( - 'Signed request is using the wrong algorithm.', 605 - ); - } - - /** - * Hashes the signature used in a signed request. - * - * @param string $encodedData - * - * @return string - * - * @throws FacebookSDKException - */ - protected function hashSignature($encodedData) - { - $hashedSig = hash_hmac( - 'sha256', $encodedData, $this->app->getSecret(), $raw_output = true - ); - - if ($hashedSig) { - return $hashedSig; + /** + * Decodes the raw signature from a signed request. + * + * @param string $encodedSig + * + * @returns string + * + * @throws FacebookSDKException + */ + protected function decodeSignature($encodedSig) + { + $sig = $this->base64UrlDecode($encodedSig); + + if (!$sig) { + throw new FacebookSDKException('Signed request has malformed encoded signature data.', 607); + } + + return $sig; } - throw new FacebookSDKException( - 'Unable to hash signature from encoded payload data.', 602 - ); - } - - /** - * Validates the signature used in a signed request. - * - * @param string $hashedSig - * @param string $sig - * - * @throws FacebookSDKException - */ - protected function validateSignature($hashedSig, $sig) - { - if (mb_strlen($hashedSig) === mb_strlen($sig)) { - $validate = 0; - for ($i = 0; $i < mb_strlen($sig); $i++) { - $validate |= ord($hashedSig[$i]) ^ ord($sig[$i]); - } - if ($validate === 0) { - return; - } + /** + * Decodes the raw payload from a signed request. + * + * @param string $encodedPayload + * + * @returns array + * + * @throws FacebookSDKException + */ + protected function decodePayload($encodedPayload) + { + $payload = $this->base64UrlDecode($encodedPayload); + + if ($payload) { + $payload = json_decode($payload, true); + } + + if (!is_array($payload)) { + throw new FacebookSDKException('Signed request has malformed encoded payload data.', 607); + } + + return $payload; } - throw new FacebookSDKException( - 'Signed request has an invalid signature.', 602 - ); - } - - /** - * Base64 decoding which replaces characters: - * + instead of - - * / instead of _ - * @link http://en.wikipedia.org/wiki/Base64#URL_applications - * - * @param string $input base64 url encoded input - * - * @return string decoded string - */ - public function base64UrlDecode($input) - { - $urlDecodedBase64 = strtr($input, '-_', '+/'); - $this->validateBase64($urlDecodedBase64); - - return base64_decode($urlDecodedBase64); - } - - /** - * Base64 encoding which replaces characters: - * + instead of - - * / 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) - { - return strtr(base64_encode($input), '+/', '-_'); - } - - /** - * Validates a base64 string. - * - * @param string $input base64 value to validate - * - * @throws FacebookSDKException - */ - protected function validateBase64($input) - { - $pattern = '/^[a-zA-Z0-9\/\r\n+]*={0,2}$/'; - if (preg_match($pattern, $input)) { - return; + /** + * Validates the algorithm used in a signed request. + * + * @throws FacebookSDKException + */ + protected function validateAlgorithm() + { + if ($this->get('algorithm') !== 'HMAC-SHA256') { + throw new FacebookSDKException('Signed request is using the wrong algorithm.', 605); + } } - throw new FacebookSDKException( - 'Signed request contains malformed base64 encoding.', 608 - ); - } + /** + * Hashes the signature used in a signed request. + * + * @param string $encodedData + * + * @return string + * + * @throws FacebookSDKException + */ + protected function hashSignature($encodedData) + { + $hashedSig = hash_hmac( + 'sha256', + $encodedData, + $this->app->getSecret(), + $raw_output = true + ); + + if (!$hashedSig) { + throw new FacebookSDKException('Unable to hash signature from encoded payload data.', 602); + } + + return $hashedSig; + } + /** + * Validates the signature used in a signed request. + * + * @param string $hashedSig + * @param string $sig + * + * @throws FacebookSDKException + */ + protected function validateSignature($hashedSig, $sig) + { + if (mb_strlen($hashedSig) === mb_strlen($sig)) { + $validate = 0; + for ($i = 0; $i < mb_strlen($sig); $i++) { + $validate |= ord($hashedSig[$i]) ^ ord($sig[$i]); + } + if ($validate === 0) { + return; + } + } + + throw new FacebookSDKException('Signed request has an invalid signature.', 602); + } + + /** + * Base64 decoding which replaces characters: + * + instead of - + * / instead of _ + * + * @link http://en.wikipedia.org/wiki/Base64#URL_applications + * + * @param string $input base64 url encoded input + * + * @return string decoded string + */ + public function base64UrlDecode($input) + { + $urlDecodedBase64 = strtr($input, '-_', '+/'); + $this->validateBase64($urlDecodedBase64); + + return base64_decode($urlDecodedBase64); + } + + /** + * Base64 encoding which replaces characters: + * + instead of - + * / 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) + { + return strtr(base64_encode($input), '+/', '-_'); + } + + /** + * Validates a base64 string. + * + * @param string $input base64 value to validate + * + * @throws FacebookSDKException + */ + protected function validateBase64($input) + { + 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 e37167842..5fbb9ce47 100755 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -25,11 +25,11 @@ /** * Class FacebookUrlDetectionHandler + * * @package Facebook */ class FacebookUrlDetectionHandler implements UrlDetectionInterface { - /** * @inheritdoc */ @@ -66,7 +66,7 @@ protected function isBehindSsl() return $this->protocolWithActiveSsl($protocol); } - return (string) $this->getServerVar('SERVER_PORT') === '443'; + return (string)$this->getServerVar('SERVER_PORT') === '443'; } /** @@ -78,14 +78,16 @@ protected function isBehindSsl() */ protected function protocolWithActiveSsl($protocol) { - $protocol = strtolower((string) $protocol); + $protocol = strtolower((string)$protocol); - return in_array($protocol, array('on', '1', 'https', 'ssl'), true); + return in_array($protocol, ['on', '1', 'https', 'ssl'], true); } /** * Tries to detect the host name of the server. + * * Some elements adapted from + * * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php * * @return string @@ -112,8 +114,7 @@ protected function getHostName() $appendPort = ':' . $port; // Don't append port number if a normal port. - if (($scheme == 'http' && $port == '80') - || ($scheme == 'https' && $port == '443')) { + if (($scheme == 'http' && $port == '80') || ($scheme == 'https' && $port == '443')) { $appendPort = ''; } @@ -125,15 +126,15 @@ protected function getCurrentPort() // Check for proxy first $port = $this->getHeader('X_FORWARDED_PORT'); if ($port) { - return (string) $port; + return (string)$port; } - $protocol = (string) $this->getHeader('X_FORWARDED_PROTO'); + $protocol = (string)$this->getHeader('X_FORWARDED_PROTO'); if ($protocol === 'https') { return '443'; } - return (string) $this->getServerVar('SERVER_PORT'); + return (string)$this->getServerVar('SERVER_PORT'); } /** diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index 1d6640917..20a0299e0 100755 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -25,6 +25,7 @@ /** * Class FacebookUrlManipulator + * * @package Facebook */ class FacebookUrlManipulator @@ -32,8 +33,8 @@ 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 $url The URL to filter. + * @param array $paramsToFilter The params to filter from the URL. * * @return string The URL with the params removed. */ @@ -68,8 +69,8 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) /** * Gracefully appends params to the URL. * - * @param string $url The URL that will receive the params. - * @param array $newParams The params to append to the URL. + * @param string $url The URL that will receive the params. + * @param array $newParams The params to append to the URL. * * @return string */ @@ -117,10 +118,11 @@ public static function getParamsAsArray($url) /** * Adds the params of the first URL to the second URL. + * * Any params that already exist in the second URL will go untouched. * * @param string $urlToStealFrom The URL harvest the params from. - * @param string $urlToAddTo The URL that will receive the new params. + * @param string $urlToAddTo The URL that will receive the new params. * * @return string The $urlToAddTo with any new params from $urlToStealFrom. */ @@ -160,10 +162,6 @@ public static function forceSlashPrefix($string) */ public static function baseGraphUrlEndpoint($urlToTrim) { - return '/' . preg_replace( - '/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', - '', - $urlToTrim - ); + return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); } } diff --git a/src/Facebook/Url/UrlDetectionInterface.php b/src/Facebook/Url/UrlDetectionInterface.php index e7323c030..764a606e0 100755 --- a/src/Facebook/Url/UrlDetectionInterface.php +++ b/src/Facebook/Url/UrlDetectionInterface.php @@ -25,11 +25,11 @@ /** * Interface UrlDetectionInterface + * * @package Facebook */ interface UrlDetectionInterface { - /** * Get the currently active URL. * diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 503e5ce94..9a707e816 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -29,42 +29,43 @@ */ if (version_compare(PHP_VERSION, '5.4.0', '<')) { - throw new Exception('The Facebook SDK v4 requires PHP version 5.4 or higher.'); + throw new Exception('The Facebook SDK v4 requires PHP version 5.4 or higher.'); } /** * Register the autoloader for the Facebook SDK classes. + * * Based off the official PSR-4 autoloader example found here: * https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md * * @param string $class The fully-qualified class name. + * * @return void */ -spl_autoload_register(function ($class) -{ - // project-specific namespace prefix - $prefix = '\Facebook\\'; +spl_autoload_register(function ($class) { + // project-specific namespace prefix + $prefix = '\Facebook\\'; - // base directory for the namespace prefix - $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/'; + // base directory for the namespace prefix + $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/'; - // does the class use the namespace prefix? - $len = strlen($prefix); - if (strncmp($prefix, $class, $len) !== 0) { - // no, move to the next registered autoloader - return; - } + // does the class use the namespace prefix? + $len = strlen($prefix); + if (strncmp($prefix, $class, $len) !== 0) { + // no, move to the next registered autoloader + return; + } - // get the relative class name - $relative_class = substr($class, $len); + // get the relative class name + $relative_class = substr($class, $len); - // replace the namespace prefix with the base directory, replace namespace - // separators with directory separators in the relative class name, append - // with .php - $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; + // replace the namespace prefix with the base directory, replace namespace + // separators with directory separators in the relative class name, append + // with .php + $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; - // if the file exists, require it - if (file_exists($file)) { - require $file; - } + // if the file exists, require it + if (file_exists($file)) { + require $file; + } }); diff --git a/tests/Authentication/AccessTokenTest.php b/tests/Authentication/AccessTokenTest.php index 92269e4ae..d66a5bac5 100644 --- a/tests/Authentication/AccessTokenTest.php +++ b/tests/Authentication/AccessTokenTest.php @@ -33,7 +33,7 @@ public function testAnAccessTokenCanBeReturnedAsAString() $accessToken = new AccessToken('foo_token'); $this->assertEquals('foo_token', $accessToken->getValue()); - $this->assertEquals('foo_token', (string) $accessToken); + $this->assertEquals('foo_token', (string)$accessToken); } public function testAnAppSecretProofWillBeProperlyGenerated() @@ -100,7 +100,7 @@ public function testAccessTokenCanBeSerialized() $newAccessToken = unserialize(serialize($accessToken)); - $this->assertEquals((string) $accessToken, (string) $newAccessToken); + $this->assertEquals((string)$accessToken, (string)$newAccessToken); $this->assertEquals($accessToken->getExpiresAt(), $newAccessToken->getExpiresAt()); } diff --git a/tests/FacebookAppTest.php b/tests/FacebookAppTest.php index 796a81cf0..d1b453dbc 100644 --- a/tests/FacebookAppTest.php +++ b/tests/FacebookAppTest.php @@ -27,42 +27,40 @@ class FacebookAppTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ + private $app; - /** - * @var FacebookApp - */ - private $app; + public function setUp() + { + $this->app = new FacebookApp('id', 'secret'); + } - public function setUp() - { - $this->app = new FacebookApp('id', 'secret'); - } + public function testGetId() + { + $this->assertEquals('id', $this->app->getId()); + } - public function testGetId() - { - $this->assertEquals('id', $this->app->getId()); - } + public function testGetSecret() + { + $this->assertEquals('secret', $this->app->getSecret()); + } - public function testGetSecret() - { - $this->assertEquals('secret', $this->app->getSecret()); - } + public function testAnAppAccessTokenCanBeGenerated() + { + $accessToken = $this->app->getAccessToken(); - public function testAnAppAccessTokenCanBeGenerated() - { - $accessToken = $this->app->getAccessToken(); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('id|secret', (string)$accessToken); + } - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); - $this->assertEquals('id|secret', (string) $accessToken); - } - - public function testSerialization() - { - $newApp = unserialize(serialize($this->app)); - - $this->assertInstanceOf('Facebook\FacebookApp', $newApp); - $this->assertEquals('id', $newApp->getId()); - $this->assertEquals('secret', $newApp->getSecret()); - } + public function testSerialization() + { + $newApp = unserialize(serialize($this->app)); + $this->assertInstanceOf('Facebook\FacebookApp', $newApp); + $this->assertEquals('id', $newApp->getId()); + $this->assertEquals('secret', $newApp->getSecret()); + } } diff --git a/tests/FacebookBatchRequestTest.php b/tests/FacebookBatchRequestTest.php index cffbd6eba..cef05863f 100755 --- a/tests/FacebookBatchRequestTest.php +++ b/tests/FacebookBatchRequestTest.php @@ -31,349 +31,351 @@ class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ + private $app; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + } + + public function testABatchRequestWillInstantiateWithTheProperProperties() + { + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token', 'v0.1337'); + + $this->assertSame($this->app, $batchRequest->getApp()); + $this->assertEquals('foo_token', $batchRequest->getAccessToken()); + $this->assertEquals('POST', $batchRequest->getMethod()); + $this->assertEquals('', $batchRequest->getEndpoint()); + $this->assertEquals('v0.1337', $batchRequest->getGraphVersion()); + } + + public function testEmptyRequestWillFallbackToBatchDefaults() + { + $request = new FacebookRequest(); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $this->app, 'foo_token'); + } + + public function testRequestWithTokenOnlyWillFallbackToBatchDefaults() + { + $request = new FacebookRequest(null, 'bar_token'); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $this->app, 'bar_token'); + } + + public function testRequestWithAppOnlyWillFallbackToBatchDefaults() + { + $customApp = new FacebookApp('1337', 'bar_secret'); + $request = new FacebookRequest($customApp); + + $this->createBatchRequest()->addFallbackDefaults($request); + + $this->assertRequestContainsAppAndToken($request, $customApp, 'foo_token'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testWillThrowWhenNoThereIsNoAppFallback() + { + $batchRequest = new FacebookBatchRequest(); + + $batchRequest->addFallbackDefaults(new FacebookRequest(null, 'foo_token')); + } - /** - * @var FacebookApp - */ - private $app; - - public function setUp() - { - $this->app = new FacebookApp('123', 'foo_secret'); - } + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testWillThrowWhenNoThereIsNoAccessTokenFallback() + { + $request = new FacebookBatchRequest(); + + $request->addFallbackDefaults(new FacebookRequest($this->app)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testAnInvalidTypeGivenToAddWillThrow() + { + $request = new FacebookBatchRequest(); + + $request->add('foo'); + } + + public function testAddingRequestsWillBeFormattedInAnArrayProperly() + { + $requests = [ + null => new FacebookRequest(null, null, 'GET', '/foo'), + 'my-second-request' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + 'my-third-request' => new FacebookRequest(null, null, 'DELETE', '/baz') + ]; + + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($requests[null]); + $batchRequest->add($requests['my-second-request'], 'my-second-request'); + $batchRequest->add($requests['my-third-request'], 'my-third-request'); + + $formattedRequests = $batchRequest->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + public function testANumericArrayOfRequestsCanBeAdded() + { + $requests = [ + new FacebookRequest(null, null, 'GET', '/foo'), + new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + public function testAnAssociativeArrayOfRequestsCanBeAdded() + { + $requests = [ + 'req-one' => new FacebookRequest(null, null, 'GET', '/foo'), + 'req-two' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + 'req-three' => new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } - public function testABatchRequestWillInstantiateWithTheProperProperties() - { - $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token', 'v0.1337'); - - $this->assertSame($this->app, $batchRequest->getApp()); - $this->assertEquals('foo_token', $batchRequest->getAccessToken()); - $this->assertEquals('POST', $batchRequest->getMethod()); - $this->assertEquals('', $batchRequest->getEndpoint()); - $this->assertEquals('v0.1337', $batchRequest->getGraphVersion()); - } - - public function testEmptyRequestWillFallbackToBatchDefaults() - { - $request = new FacebookRequest(); - - $this->createBatchRequest()->addFallbackDefaults($request); - - $this->assertRequestContainsAppAndToken($request, $this->app, 'foo_token'); - } - - public function testRequestWithTokenOnlyWillFallbackToBatchDefaults() - { - $request = new FacebookRequest(null, 'bar_token'); - - $this->createBatchRequest()->addFallbackDefaults($request); - - $this->assertRequestContainsAppAndToken($request, $this->app, 'bar_token'); - } - - public function testRequestWithAppOnlyWillFallbackToBatchDefaults() - { - $customApp = new FacebookApp('1337', 'bar_secret'); - $request = new FacebookRequest($customApp); - - $this->createBatchRequest()->addFallbackDefaults($request); - - $this->assertRequestContainsAppAndToken($request, $customApp, 'foo_token'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testWillThrowWhenNoThereIsNoAppFallback() - { - $batchRequest = new FacebookBatchRequest(); - - $batchRequest->addFallbackDefaults(new FacebookRequest(null, 'foo_token')); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testWillThrowWhenNoThereIsNoAccessTokenFallback() - { - $request = new FacebookBatchRequest(); - - $request->addFallbackDefaults(new FacebookRequest($this->app)); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testAnInvalidTypeGivenToAddWillThrow() - { - $request = new FacebookBatchRequest(); - - $request->add('foo'); - } - - public function testAddingRequestsWillBeFormattedInAnArrayProperly() - { - $requests = [ - null => new FacebookRequest(null, null, 'GET', '/foo'), - 'my-second-request' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), - 'my-third-request' => new FacebookRequest(null, null, 'DELETE', '/baz') - ]; - - $batchRequest = $this->createBatchRequest(); - $batchRequest->add($requests[null]); - $batchRequest->add($requests['my-second-request'], 'my-second-request'); - $batchRequest->add($requests['my-third-request'], 'my-third-request'); - - $formattedRequests = $batchRequest->getRequests(); - - $this->assertRequestsMatch($requests, $formattedRequests); - } - - public function testANumericArrayOfRequestsCanBeAdded() - { - $requests = [ - new FacebookRequest(null, null, 'GET', '/foo'), - new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), - new FacebookRequest(null, null, 'DELETE', '/baz'), - ]; - - $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); - - $this->assertRequestsMatch($requests, $formattedRequests); - } - - public function testAnAssociativeArrayOfRequestsCanBeAdded() - { - $requests = [ - 'req-one' => new FacebookRequest(null, null, 'GET', '/foo'), - 'req-two' => new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), - 'req-three' => new FacebookRequest(null, null, 'DELETE', '/baz'), - ]; - - $formattedRequests = $this->createBatchRequestWithRequests($requests)->getRequests(); - - $this->assertRequestsMatch($requests, $formattedRequests); - } - - public function testRequestsCanBeInjectedIntoConstructor() - { - $requests = [ - new FacebookRequest(null, null, 'GET', '/foo'), - new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), - new FacebookRequest(null, null, 'DELETE', '/baz'), - ]; - - $batchRequest = new FacebookBatchRequest($this->app, $requests, 'foo_token'); - $formattedRequests = $batchRequest->getRequests(); - - $this->assertRequestsMatch($requests, $formattedRequests); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAZeroRequestCountWithThrow() - { - $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token'); - - $batchRequest->validateBatchRequestCount(); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testMoreThanFiftyRequestsWillThrow() - { - $batchRequest = $this->createBatchRequest(); - - $this->createAndAppendRequestsTo($batchRequest, 51); - - $batchRequest->validateBatchRequestCount(); - } - - public function testLessOrEqualThanFiftyRequestsWillNotThrow() - { - $batchRequest = $this->createBatchRequest(); - - $this->createAndAppendRequestsTo($batchRequest, 50); - - $batchRequest->validateBatchRequestCount(); - } - - /** - * @dataProvider requestsAndExpectedResponsesProvider - */ - public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $expectedArray) - { - $batchRequest = $this->createBatchRequest(); - $batchRequest->add($request, 'foo_name'); - - $requests = $batchRequest->getRequests(); - $batchRequestArray = $batchRequest->requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); - - $this->assertEquals($expectedArray, $batchRequestArray); - } - - public function requestsAndExpectedResponsesProvider() - { - $headers = $this->defaultHeaders(); - $apiVersion = Facebook::DEFAULT_GRAPH_VERSION; - return [ - [ - new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), - [ - 'headers' => $headers, - 'method' => 'GET', - 'relative_url' => '/' . $apiVersion . '/foo?foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - 'name' => 'foo_name', - ], - ], - [ - new FacebookRequest(null, null, 'POST', '/bar', ['bar' => 'baz']), - [ - 'headers' => $headers, - 'method' => 'POST', - 'relative_url' => '/' . $apiVersion . '/bar', - 'body' => 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - 'name' => 'foo_name', - ], - ], - [ - new FacebookRequest(null, null, 'DELETE', '/bar'), - [ - 'headers' => $headers, - 'method' => 'DELETE', - 'relative_url' => '/' . $apiVersion . '/bar?access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - 'name' => 'foo_name', - ], - ], - ]; - } - - public function testBatchRequestsWithFilesGetConvertedToAnArray() - { - $request = new FacebookRequest(null, null, 'POST', '/bar', [ - 'message' => 'foobar', - 'source' => new FacebookFile(__DIR__ . '/foo.txt'), - ]); - - $batchRequest = $this->createBatchRequest(); - $batchRequest->add($request, 'foo_name'); - - $requests = $batchRequest->getRequests(); - - $attachedFiles = $requests[0]['attached_files']; - - $batchRequestArray = $batchRequest->requestEntityToBatchArray( - $requests[0]['request'], - $requests[0]['name'], - $attachedFiles); - - $this->assertEquals([ - 'headers' => $this->defaultHeaders(), - 'method' => 'POST', - 'relative_url' => '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar', - 'body' => 'message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - 'name' => 'foo_name', - 'attached_files' => $attachedFiles, - ], $batchRequestArray); - } - - public function testPreppingABatchRequestProperlySetsThePostParams() - { - $batchRequest = $this->createBatchRequest(); - $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); - $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar'])); - $batchRequest->prepareRequestsForBatch(); - - $params = $batchRequest->getParams(); - - $expectedHeaders = json_encode($this->defaultHeaders()); - $version = Facebook::DEFAULT_GRAPH_VERSION; - $expectedBatchParams = [ - 'batch' => '[{"headers":'.$expectedHeaders.',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' - .'{"headers":'.$expectedHeaders.',"method":"POST","relative_url":"\\/' . $version . '\\/bar","body":"foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9"}]', - 'include_headers' => true, - 'access_token' => 'foo_token', - 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - ]; - $this->assertEquals($expectedBatchParams, $params); - } - - public function testPreppingABatchRequestProperlyMovesTheFiles() - { - $batchRequest = $this->createBatchRequest(); - $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); - $batchRequest->add(new FacebookRequest(null, null, 'POST', '/me/photos', [ - 'message' => 'foobar', - 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + public function testRequestsCanBeInjectedIntoConstructor() + { + $requests = [ + new FacebookRequest(null, null, 'GET', '/foo'), + new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar']), + new FacebookRequest(null, null, 'DELETE', '/baz'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests, 'foo_token'); + $formattedRequests = $batchRequest->getRequests(); + + $this->assertRequestsMatch($requests, $formattedRequests); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAZeroRequestCountWithThrow() + { + $batchRequest = new FacebookBatchRequest($this->app, [], 'foo_token'); + + $batchRequest->validateBatchRequestCount(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testMoreThanFiftyRequestsWillThrow() + { + $batchRequest = $this->createBatchRequest(); + + $this->createAndAppendRequestsTo($batchRequest, 51); + + $batchRequest->validateBatchRequestCount(); + } + + public function testLessOrEqualThanFiftyRequestsWillNotThrow() + { + $batchRequest = $this->createBatchRequest(); + + $this->createAndAppendRequestsTo($batchRequest, 50); + + $batchRequest->validateBatchRequestCount(); + } + + /** + * @dataProvider requestsAndExpectedResponsesProvider + */ + public function testBatchRequestEntitiesProperlyGetConvertedToAnArray($request, $expectedArray) + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, 'foo_name'); + + $requests = $batchRequest->getRequests(); + $batchRequestArray = $batchRequest->requestEntityToBatchArray($requests[0]['request'], $requests[0]['name']); + + $this->assertEquals($expectedArray, $batchRequestArray); + } + + public function requestsAndExpectedResponsesProvider() + { + $headers = $this->defaultHeaders(); + $apiVersion = Facebook::DEFAULT_GRAPH_VERSION; + + return [ + [ + new FacebookRequest(null, null, 'GET', '/foo', ['foo' => 'bar']), + [ + 'headers' => $headers, + 'method' => 'GET', + 'relative_url' => '/' . $apiVersion . '/foo?foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + [ + new FacebookRequest(null, null, 'POST', '/bar', ['bar' => 'baz']), + [ + 'headers' => $headers, + 'method' => 'POST', + 'relative_url' => '/' . $apiVersion . '/bar', + 'body' => 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + [ + new FacebookRequest(null, null, 'DELETE', '/bar'), + [ + 'headers' => $headers, + 'method' => 'DELETE', + 'relative_url' => '/' . $apiVersion . '/bar?access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + ], + ], + ]; + } + + public function testBatchRequestsWithFilesGetConvertedToAnArray() + { + $request = new FacebookRequest(null, null, 'POST', '/bar', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + ]); + + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, 'foo_name'); + + $requests = $batchRequest->getRequests(); + + $attachedFiles = $requests[0]['attached_files']; + + $batchRequestArray = $batchRequest->requestEntityToBatchArray( + $requests[0]['request'], + $requests[0]['name'], + $attachedFiles + ); + + $this->assertEquals([ + 'headers' => $this->defaultHeaders(), + 'method' => 'POST', + 'relative_url' => '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar', + 'body' => 'message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + 'attached_files' => $attachedFiles, + ], $batchRequestArray); + } + + public function testPreppingABatchRequestProperlySetsThePostParams() + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/bar', ['foo' => 'bar'])); + $batchRequest->prepareRequestsForBatch(); + + $params = $batchRequest->getParams(); + + $expectedHeaders = json_encode($this->defaultHeaders()); + $version = Facebook::DEFAULT_GRAPH_VERSION; + $expectedBatchParams = [ + 'batch' => '[{"headers":' . $expectedHeaders . ',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' + . '{"headers":' . $expectedHeaders . ',"method":"POST","relative_url":"\\/' . $version . '\\/bar","body":"foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9"}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + + public function testPreppingABatchRequestProperlyMovesTheFiles() + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add(new FacebookRequest(null, 'bar_token', 'GET', '/foo'), 'foo_name'); + $batchRequest->add(new FacebookRequest(null, null, 'POST', '/me/photos', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), ])); - $batchRequest->prepareRequestsForBatch(); - - $params = $batchRequest->getParams(); - $files = $batchRequest->getFiles(); - - $attachedFiles = implode(',', array_keys($files)); - - $expectedHeaders = json_encode($this->defaultHeaders()); - $version = Facebook::DEFAULT_GRAPH_VERSION; - $expectedBatchParams = [ - 'batch' => '[{"headers":'.$expectedHeaders.',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' - .'{"headers":'.$expectedHeaders.',"method":"POST","relative_url":"\\/' . $version . '\\/me\\/photos","body":"message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9","attached_files":"' . $attachedFiles . '"}]', - 'include_headers' => true, - 'access_token' => 'foo_token', - 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - ]; - $this->assertEquals($expectedBatchParams, $params); - } - - private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) - { - $app = $request->getApp(); - $token = $request->getAccessToken(); - - $this->assertSame($expectedApp, $app); - $this->assertEquals($expectedToken, $token); - } - - private function defaultHeaders() - { - $headers = []; - foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { - $headers[] = $name . ': ' . $value; + $batchRequest->prepareRequestsForBatch(); + + $params = $batchRequest->getParams(); + $files = $batchRequest->getFiles(); + + $attachedFiles = implode(',', array_keys($files)); + + $expectedHeaders = json_encode($this->defaultHeaders()); + $version = Facebook::DEFAULT_GRAPH_VERSION; + $expectedBatchParams = [ + 'batch' => '[{"headers":' . $expectedHeaders . ',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=bar_token&appsecret_proof=2ceec40b7b9fd7d38fff1767b766bcc6b1f9feb378febac4612c156e6a8354bd","name":"foo_name"},' + . '{"headers":' . $expectedHeaders . ',"method":"POST","relative_url":"\\/' . $version . '\\/me\\/photos","body":"message=foobar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9","attached_files":"' . $attachedFiles . '"}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + + private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) + { + $app = $request->getApp(); + $token = $request->getAccessToken(); + + $this->assertSame($expectedApp, $app); + $this->assertEquals($expectedToken, $token); } - return $headers; - } - private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $number) - { - for ($i = 0; $i < $number; $i++) { - $batchRequest->add(new FacebookRequest()); + private function defaultHeaders() + { + $headers = []; + foreach (FacebookRequest::getDefaultHeaders() as $name => $value) { + $headers[] = $name . ': ' . $value; + } + + return $headers; } - } - - private function createBatchRequest() - { - return new FacebookBatchRequest($this->app, [], 'foo_token'); - } - - private function createBatchRequestWithRequests(array $requests) - { - $batchRequest = $this->createBatchRequest(); - $batchRequest->add($requests); - return $batchRequest; - } - - private function assertRequestsMatch($requests, $formattedRequests) - { - $expectedRequests = []; - foreach ($requests as $name => $request) { - $expectedRequests[] = [ - 'name' => $name, - 'request' => $request - ]; + + private function createAndAppendRequestsTo(FacebookBatchRequest $batchRequest, $number) + { + for ($i = 0; $i < $number; $i++) { + $batchRequest->add(new FacebookRequest()); + } + } + + private function createBatchRequest() + { + return new FacebookBatchRequest($this->app, [], 'foo_token'); } - $this->assertEquals($expectedRequests, $formattedRequests); - } + private function createBatchRequestWithRequests(array $requests) + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($requests); + + return $batchRequest; + } + + private function assertRequestsMatch($requests, $formattedRequests) + { + $expectedRequests = []; + foreach ($requests as $name => $request) { + $expectedRequests[] = [ + 'name' => $name, + 'request' => $request + ]; + } + $this->assertEquals($expectedRequests, $formattedRequests); + } } diff --git a/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index f7d8ea9eb..b633e25e5 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -31,110 +31,108 @@ class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase { - - /** - * @var \Facebook\FacebookApp - */ - protected $app; - - /** - * @var \Facebook\FacebookRequest - */ - protected $request; - - public function setUp() - { - $this->app = new FacebookApp('123', 'foo_secret'); - $this->request = new FacebookRequest( - $this->app, - 'foo_token', - 'POST', - '/', - ['batch' => 'foo'], - 'foo_eTag', - 'v1337'); - } - - public function testASuccessfulJsonBatchResponseWillBeDecoded() - { - $graphResponseJson = '['; - // Single Graph object. - $graphResponseJson .= '{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Last-Modified","value":"2013-12-24T00:34:20+0000"},{"name":"Facebook-API-Version","value":"v2.0"},{"name":"ETag","value":"\"fooTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"id\":\"123\",\"name\":\"Foo McBar\",\"updated_time\":\"2013-12-24T00:34:20+0000\",\"verified\":true}"}'; - // Paginated list of Graph objects. - $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Facebook-API-Version","value":"v1.0"},{"name":"ETag","value":"\"barTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"data\":[{\"id\":\"1337\",\"story\":\"Foo story.\"},{\"id\":\"1338\",\"story\":\"Bar story.\"}],\"paging\":{\"previous\":\"previous_url\",\"next\":\"next_url\"}}"}'; - // After POST operation. - $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"{\"id\":\"123_1337\"}"}'; - // After DELETE operation. - $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"true"}'; - $graphResponseJson .= ']'; - $response = new FacebookResponse($this->request, $graphResponseJson, 200); - $batchRequest = new FacebookBatchRequest($this->app, [ - new FacebookRequest($this->app, 'token'), - new FacebookRequest($this->app, 'token'), - new FacebookRequest($this->app, 'token'), - new FacebookRequest($this->app, 'token'), - ]); - $batchResponse = new FacebookBatchResponse($batchRequest, $response); - - $decodedResponses = $batchResponse->getResponses(); - - // Single Graph object. - $this->assertFalse($decodedResponses[0]->isError(), 'Did not expect Response to return an error for single Graph object.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[0]->getGraphObject()); - // Paginated list of Graph objects. - $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); - $graphList = $decodedResponses[1]->getGraphList(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[1]); - } - - - public function testABatchResponseCanBeIteratedOver() - { - $graphResponseJson = '['; - $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; - $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; - $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; - $graphResponseJson .= ']'; - $response = new FacebookResponse($this->request, $graphResponseJson, 200); - $batchRequest = new FacebookBatchRequest($this->app, [ - 'req_one' => new FacebookRequest($this->app, 'token'), - 'req_two' => new FacebookRequest($this->app, 'token'), - 'req_three' => new FacebookRequest($this->app, 'token'), - ]); - $batchResponse = new FacebookBatchResponse($batchRequest, $response); - - $this->assertInstanceOf('IteratorAggregate', $batchResponse); - - foreach ($batchResponse as $key => $responseEntity) { - $this->assertTrue(in_array($key, ['req_one', 'req_two', 'req_three'])); - $this->assertInstanceOf('Facebook\FacebookResponse', $responseEntity); + /** + * @var \Facebook\FacebookApp + */ + protected $app; + + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $this->app, + 'foo_token', + 'POST', + '/', + ['batch' => 'foo'], + 'foo_eTag', + 'v1337' + ); } - } - - public function testTheOriginalRequestCanBeObtainedForEachRequest() - { - $graphResponseJson = '['; - $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; - $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; - $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; - $graphResponseJson .= ']'; - $response = new FacebookResponse($this->request, $graphResponseJson, 200); - - $requests = [ - new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), - new FacebookRequest($this->app, 'foo_token_two', 'POST', '/you'), - new FacebookRequest($this->app, 'foo_token_three', 'DELETE', '/123456'), - ]; - $batchRequest = new FacebookBatchRequest($this->app, $requests); - $batchResponse = new FacebookBatchResponse($batchRequest, $response); + public function testASuccessfulJsonBatchResponseWillBeDecoded() + { + $graphResponseJson = '['; + // Single Graph object. + $graphResponseJson .= '{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Last-Modified","value":"2013-12-24T00:34:20+0000"},{"name":"Facebook-API-Version","value":"v2.0"},{"name":"ETag","value":"\"fooTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"id\":\"123\",\"name\":\"Foo McBar\",\"updated_time\":\"2013-12-24T00:34:20+0000\",\"verified\":true}"}'; + // Paginated list of Graph objects. + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Facebook-API-Version","value":"v1.0"},{"name":"ETag","value":"\"barTag\""},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Pragma","value":"no-cache"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"}],"body":"{\"data\":[{\"id\":\"1337\",\"story\":\"Foo story.\"},{\"id\":\"1338\",\"story\":\"Bar story.\"}],\"paging\":{\"previous\":\"previous_url\",\"next\":\"next_url\"}}"}'; + // After POST operation. + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"{\"id\":\"123_1337\"}"}'; + // After DELETE operation. + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Connection","value":"close"},{"name":"Expires","value":"Sat, 01 Jan 2000 00:00:00 GMT"},{"name":"Cache-Control","value":"private, no-cache, no-store, must-revalidate"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Pragma","value":"no-cache"},{"name":"Content-Type","value":"text\/javascript; charset=UTF-8"},{"name":"Facebook-API-Version","value":"v2.0"}],"body":"true"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, [ + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + new FacebookRequest($this->app, 'token'), + ]); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $decodedResponses = $batchResponse->getResponses(); + + // Single Graph object. + $this->assertFalse($decodedResponses[0]->isError(), 'Did not expect Response to return an error for single Graph object.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $decodedResponses[0]->getGraphObject()); + // Paginated list of Graph objects. + $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); + $graphList = $decodedResponses[1]->getGraphList(); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[1]); + } - $this->assertInstanceOf('Facebook\FacebookResponse', $batchResponse[0]); - $this->assertInstanceOf('Facebook\FacebookRequest', $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()); - } + public function testABatchResponseCanBeIteratedOver() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + $batchRequest = new FacebookBatchRequest($this->app, [ + 'req_one' => new FacebookRequest($this->app, 'token'), + 'req_two' => new FacebookRequest($this->app, 'token'), + 'req_three' => new FacebookRequest($this->app, 'token'), + ]); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertInstanceOf('IteratorAggregate', $batchResponse); + + foreach ($batchResponse as $key => $responseEntity) { + $this->assertTrue(in_array($key, ['req_one', 'req_two', 'req_three'])); + $this->assertInstanceOf('Facebook\FacebookResponse', $responseEntity); + } + } + public function testTheOriginalRequestCanBeObtainedForEachRequest() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $requests = [ + new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), + new FacebookRequest($this->app, 'foo_token_two', 'POST', '/you'), + new FacebookRequest($this->app, 'foo_token_three', 'DELETE', '/123456'), + ]; + + $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->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 e31819719..bd2ce2ae4 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -40,264 +40,269 @@ class MyFooClientHandler implements FacebookHttpClientInterface { - public function send($url, $method, $body, array $headers, $timeOut) { - return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", - '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' - ); - } + public function send($url, $method, $body, array $headers, $timeOut) + { + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' + ); + } } class MyFooBatchClientHandler implements FacebookHttpClientInterface { - public function send($url, $method, $body, array $headers, $timeOut) { - return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", - '[{"code":"123","body":"Foo"},{"code":"1337","body":"Bar"}]' - ); - } + public function send($url, $method, $body, array $headers, $timeOut) + { + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '[{"code":"123","body":"Foo"},{"code":"1337","body":"Bar"}]' + ); + } } class FacebookClientTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookApp + */ + public $fbApp; + + /** + * @var FacebookClient + */ + public $fbClient; + + /** + * @var FacebookApp + */ + public static $testFacebookApp; + + /** + * @var FacebookClient + */ + public static $testFacebookClient; + + public function setUp() + { + $this->fbApp = new FacebookApp('id', 'shhhh!'); + $this->fbClient = new FacebookClient(new MyFooClientHandler()); + } + + public function testACustomHttpClientCanBeInjected() + { + $handler = new MyFooClientHandler(); + $client = new FacebookClient($handler); + $httpHandler = $client->getHttpClientHandler(); + + $this->assertInstanceOf('Facebook\Tests\MyFooClientHandler', $httpHandler); + } + + public function testTheHttpClientWillFallbackToDefault() + { + $client = new FacebookClient(); + $httpHandler = $client->getHttpClientHandler(); + + if (function_exists('curl_init')) { + $this->assertInstanceOf('Facebook\HttpClients\FacebookCurlHttpClient', $httpHandler); + } else { + $this->assertInstanceOf('Facebook\HttpClients\FacebookStreamHttpClient', $httpHandler); + } + } + + public function testBetaModeCanBeDisabledOrEnabledViaConstructor() + { + $client = new FacebookClient(null, false); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); + + $client = new FacebookClient(null, true); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); + } + + public function testBetaModeCanBeDisabledOrEnabledViaMethod() + { + $client = new FacebookClient(); + $client->enableBetaMode(false); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); + + $client->enableBetaMode(true); + $url = $client->getBaseGraphUrl(); + $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); + } + + public function testGraphVideoUrlCanBeSet() + { + $client = new FacebookClient(); + $client->enableBetaMode(false); + $url = $client->getBaseGraphUrl($postToVideoUrl = true); + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL, $url); - /** - * @var FacebookApp - */ - public $fbApp; - - /** - * @var FacebookClient - */ - public $fbClient; - - /** - * @var FacebookApp - */ - public static $testFacebookApp; - - /** - * @var FacebookClient - */ - public static $testFacebookClient; - - public function setUp() - { - $this->fbApp = new FacebookApp('id', 'shhhh!'); - $this->fbClient = new FacebookClient(new MyFooClientHandler()); - } - - public function testACustomHttpClientCanBeInjected() - { - $handler = new MyFooClientHandler(); - $client = new FacebookClient($handler); - $httpHandler = $client->getHttpClientHandler(); - - $this->assertInstanceOf('Facebook\Tests\MyFooClientHandler', $httpHandler); - } - - public function testTheHttpClientWillFallbackToDefault() - { - $client = new FacebookClient(); - $httpHandler = $client->getHttpClientHandler(); - - if (function_exists('curl_init')) { - $this->assertInstanceOf('Facebook\HttpClients\FacebookCurlHttpClient', $httpHandler); - } else { - $this->assertInstanceOf('Facebook\HttpClients\FacebookStreamHttpClient', $httpHandler); + $client->enableBetaMode(true); + $url = $client->getBaseGraphUrl($postToVideoUrl = true); + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL_BETA, $url); } - } - - public function testBetaModeCanBeDisabledOrEnabledViaConstructor() - { - $client = new FacebookClient(null, false); - $url = $client->getBaseGraphUrl(); - $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); - - $client = new FacebookClient(null, true); - $url = $client->getBaseGraphUrl(); - $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); - } - - public function testBetaModeCanBeDisabledOrEnabledViaMethod() - { - $client = new FacebookClient(); - $client->enableBetaMode(false); - $url = $client->getBaseGraphUrl(); - $this->assertEquals(FacebookClient::BASE_GRAPH_URL, $url); - - $client->enableBetaMode(true); - $url = $client->getBaseGraphUrl(); - $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, $url); - } - - public function testGraphVideoUrlCanBeSet() - { - $client = new FacebookClient(); - $client->enableBetaMode(false); - $url = $client->getBaseGraphUrl($postToVideoUrl = true); - $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL, $url); - - $client->enableBetaMode(true); - $url = $client->getBaseGraphUrl($postToVideoUrl = true); - $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL_BETA, $url); - } - - public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() - { - $fbRequest = new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'); - $response = $this->fbClient->sendRequest($fbRequest); - - $this->assertInstanceOf('Facebook\FacebookResponse', $response); - $this->assertEquals(200, $response->getHttpStatusCode()); - $this->assertEquals('{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}', $response->getBody()); - } - - public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() - { - $fbRequests = [ - new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'), - new FacebookRequest($this->fbApp, 'token', 'POST', '/bar'), - ]; - $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); - - $fbBatchClient = new FacebookClient(new MyFooBatchClientHandler()); - $response = $fbBatchClient->sendBatchRequest($fbBatchRequest); - - $this->assertInstanceOf('Facebook\FacebookBatchResponse', $response); - $this->assertEquals('GET', $response[0]->getRequest()->getMethod()); - $this->assertEquals('POST', $response[1]->getRequest()->getMethod()); - } - - public function testAFacebookBatchRequestWillProperlyBatchFiles() - { - $fbRequests = [ - new FacebookRequest($this->fbApp, 'token', 'POST', '/photo', [ - 'message' => 'foobar', - 'source' => new FacebookFile(__DIR__ . '/foo.txt'), - ]), - new FacebookRequest($this->fbApp, 'token', 'POST', '/video', [ - 'message' => 'foobar', - 'source' => new FacebookVideo(__DIR__ . '/foo.txt'), - ]), - ]; - $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); - $fbBatchRequest->prepareRequestsForBatch(); - - list($url, $method, $headers, $body) = $this->fbClient->prepareRequestMessage($fbBatchRequest); - - $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL . '/' . Facebook::DEFAULT_GRAPH_VERSION, $url); - $this->assertEquals('POST', $method); - $this->assertContains('multipart/form-data; boundary=', $headers['Content-Type']); - $this->assertContains('Content-Disposition: form-data; name="batch"', $body); - $this->assertContains('Content-Disposition: form-data; name="include_headers"', $body); - $this->assertContains('"name":0,"attached_files":', $body); - $this->assertContains('"name":1,"attached_files":', $body); - $this->assertContains('"; filename="foo.txt"', $body); - } - - public function testARequestOfParamsWillBeUrlEncoded() - { - $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['foo' => 'bar']); - $response = $this->fbClient->sendRequest($fbRequest); - - $headersSent = $response->getRequest()->getHeaders(); - - $this->assertEquals('application/x-www-form-urlencoded', $headersSent['Content-Type']); - } - - public function testARequestWithFilesWillBeMultipart() - { - $myFile = new FacebookFile(__DIR__ . '/foo.txt'); - $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['file' => $myFile]); - $response = $this->fbClient->sendRequest($fbRequest); - - $headersSent = $response->getRequest()->getHeaders(); - - $this->assertContains('multipart/form-data; boundary=', $headersSent['Content-Type']); - } - - /** - * @group integration - */ - public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() - { - $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)->getGraphObject(); - - $testUserId = $response->getProperty('id'); - $testUserAccessToken = $response->getProperty('access_token'); - - // Get the test user's profile - $request = new FacebookRequest( - static::$testFacebookApp, - $testUserAccessToken, - 'GET', - '/me'); - $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); - - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); - $this->assertNotNull($graphObject->getProperty('id')); - $this->assertEquals('Foo Phpunit User', $graphObject->getProperty('name')); - - // Delete test user - $request = new FacebookRequest( - static::$testFacebookApp, - static::$testFacebookApp->getAccessToken(), - 'DELETE', - '/' . $testUserId); - $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); - - $this->assertTrue($graphObject->getProperty('success')); - } - - public function initializeTestApp() - { - if (!file_exists(__DIR__ . '/FacebookTestCredentials.php')) { - throw new FacebookSDKException( - 'You must create a FacebookTestCredentials.php file from FacebookTestCredentials.php.dist' - ); + + public function testAFacebookRequestEntityCanBeUsedToSendARequestToGraph() + { + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'); + $response = $this->fbClient->sendRequest($fbRequest); + + $this->assertInstanceOf('Facebook\FacebookResponse', $response); + $this->assertEquals(200, $response->getHttpStatusCode()); + $this->assertEquals('{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}', $response->getBody()); + } + + public function testAFacebookBatchRequestEntityCanBeUsedToSendABatchRequestToGraph() + { + $fbRequests = [ + new FacebookRequest($this->fbApp, 'token', 'GET', '/foo'), + new FacebookRequest($this->fbApp, 'token', 'POST', '/bar'), + ]; + $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); + + $fbBatchClient = new FacebookClient(new MyFooBatchClientHandler()); + $response = $fbBatchClient->sendBatchRequest($fbBatchRequest); + + $this->assertInstanceOf('Facebook\FacebookBatchResponse', $response); + $this->assertEquals('GET', $response[0]->getRequest()->getMethod()); + $this->assertEquals('POST', $response[1]->getRequest()->getMethod()); } - if (!strlen(FacebookTestCredentials::$appId) || - !strlen(FacebookTestCredentials::$appSecret)) { - throw new FacebookSDKException( - 'You must fill out FacebookTestCredentials.php' - ); + public function testAFacebookBatchRequestWillProperlyBatchFiles() + { + $fbRequests = [ + new FacebookRequest($this->fbApp, 'token', 'POST', '/photo', [ + 'message' => 'foobar', + 'source' => new FacebookFile(__DIR__ . '/foo.txt'), + ]), + new FacebookRequest($this->fbApp, 'token', 'POST', '/video', [ + 'message' => 'foobar', + 'source' => new FacebookVideo(__DIR__ . '/foo.txt'), + ]), + ]; + $fbBatchRequest = new FacebookBatchRequest($this->fbApp, $fbRequests); + $fbBatchRequest->prepareRequestsForBatch(); + + list($url, $method, $headers, $body) = $this->fbClient->prepareRequestMessage($fbBatchRequest); + + $this->assertEquals(FacebookClient::BASE_GRAPH_VIDEO_URL . '/' . Facebook::DEFAULT_GRAPH_VERSION, $url); + $this->assertEquals('POST', $method); + $this->assertContains('multipart/form-data; boundary=', $headers['Content-Type']); + $this->assertContains('Content-Disposition: form-data; name="batch"', $body); + $this->assertContains('Content-Disposition: form-data; name="include_headers"', $body); + $this->assertContains('"name":0,"attached_files":', $body); + $this->assertContains('"name":1,"attached_files":', $body); + $this->assertContains('"; filename="foo.txt"', $body); } - static::$testFacebookApp = new FacebookApp( - FacebookTestCredentials::$appId, FacebookTestCredentials::$appSecret - ); - // Use default client - $client = null; + public function testARequestOfParamsWillBeUrlEncoded() + { + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['foo' => 'bar']); + $response = $this->fbClient->sendRequest($fbRequest); + + $headersSent = $response->getRequest()->getHeaders(); - // Uncomment to enable curl implementation. - //$client = new FacebookCurlHttpClient(); + $this->assertEquals('application/x-www-form-urlencoded', $headersSent['Content-Type']); + } - // Uncomment to enable stream wrapper implementation. - //$client = new FacebookStreamHttpClient(); + public function testARequestWithFilesWillBeMultipart() + { + $myFile = new FacebookFile(__DIR__ . '/foo.txt'); + $fbRequest = new FacebookRequest($this->fbApp, 'token', 'POST', '/foo', ['file' => $myFile]); + $response = $this->fbClient->sendRequest($fbRequest); - // Uncomment to enable Guzzle implementation. - //$client = new FacebookGuzzleHttpClient(); + $headersSent = $response->getRequest()->getHeaders(); - static::$testFacebookClient = new FacebookClient($client); - } + $this->assertContains('multipart/form-data; boundary=', $headersSent['Content-Type']); + } + /** + * @group integration + */ + public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() + { + $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)->getGraphObject(); + + $testUserId = $response->getProperty('id'); + $testUserAccessToken = $response->getProperty('access_token'); + + // Get the test user's profile + $request = new FacebookRequest( + static::$testFacebookApp, + $testUserAccessToken, + 'GET', + '/me' + ); + $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertNotNull($graphObject->getProperty('id')); + $this->assertEquals('Foo Phpunit User', $graphObject->getProperty('name')); + + // Delete test user + $request = new FacebookRequest( + static::$testFacebookApp, + static::$testFacebookApp->getAccessToken(), + 'DELETE', + '/' . $testUserId + ); + $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + + $this->assertTrue($graphObject->getProperty('success')); + } + + public function initializeTestApp() + { + 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 39ccd521a..fdea644f9 100755 --- a/tests/FacebookRequestTest.php +++ b/tests/FacebookRequestTest.php @@ -31,179 +31,177 @@ class FacebookRequestTest extends \PHPUnit_Framework_TestCase { - - public function testAnEmptyRequestEntityCanInstantiate() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app); - - $this->assertInstanceOf('Facebook\FacebookRequest', $request); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAMissingAccessTokenWillThrow() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app); - - $request->validateAccessToken(); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAMissingMethodWillThrow() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app); - - $request->validateMethod(); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAnInvalidMethodWillThrow() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app, 'foo_token', 'FOO'); - - $request->validateMethod(); - } - - public function testGetHeadersWillAutoAppendETag() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app, null, 'GET', '/foo', [], 'fooETag'); - - $headers = $request->getHeaders(); - - $expectedHeaders = FacebookRequest::getDefaultHeaders(); - $expectedHeaders['If-None-Match'] = 'fooETag'; - - $this->assertEquals($expectedHeaders, $headers); - } - - public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo', ['foo' => 'bar']); - - $params = $request->getParams(); - - $this->assertEquals([ - 'foo' => 'bar', - 'access_token' => 'foo_token', - 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - ], $params); - } - - public function testAnAccessTokenCanBeSetFromTheParams() - { - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app, null, 'POST', '/me', ['access_token' => 'bar_token']); - - $accessToken = $request->getAccessToken(); - - $this->assertEquals('bar_token', $accessToken); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAccessTokenConflictsWillThrow() - { - $app = new FacebookApp('123', 'foo_secret'); - new FacebookRequest($app, 'foo_token', 'POST', '/me', ['access_token' => 'bar_token']); - } - - public function testAProperUrlWillBeGenerated() - { - $app = new FacebookApp('123', 'foo_secret'); - $getRequest = new FacebookRequest($app, 'foo_token', 'GET', '/foo', ['foo' => 'bar']); - - $getUrl = $getRequest->getUrl(); - $expectedParams = 'foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; - $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; - - $this->assertEquals($expectedUrl, $getUrl); - - $postRequest = new FacebookRequest($app, 'foo_token', 'POST', '/bar', ['foo' => 'bar']); - - $postUrl = $postRequest->getUrl(); - $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar'; - - $this->assertEquals($expectedUrl, $postUrl); - } - - public function testAuthenticationParamsAreStrippedAndReapplied() - { - $app = new FacebookApp('123', 'foo_secret'); - - $request = new FacebookRequest( - $app, - $accessToken = 'foo_token', - $method = 'GET', - $endpoint = '/foo', - $params = [ - 'access_token' => 'foo_token', - 'appsecret_proof' => 'bar_app_secret', - 'bar' => 'baz', - ] - ); - - $url = $request->getUrl(); - - $expectedParams = 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; - $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; - $this->assertEquals($expectedUrl, $url); - - $params = $request->getParams(); - - $expectedParams = [ - 'access_token' => 'foo_token', - 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', - 'bar' => 'baz', - ]; - $this->assertEquals($expectedParams, $params); - } - - public function testAFileCanBeAddedToParams() - { - $myFile = new FacebookFile(__DIR__ . '/foo.txt'); - $params = [ - 'name' => 'Foo Bar', - 'source' => $myFile, - ]; - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/photos', $params); - - $actualParams = $request->getParams(); - - $this->assertTrue($request->containsFileUploads()); - $this->assertFalse($request->containsVideoUploads()); - $this->assertTrue( ! isset($actualParams['source'])); - $this->assertEquals('Foo Bar', $actualParams['name']); - } - - public function testAVideoCanBeAddedToParams() - { - $myFile = new FacebookVideo(__DIR__ . '/foo.txt'); - $params = [ - 'name' => 'Foo Bar', - 'source' => $myFile, - ]; - $app = new FacebookApp('123', 'foo_secret'); - $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/videos', $params); - - $actualParams = $request->getParams(); - - $this->assertTrue($request->containsFileUploads()); - $this->assertTrue($request->containsVideoUploads()); - $this->assertTrue( ! isset($actualParams['source'])); - $this->assertEquals('Foo Bar', $actualParams['name']); - } - + public function testAnEmptyRequestEntityCanInstantiate() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $this->assertInstanceOf('Facebook\FacebookRequest', $request); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAMissingAccessTokenWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $request->validateAccessToken(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAMissingMethodWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app); + + $request->validateMethod(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnInvalidMethodWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'FOO'); + + $request->validateMethod(); + } + + public function testGetHeadersWillAutoAppendETag() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'GET', '/foo', [], 'fooETag'); + + $headers = $request->getHeaders(); + + $expectedHeaders = FacebookRequest::getDefaultHeaders(); + $expectedHeaders['If-None-Match'] = 'fooETag'; + + $this->assertEquals($expectedHeaders, $headers); + } + + public function testGetParamsWillAutoAppendAccessTokenAndAppSecretProof() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo', ['foo' => 'bar']); + + $params = $request->getParams(); + + $this->assertEquals([ + 'foo' => 'bar', + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ], $params); + } + + public function testAnAccessTokenCanBeSetFromTheParams() + { + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, null, 'POST', '/me', ['access_token' => 'bar_token']); + + $accessToken = $request->getAccessToken(); + + $this->assertEquals('bar_token', $accessToken); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAccessTokenConflictsWillThrow() + { + $app = new FacebookApp('123', 'foo_secret'); + new FacebookRequest($app, 'foo_token', 'POST', '/me', ['access_token' => 'bar_token']); + } + + public function testAProperUrlWillBeGenerated() + { + $app = new FacebookApp('123', 'foo_secret'); + $getRequest = new FacebookRequest($app, 'foo_token', 'GET', '/foo', ['foo' => 'bar']); + + $getUrl = $getRequest->getUrl(); + $expectedParams = 'foo=bar&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; + + $this->assertEquals($expectedUrl, $getUrl); + + $postRequest = new FacebookRequest($app, 'foo_token', 'POST', '/bar', ['foo' => 'bar']); + + $postUrl = $postRequest->getUrl(); + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar'; + + $this->assertEquals($expectedUrl, $postUrl); + } + + public function testAuthenticationParamsAreStrippedAndReapplied() + { + $app = new FacebookApp('123', 'foo_secret'); + + $request = new FacebookRequest( + $app, + $accessToken = 'foo_token', + $method = 'GET', + $endpoint = '/foo', + $params = [ + 'access_token' => 'foo_token', + 'appsecret_proof' => 'bar_app_secret', + 'bar' => 'baz', + ] + ); + + $url = $request->getUrl(); + + $expectedParams = 'bar=baz&access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9'; + $expectedUrl = '/' . Facebook::DEFAULT_GRAPH_VERSION . '/foo?' . $expectedParams; + $this->assertEquals($expectedUrl, $url); + + $params = $request->getParams(); + + $expectedParams = [ + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'bar' => 'baz', + ]; + $this->assertEquals($expectedParams, $params); + } + + public function testAFileCanBeAddedToParams() + { + $myFile = new FacebookFile(__DIR__ . '/foo.txt'); + $params = [ + 'name' => 'Foo Bar', + 'source' => $myFile, + ]; + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/photos', $params); + + $actualParams = $request->getParams(); + + $this->assertTrue($request->containsFileUploads()); + $this->assertFalse($request->containsVideoUploads()); + $this->assertTrue(!isset($actualParams['source'])); + $this->assertEquals('Foo Bar', $actualParams['name']); + } + + public function testAVideoCanBeAddedToParams() + { + $myFile = new FacebookVideo(__DIR__ . '/foo.txt'); + $params = [ + 'name' => 'Foo Bar', + 'source' => $myFile, + ]; + $app = new FacebookApp('123', 'foo_secret'); + $request = new FacebookRequest($app, 'foo_token', 'POST', '/foo/videos', $params); + + $actualParams = $request->getParams(); + + $this->assertTrue($request->containsFileUploads()); + $this->assertTrue($request->containsVideoUploads()); + $this->assertTrue(!isset($actualParams['source'])); + $this->assertEquals('Foo Bar', $actualParams['name']); + } } diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index cdc98f88a..eece6d8d9 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -29,94 +29,93 @@ class FacebookResponseTest extends \PHPUnit_Framework_TestCase { - - /** - * @var \Facebook\FacebookRequest - */ - protected $request; - - public function setUp() - { - $app = new FacebookApp('123', 'foo_secret'); - $this->request = new FacebookRequest( - $app, - 'foo_token', - 'GET', - '/me/photos?keep=me', - ['foo' => 'bar'], - 'foo_eTag', - 'v1337'); - } - - public function testAnETagCanBeProperlyAccessed() - { - $response = new FacebookResponse($this->request, '', 200, ['ETag' => 'foo_tag']); - - $eTag = $response->getETag(); - - $this->assertEquals('foo_tag', $eTag); - } - - public function testAProperAppSecretProofCanBeGenerated() - { - $response = new FacebookResponse($this->request); - - $appSecretProof = $response->getAppSecretProof(); - - $this->assertEquals('df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', $appSecretProof); - } - - public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() - { - $graphResponseJson = '{"id":"123","name":"Foo"}'; - $response = new FacebookResponse($this->request, $graphResponseJson, 200); - - $decodedResponse = $response->getDecodedBody(); - $graphObject = $response->getGraphObject(); - - $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertEquals([ - 'id' => '123', - 'name' => 'Foo', - ], $decodedResponse); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); - } - - public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() - { - $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; - $response = new FacebookResponse($this->request, $graphResponseJson, 200); - - $graphObjectList = $response->getGraphList(); - - $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[1]); - } - - public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() - { - $graphResponseKeyValuePairs = 'id=123&name=Foo'; - $response = new FacebookResponse($this->request, $graphResponseKeyValuePairs, 200); - - $decodedResponse = $response->getDecodedBody(); - - $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertEquals([ - 'id' => '123', - 'name' => 'Foo', - ], $decodedResponse); - } - - public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() - { - $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; - $response = new FacebookResponse($this->request, $graphResponse, 401); - - $exception = $response->getThrownException(); - - $this->assertTrue($response->isError(), 'Expected Response to return an error.'); - $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $exception); - } - + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } + + public function testAnETagCanBeProperlyAccessed() + { + $response = new FacebookResponse($this->request, '', 200, ['ETag' => 'foo_tag']); + + $eTag = $response->getETag(); + + $this->assertEquals('foo_tag', $eTag); + } + + public function testAProperAppSecretProofCanBeGenerated() + { + $response = new FacebookResponse($this->request); + + $appSecretProof = $response->getAppSecretProof(); + + $this->assertEquals('df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', $appSecretProof); + } + + public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() + { + $graphResponseJson = '{"id":"123","name":"Foo"}'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $decodedResponse = $response->getDecodedBody(); + $graphObject = $response->getGraphObject(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo', + ], $decodedResponse); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + } + + public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() + { + $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $graphObjectList = $response->getGraphList(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[1]); + } + + public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() + { + $graphResponseKeyValuePairs = 'id=123&name=Foo'; + $response = new FacebookResponse($this->request, $graphResponseKeyValuePairs, 200); + + $decodedResponse = $response->getDecodedBody(); + + $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); + $this->assertEquals([ + 'id' => '123', + 'name' => 'Foo', + ], $decodedResponse); + } + + public function testErrorStatusCanBeCheckedWhenAnErrorResponseIsReturned() + { + $graphResponse = '{"error":{"message":"Foo error.","type":"OAuthException","code":190,"error_subcode":463}}'; + $response = new FacebookResponse($this->request, $graphResponse, 401); + + $exception = $response->getThrownException(); + + $this->assertTrue($response->isError(), 'Expected Response to return an error.'); + $this->assertInstanceOf('Facebook\Exceptions\FacebookResponseException', $exception); + } } diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 215d6df2c..160af574e 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -36,312 +36,346 @@ class FooClientInterface implements FacebookHttpClientInterface { - public function send($url, $method, $body, array $headers, $timeOut) { - return new GraphRawResponse( - "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", - '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' - ); - } + public function send($url, $method, $body, array $headers, $timeOut) + { + return new GraphRawResponse( + "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", + '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' + ); + } } class FooPersistentDataInterface implements PersistentDataInterface { - public function get($key) { return 'foo'; } - public function set($key, $value) {} + public function get($key) + { + return 'foo'; + } + + public function set($key, $value) + { + } } class FooUrlDetectionInterface implements UrlDetectionInterface { - public function getCurrentUrl() { return 'https://foo.bar'; } + public function getCurrentUrl() + { + return 'https://foo.bar'; + } } class FooBarPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { - public function getPseudoRandomString($length) { - return 'csprs123'; - } + public function getPseudoRandomString($length) + { + return 'csprs123'; + } } class FacebookTest extends \PHPUnit_Framework_TestCase { - - protected $config = [ - 'app_id' => '1337', - 'app_secret' => 'foo_secret', - ]; - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testInstantiatingWithoutAppIdThrows() - { - // unset value so there is no fallback to test expected Exception - putenv(Facebook::APP_ID_ENV_NAME.'='); - $config = [ - 'app_secret' => 'foo_secret', - ]; - $fb = new Facebook($config); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testInstantiatingWithoutAppSecretThrows() - { - // unset value so there is no fallback to test expected Exception - putenv(Facebook::APP_SECRET_ENV_NAME.'='); - $config = [ - 'app_id' => 'foo_id', + protected $config = [ + 'app_id' => '1337', + 'app_secret' => 'foo_secret', ]; - $fb = new Facebook($config); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSettingAnInvalidHttpClientHandlerThrows() - { - $config = array_merge($this->config, [ - 'http_client_handler' => 'foo_handler', - ]); - $fb = new Facebook($config); - } - - public function testCurlHttpClientHandlerCanBeForced() - { - $config = array_merge($this->config, [ - 'http_client_handler' => 'curl' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\HttpClients\FacebookCurlHttpClient', - $fb->getClient()->getHttpClientHandler()); - } - - public function testStreamHttpClientHandlerCanBeForced() - { - $config = array_merge($this->config, [ - 'http_client_handler' => 'stream' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\HttpClients\FacebookStreamHttpClient', - $fb->getClient()->getHttpClientHandler()); - } - - public function testGuzzleHttpClientHandlerCanBeForced() - { - $config = array_merge($this->config, [ - 'http_client_handler' => 'guzzle' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\HttpClients\FacebookGuzzleHttpClient', - $fb->getClient()->getHttpClientHandler()); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSettingAnInvalidPersistentDataHandlerThrows() - { - $config = array_merge($this->config, [ - 'persistent_data_handler' => 'foo_handler', - ]); - $fb = new Facebook($config); - } - - public function testPersistentDataHandlerCanBeForced() - { - $config = array_merge($this->config, [ - 'persistent_data_handler' => 'memory' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\PersistentData\FacebookMemoryPersistentDataHandler', - $fb->getRedirectLoginHelper()->getPersistentDataHandler()); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSettingAnInvalidUrlHandlerThrows() - { - $config = array_merge($this->config, [ - 'url_detection_handler' => 'foo_handler', - ]); - $fb = new Facebook($config); - } - - public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() - { - $fb = new Facebook($this->config); - $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); - } - - public function testAnAccessTokenCanBeSetAsAString() - { - $fb = new Facebook($this->config); - $fb->setDefaultAccessToken('foo_token'); - $accessToken = $fb->getDefaultAccessToken(); - - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); - $this->assertEquals('foo_token', (string) $accessToken); - } - - public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() - { - $fb = new Facebook($this->config); - $fb->setDefaultAccessToken(new AccessToken('bar_token')); - $accessToken = $fb->getDefaultAccessToken(); - - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); - $this->assertEquals('bar_token', (string) $accessToken); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSettingAnInvalidPseudoRandomStringGeneratorThrows() - { - $config = array_merge($this->config, [ - 'pseudo_random_string_generator' => 'foo_generator', - ]); - new Facebook($config); - } - - public function testMcryptCsprgCanBeForced() - { - if ( ! function_exists('mcrypt_create_iv')) { - $this->markTestSkipped( - 'Mcrypt must be installed to test mcrypt_create_iv().' - ); + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInstantiatingWithoutAppIdThrows() + { + // unset value so there is no fallback to test expected Exception + putenv(Facebook::APP_ID_ENV_NAME.'='); + $config = [ + 'app_secret' => 'foo_secret', + ]; + $fb = new Facebook($config); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInstantiatingWithoutAppSecretThrows() + { + // unset value so there is no fallback to test expected Exception + putenv(Facebook::APP_SECRET_ENV_NAME.'='); + $config = [ + 'app_id' => 'foo_id', + ]; + $fb = new Facebook($config); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidHttpClientHandlerThrows() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); + } + + public function testCurlHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'curl' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\HttpClients\FacebookCurlHttpClient', + $fb->getClient()->getHttpClientHandler() + ); + } + + public function testStreamHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'stream' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\HttpClients\FacebookStreamHttpClient', + $fb->getClient()->getHttpClientHandler() + ); + } + + public function testGuzzleHttpClientHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'http_client_handler' => 'guzzle' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\HttpClients\FacebookGuzzleHttpClient', + $fb->getClient()->getHttpClientHandler() + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidPersistentDataHandlerThrows() + { + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); } - $config = array_merge($this->config, [ - 'persistent_data_handler' => 'memory', // To keep session errors from happening - 'pseudo_random_string_generator' => 'mcrypt' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator', - $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); - } - - public function testOpenSslCsprgCanBeForced() - { - if ( ! function_exists('openssl_random_pseudo_bytes')) { - $this->markTestSkipped( - 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' - ); + public function testPersistentDataHandlerCanBeForced() + { + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PersistentData\FacebookMemoryPersistentDataHandler', + $fb->getRedirectLoginHelper()->getPersistentDataHandler() + ); } - $config = array_merge($this->config, [ - 'persistent_data_handler' => 'memory', // To keep session errors from happening - 'pseudo_random_string_generator' => 'openssl' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator', - $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); - } - - public function testUrandomCsprgCanBeForced() - { - if (ini_get('open_basedir')) { - $this->markTestSkipped( - 'Cannot test /dev/urandom generator due to open_basedir constraint.' - ); + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidUrlHandlerThrows() + { + $config = array_merge($this->config, [ + 'url_detection_handler' => 'foo_handler', + ]); + $fb = new Facebook($config); } - if ( ! is_readable('/dev/urandom')) { - $this->markTestSkipped( - '/dev/urandom not found or is not readable.' - ); + public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() + { + $fb = new Facebook($this->config); + $this->assertInstanceOf('Facebook\Url\FacebookUrlDetectionHandler', $fb->getUrlDetectionHandler()); } - $config = array_merge($this->config, [ - 'persistent_data_handler' => 'memory', // To keep session errors from happening - 'pseudo_random_string_generator' => 'urandom' - ]); - $fb = new Facebook($config); - $this->assertInstanceOf('Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator', - $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testSettingAnAccessThatIsNotStringOrAccessTokenThrows() - { - $config = array_merge($this->config, [ - 'default_access_token' => 123, - ]); - $fb = new Facebook($config); - } - - public function testCreatingANewRequestWillDefaultToTheProperConfig() - { - $config = array_merge($this->config, [ - 'default_access_token' => 'foo_token', - 'enable_beta_mode' => true, - 'default_graph_version' => 'v1337', - ]); - $fb = new Facebook($config); - - $request = $fb->request('FOO_VERB', '/foo'); - $this->assertEquals('1337', $request->getApp()->getId()); - $this->assertEquals('foo_secret', $request->getApp()->getSecret()); - $this->assertEquals('foo_token', (string) $request->getAccessToken()); - $this->assertEquals('v1337', $request->getGraphVersion()); - $this->assertEquals(FacebookClient::BASE_GRAPH_URL_BETA, - $fb->getClient()->getBaseGraphUrl()); - } - - public function testCanInjectCustomHandlers() - { - $config = array_merge($this->config, [ - 'http_client_handler' => new FooClientInterface(), - 'persistent_data_handler' => new FooPersistentDataInterface(), - 'url_detection_handler' => new FooUrlDetectionInterface(), - 'pseudo_random_string_generator' => new FooBarPseudoRandomStringGenerator(), - ]); - $fb = new Facebook($config); - - $this->assertInstanceOf('Facebook\Tests\FooClientInterface', - $fb->getClient()->getHttpClientHandler()); - $this->assertInstanceOf('Facebook\Tests\FooPersistentDataInterface', - $fb->getRedirectLoginHelper()->getPersistentDataHandler()); - $this->assertInstanceOf('Facebook\Tests\FooUrlDetectionInterface', - $fb->getRedirectLoginHelper()->getUrlDetectionHandler()); - $this->assertInstanceOf('Facebook\Tests\FooBarPseudoRandomStringGenerator', - $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator()); - } - - public function testPaginationReturnsProperResponse() - { - $config = array_merge($this->config, [ - 'http_client_handler' => new FooClientInterface(), - ]); - $fb = new Facebook($config); - - $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); - $graphList = new GraphList( - $request, - [], - [ - 'paging' => [ - 'cursors' => [ - 'after' => 'bar_after_cursor', - 'before' => 'bar_before_cursor', - ], - ] - ], - '/1337/photos', - '\Facebook\GraphNodes\GraphUser'); - - $nextPage = $fb->next($graphList); - $this->assertInstanceOf('Facebook\GraphNodes\GraphList', $nextPage); - $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); - $this->assertEquals('Foo', $nextPage[0]['name']); - - $lastResponse = $fb->getLastResponse(); - $this->assertInstanceOf('Facebook\FacebookResponse', $lastResponse); - $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); - } + public function testAnAccessTokenCanBeSetAsAString() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken('foo_token'); + $accessToken = $fb->getDefaultAccessToken(); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_token', (string)$accessToken); + } + + public function testAnAccessTokenCanBeSetAsAnAccessTokenEntity() + { + $fb = new Facebook($this->config); + $fb->setDefaultAccessToken(new AccessToken('bar_token')); + $accessToken = $fb->getDefaultAccessToken(); + + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('bar_token', (string)$accessToken); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnInvalidPseudoRandomStringGeneratorThrows() + { + $config = array_merge($this->config, [ + 'pseudo_random_string_generator' => 'foo_generator', + ]); + new Facebook($config); + } + + public function testMcryptCsprgCanBeForced() + { + if (!function_exists('mcrypt_create_iv')) { + $this->markTestSkipped( + 'Mcrypt must be installed to test mcrypt_create_iv().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'mcrypt' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + public function testOpenSslCsprgCanBeForced() + { + if (!function_exists('openssl_random_pseudo_bytes')) { + $this->markTestSkipped( + 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'openssl' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + public function testUrandomCsprgCanBeForced() + { + if (ini_get('open_basedir')) { + $this->markTestSkipped( + 'Cannot test /dev/urandom generator due to open_basedir constraint.' + ); + } + + if (!is_readable('/dev/urandom')) { + $this->markTestSkipped( + '/dev/urandom not found or is not readable.' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'urandom' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testSettingAnAccessThatIsNotStringOrAccessTokenThrows() + { + $config = array_merge($this->config, [ + 'default_access_token' => 123, + ]); + $fb = new Facebook($config); + } + + public function testCreatingANewRequestWillDefaultToTheProperConfig() + { + $config = array_merge($this->config, [ + 'default_access_token' => 'foo_token', + 'enable_beta_mode' => true, + 'default_graph_version' => 'v1337', + ]); + $fb = new Facebook($config); + + $request = $fb->request('FOO_VERB', '/foo'); + $this->assertEquals('1337', $request->getApp()->getId()); + $this->assertEquals('foo_secret', $request->getApp()->getSecret()); + $this->assertEquals('foo_token', (string)$request->getAccessToken()); + $this->assertEquals('v1337', $request->getGraphVersion()); + $this->assertEquals( + FacebookClient::BASE_GRAPH_URL_BETA, + $fb->getClient()->getBaseGraphUrl() + ); + } + + public function testCanInjectCustomHandlers() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + 'persistent_data_handler' => new FooPersistentDataInterface(), + 'url_detection_handler' => new FooUrlDetectionInterface(), + 'pseudo_random_string_generator' => new FooBarPseudoRandomStringGenerator(), + ]); + $fb = new Facebook($config); + + $this->assertInstanceOf( + 'Facebook\Tests\FooClientInterface', + $fb->getClient()->getHttpClientHandler() + ); + $this->assertInstanceOf( + 'Facebook\Tests\FooPersistentDataInterface', + $fb->getRedirectLoginHelper()->getPersistentDataHandler() + ); + $this->assertInstanceOf( + 'Facebook\Tests\FooUrlDetectionInterface', + $fb->getRedirectLoginHelper()->getUrlDetectionHandler() + ); + $this->assertInstanceOf( + 'Facebook\Tests\FooBarPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + + public function testPaginationReturnsProperResponse() + { + $config = array_merge($this->config, [ + 'http_client_handler' => new FooClientInterface(), + ]); + $fb = new Facebook($config); + + $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); + $graphList = new GraphList( + $request, + [], + [ + 'paging' => [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ] + ], + '/1337/photos', + '\Facebook\GraphNodes\GraphUser' + ); + + $nextPage = $fb->next($graphList); + $this->assertInstanceOf('Facebook\GraphNodes\GraphList', $nextPage); + $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); + $this->assertEquals('Foo', $nextPage[0]['name']); + + $lastResponse = $fb->getLastResponse(); + $this->assertInstanceOf('Facebook\FacebookResponse', $lastResponse); + $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); + } } diff --git a/tests/FileUpload/FacebookFileTest.php b/tests/FileUpload/FacebookFileTest.php index 885d0caae..1eb5c0bc9 100644 --- a/tests/FileUpload/FacebookFileTest.php +++ b/tests/FileUpload/FacebookFileTest.php @@ -28,27 +28,26 @@ class FacebookFileTest extends \PHPUnit_Framework_TestCase { - protected $testFile = ''; - - public function setUp() - { - $this->testFile = __DIR__ . '/../foo.txt'; - } - - 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); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testTryingToOpenAFileThatDoesntExistsThrows() - { - new FacebookFile('does_not_exist.file'); - } - + protected $testFile = ''; + + public function setUp() + { + $this->testFile = __DIR__ . '/../foo.txt'; + } + + 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); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testTryingToOpenAFileThatDoesntExistsThrows() + { + new FacebookFile('does_not_exist.file'); + } } diff --git a/tests/FileUpload/MimetypesTest.php b/tests/FileUpload/MimetypesTest.php index 26be32134..c2092c1de 100644 --- a/tests/FileUpload/MimetypesTest.php +++ b/tests/FileUpload/MimetypesTest.php @@ -28,25 +28,28 @@ class MimetypesTest extends \PHPUnit_Framework_TestCase { - /** - * Taken from Guzzle - * @see https://github.com/guzzle/guzzle/blob/master/tests/MimetypesTest.php - */ - public function testGetsFromExtension() - { - $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromExtension('php')); - } - public function testGetsFromFilename() - { - $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(__FILE__)); - } - public function testGetsFromCaseInsensitiveFilename() - { - $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(strtoupper(__FILE__))); - } - public function testReturnsNullWhenNoMatchFound() - { - $this->assertNull(Mimetypes::getInstance()->fromExtension('foobar')); - } + /** + * Taken from Guzzle + * + * @see https://github.com/guzzle/guzzle/blob/master/tests/MimetypesTest.php + */ + public function testGetsFromExtension() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromExtension('php')); + } + public function testGetsFromFilename() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(__FILE__)); + } + + public function testGetsFromCaseInsensitiveFilename() + { + $this->assertEquals('text/x-php', Mimetypes::getInstance()->fromFilename(strtoupper(__FILE__))); + } + + public function testReturnsNullWhenNoMatchFound() + { + $this->assertNull(Mimetypes::getInstance()->fromExtension('foobar')); + } } diff --git a/tests/GraphNodes/CollectionTest.php b/tests/GraphNodes/CollectionTest.php index 3eefcd61c..cce1a3974 100755 --- a/tests/GraphNodes/CollectionTest.php +++ b/tests/GraphNodes/CollectionTest.php @@ -28,87 +28,86 @@ class CollectionTest extends \PHPUnit_Framework_TestCase { - public function testAnExistingPropertyCanBeAccessed() - { - $graphObject = new Collection(['foo' => 'bar']); - $property = $graphObject->getProperty('foo'); + public function testAnExistingPropertyCanBeAccessed() + { + $graphObject = new Collection(['foo' => 'bar']); + $property = $graphObject->getProperty('foo'); - $this->assertEquals('bar', $property); - } - - public function testAMissingPropertyWillReturnNull() - { - $graphObject = new Collection(['foo' => 'bar']); - $property = $graphObject->getProperty('baz'); + $this->assertEquals('bar', $property); + } - $this->assertNull($property, 'Expected the property to return null.'); - } + public function testAMissingPropertyWillReturnNull() + { + $graphObject = new Collection(['foo' => 'bar']); + $property = $graphObject->getProperty('baz'); - public function testAMissingPropertyWillReturnTheDefault() - { - $graphObject = new Collection(['foo' => 'bar']); - $property = $graphObject->getProperty('baz', 'faz'); + $this->assertNull($property, 'Expected the property to return null.'); + } - $this->assertEquals('faz', $property); - } + public function testAMissingPropertyWillReturnTheDefault() + { + $graphObject = new Collection(['foo' => 'bar']); + $property = $graphObject->getProperty('baz', 'faz'); - public function testTheKeysFromTheCollectionCanBeReturned() - { - $graphObject = new Collection([ - 'key1' => 'foo', - 'key2' => 'bar', - 'key3' => 'baz', - ]); - $propertyKeys = $graphObject->getPropertyNames(); + $this->assertEquals('faz', $property); + } - $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); - } + public function testTheKeysFromTheCollectionCanBeReturned() + { + $graphObject = new Collection([ + 'key1' => 'foo', + 'key2' => 'bar', + 'key3' => 'baz', + ]); + $propertyKeys = $graphObject->getPropertyNames(); - public function testAnArrayCanBeInjectedViaTheConstructor() - { - $collection = new Collection(['foo', 'bar']); - $this->assertEquals(['foo', 'bar'], $collection->asArray()); - } + $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); + } - public function testACollectionCanBeConvertedToProperJson() - { - $collection = new Collection(['foo', 'bar', 123]); + public function testAnArrayCanBeInjectedViaTheConstructor() + { + $collection = new Collection(['foo', 'bar']); + $this->assertEquals(['foo', 'bar'], $collection->asArray()); + } - $collectionAsString = $collection->asJson(); + public function testACollectionCanBeConvertedToProperJson() + { + $collection = new Collection(['foo', 'bar', 123]); - $this->assertEquals('["foo","bar",123]', $collectionAsString); - } + $collectionAsString = $collection->asJson(); - public function testACollectionCanBeCounted() - { - $collection = new Collection(['foo', 'bar', 'baz']); + $this->assertEquals('["foo","bar",123]', $collectionAsString); + } - $collectionCount = count($collection); + public function testACollectionCanBeCounted() + { + $collection = new Collection(['foo', 'bar', 'baz']); - $this->assertEquals(3, $collectionCount); - } + $collectionCount = count($collection); - public function testACollectionCanBeAccessedAsAnArray() - { - $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); + $this->assertEquals(3, $collectionCount); + } - $this->assertEquals('bar', $collection['foo']); - $this->assertEquals('baz', $collection['faz']); - } + public function testACollectionCanBeAccessedAsAnArray() + { + $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); - public function testACollectionCanBeIteratedOver() - { - $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); + $this->assertEquals('bar', $collection['foo']); + $this->assertEquals('baz', $collection['faz']); + } - $this->assertInstanceOf('IteratorAggregate', $collection); + public function testACollectionCanBeIteratedOver() + { + $collection = new Collection(['foo' => 'bar', 'faz' => 'baz']); - $newArray = []; + $this->assertInstanceOf('IteratorAggregate', $collection); - foreach ($collection as $k => $v) { - $newArray[$k] = $v; - } + $newArray = []; - $this->assertEquals(['foo' => 'bar', 'faz' => 'baz'], $newArray); - } + foreach ($collection as $k => $v) { + $newArray[$k] = $v; + } + $this->assertEquals(['foo' => 'bar', 'faz' => 'baz'], $newArray); + } } diff --git a/tests/GraphNodes/GraphAchievementTest.php b/tests/GraphNodes/GraphAchievementTest.php index 14e6015e2..bfd9f2096 100644 --- a/tests/GraphNodes/GraphAchievementTest.php +++ b/tests/GraphNodes/GraphAchievementTest.php @@ -26,8 +26,8 @@ class GraphAchievementTest extends GraphNodeTest { - public function testIdIsString() - { + public function testIdIsString() + { $dataFromGraph = [ 'id' => '1337' ]; @@ -38,10 +38,10 @@ public function testIdIsString() $id = $graphObject->getId(); $this->assertEquals($dataFromGraph['id'], $id); - } + } - public function testTypeIsAlwaysString() - { + public function testTypeIsAlwaysString() + { $dataFromGraph = [ 'id' => '1337' ]; @@ -52,12 +52,12 @@ public function testTypeIsAlwaysString() $type = $graphObject->getType(); $this->assertEquals('game.achievement', $type); - } + } - public function testNoFeedStoryIsBoolean() - { + public function testNoFeedStoryIsBoolean() + { $dataFromGraph = [ - 'no_feed_story' => (rand(0,1) == 1) + 'no_feed_story' => (rand(0, 1) == 1) ]; $factory = $this->makeFactoryWithData($dataFromGraph); @@ -66,10 +66,10 @@ public function testNoFeedStoryIsBoolean() $isNoFeedStory = $graphObject->isNoFeedStory(); $this->assertTrue(is_bool($isNoFeedStory)); - } + } - public function testDatesGetCastToDateTime() - { + public function testDatesGetCastToDateTime() + { $dataFromGraph = [ 'publish_time' => '2014-07-15T03:54:34+0000' ]; @@ -80,10 +80,10 @@ public function testDatesGetCastToDateTime() $publishTime = $graphObject->getPublishTime(); $this->assertInstanceOf('DateTime', $publishTime); - } + } - public function testFromGetsCastAsGraphUser() - { + public function testFromGetsCastAsGraphUser() + { $dataFromGraph = [ 'from' => [ 'id' => '1337', @@ -97,10 +97,10 @@ public function testFromGetsCastAsGraphUser() $from = $graphObject->getFrom(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphUser', $from); - } + } - public function testApplicationGetsCastAsGraphApplication() - { + public function testApplicationGetsCastAsGraphApplication() + { $dataFromGraph = [ 'application' => [ 'id' => '1337' @@ -113,5 +113,5 @@ public function testApplicationGetsCastAsGraphApplication() $app = $graphObject->getApplication(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphApplication', $app); - } + } } diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 0af00322d..50484c4e3 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -29,82 +29,81 @@ class GraphAlbumTest extends \PHPUnit_Framework_TestCase { - /** - * @var \Facebook\FacebookResponse - */ - protected $responseMock; - - public function setUp() - { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); - } - - public function testDatesGetCastToDateTime() - { - $dataFromGraph = [ - 'created_time' => '2014-07-15T03:54:34+0000', - 'updated_time' => '2014-07-12T01:24:09+0000', - 'id' => '123', - 'name' => 'Bar', - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphAlbum(); - - $createdTime = $graphObject->getCreatedTime(); - $updatedTime = $graphObject->getUpdatedTime(); - - $this->assertInstanceOf('DateTime', $createdTime); - $this->assertInstanceOf('DateTime', $updatedTime); - } - - public function testFromGetsCastAsGraphUser() - { - $dataFromGraph = [ - 'id' => '123', - 'from' => [ - 'id' => '1337', - 'name' => 'Foo McBar', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphAlbum(); - - $from = $graphObject->getFrom(); - - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $from); - } - - public function testPlacePropertyWillGetCastAsGraphPageObject() - { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo Album', - 'place' => [ - 'id' => '1', - 'name' => 'For Bar Place', - ] - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphAlbum(); - - $place = $graphObject->getPlace(); - - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $place); - } - + /** + * @var \Facebook\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'created_time' => '2014-07-15T03:54:34+0000', + 'updated_time' => '2014-07-12T01:24:09+0000', + 'id' => '123', + 'name' => 'Bar', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphAlbum(); + + $createdTime = $graphObject->getCreatedTime(); + $updatedTime = $graphObject->getUpdatedTime(); + + $this->assertInstanceOf('DateTime', $createdTime); + $this->assertInstanceOf('DateTime', $updatedTime); + } + + public function testFromGetsCastAsGraphUser() + { + $dataFromGraph = [ + 'id' => '123', + 'from' => [ + 'id' => '1337', + 'name' => 'Foo McBar', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphAlbum(); + + $from = $graphObject->getFrom(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $from); + } + + public function testPlacePropertyWillGetCastAsGraphPageObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Album', + 'place' => [ + 'id' => '1', + 'name' => 'For Bar Place', + ] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphAlbum(); + + $place = $graphObject->getPlace(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $place); + } } diff --git a/tests/GraphNodes/GraphListTest.php b/tests/GraphNodes/GraphListTest.php index 5419bfb92..f048aae49 100644 --- a/tests/GraphNodes/GraphListTest.php +++ b/tests/GraphNodes/GraphListTest.php @@ -30,88 +30,91 @@ class GraphListTest extends \PHPUnit_Framework_TestCase { - /** - * @var \Facebook\FacebookRequest - */ - protected $request; + /** + * @var \Facebook\FacebookRequest + */ + protected $request; - protected $basePagination = [ - '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', - ]; - protected $cursorPagination = [ - 'cursors' => [ - 'after' => 'bar_after_cursor', - 'before' => 'bar_before_cursor', - ], - ]; + protected $basePagination = [ + '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', + ]; + protected $cursorPagination = [ + 'cursors' => [ + 'after' => 'bar_after_cursor', + 'before' => 'bar_before_cursor', + ], + ]; - public function setUp() - { - $app = new FacebookApp('123', 'foo_app_secret'); - $this->request = new FacebookRequest( - $app, - 'foo_token', - 'GET', - '/me/photos?keep=me', - ['foo' => 'bar'], - 'foo_eTag', - 'v1337'); - } + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testNonGetRequestsWillThrow() - { - $this->request->setMethod('POST'); - $graphList = new GraphList($this->request); - $graphList->validateForPagination(); - } + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonGetRequestsWillThrow() + { + $this->request->setMethod('POST'); + $graphList = new GraphList($this->request); + $graphList->validateForPagination(); + } - public function testCanReturnGraphGeneratedPaginationEndpoints() - { - $graphList = new GraphList( - $this->request, - [], - ['paging' => $this->basePagination]); - $nextPage = $graphList->getPaginationUrl('next'); - $prevPage = $graphList->getPaginationUrl('previous'); + public function testCanReturnGraphGeneratedPaginationEndpoints() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->basePagination] + ); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); - $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); - $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); - } + $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); + $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); + } - public function testCanGeneratePaginationEndpointsFromACursor() - { - $graphList = new GraphList( - $this->request, - [], - ['paging' => $this->cursorPagination], - '/1234567890/likes'); - $nextPage = $graphList->getPaginationUrl('next'); - $prevPage = $graphList->getPaginationUrl('previous'); + public function testCanGeneratePaginationEndpointsFromACursor() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes' + ); + $nextPage = $graphList->getPaginationUrl('next'); + $prevPage = $graphList->getPaginationUrl('previous'); - $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); - $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); - } + $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); + $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); + } - public function testCanInstantiateNewPaginationRequest() - { - $graphList = new GraphList( - $this->request, - [], - ['paging' => $this->cursorPagination], - '/1234567890/likes'); - $nextPage = $graphList->getNextPageRequest(); - $prevPage = $graphList->getPreviousPageRequest(); - - $this->assertInstanceOf('Facebook\FacebookRequest', $nextPage); - $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); - $this->assertNotSame($this->request, $nextPage); - $this->assertNotSame($this->request, $prevPage); - $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); - $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); - } + public function testCanInstantiateNewPaginationRequest() + { + $graphList = new GraphList( + $this->request, + [], + ['paging' => $this->cursorPagination], + '/1234567890/likes' + ); + $nextPage = $graphList->getNextPageRequest(); + $prevPage = $graphList->getPreviousPageRequest(); + $this->assertInstanceOf('Facebook\FacebookRequest', $nextPage); + $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); + $this->assertNotSame($this->request, $nextPage); + $this->assertNotSame($this->request, $prevPage); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); + $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); + } } diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php index a0ab7a707..17036c856 100644 --- a/tests/GraphNodes/GraphNodeTest.php +++ b/tests/GraphNodes/GraphNodeTest.php @@ -45,6 +45,7 @@ protected function makeFactoryWithData($data) ->shouldReceive('getDecodedBody') ->once() ->andReturn($data); + return new GraphObjectFactory($this->responseMock); } } diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index e6df80279..8a397eefd 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -29,407 +29,409 @@ use Facebook\GraphNodes\GraphObjectFactory; use Facebook\GraphNodes\GraphObject; -class MyFooSubClassGraphObject extends GraphObject {} +class MyFooSubClassGraphObject extends GraphObject +{ +} -class MyFooGraphObject extends GraphObject { - protected static $graphObjectMap = [ - 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', - ]; +class MyFooGraphObject extends GraphObject +{ + protected static $graphObjectMap = [ + 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', + ]; } class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase { - - /** - * @var \Facebook\FacebookRequest - */ - protected $request; - - public function setUp() - { - $app = new FacebookApp('123', 'foo_app_secret'); - $this->request = new FacebookRequest( - $app, - 'foo_token', - 'GET', - '/me/photos?keep=me', - ['foo' => 'bar'], - 'foo_eTag', - 'v1337'); - } - - public function testAValidGraphObjectResponseWillNotThrow() - { - $data = '{"id":"123","name":"foo"}'; - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $factory->validateResponseCastableAsGraphObject(); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testANonGraphObjectResponseWillThrow() - { - $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $factory->validateResponseCastableAsGraphObject(); - } - - public function testAValidGraphListResponseWillNotThrow() - { - $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $factory->validateResponseCastableAsGraphList(); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testANonGraphListResponseWillThrow() - { - $data = '{"id":"123","name":"foo"}'; - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $factory->validateResponseCastableAsGraphList(); - } - - public function testOnlyNumericArraysAreCastableAsAGraphList() - { - $shouldPassOne = GraphObjectFactory::isCastableAsGraphList([]); - $shouldPassTwo = GraphObjectFactory::isCastableAsGraphList(['foo', 'bar']); - $shouldFail = GraphObjectFactory::isCastableAsGraphList(['faz' => 'baz']); - - $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphList.'); - $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphList.'); - $this->assertFalse($shouldFail, 'Expected the given array to not be castable as a GraphList.'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testInvalidSubClassesWillThrow() - { - GraphObjectFactory::validateSubclass('FooSubClass'); - } - - public function testValidSubClassesWillNotThrow() - { - GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphObject'); - GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); - GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - } - - public function testCastingAsASubClassObjectWillInstantiateTheSubClass() - { - $data = '{"id":"123","name":"foo"}'; - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); - } - - public function testASubClassMappingWillAutomaticallyInstantiateSubClass() - { - $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - $fooObject = $mySubClassObject->getProperty('foo_object'); - - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $fooObject); - } - - public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() - { - $data = json_encode([ - 'id' => '123', - 'name' => 'Foo Name', - 'unknown_object' => [ - 'id' => '1337', - 'name' => 'Should be generic!', - ], - ]); - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); - $unknownObject = $mySubClassObject->getProperty('unknown_object'); - - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $unknownObject); - $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $unknownObject); - } - - public function testAListFromGraphWillBeCastAsAGraphList() - { - $data = json_encode([ - 'data' => [ - [ + /** + * @var \Facebook\FacebookRequest + */ + protected $request; + + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->request = new FacebookRequest( + $app, + 'foo_token', + 'GET', + '/me/photos?keep=me', + ['foo' => 'bar'], + 'foo_eTag', + 'v1337' + ); + } + + public function testAValidGraphObjectResponseWillNotThrow() + { + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $factory->validateResponseCastableAsGraphObject(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testANonGraphObjectResponseWillThrow() + { + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $factory->validateResponseCastableAsGraphObject(); + } + + public function testAValidGraphListResponseWillNotThrow() + { + $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $factory->validateResponseCastableAsGraphList(); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testANonGraphListResponseWillThrow() + { + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $factory->validateResponseCastableAsGraphList(); + } + + public function testOnlyNumericArraysAreCastableAsAGraphList() + { + $shouldPassOne = GraphObjectFactory::isCastableAsGraphList([]); + $shouldPassTwo = GraphObjectFactory::isCastableAsGraphList(['foo', 'bar']); + $shouldFail = GraphObjectFactory::isCastableAsGraphList(['faz' => 'baz']); + + $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphList.'); + $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphList.'); + $this->assertFalse($shouldFail, 'Expected the given array to not be castable as a GraphList.'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidSubClassesWillThrow() + { + GraphObjectFactory::validateSubclass('FooSubClass'); + } + + public function testValidSubClassesWillNotThrow() + { + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); + GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + } + + public function testCastingAsASubClassObjectWillInstantiateTheSubClass() + { + $data = '{"id":"123","name":"foo"}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + } + + public function testASubClassMappingWillAutomaticallyInstantiateSubClass() + { + $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + $fooObject = $mySubClassObject->getProperty('foo_object'); + + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $fooObject); + } + + public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() + { + $data = json_encode([ + 'id' => '123', + 'name' => 'Foo Name', + 'unknown_object' => [ + 'id' => '1337', + 'name' => 'Should be generic!', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + $unknownObject = $mySubClassObject->getProperty('unknown_object'); + + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $unknownObject); + } + + public function testAListFromGraphWillBeCastAsAGraphList() + { + $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', - ], - ], - '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]); - } - - public function testAGraphObjectWillBeCastAsAGraphObject() - { - $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 testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() - { - $data = json_encode([ - 'data' => [ - '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 testAGraphListWillBeCastRecursively() - { - $someUser = [ - 'id' => '123', - 'name' => 'Foo McBar', - ]; - $likesCollection = [ - 'data' => [ - [ - 'id' => '1', - 'name' => 'Sammy Kaye Powers', - 'is_sexy' => true, - ], - [ - 'id' => '2', - 'name' => 'Yassine Guedidi', - 'is_sexy' => true, - ], - [ - 'id' => '3', - 'name' => 'Fosco Marotto', - 'is_sexy' => true, - ], - [ - 'id' => '4', - 'name' => 'Foo McUgly', - 'is_sexy' => false, - ], - ], - 'paging' => [ - 'next' => 'http://facebook/next_likes', - 'previous' => 'http://facebook/prev_likes', - ], - ]; - $commentsCollection = [ - 'data' => [ - [ - 'id' => '42_1', - 'from' => $someUser, - 'message' => 'Foo comment.', - 'created_time' => '2014-07-15T03:54:34+0000', - 'likes' => $likesCollection, - ], - [ - 'id' => '42_2', - 'from' => $someUser, - 'message' => 'Bar comment.', - 'created_time' => '2014-07-15T04:11:24+0000', - 'likes' => $likesCollection, - ], - ], - 'paging' => [ - 'next' => 'http://facebook/next_comments', - 'previous' => 'http://facebook/prev_comments', - ], - ]; - $dataFromGraph = [ - 'data' => [ - [ - 'id' => '1337_1', - 'from' => $someUser, - 'story' => 'Some great foo story.', - 'likes' => $likesCollection, - 'comments' => $commentsCollection, - ], - [ - 'id' => '1337_2', - 'from' => $someUser, - 'to' => [ - 'data' => [$someUser], - ], - 'message' => 'Some great bar message.', - 'likes' => $likesCollection, - 'comments' => $commentsCollection, - ], - ], - 'paging' => [ - 'next' => 'http://facebook/next', - 'previous' => 'http://facebook/prev', - ], - ]; - $data = json_encode($dataFromGraph); - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $graphObject = $factory->makeGraphList(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); - - // Story - $storyObject = $graphObject[0]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $storyObject['from']); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); - - // Story Comments - $storyComments = $storyObject['comments']; - $firstStoryComment = $storyComments[0]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $firstStoryComment['from']); - - // Message - $messageObject = $graphObject[1]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); - $toUsers = $messageObject['to']; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $toUsers[0]); - } - - public function testAGraphListWillGenerateTheProperParentGraphEdges() - { - $likesList = [ - 'data' => [ - [ - 'id' => '1', - 'name' => 'Sammy Kaye Powers', - ], - ], - 'paging' => [ - 'cursors' => [ - 'after' => 'like_after_cursor', - 'before' => 'like_before_cursor', - ], - ], - ]; + ], $graphData[1]); + } - $photosList = [ - 'data' => [ - [ - 'id' => '777', - 'name' => 'Foo Photo', - 'likes' => $likesList, - ], - ], - 'paging' => [ - 'cursors' => [ - 'after' => 'photo_after_cursor', - 'before' => 'photo_before_cursor', - ], - ], - ]; + public function testAGraphObjectWillBeCastAsAGraphObject() + { + $data = json_encode([ + 'id' => '123', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ]); + $res = new FacebookResponse($this->request, $data); - $data = json_encode([ - 'data' => [ - [ - 'id' => '111', + $factory = new GraphObjectFactory($res); + $graphObject = $factory->makeGraphObject(); + $graphData = $graphObject->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertEquals([ + 'id' => '123', 'name' => 'Foo McBar', - 'likes' => $likesList, - 'photos' => $photosList, - ], - [ - 'id' => '222', - 'name' => 'Bar McBaz', - 'likes' => $likesList, - 'photos' => $photosList, - ], - ], - 'paging' => [ - 'next' => 'http://facebook/next', - 'previous' => 'http://facebook/prev', - ], - ]); - $res = new FacebookResponse($this->request, $data); - - $factory = new GraphObjectFactory($res); - $graphList = $factory->makeGraphList(); - $topGraphEdge = $graphList->getParentGraphEdge(); - $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); - $childGraphEdgeTwo = $graphList[1]['likes']->getParentGraphEdge(); - $childGraphEdgeThree = $graphList[1]['photos']->getParentGraphEdge(); - $childGraphEdgeFour = $graphList[1]['photos'][0]['likes']->getParentGraphEdge(); - - $this->assertNull($topGraphEdge); - $this->assertEquals('/111/likes', $childGraphEdgeOne); - $this->assertEquals('/222/likes', $childGraphEdgeTwo); - $this->assertEquals('/222/photos', $childGraphEdgeThree); - $this->assertEquals('/777/likes', $childGraphEdgeFour); - } + 'link' => 'http://facebook/foo', + ], $graphData); + } + + public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() + { + $data = json_encode([ + 'data' => [ + '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 testAGraphListWillBeCastRecursively() + { + $someUser = [ + 'id' => '123', + 'name' => 'Foo McBar', + ]; + $likesCollection = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + 'is_sexy' => true, + ], + [ + 'id' => '2', + 'name' => 'Yassine Guedidi', + 'is_sexy' => true, + ], + [ + 'id' => '3', + 'name' => 'Fosco Marotto', + 'is_sexy' => true, + ], + [ + 'id' => '4', + 'name' => 'Foo McUgly', + 'is_sexy' => false, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next_likes', + 'previous' => 'http://facebook/prev_likes', + ], + ]; + $commentsCollection = [ + 'data' => [ + [ + 'id' => '42_1', + 'from' => $someUser, + 'message' => 'Foo comment.', + 'created_time' => '2014-07-15T03:54:34+0000', + 'likes' => $likesCollection, + ], + [ + 'id' => '42_2', + 'from' => $someUser, + 'message' => 'Bar comment.', + 'created_time' => '2014-07-15T04:11:24+0000', + 'likes' => $likesCollection, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next_comments', + 'previous' => 'http://facebook/prev_comments', + ], + ]; + $dataFromGraph = [ + 'data' => [ + [ + 'id' => '1337_1', + 'from' => $someUser, + 'story' => 'Some great foo story.', + 'likes' => $likesCollection, + 'comments' => $commentsCollection, + ], + [ + 'id' => '1337_2', + 'from' => $someUser, + 'to' => [ + 'data' => [$someUser], + ], + 'message' => 'Some great bar message.', + 'likes' => $likesCollection, + 'comments' => $commentsCollection, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]; + $data = json_encode($dataFromGraph); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphObject = $factory->makeGraphList(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); + + // Story + $storyObject = $graphObject[0]; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $storyObject['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); + + // Story Comments + $storyComments = $storyObject['comments']; + $firstStoryComment = $storyComments[0]; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $firstStoryComment['from']); + + // Message + $messageObject = $graphObject[1]; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); + $toUsers = $messageObject['to']; + $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $toUsers[0]); + } + + public function testAGraphListWillGenerateTheProperParentGraphEdges() + { + $likesList = [ + 'data' => [ + [ + 'id' => '1', + 'name' => 'Sammy Kaye Powers', + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'like_after_cursor', + 'before' => 'like_before_cursor', + ], + ], + ]; + + $photosList = [ + 'data' => [ + [ + 'id' => '777', + 'name' => 'Foo Photo', + 'likes' => $likesList, + ], + ], + 'paging' => [ + 'cursors' => [ + 'after' => 'photo_after_cursor', + 'before' => 'photo_before_cursor', + ], + ], + ]; + + $data = json_encode([ + 'data' => [ + [ + 'id' => '111', + 'name' => 'Foo McBar', + 'likes' => $likesList, + 'photos' => $photosList, + ], + [ + 'id' => '222', + 'name' => 'Bar McBaz', + 'likes' => $likesList, + 'photos' => $photosList, + ], + ], + 'paging' => [ + 'next' => 'http://facebook/next', + 'previous' => 'http://facebook/prev', + ], + ]); + $res = new FacebookResponse($this->request, $data); + + $factory = new GraphObjectFactory($res); + $graphList = $factory->makeGraphList(); + $topGraphEdge = $graphList->getParentGraphEdge(); + $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); + $childGraphEdgeTwo = $graphList[1]['likes']->getParentGraphEdge(); + $childGraphEdgeThree = $graphList[1]['photos']->getParentGraphEdge(); + $childGraphEdgeFour = $graphList[1]['photos'][0]['likes']->getParentGraphEdge(); + + $this->assertNull($topGraphEdge); + $this->assertEquals('/111/likes', $childGraphEdgeOne); + $this->assertEquals('/222/likes', $childGraphEdgeTwo); + $this->assertEquals('/222/photos', $childGraphEdgeThree); + $this->assertEquals('/777/likes', $childGraphEdgeFour); + } } diff --git a/tests/GraphNodes/GraphObjectTest.php b/tests/GraphNodes/GraphObjectTest.php index 9ddea1d75..9ef900bba 100644 --- a/tests/GraphNodes/GraphObjectTest.php +++ b/tests/GraphNodes/GraphObjectTest.php @@ -27,114 +27,112 @@ class GraphObjectTest extends \PHPUnit_Framework_TestCase { - - public function testAnEmptyBaseGraphObjectCanInstantiate() - { - $graphObject = new GraphObject(); - $backingData = $graphObject->asArray(); - - $this->assertEquals([], $backingData); - } - - public function testAGraphObjectCanInstantiateWithData() - { - $graphObject = new GraphObject(['foo' => 'bar']); - $backingData = $graphObject->asArray(); - - $this->assertEquals(['foo' => 'bar'], $backingData); - } - - public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() - { - $graphObject = new GraphObject(); - - // Should pass - $shouldPass = $graphObject->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 = $graphObject->isIso8601DateString('1999-12-31'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); - - $shouldPass = $graphObject->isIso8601DateString('2009-05-19T14:39Z'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - - $shouldPass = $graphObject->isIso8601DateString('2014-W36'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - - // Should fail - $shouldFail = $graphObject->isIso8601DateString('2009-05-19T14a39r'); - $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); - - $shouldFail = $graphObject->isIso8601DateString('foo_time'); - $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); - } - - public function testATimeStampCanBeConvertedToADateTimeObject() - { - $someTimeStampFromGraph = 1405547020; - $graphObject = new GraphObject(); - $dateTime = $graphObject->castToDateTime($someTimeStampFromGraph); - $prettyDate = $dateTime->format(\DateTime::RFC1036); - $timeStamp = $dateTime->getTimestamp(); - - $this->assertInstanceOf('DateTime', $dateTime); - $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); - $this->assertEquals(1405547020, $timeStamp); - } - - public function testAGraphDateStringCanBeConvertedToADateTimeObject() - { - $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; - $graphObject = new GraphObject(); - $dateTime = $graphObject->castToDateTime($someDateStringFromGraph); - $prettyDate = $dateTime->format(\DateTime::RFC1036); - $timeStamp = $dateTime->getTimestamp(); - - $this->assertInstanceOf('DateTime', $dateTime); - $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); - $this->assertEquals(1405395893, $timeStamp); - } - - public function testUncastingAGraphObjectWillUncastTheDateTimeObject() - { - $collectionOne = new GraphObject(['foo', 'bar']); - $collectionTwo = new GraphObject([ - 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), - 'some_collection' => $collectionOne, - ]); - - $uncastArray = $collectionTwo->uncastItems(); - - $this->assertEquals([ - 'id' => '123', - 'date' => '2014-07-15T03:44:53+0000', - 'some_collection' => ['foo', 'bar'], - ], $uncastArray); - } - - public function testGettingGraphObjectAsAnArrayWillNotUncastTheDateTimeObject() - { - $collection = new GraphObject([ - 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), - ]); - - $collectionAsArray = $collection->asArray(); - - $this->assertInstanceOf('DateTime', $collectionAsArray['date']); - } - - public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() - { - $collection = new GraphObject([ - 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), - ]); - - $collectionAsString = $collection->asJson(); - - $this->assertEquals('{"id":"123","date":"2014-07-15T03:44:53+0000"}', $collectionAsString); - } - + public function testAnEmptyBaseGraphObjectCanInstantiate() + { + $graphObject = new GraphObject(); + $backingData = $graphObject->asArray(); + + $this->assertEquals([], $backingData); + } + + public function testAGraphObjectCanInstantiateWithData() + { + $graphObject = new GraphObject(['foo' => 'bar']); + $backingData = $graphObject->asArray(); + + $this->assertEquals(['foo' => 'bar'], $backingData); + } + + public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() + { + $graphObject = new GraphObject(); + + // Should pass + $shouldPass = $graphObject->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 = $graphObject->isIso8601DateString('1999-12-31'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); + + $shouldPass = $graphObject->isIso8601DateString('2009-05-19T14:39Z'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + $shouldPass = $graphObject->isIso8601DateString('2014-W36'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + // Should fail + $shouldFail = $graphObject->isIso8601DateString('2009-05-19T14a39r'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + + $shouldFail = $graphObject->isIso8601DateString('foo_time'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + } + + public function testATimeStampCanBeConvertedToADateTimeObject() + { + $someTimeStampFromGraph = 1405547020; + $graphObject = new GraphObject(); + $dateTime = $graphObject->castToDateTime($someTimeStampFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); + + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); + $this->assertEquals(1405547020, $timeStamp); + } + + public function testAGraphDateStringCanBeConvertedToADateTimeObject() + { + $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; + $graphObject = new GraphObject(); + $dateTime = $graphObject->castToDateTime($someDateStringFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); + + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); + $this->assertEquals(1405395893, $timeStamp); + } + + public function testUncastingAGraphObjectWillUncastTheDateTimeObject() + { + $collectionOne = new GraphObject(['foo', 'bar']); + $collectionTwo = new GraphObject([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'some_collection' => $collectionOne, + ]); + + $uncastArray = $collectionTwo->uncastItems(); + + $this->assertEquals([ + 'id' => '123', + 'date' => '2014-07-15T03:44:53+0000', + 'some_collection' => ['foo', 'bar'], + ], $uncastArray); + } + + public function testGettingGraphObjectAsAnArrayWillNotUncastTheDateTimeObject() + { + $collection = new GraphObject([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsArray = $collection->asArray(); + + $this->assertInstanceOf('DateTime', $collectionAsArray['date']); + } + + public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() + { + $collection = new GraphObject([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsString = $collection->asJson(); + + $this->assertEquals('{"id":"123","date":"2014-07-15T03:44:53+0000"}', $collectionAsString); + } } diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php index d2069bd14..f6861a23f 100644 --- a/tests/GraphNodes/GraphPageTest.php +++ b/tests/GraphNodes/GraphPageTest.php @@ -28,70 +28,68 @@ class GraphPageTest extends \PHPUnit_Framework_TestCase { + /** + * @var \Facebook\FacebookResponse + */ + protected $responseMock; - /** - * @var \Facebook\FacebookResponse - */ - protected $responseMock; + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } - public function setUp() - { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); - } + public function testPagePropertiesReturnGraphPageObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Page', + 'best_page' => [ + 'id' => '1', + 'name' => 'Bar Page', + ], + 'global_brand_parent_page' => [ + 'id' => '2', + 'name' => 'Faz Page', + ], + ]; - public function testPagePropertiesReturnGraphPageObjects() - { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo Page', - 'best_page' => [ - 'id' => '1', - 'name' => 'Bar Page', - ], - 'global_brand_parent_page' => [ - 'id' => '2', - 'name' => 'Faz Page', - ], - ]; + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphPage(); - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphPage(); + $bestPage = $graphObject->getBestPage(); + $globalBrandParentPage = $graphObject->getGlobalBrandParentPage(); - $bestPage = $graphObject->getBestPage(); - $globalBrandParentPage = $graphObject->getGlobalBrandParentPage(); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $bestPage); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $globalBrandParentPage); + } - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $bestPage); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $globalBrandParentPage); - } + public function testLocationPropertyWillGetCastAsGraphLocationObject() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo Page', + 'location' => [ + 'city' => 'Washington', + 'country' => 'United States', + 'latitude' => 38.881634205431, + 'longitude' => -77.029121075722, + 'state' => 'DC', + ], + ]; - public function testLocationPropertyWillGetCastAsGraphLocationObject() - { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo Page', - 'location' => [ - 'city' => 'Washington', - 'country' => 'United States', - 'latitude' => 38.881634205431, - 'longitude' => -77.029121075722, - 'state' => 'DC', - ], - ]; + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphPage(); - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphPage(); - - $location = $graphObject->getLocation(); - - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphLocation', $location); - } + $location = $graphObject->getLocation(); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphLocation', $location); + } } diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index 8b3da8442..51322be25 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -28,37 +28,35 @@ class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase { - - /** - * @var \Facebook\FacebookResponse - */ - protected $responseMock; - - public function setUp() - { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); - } - - public function testDatesGetCastToDateTime() - { - $dataFromGraph = [ - 'expires_at' => 123, - 'issued_at' => 1337, - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - - $graphObject = $factory->makeGraphSessionInfo(); - - $expires = $graphObject->getExpiresAt(); - $issuedAt = $graphObject->getIssuedAt(); - - $this->assertInstanceOf('DateTime', $expires); - $this->assertInstanceOf('DateTime', $issuedAt); - } - + /** + * @var \Facebook\FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'expires_at' => 123, + 'issued_at' => 1337, + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + + $graphObject = $factory->makeGraphSessionInfo(); + + $expires = $graphObject->getExpiresAt(); + $issuedAt = $graphObject->getIssuedAt(); + + $this->assertInstanceOf('DateTime', $expires); + $this->assertInstanceOf('DateTime', $issuedAt); + } } diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index ea4b4d673..5de8119c3 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -29,113 +29,112 @@ class GraphUserTest extends \PHPUnit_Framework_TestCase { - - /** - * @var FacebookResponse - */ - protected $responseMock; - - public function setUp() - { - $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); - } - - public function testDatesGetCastToDateTime() - { - $dataFromGraph = [ - 'birthday' => '1984-01-01', - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); - - $birthday = $graphObject->getBirthday(); - - $this->assertInstanceOf('DateTime', $birthday); - } - - public function testPagePropertiesWillGetCastAsGraphPageObjects() - { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo User', - 'hometown' => [ - 'id' => '1', - 'name' => 'Foo Place', - ], - 'location' => [ - 'id' => '2', - 'name' => 'Bar Place', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); - - $hometown = $graphObject->getHometown(); - $location = $graphObject->getLocation(); - - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $hometown); - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $location); - } - - public function testUserPropertiesWillGetCastAsGraphUserObjects() - { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo User', - 'significant_other' => [ - 'id' => '1337', - 'name' => 'Bar User', - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); - - $significantOther = $graphObject->getSignificantOther(); - - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); - } - - public function testPicturePropertiesWillGetCastAsGraphPictureObjects() - { - $dataFromGraph = [ - 'id' => '123', - 'name' => 'Foo User', - 'picture' => [ - 'is_silhouette' => true, - 'url' => 'http://foo.bar', - 'width' => 200, - 'height' => 200, - ], - ]; - - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); - - $Picture = $graphObject->getPicture(); - - $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPicture', $Picture); - $this->assertTrue($Picture->isSilhouette()); - $this->assertEquals(200, $Picture->getWidth()); - $this->assertEquals(200, $Picture->getHeight()); - $this->assertEquals('http://foo.bar', $Picture->getUrl()); - } + /** + * @var FacebookResponse + */ + protected $responseMock; + + public function setUp() + { + $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'birthday' => '1984-01-01', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $birthday = $graphObject->getBirthday(); + + $this->assertInstanceOf('DateTime', $birthday); + } + + public function testPagePropertiesWillGetCastAsGraphPageObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'hometown' => [ + 'id' => '1', + 'name' => 'Foo Place', + ], + 'location' => [ + 'id' => '2', + 'name' => 'Bar Place', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $hometown = $graphObject->getHometown(); + $location = $graphObject->getLocation(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $hometown); + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $location); + } + + public function testUserPropertiesWillGetCastAsGraphUserObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'significant_other' => [ + 'id' => '1337', + 'name' => 'Bar User', + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $significantOther = $graphObject->getSignificantOther(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); + } + + public function testPicturePropertiesWillGetCastAsGraphPictureObjects() + { + $dataFromGraph = [ + 'id' => '123', + 'name' => 'Foo User', + 'picture' => [ + 'is_silhouette' => true, + 'url' => 'http://foo.bar', + 'width' => 200, + 'height' => 200, + ], + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphUser(); + + $Picture = $graphObject->getPicture(); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPicture', $Picture); + $this->assertTrue($Picture->isSilhouette()); + $this->assertEquals(200, $Picture->getWidth()); + $this->assertEquals(200, $Picture->getHeight()); + $this->assertEquals('http://foo.bar', $Picture->getUrl()); + } } diff --git a/tests/Helpers/FacebookCanvasHelperTest.php b/tests/Helpers/FacebookCanvasHelperTest.php index 9f4c7b744..294440efe 100644 --- a/tests/Helpers/FacebookCanvasHelperTest.php +++ b/tests/Helpers/FacebookCanvasHelperTest.php @@ -27,29 +27,27 @@ use Facebook\FacebookClient; use Facebook\Helpers\FacebookCanvasHelper; -class FacebookCanvasLoginHelperTest extends \PHPUnit_Framework_TestCase +class FacebookCanvasHelperTest extends \PHPUnit_Framework_TestCase { + public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; - public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + /** + * @var FacebookCanvasHelper + */ + protected $helper; - /** - * @var FacebookCanvasHelper - */ - protected $helper; + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->helper = new FacebookCanvasHelper($app, new FacebookClient()); + } - public function setUp() - { - $app = new FacebookApp('123', 'foo_app_secret'); - $this->helper = new FacebookCanvasHelper($app, new FacebookClient()); - } + public function testSignedRequestDataCanBeRetrievedFromPostData() + { + $_POST['signed_request'] = $this->rawSignedRequestAuthorized; - public function testSignedRequestDataCanBeRetrievedFromPostData() - { - $_POST['signed_request'] = $this->rawSignedRequestAuthorized; - - $rawSignedRequest = $this->helper->getRawSignedRequest(); - - $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); - } + $rawSignedRequest = $this->helper->getRawSignedRequest(); + $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); + } } diff --git a/tests/Helpers/FacebookJavaScriptHelperTest.php b/tests/Helpers/FacebookJavaScriptHelperTest.php index 2fae603d7..3f9cb88e0 100644 --- a/tests/Helpers/FacebookJavaScriptHelperTest.php +++ b/tests/Helpers/FacebookJavaScriptHelperTest.php @@ -27,21 +27,19 @@ use Facebook\FacebookClient; use Facebook\Helpers\FacebookJavaScriptHelper; -class FacebookJavaScriptLoginHelperTest extends \PHPUnit_Framework_TestCase +class FacebookJavaScriptHelperTest extends \PHPUnit_Framework_TestCase { + public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; - public $rawSignedRequestAuthorized = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public function testARawSignedRequestCanBeRetrievedFromCookieData() + { + $_COOKIE['fbsr_123'] = $this->rawSignedRequestAuthorized; - public function testARawSignedRequestCanBeRetrievedFromCookieData() - { - $_COOKIE['fbsr_123'] = $this->rawSignedRequestAuthorized; + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookJavaScriptHelper($app, new FacebookClient()); - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookJavaScriptHelper($app, new FacebookClient()); - - $rawSignedRequest = $helper->getRawSignedRequest(); - - $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); - } + $rawSignedRequest = $helper->getRawSignedRequest(); + $this->assertEquals($this->rawSignedRequestAuthorized, $rawSignedRequest); + } } diff --git a/tests/Helpers/FacebookPageTabHelperTest.php b/tests/Helpers/FacebookPageTabHelperTest.php index 5d5b33d4e..a4b06c17c 100644 --- a/tests/Helpers/FacebookPageTabHelperTest.php +++ b/tests/Helpers/FacebookPageTabHelperTest.php @@ -29,20 +29,18 @@ class FacebookPageTabHelperTest extends \PHPUnit_Framework_TestCase { + protected $rawSignedRequestAuthorized = '6Hi26ECjkj347belC0O8b8H5lwiIz5eA6V9VVjTg-HU=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MzIxLCJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsInVzZXJfaWQiOiIxMjMiLCJwYWdlIjp7ImlkIjoiNDIiLCJsaWtlZCI6dHJ1ZSwiYWRtaW4iOmZhbHNlfX0='; - protected $rawSignedRequestAuthorized = '6Hi26ECjkj347belC0O8b8H5lwiIz5eA6V9VVjTg-HU=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MzIxLCJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsInVzZXJfaWQiOiIxMjMiLCJwYWdlIjp7ImlkIjoiNDIiLCJsaWtlZCI6dHJ1ZSwiYWRtaW4iOmZhbHNlfX0='; + public function testPageDataCanBeAccessed() + { + $_POST['signed_request'] = $this->rawSignedRequestAuthorized; - public function testPageDataCanBeAccessed() - { - $_POST['signed_request'] = $this->rawSignedRequestAuthorized; - - $app = new FacebookApp('123', 'foo_app_secret'); - $helper = new FacebookPageTabHelper($app, new FacebookClient()); - - $this->assertFalse($helper->isAdmin()); - $this->assertEquals('42', $helper->getPageId()); - $this->assertEquals('42', $helper->getPageData('id')); - $this->assertEquals('default', $helper->getPageData('foo', 'default')); - } + $app = new FacebookApp('123', 'foo_app_secret'); + $helper = new FacebookPageTabHelper($app, new FacebookClient()); + $this->assertFalse($helper->isAdmin()); + $this->assertEquals('42', $helper->getPageId()); + $this->assertEquals('42', $helper->getPageData('id')); + $this->assertEquals('default', $helper->getPageData('foo', 'default')); + } } diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index d6f41a27a..faa4647bf 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -33,108 +33,108 @@ class FooPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface { - public function getPseudoRandomString($length) { - return 'csprs123'; - } + public function getPseudoRandomString($length) + { + return 'csprs123'; + } } class FooRedirectLoginOAuth2Client extends OAuth2Client { - public function getAccessTokenFromCode($code, $redirectUri = '', $machineId = null) { - return 'foo_token_from_code|' . $code . '|' . $redirectUri; - } + public function getAccessTokenFromCode($code, $redirectUri = '', $machineId = null) + { + return 'foo_token_from_code|' . $code . '|' . $redirectUri; + } } class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase { + /** + * @var FacebookMemoryPersistentDataHandler + */ + protected $persistentDataHandler; + + /** + * @var FacebookRedirectLoginHelper + */ + protected $redirectLoginHelper; + + const REDIRECT_URL = 'http://invalid.zzz'; + + public function setUp() + { + $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); - /** - * @var FacebookMemoryPersistentDataHandler - */ - protected $persistentDataHandler; - - /** - * @var FacebookRedirectLoginHelper - */ - protected $redirectLoginHelper; - - const REDIRECT_URL = 'http://invalid.zzz'; - - public function setUp() - { - $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); - - $app = new FacebookApp('123', 'foo_app_secret'); - $oAuth2Client = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); - $this->redirectLoginHelper = new FacebookRedirectLoginHelper($oAuth2Client, $this->persistentDataHandler); - } - - public function testLoginURL() - { - $scope = ['foo','bar']; - $loginUrl = $this->redirectLoginHelper->getLoginUrl(self::REDIRECT_URL, $scope); - - $expectedUrl = 'https://www.facebook.com/v1337/dialog/oauth?'; - $this->assertTrue(strpos($loginUrl, $expectedUrl) === 0, 'Unexpected base login URL returned from getLoginUrl().'); - - $params = [ - 'client_id' => '123', - 'redirect_uri' => self::REDIRECT_URL, - 'state' => $this->persistentDataHandler->get('state'), - 'sdk' => 'php-sdk-' . Facebook::VERSION, - 'scope' => implode(',', $scope), - ]; - foreach ($params as $key => $value) { - $this->assertContains($key . '=' . urlencode($value), $loginUrl); + $app = new FacebookApp('123', 'foo_app_secret'); + $oAuth2Client = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); + $this->redirectLoginHelper = new FacebookRedirectLoginHelper($oAuth2Client, $this->persistentDataHandler); } - } - - public function testLogoutURL() - { - $logoutUrl = $this->redirectLoginHelper->getLogoutUrl('foo_token', self::REDIRECT_URL); - $expectedUrl = 'https://www.facebook.com/logout.php?'; - $this->assertTrue(strpos($logoutUrl, $expectedUrl) === 0, 'Unexpected base logout URL returned from getLogoutUrl().'); - - $params = [ - 'next' => self::REDIRECT_URL, - 'access_token' => 'foo_token', - ]; - foreach ($params as $key => $value) { - $this->assertTrue( - strpos($logoutUrl, $key . '=' . urlencode($value)) !== false - ); + + public function testLoginURL() + { + $scope = ['foo', 'bar']; + $loginUrl = $this->redirectLoginHelper->getLoginUrl(self::REDIRECT_URL, $scope); + + $expectedUrl = 'https://www.facebook.com/v1337/dialog/oauth?'; + $this->assertTrue(strpos($loginUrl, $expectedUrl) === 0, 'Unexpected base login URL returned from getLoginUrl().'); + + $params = [ + 'client_id' => '123', + 'redirect_uri' => self::REDIRECT_URL, + 'state' => $this->persistentDataHandler->get('state'), + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'scope' => implode(',', $scope), + ]; + foreach ($params as $key => $value) { + $this->assertContains($key . '=' . urlencode($value), $loginUrl); + } } - } - public function testAnAccessTokenCanBeObtainedFromRedirect() - { - $this->persistentDataHandler->set('state', 'foo_state'); - $_GET['state'] = 'foo_state'; - $_GET['code'] = 'foo_code'; + public function testLogoutURL() + { + $logoutUrl = $this->redirectLoginHelper->getLogoutUrl('foo_token', self::REDIRECT_URL); + $expectedUrl = 'https://www.facebook.com/logout.php?'; + $this->assertTrue(strpos($logoutUrl, $expectedUrl) === 0, 'Unexpected base logout URL returned from getLogoutUrl().'); + + $params = [ + 'next' => self::REDIRECT_URL, + 'access_token' => 'foo_token', + ]; + foreach ($params as $key => $value) { + $this->assertTrue( + strpos($logoutUrl, $key . '=' . urlencode($value)) !== false + ); + } + } - $accessToken = $this->redirectLoginHelper->getAccessToken(self::REDIRECT_URL); + public function testAnAccessTokenCanBeObtainedFromRedirect() + { + $this->persistentDataHandler->set('state', 'foo_state'); + $_GET['state'] = 'foo_state'; + $_GET['code'] = 'foo_code'; - $this->assertEquals('foo_token_from_code|foo_code|' . self::REDIRECT_URL, (string) $accessToken); - } + $accessToken = $this->redirectLoginHelper->getAccessToken(self::REDIRECT_URL); - public function testACustomCsprsgCanBeInjected() - { - $app = new FacebookApp('123', 'foo_app_secret'); - $accessTokenClient = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); - $fooPrsg = new FooPseudoRandomStringGenerator(); - $helper = new FacebookRedirectLoginHelper($accessTokenClient, $this->persistentDataHandler, null, $fooPrsg); + $this->assertEquals('foo_token_from_code|foo_code|' . self::REDIRECT_URL, (string)$accessToken); + } - $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); + public function testACustomCsprsgCanBeInjected() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $accessTokenClient = new FooRedirectLoginOAuth2Client($app, new FacebookClient(), 'v1337'); + $fooPrsg = new FooPseudoRandomStringGenerator(); + $helper = new FacebookRedirectLoginHelper($accessTokenClient, $this->persistentDataHandler, null, $fooPrsg); - $this->assertContains('state=csprs123', $loginUrl); - } + $loginUrl = $helper->getLoginUrl(self::REDIRECT_URL); - public function testThePseudoRandomStringGeneratorWillAutoDetectCsprsg() - { - $this->assertInstanceOf( - 'Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface', - $this->redirectLoginHelper->getPseudoRandomStringGenerator() - ); - } + $this->assertContains('state=csprs123', $loginUrl); + } + public function testThePseudoRandomStringGeneratorWillAutoDetectCsprsg() + { + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface', + $this->redirectLoginHelper->getPseudoRandomStringGenerator() + ); + } } diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 3ef124737..d9bd8030c 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -29,84 +29,85 @@ use Facebook\FacebookResponse; use Facebook\Helpers\FacebookSignedRequestFromInputHelper; -class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper { - public function getRawSignedRequest() { - return null; - } +class FooSignedRequestHelper extends FacebookSignedRequestFromInputHelper +{ + public function getRawSignedRequest() + { + return null; + } } class FooSignedRequestHelperFacebookClient extends FacebookClient { - public function sendRequest(FacebookRequest $request) { - $params = $request->getParams(); - $rawResponse = json_encode([ - 'access_token' => 'foo_access_token_from:' . $params['code'], - ]); - - return new FacebookResponse($request, $rawResponse, 200); - } + public function sendRequest(FacebookRequest $request) + { + $params = $request->getParams(); + $rawResponse = json_encode([ + 'access_token' => 'foo_access_token_from:' . $params['code'], + ]); + + return new FacebookResponse($request, $rawResponse, 200); + } } class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCase { + /** + * @var FooSignedRequestHelper + */ + protected $helper; - /** - * @var FooSignedRequestHelper - */ - protected $helper; - - public $rawSignedRequestAuthorizedWithAccessToken = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; - public $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; - public $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; - - public function setUp() - { - $app = new FacebookApp('123', 'foo_app_secret'); - $this->helper = new FooSignedRequestHelper($app, new FooSignedRequestHelperFacebookClient()); - } + public $rawSignedRequestAuthorizedWithAccessToken = 'vdZXlVEQ5NTRRTFvJ7Jeo_kP4SKnBDvbNP0fEYKS0Sg=.eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjoxNDAyNTUxMDMxLCJ1c2VyX2lkIjoiMTIzIn0='; + public $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; + public $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; - public function testSignedRequestDataCanBeRetrievedFromPostData() - { - $_POST['signed_request'] = 'foo_signed_request'; + public function setUp() + { + $app = new FacebookApp('123', 'foo_app_secret'); + $this->helper = new FooSignedRequestHelper($app, new FooSignedRequestHelperFacebookClient()); + } - $rawSignedRequest = $this->helper->getRawSignedRequestFromPost(); + public function testSignedRequestDataCanBeRetrievedFromPostData() + { + $_POST['signed_request'] = 'foo_signed_request'; - $this->assertEquals('foo_signed_request', $rawSignedRequest); - } + $rawSignedRequest = $this->helper->getRawSignedRequestFromPost(); - public function testSignedRequestDataCanBeRetrievedFromCookieData() - { - $_COOKIE['fbsr_123'] = 'foo_signed_request'; + $this->assertEquals('foo_signed_request', $rawSignedRequest); + } - $rawSignedRequest = $this->helper->getRawSignedRequestFromCookie(); + public function testSignedRequestDataCanBeRetrievedFromCookieData() + { + $_COOKIE['fbsr_123'] = 'foo_signed_request'; - $this->assertEquals('foo_signed_request', $rawSignedRequest); - } + $rawSignedRequest = $this->helper->getRawSignedRequestFromCookie(); - public function testAccessTokenWillBeNullWhenAUserHasNotYetAuthorizedTheApp() - { - $this->helper->instantiateSignedRequest($this->rawSignedRequestUnauthorized); - $accessToken = $this->helper->getAccessToken(); + $this->assertEquals('foo_signed_request', $rawSignedRequest); + } - $this->assertNull($accessToken); - } + public function testAccessTokenWillBeNullWhenAUserHasNotYetAuthorizedTheApp() + { + $this->helper->instantiateSignedRequest($this->rawSignedRequestUnauthorized); + $accessToken = $this->helper->getAccessToken(); - public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessToken() - { - $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); - $accessToken = $this->helper->getAccessToken(); + $this->assertNull($accessToken); + } - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); - $this->assertEquals('foo_token', $accessToken->getValue()); - } + public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsAnAccessToken() + { + $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithAccessToken); + $accessToken = $this->helper->getAccessToken(); - public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() - { - $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); - $accessToken = $this->helper->getAccessToken(); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_token', $accessToken->getValue()); + } - $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); - $this->assertEquals('foo_access_token_from:foo_code', $accessToken->getValue()); - } + public function testAnAccessTokenCanBeInstantiatedWhenRedirectReturnsACode() + { + $this->helper->instantiateSignedRequest($this->rawSignedRequestAuthorizedWithCode); + $accessToken = $this->helper->getAccessToken(); + $this->assertInstanceOf('Facebook\Authentication\AccessToken', $accessToken); + $this->assertEquals('foo_access_token_from:foo_code', $accessToken->getValue()); + } } diff --git a/tests/Http/RequestBodyMultipartTest.php b/tests/Http/RequestBodyMultipartTest.php index f7574db17..e344ea2cb 100644 --- a/tests/Http/RequestBodyMultipartTest.php +++ b/tests/Http/RequestBodyMultipartTest.php @@ -28,13 +28,12 @@ class RequestBodyMultipartTest extends \PHPUnit_Framework_TestCase { - public function testCanProperlyEncodeAnArrayOfParams() { $message = new RequestBodyMultipart([ - 'foo' => 'bar', - 'scawy_vawues' => '@FooBar is a real twitter handle.', - ], [], 'foo_boundary'); + 'foo' => 'bar', + 'scawy_vawues' => '@FooBar is a real twitter handle.', + ], [], 'foo_boundary'); $body = $message->getBody(); $expectedBody = "--foo_boundary\r\n"; @@ -50,10 +49,10 @@ public function testCanProperlyEncodeFilesAndParams() { $file = new FacebookFile(__DIR__ . '/../foo.txt'); $message = new RequestBodyMultipart([ - 'foo' => 'bar', - ], [ - 'foo_file' => $file, - ], 'foo_boundary'); + 'foo' => 'bar', + ], [ + 'foo_file' => $file, + ], 'foo_boundary'); $body = $message->getBody(); $expectedBody = "--foo_boundary\r\n"; diff --git a/tests/Http/RequestUrlEncodedTest.php b/tests/Http/RequestUrlEncodedTest.php index bad9675a0..595cdc78f 100644 --- a/tests/Http/RequestUrlEncodedTest.php +++ b/tests/Http/RequestUrlEncodedTest.php @@ -25,9 +25,8 @@ use Facebook\Http\RequestBodyUrlEncoded; -class RequestBodyUrlEncodedTest extends \PHPUnit_Framework_TestCase +class RequestUrlEncodedTest extends \PHPUnit_Framework_TestCase { - public function testCanProperlyEncodeAnArrayOfParams() { $message = new RequestBodyUrlEncoded([ diff --git a/tests/HttpClients/AbstractTestHttpClient.php b/tests/HttpClients/AbstractTestHttpClient.php index 774a13e10..269b235d1 100644 --- a/tests/HttpClients/AbstractTestHttpClient.php +++ b/tests/HttpClients/AbstractTestHttpClient.php @@ -25,14 +25,13 @@ abstract class AbstractTestHttpClient extends \PHPUnit_Framework_TestCase { - - protected $fakeRawRedirectHeader = "HTTP/1.1 302 Found + protected $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 $fakeRawProxyHeader = "HTTP/1.0 200 Connection established\r\n\r\n"; + protected $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 $fakeRawHeader = "HTTP/1.1 200 OK Etag: \"9d86b21aa74d74e574bbb35ba13524a52deb96e3\" Content-Type: text/javascript; charset=UTF-8 X-FB-Rev: 9244768 @@ -44,19 +43,18 @@ abstract class AbstractTestHttpClient extends \PHPUnit_Framework_TestCase 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 = [ - 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', - 'Content-Type' => 'text/javascript; charset=UTF-8', - 'X-FB-Rev' => '9244768', - 'Pragma' => 'no-cache', - 'Expires' => 'Sat, 01 Jan 2000 00:00:00 GMT', - 'Connection' => 'close', - 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', - 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', - 'Content-Length' => '29', - 'Cache-Control' => 'private, no-cache, no-store, must-revalidate', - 'Access-Control-Allow-Origin' => '*', - ]; - + protected $fakeRawBody = "{\"id\":\"123\",\"name\":\"Foo Bar\"}"; + protected $fakeHeadersAsArray = [ + 'Etag' => '"9d86b21aa74d74e574bbb35ba13524a52deb96e3"', + 'Content-Type' => 'text/javascript; charset=UTF-8', + 'X-FB-Rev' => '9244768', + 'Pragma' => 'no-cache', + 'Expires' => 'Sat, 01 Jan 2000 00:00:00 GMT', + 'Connection' => 'close', + 'Date' => 'Mon, 19 May 2014 18:37:17 GMT', + 'X-FB-Debug' => '02QQiffE7JG2rV6i/Agzd0gI2/OOQ2lk5UW0=', + 'Content-Length' => '29', + 'Cache-Control' => 'private, no-cache, no-store, must-revalidate', + 'Access-Control-Allow-Origin' => '*', + ]; } diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 9eaaee094..4cf31d339 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -28,309 +28,307 @@ class FacebookCurlHttpClientTest extends AbstractTestHttpClient { - - /** - * @var \Facebook\HttpClients\FacebookCurl - */ - protected $curlMock; - - /** - * @var FacebookCurlHttpClient - */ - protected $curlClient; - - const CURL_VERSION_STABLE = 0x072400; - const CURL_VERSION_BUGGY = 0x071400; - - public function setUp() - { - $this->curlMock = m::mock('Facebook\HttpClients\FacebookCurl'); - $this->curlClient = new FacebookCurlHttpClient($this->curlMock); - } - - public function testCanOpenGetCurlConnection() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->with(m::on(function($arg) { - - // array_diff() will sometimes trigger error on child-arrays - if (['X-Foo-Header: X-Bar'] !== $arg[CURLOPT_HTTPHEADER]) { - return false; - } - unset($arg[CURLOPT_HTTPHEADER]); - - $caInfo = array_diff($arg, [ - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_URL => 'http://foo.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 123, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_SSL_VERIFYHOST => 2, - CURLOPT_SSL_VERIFYPEER => true, - ]); - - if (count($caInfo) !== 1) { - return false; - } - - if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { - return false; - } - - return true; - })) - ->once() - ->andReturn(null); - - $this->curlClient->openConnection('http://foo.com', 'GET', 'foo_body', ['X-Foo-Header' => 'X-Bar'], 123); - } - - public function testCanOpenCurlConnectionWithPostBody() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->with(m::on(function($arg) { - - // array_diff() will sometimes trigger error on child-arrays - if ([] !== $arg[CURLOPT_HTTPHEADER]) { - return false; - } - unset($arg[CURLOPT_HTTPHEADER]); - - $caInfo = array_diff($arg, [ - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_URL => 'http://bar.com', - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 60, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_SSL_VERIFYHOST => 2, - CURLOPT_SSL_VERIFYPEER => true, - CURLOPT_POSTFIELDS => 'baz=bar', - ]); - - if (count($caInfo) !== 1) { - return false; - } - - if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { - return false; - } - - return true; - })) - ->once() - ->andReturn(null); - - $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', [], 60); - } - - public function testCanCloseConnection() - { - $this->curlMock - ->shouldReceive('close') - ->once() - ->andReturn(null); - - $this->curlClient->closeConnection(); - } - - public function testIsolatesTheHeaderAndBody() - { - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(strlen($this->fakeRawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($this->fakeRawHeader . $this->fakeRawBody); - - $this->curlClient->sendRequest(); - list($rawHeader, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); - - $this->assertEquals($rawHeader, trim($this->fakeRawHeader)); - $this->assertEquals($rawBody, $this->fakeRawBody); - } - - public function testProperlyHandlesProxyHeaders() - { - $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($rawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($rawHeader . $this->fakeRawBody); - - $this->curlClient->sendRequest(); - list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); - - $this->assertEquals($rawHeaders, trim($rawHeader)); - $this->assertEquals($rawBody, $this->fakeRawBody); - } - - public function testProperlyHandlesProxyHeadersWithCurlBug() - { - $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($rawHeader . $this->fakeRawBody); - - $this->curlClient->sendRequest(); - list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); - - $this->assertEquals($rawHeaders, trim($rawHeader)); - $this->assertEquals($rawBody, $this->fakeRawBody); - } - - public function testProperlyHandlesProxyHeadersWithCurlBug2() - { - $rawHeader = $this->fakeRawProxyHeader2 . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($rawHeader . $this->fakeRawBody); - - $this->curlClient->sendRequest(); - list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); - - $this->assertEquals($rawHeaders, trim($rawHeader)); - $this->assertEquals($rawBody, $this->fakeRawBody); - } - - public function testProperlyHandlesRedirectHeaders() - { - $rawHeader = $this->fakeRawRedirectHeader . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($rawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($rawHeader . $this->fakeRawBody); - - $this->curlClient->sendRequest(); - list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); - - $this->assertEquals($rawHeaders, trim($rawHeader)); - $this->assertEquals($rawBody, $this->fakeRawBody); - } - - public function testCanSendNormalRequest() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn($this->fakeRawHeader . $this->fakeRawBody); - $this->curlMock - ->shouldReceive('errno') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); - $this->curlMock - ->shouldReceive('close') - ->once() - ->andReturn(null); - - $response = $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); - - $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); - $this->assertEquals($this->fakeRawBody, $response->getBody()); - $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); - $this->assertEquals(200, $response->getHttpResponseCode()); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testThrowsExceptionOnClientError() - { - $this->curlMock - ->shouldReceive('init') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('setopt_array') - ->once() - ->andReturn(null); - $this->curlMock - ->shouldReceive('exec') - ->once() - ->andReturn(false); - $this->curlMock - ->shouldReceive('errno') - ->once() - ->andReturn(123); - $this->curlMock - ->shouldReceive('error') - ->once() - ->andReturn('Foo error'); - - $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); - } - + /** + * @var \Facebook\HttpClients\FacebookCurl + */ + protected $curlMock; + + /** + * @var FacebookCurlHttpClient + */ + protected $curlClient; + + const CURL_VERSION_STABLE = 0x072400; + const CURL_VERSION_BUGGY = 0x071400; + + public function setUp() + { + $this->curlMock = m::mock('Facebook\HttpClients\FacebookCurl'); + $this->curlClient = new FacebookCurlHttpClient($this->curlMock); + } + + public function testCanOpenGetCurlConnection() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->with(m::on(function ($arg) { + + // array_diff() will sometimes trigger error on child-arrays + if (['X-Foo-Header: X-Bar'] !== $arg[CURLOPT_HTTPHEADER]) { + return false; + } + unset($arg[CURLOPT_HTTPHEADER]); + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'GET', + CURLOPT_URL => 'http://foo.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 123, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) + ->once() + ->andReturn(null); + + $this->curlClient->openConnection('http://foo.com', 'GET', 'foo_body', ['X-Foo-Header' => 'X-Bar'], 123); + } + + public function testCanOpenCurlConnectionWithPostBody() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->with(m::on(function ($arg) { + + // array_diff() will sometimes trigger error on child-arrays + if ([] !== $arg[CURLOPT_HTTPHEADER]) { + return false; + } + unset($arg[CURLOPT_HTTPHEADER]); + + $caInfo = array_diff($arg, [ + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_URL => 'http://bar.com', + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 60, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_POSTFIELDS => 'baz=bar', + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo[CURLOPT_CAINFO])) { + return false; + } + + return true; + })) + ->once() + ->andReturn(null); + + $this->curlClient->openConnection('http://bar.com', 'POST', 'baz=bar', [], 60); + } + + public function testCanCloseConnection() + { + $this->curlMock + ->shouldReceive('close') + ->once() + ->andReturn(null); + + $this->curlClient->closeConnection(); + } + + public function testIsolatesTheHeaderAndBody() + { + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(strlen($this->fakeRawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($this->fakeRawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeader, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeader, trim($this->fakeRawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesProxyHeaders() + { + $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($rawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesProxyHeadersWithCurlBug() + { + $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesProxyHeadersWithCurlBug2() + { + $rawHeader = $this->fakeRawProxyHeader2 . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testProperlyHandlesRedirectHeaders() + { + $rawHeader = $this->fakeRawRedirectHeader . $this->fakeRawHeader; + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($rawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($rawHeader . $this->fakeRawBody); + + $this->curlClient->sendRequest(); + list($rawHeaders, $rawBody) = $this->curlClient->extractResponseHeadersAndBody(); + + $this->assertEquals($rawHeaders, trim($rawHeader)); + $this->assertEquals($rawBody, $this->fakeRawBody); + } + + public function testCanSendNormalRequest() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn($this->fakeRawHeader . $this->fakeRawBody); + $this->curlMock + ->shouldReceive('errno') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('getinfo') + ->with(CURLINFO_HEADER_SIZE) + ->once() + ->andReturn(mb_strlen($this->fakeRawHeader)); + $this->curlMock + ->shouldReceive('version') + ->once() + ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); + $this->curlMock + ->shouldReceive('close') + ->once() + ->andReturn(null); + + $response = $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); + + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testThrowsExceptionOnClientError() + { + $this->curlMock + ->shouldReceive('init') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('setoptArray') + ->once() + ->andReturn(null); + $this->curlMock + ->shouldReceive('exec') + ->once() + ->andReturn(false); + $this->curlMock + ->shouldReceive('errno') + ->once() + ->andReturn(123); + $this->curlMock + ->shouldReceive('error') + ->once() + ->andReturn('Foo error'); + + $this->curlClient->send('http://foo.com/', 'GET', '', [], 60); + } } diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index 1a71d36af..12eb36ae9 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -32,114 +32,112 @@ class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient { - - /** - * @var \GuzzleHttp\Client - */ - protected $guzzleMock; - - /** - * @var FacebookGuzzleHttpClient - */ - protected $guzzleClient; - - public function setUp() - { - $this->guzzleMock = m::mock('GuzzleHttp\Client'); - $this->guzzleClient = new FacebookGuzzleHttpClient($this->guzzleMock); - } - - public function testCanSendNormalRequest() - { - $request = new Request('GET', 'http://foo.com'); - - $body = Stream::factory($this->fakeRawBody); - $response = new Response(200, $this->fakeHeadersAsArray, $body); - - $this->guzzleMock - ->shouldReceive('createRequest') - ->once() - ->with('GET', 'http://foo.com/', m::on(function($arg) { - - // array_diff_assoc() will sometimes trigger error on child-arrays - if (['X-foo' => 'bar'] !== $arg['headers']) { - return false; - } - unset($arg['headers']); - - $caInfo = array_diff_assoc($arg, [ - 'body' => 'foo_body', - 'timeout' => 123, - 'connect_timeout' => 10, - ]); - - if (count($caInfo) !== 1) { - return false; - } - - if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { - return false; - } - - return true; - })) - ->andReturn($request); - $this->guzzleMock - ->shouldReceive('send') - ->once() - ->with($request) - ->andReturn($response); - - $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); - - $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); - $this->assertEquals($this->fakeRawBody, $response->getBody()); - $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); - $this->assertEquals(200, $response->getHttpResponseCode()); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testThrowsExceptionOnClientError() - { - $request = new Request('GET', 'http://foo.com'); - - $this->guzzleMock - ->shouldReceive('createRequest') - ->once() - ->with('GET', 'http://foo.com/', m::on(function($arg) { - - // array_diff_assoc() will sometimes trigger error on child-arrays - if ([] !== $arg['headers']) { - return false; - } - unset($arg['headers']); - - $caInfo = array_diff_assoc($arg, [ - 'body' => 'foo_body', - 'timeout' => 60, - 'connect_timeout' => 10, - ]); - - if (count($caInfo) !== 1) { - return false; - } - - if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { - return false; - } - - return true; - })) - ->andReturn($request); - $this->guzzleMock - ->shouldReceive('send') - ->once() - ->with($request) - ->andThrow(new RequestException('Foo', $request)); - - $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); - } - + /** + * @var \GuzzleHttp\Client + */ + protected $guzzleMock; + + /** + * @var FacebookGuzzleHttpClient + */ + protected $guzzleClient; + + public function setUp() + { + $this->guzzleMock = m::mock('GuzzleHttp\Client'); + $this->guzzleClient = new FacebookGuzzleHttpClient($this->guzzleMock); + } + + public function testCanSendNormalRequest() + { + $request = new Request('GET', 'http://foo.com'); + + $body = Stream::factory($this->fakeRawBody); + $response = new Response(200, $this->fakeHeadersAsArray, $body); + + $this->guzzleMock + ->shouldReceive('createRequest') + ->once() + ->with('GET', 'http://foo.com/', m::on(function ($arg) { + + // array_diff_assoc() will sometimes trigger error on child-arrays + if (['X-foo' => 'bar'] !== $arg['headers']) { + return false; + } + unset($arg['headers']); + + $caInfo = array_diff_assoc($arg, [ + 'body' => 'foo_body', + 'timeout' => 123, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); + $this->guzzleMock + ->shouldReceive('send') + ->once() + ->with($request) + ->andReturn($response); + + $response = $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); + + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testThrowsExceptionOnClientError() + { + $request = new Request('GET', 'http://foo.com'); + + $this->guzzleMock + ->shouldReceive('createRequest') + ->once() + ->with('GET', 'http://foo.com/', m::on(function ($arg) { + + // array_diff_assoc() will sometimes trigger error on child-arrays + if ([] !== $arg['headers']) { + return false; + } + unset($arg['headers']); + + $caInfo = array_diff_assoc($arg, [ + 'body' => 'foo_body', + 'timeout' => 60, + 'connect_timeout' => 10, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['verify'])) { + return false; + } + + return true; + })) + ->andReturn($request); + $this->guzzleMock + ->shouldReceive('send') + ->once() + ->with($request) + ->andThrow(new RequestException('Foo', $request)); + + $this->guzzleClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); + } } diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index 9f9247c5f..9102b08df 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -28,108 +28,107 @@ class FacebookStreamHttpClientTest extends AbstractTestHttpClient { - - /** - * @var \Facebook\HttpClients\FacebookStream - */ - protected $streamMock; - - /** - * @var FacebookStreamHttpClient - */ - protected $streamClient; - - public function setUp() - { - $this->streamMock = m::mock('Facebook\HttpClients\FacebookStream'); - $this->streamClient = new FacebookStreamHttpClient($this->streamMock); - } - - public function testCanCompileHeader() - { - $headers = [ - 'X-foo' => 'bar', - 'X-bar' => 'faz', - ]; - $header = $this->streamClient->compileHeader($headers); - $this->assertEquals("X-foo: bar\r\nX-bar: faz", $header); - } - - public function testCanSendNormalRequest() - { - $this->streamMock - ->shouldReceive('streamContextCreate') - ->once() - ->with(m::on(function($arg) { - if ( ! isset($arg['http']) || ! isset($arg['ssl'])) { - return false; - } - - if ($arg['http'] !== [ - 'method' => 'GET', - 'header' => 'X-foo: bar', - 'content' => 'foo_body', - 'timeout' => 123, - 'ignore_errors' => true, - ]) { - return false; - } - - $caInfo = array_diff_assoc($arg['ssl'], [ - 'verify_peer' => true, - 'verify_peer_name' => true, - 'allow_self_signed' => true, - ]); - - if (count($caInfo) !== 1) { - return false; - } - - if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['cafile'])) { - return false; - } - - return true; - })) - ->andReturn(null); - $this->streamMock - ->shouldReceive('getResponseHeaders') - ->once() - ->andReturn(explode("\n", trim($this->fakeRawHeader))); - $this->streamMock - ->shouldReceive('fileGetContents') - ->once() - ->with('http://foo.com/') - ->andReturn($this->fakeRawBody); - - $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); - - $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); - $this->assertEquals($this->fakeRawBody, $response->getBody()); - $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); - $this->assertEquals(200, $response->getHttpResponseCode()); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testThrowsExceptionOnClientError() - { - $this->streamMock - ->shouldReceive('streamContextCreate') - ->once() - ->andReturn(null); - $this->streamMock - ->shouldReceive('getResponseHeaders') - ->once() - ->andReturn(null); - $this->streamMock - ->shouldReceive('fileGetContents') - ->once() - ->with('http://foo.com/') - ->andReturn(false); - - $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); - } - + /** + * @var \Facebook\HttpClients\FacebookStream + */ + protected $streamMock; + + /** + * @var FacebookStreamHttpClient + */ + protected $streamClient; + + public function setUp() + { + $this->streamMock = m::mock('Facebook\HttpClients\FacebookStream'); + $this->streamClient = new FacebookStreamHttpClient($this->streamMock); + } + + public function testCanCompileHeader() + { + $headers = [ + 'X-foo' => 'bar', + 'X-bar' => 'faz', + ]; + $header = $this->streamClient->compileHeader($headers); + $this->assertEquals("X-foo: bar\r\nX-bar: faz", $header); + } + + public function testCanSendNormalRequest() + { + $this->streamMock + ->shouldReceive('streamContextCreate') + ->once() + ->with(m::on(function ($arg) { + if (!isset($arg['http']) || !isset($arg['ssl'])) { + return false; + } + + if ($arg['http'] !== [ + 'method' => 'GET', + 'header' => 'X-foo: bar', + 'content' => 'foo_body', + 'timeout' => 123, + 'ignore_errors' => true, + ] + ) { + return false; + } + + $caInfo = array_diff_assoc($arg['ssl'], [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, + ]); + + if (count($caInfo) !== 1) { + return false; + } + + if (1 !== preg_match('/.+\/certs\/DigiCertHighAssuranceEVRootCA\.pem$/', $caInfo['cafile'])) { + return false; + } + + return true; + })) + ->andReturn(null); + $this->streamMock + ->shouldReceive('getResponseHeaders') + ->once() + ->andReturn(explode("\n", trim($this->fakeRawHeader))); + $this->streamMock + ->shouldReceive('fileGetContents') + ->once() + ->with('http://foo.com/') + ->andReturn($this->fakeRawBody); + + $response = $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', ['X-foo' => 'bar'], 123); + + $this->assertInstanceOf('Facebook\Http\GraphRawResponse', $response); + $this->assertEquals($this->fakeRawBody, $response->getBody()); + $this->assertEquals($this->fakeHeadersAsArray, $response->getHeaders()); + $this->assertEquals(200, $response->getHttpResponseCode()); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testThrowsExceptionOnClientError() + { + $this->streamMock + ->shouldReceive('streamContextCreate') + ->once() + ->andReturn(null); + $this->streamMock + ->shouldReceive('getResponseHeaders') + ->once() + ->andReturn(null); + $this->streamMock + ->shouldReceive('fileGetContents') + ->once() + ->with('http://foo.com/') + ->andReturn(false); + + $this->streamClient->send('http://foo.com/', 'GET', 'foo_body', [], 60); + } } diff --git a/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php b/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php index 6940864db..2b09d29cf 100644 --- a/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php +++ b/tests/PersistentData/FacebookMemoryPersistentDataHandlerTest.php @@ -27,22 +27,20 @@ class FacebookMemoryPersistentDataHandlerTest extends \PHPUnit_Framework_TestCase { + public function testCanGetAndSetAVirtualValue() + { + $handler = new FacebookMemoryPersistentDataHandler(); + $handler->set('foo', 'bar'); + $value = $handler->get('foo'); - public function testCanGetAndSetAVirtualValue() - { - $handler = new FacebookMemoryPersistentDataHandler(); - $handler->set('foo', 'bar'); - $value = $handler->get('foo'); + $this->assertEquals('bar', $value); + } - $this->assertEquals('bar', $value); - } - - public function testGettingAValueThatDoesntExistWillReturnNull() - { - $handler = new FacebookMemoryPersistentDataHandler(); - $value = $handler->get('does_not_exist'); - - $this->assertNull($value); - } + public function testGettingAValueThatDoesntExistWillReturnNull() + { + $handler = new FacebookMemoryPersistentDataHandler(); + $value = $handler->get('does_not_exist'); + $this->assertNull($value); + } } diff --git a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php index 1035d72f6..e21d36618 100644 --- a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php +++ b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php @@ -27,38 +27,36 @@ class FacebookSessionPersistentDataHandlerTest extends \PHPUnit_Framework_TestCase { - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testInactiveSessionsWillThrow() - { - $handler = new FacebookSessionPersistentDataHandler(); - } - - public function testCanSetAValue() - { - $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); - $handler->set('foo', 'bar'); - - $this->assertEquals('bar', $_SESSION['FBRLH_foo']); - } - - public function testCanGetAValue() - { - $_SESSION['FBRLH_faz'] = 'baz'; - $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); - $value = $handler->get('faz'); - - $this->assertEquals('baz', $value); - } - - public function testGettingAValueThatDoesntExistWillReturnNull() - { - $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); - $value = $handler->get('does_not_exist'); - - $this->assertNull($value); - } - + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInactiveSessionsWillThrow() + { + $handler = new FacebookSessionPersistentDataHandler(); + } + + public function testCanSetAValue() + { + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $handler->set('foo', 'bar'); + + $this->assertEquals('bar', $_SESSION['FBRLH_foo']); + } + + public function testCanGetAValue() + { + $_SESSION['FBRLH_faz'] = 'baz'; + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $value = $handler->get('faz'); + + $this->assertEquals('baz', $value); + } + + public function testGettingAValueThatDoesntExistWillReturnNull() + { + $handler = new FacebookSessionPersistentDataHandler($enableSessionCheck = false); + $value = $handler->get('does_not_exist'); + + $this->assertNull($value); + } } diff --git a/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php index 66ec9c4c3..a45a3cf07 100644 --- a/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php +++ b/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php @@ -27,20 +27,18 @@ class McryptPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase { + public function testCanGenerateRandomStringOfArbitraryLength() + { + if (!function_exists('mcrypt_create_iv')) { + $this->markTestSkipped( + 'Mcrypt must be installed to test mcrypt_create_iv().' + ); + } - public function testCanGenerateRandomStringOfArbitraryLength() - { - if ( ! function_exists('mcrypt_create_iv')) { - $this->markTestSkipped( - 'Mcrypt must be installed to test mcrypt_create_iv().' - ); - } - - $prsg = new McryptPseudoRandomStringGenerator(); - $randomString = $prsg->getPseudoRandomString(10); - - $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); - $this->assertEquals(10, mb_strlen($randomString)); - } + $prsg = new McryptPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } } diff --git a/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php index 0284aca81..c740d0b1a 100644 --- a/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php +++ b/tests/PseudoRandomString/OpenSslPseudoRandomStringGeneratorTest.php @@ -27,20 +27,18 @@ class OpenSslPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase { + public function testCanGenerateRandomStringOfArbitraryLength() + { + if (!function_exists('openssl_random_pseudo_bytes')) { + $this->markTestSkipped( + 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' + ); + } - public function testCanGenerateRandomStringOfArbitraryLength() - { - if ( ! function_exists('openssl_random_pseudo_bytes')) { - $this->markTestSkipped( - 'The OpenSSL extension must be enabled to test openssl_random_pseudo_bytes().' - ); - } - - $prsg = new OpenSslPseudoRandomStringGenerator(); - $randomString = $prsg->getPseudoRandomString(10); - - $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); - $this->assertEquals(10, mb_strlen($randomString)); - } + $prsg = new OpenSslPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } } diff --git a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php index 313d965ed..ea3a1f83c 100644 --- a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php +++ b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php @@ -27,28 +27,26 @@ class MyFooBarPseudoRandomStringGenerator { - use PseudoRandomStringGeneratorTrait; + use PseudoRandomStringGeneratorTrait; } class PseudoRandomStringGeneratorTraitTest extends \PHPUnit_Framework_TestCase { + /** + * @expectedException \InvalidArgumentException + */ + public function testAnInvalidLengthWillThrow() + { + $prsg = new MyFooBarPseudoRandomStringGenerator(); + $prsg->validateLength('foo_len'); + } - /** - * @expectedException \InvalidArgumentException - */ - public function testAnInvalidLengthWillThrow() - { - $prsg = new MyFooBarPseudoRandomStringGenerator(); - $prsg->validateLength('foo_len'); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testALengthThatIsNotAtLeastOneCharacterWillThrow() - { - $prsg = new MyFooBarPseudoRandomStringGenerator(); - $prsg->validateLength(0); - } - + /** + * @expectedException \InvalidArgumentException + */ + public function testALengthThatIsNotAtLeastOneCharacterWillThrow() + { + $prsg = new MyFooBarPseudoRandomStringGenerator(); + $prsg->validateLength(0); + } } diff --git a/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php index b95a6b8ee..9e12a58ba 100644 --- a/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php +++ b/tests/PseudoRandomString/UrandomPseudoRandomStringGeneratorTest.php @@ -27,26 +27,24 @@ class UrandomPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase { + public function testCanGenerateRandomStringOfArbitraryLength() + { + if (ini_get('open_basedir')) { + $this->markTestSkipped( + 'Cannot test /dev/urandom generator due to open_basedir constraint.' + ); + } - public function testCanGenerateRandomStringOfArbitraryLength() - { - if (ini_get('open_basedir')) { - $this->markTestSkipped( - 'Cannot test /dev/urandom generator due to open_basedir constraint.' - ); - } - - if ( ! is_readable('/dev/urandom')) { - $this->markTestSkipped( - '/dev/urandom not found or is not readable.' - ); - } + if (!is_readable('/dev/urandom')) { + $this->markTestSkipped( + '/dev/urandom not found or is not readable.' + ); + } - $prsg = new UrandomPseudoRandomStringGenerator(); - $randomString = $prsg->getPseudoRandomString(10); - - $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); - $this->assertEquals(10, mb_strlen($randomString)); - } + $prsg = new UrandomPseudoRandomStringGenerator(); + $randomString = $prsg->getPseudoRandomString(10); + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, mb_strlen($randomString)); + } } diff --git a/tests/SignedRequestTest.php b/tests/SignedRequestTest.php index e47cd59ab..247600f83 100644 --- a/tests/SignedRequestTest.php +++ b/tests/SignedRequestTest.php @@ -28,114 +28,112 @@ class SignedRequestTest extends \PHPUnit_Framework_TestCase { - - /** - * @var FacebookApp - */ - protected $app; - - protected $rawSignature = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8='; - protected $rawPayload = 'eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; - - protected $payloadData = [ - 'oauth_token' => 'foo_token', - 'algorithm' => 'HMAC-SHA256', - 'issued_at' => 321, - 'code' => 'foo_code', - 'state' => 'foo_state', - 'user_id' => 123, - 'foo' => 'bar', - ]; - - public function setUp() - { - $this->app = new FacebookApp('123', 'foo_app_secret'); - } - - public function testAValidSignedRequestCanBeCreated() - { - $sr = new SignedRequest($this->app); - $rawSignedRequest = $sr->make($this->payloadData); - - $srTwo = new SignedRequest($this->app, $rawSignedRequest); - $payload = $srTwo->getPayload(); - - $expectedRawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; - $this->assertEquals($expectedRawSignedRequest, $rawSignedRequest); - $this->assertEquals($this->payloadData, $payload); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testInvalidSignedRequestsWillFailFormattingValidation() - { - new SignedRequest($this->app, 'invalid_signed_request'); - } - - public function testBase64EncodingIsUrlSafe() - { - $sr = new SignedRequest($this->app); - $encodedData = $sr->base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); - - $this->assertEquals('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4_Lnx-', $encodedData); - } - - public function testAUrlSafeBase64EncodedStringCanBeDecoded() - { - $sr = new SignedRequest($this->app); - $decodedData = $sr->base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); - - $this->assertEquals('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~', $decodedData); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAnImproperlyEncodedSignatureWillThrowAnException() - { - new SignedRequest($this->app, 'foo_sig.' . $this->rawPayload); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testAnImproperlyEncodedPayloadWillThrowAnException() - { - new SignedRequest($this->app, $this->rawSignature . '.foo_payload'); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookSDKException - */ - public function testNonApprovedAlgorithmsWillThrowAnException() - { - $signedRequestData = $this->payloadData; - $signedRequestData['algorithm'] = 'FOO-ALGORITHM'; - - $sr = new SignedRequest($this->app); - $rawSignedRequest = $sr->make($signedRequestData); - - new SignedRequest($this->app, $rawSignedRequest); - } - - public function testAsRawSignedRequestCanBeValidatedAndDecoded() - { - $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; - $sr = new SignedRequest($this->app, $rawSignedRequest); - - $this->assertEquals($this->payloadData, $sr->getPayload()); - } - - public function testARawSignedRequestCanBeValidatedAndDecoded() - { - $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; - $sr = new SignedRequest($this->app, $rawSignedRequest); - - $this->assertEquals($sr->getPayload(), $this->payloadData); - $this->assertEquals($sr->getRawSignedRequest(), $rawSignedRequest); - $this->assertEquals(123, $sr->getUserId()); - $this->assertTrue($sr->hasOAuthData()); - } - + /** + * @var FacebookApp + */ + protected $app; + + protected $rawSignature = 'U0_O1MqqNKUt32633zAkdd2Ce-jGVgRgJeRauyx_zC8='; + protected $rawPayload = 'eyJvYXV0aF90b2tlbiI6ImZvb190b2tlbiIsImFsZ29yaXRobSI6IkhNQUMtU0hBMjU2IiwiaXNzdWVkX2F0IjozMjEsImNvZGUiOiJmb29fY29kZSIsInN0YXRlIjoiZm9vX3N0YXRlIiwidXNlcl9pZCI6MTIzLCJmb28iOiJiYXIifQ=='; + + protected $payloadData = [ + 'oauth_token' => 'foo_token', + 'algorithm' => 'HMAC-SHA256', + 'issued_at' => 321, + 'code' => 'foo_code', + 'state' => 'foo_state', + 'user_id' => 123, + 'foo' => 'bar', + ]; + + public function setUp() + { + $this->app = new FacebookApp('123', 'foo_app_secret'); + } + + public function testAValidSignedRequestCanBeCreated() + { + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($this->payloadData); + + $srTwo = new SignedRequest($this->app, $rawSignedRequest); + $payload = $srTwo->getPayload(); + + $expectedRawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $this->assertEquals($expectedRawSignedRequest, $rawSignedRequest); + $this->assertEquals($this->payloadData, $payload); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testInvalidSignedRequestsWillFailFormattingValidation() + { + new SignedRequest($this->app, 'invalid_signed_request'); + } + + public function testBase64EncodingIsUrlSafe() + { + $sr = new SignedRequest($this->app); + $encodedData = $sr->base64UrlEncode('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~'); + + $this->assertEquals('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4_Lnx-', $encodedData); + } + + public function testAUrlSafeBase64EncodedStringCanBeDecoded() + { + $sr = new SignedRequest($this->app); + $decodedData = $sr->base64UrlDecode('YWlqa29wcnN0QURJSktMT1BRVFVWWDEyNTYhKV0tOjsiPD4/Lnx+'); + + $this->assertEquals('aijkoprstADIJKLOPQTUVX1256!)]-:;"<>?.|~', $decodedData); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnImproperlyEncodedSignatureWillThrowAnException() + { + new SignedRequest($this->app, 'foo_sig.' . $this->rawPayload); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testAnImproperlyEncodedPayloadWillThrowAnException() + { + new SignedRequest($this->app, $this->rawSignature . '.foo_payload'); + } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testNonApprovedAlgorithmsWillThrowAnException() + { + $signedRequestData = $this->payloadData; + $signedRequestData['algorithm'] = 'FOO-ALGORITHM'; + + $sr = new SignedRequest($this->app); + $rawSignedRequest = $sr->make($signedRequestData); + + new SignedRequest($this->app, $rawSignedRequest); + } + + public function testAsRawSignedRequestCanBeValidatedAndDecoded() + { + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); + + $this->assertEquals($this->payloadData, $sr->getPayload()); + } + + public function testARawSignedRequestCanBeValidatedAndDecoded() + { + $rawSignedRequest = $this->rawSignature . '.' . $this->rawPayload; + $sr = new SignedRequest($this->app, $rawSignedRequest); + + $this->assertEquals($sr->getPayload(), $this->payloadData); + $this->assertEquals($sr->getRawSignedRequest(), $rawSignedRequest); + $this->assertEquals(123, $sr->getUserId()); + $this->assertTrue($sr->hasOAuthData()); + } } diff --git a/tests/Url/FacebookUrlDetectionHandlerTest.php b/tests/Url/FacebookUrlDetectionHandlerTest.php index 77c16ea62..c3127ef50 100644 --- a/tests/Url/FacebookUrlDetectionHandlerTest.php +++ b/tests/Url/FacebookUrlDetectionHandlerTest.php @@ -27,110 +27,108 @@ class FacebookUrlDetectionHandlerTest extends \PHPUnit_Framework_TestCase { - - public function testProperlyGeneratesUrlFromCommonScenario() - { - $_SERVER = [ - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '80', - 'REQUEST_URI' => '/baz?foo=123', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); - } - - public function testProperlyGeneratesSecureUrlFromCommonScenario() - { - $_SERVER = [ - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '443', - 'REQUEST_URI' => '/baz?foo=123', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); - } - - public function testProperlyGeneratesUrlFromProxy() - { - $_SERVER = [ - 'HTTP_X_FORWARDED_PORT' => '80', - 'HTTP_X_FORWARDED_PROTO' => 'http', - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '80', - 'REQUEST_URI' => '/baz?foo=123', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); - } - - public function testProperlyGeneratesSecureUrlFromProxy() - { - $_SERVER = [ - 'HTTP_X_FORWARDED_PORT' => '443', - 'HTTP_X_FORWARDED_PROTO' => 'https', - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '80', - 'REQUEST_URI' => '/baz?foo=123', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); - } - - public function testProperlyGeneratesUrlWithCustomPort() - { - $_SERVER = [ - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '1337', - 'REQUEST_URI' => '/foo.php', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('http://foo.bar:1337/foo.php', $currentUri); - } - - public function testProperlyGeneratesSecureUrlWithCustomPort() - { - $_SERVER = [ - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '1337', - 'REQUEST_URI' => '/foo.php', - 'HTTPS' => 'On', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('https://foo.bar:1337/foo.php', $currentUri); - } - - public function testProperlyGeneratesUrlWithCustomPortFromProxy() - { - $_SERVER = [ - 'HTTP_X_FORWARDED_PORT' => '8888', - 'HTTP_X_FORWARDED_PROTO' => 'http', - 'HTTP_HOST' => 'foo.bar', - 'SERVER_PORT' => '80', - 'REQUEST_URI' => '/foo.php', - ]; - - $urlHandler = new FacebookUrlDetectionHandler(); - $currentUri = $urlHandler->getCurrentUrl(); - - $this->assertEquals('http://foo.bar:8888/foo.php', $currentUri); - } - + public function testProperlyGeneratesUrlFromCommonScenario() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesSecureUrlFromCommonScenario() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '443', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesUrlFromProxy() + { + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '80', + 'HTTP_X_FORWARDED_PROTO' => 'http', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesSecureUrlFromProxy() + { + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '443', + 'HTTP_X_FORWARDED_PROTO' => 'https', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/baz?foo=123', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar/baz?foo=123', $currentUri); + } + + public function testProperlyGeneratesUrlWithCustomPort() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '1337', + 'REQUEST_URI' => '/foo.php', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar:1337/foo.php', $currentUri); + } + + public function testProperlyGeneratesSecureUrlWithCustomPort() + { + $_SERVER = [ + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '1337', + 'REQUEST_URI' => '/foo.php', + 'HTTPS' => 'On', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('https://foo.bar:1337/foo.php', $currentUri); + } + + public function testProperlyGeneratesUrlWithCustomPortFromProxy() + { + $_SERVER = [ + 'HTTP_X_FORWARDED_PORT' => '8888', + 'HTTP_X_FORWARDED_PROTO' => 'http', + 'HTTP_HOST' => 'foo.bar', + 'SERVER_PORT' => '80', + 'REQUEST_URI' => '/foo.php', + ]; + + $urlHandler = new FacebookUrlDetectionHandler(); + $currentUri = $urlHandler->getCurrentUrl(); + + $this->assertEquals('http://foo.bar:8888/foo.php', $currentUri); + } } diff --git a/tests/Url/FacebookUrlManipulatorTest.php b/tests/Url/FacebookUrlManipulatorTest.php index 3729cb6a0..c58e2b3d1 100644 --- a/tests/Url/FacebookUrlManipulatorTest.php +++ b/tests/Url/FacebookUrlManipulatorTest.php @@ -27,193 +27,191 @@ class FacebookUrlManipulatorTest extends \PHPUnit_Framework_TestCase { - - /** - * @dataProvider provideUris - */ - public function testParamsGetRemovedFromAUrl($dirtyUrl, $expectedCleanUrl) - { - $removeParams = [ - 'state', - 'code', - 'error', - 'error_reason', - 'error_description', - 'error_code', - ]; - $currentUri = FacebookUrlManipulator::removeParamsFromUrl($dirtyUrl, $removeParams); - $this->assertEquals($expectedCleanUrl, $currentUri); - } - - public function provideUris() - { - return [ - [ - 'http://localhost/something?state=0000&foo=bar&code=abcd', - 'http://localhost/something?foo=bar', - ], - [ - 'https://localhost/something?state=0000&foo=bar&code=abcd', - 'https://localhost/something?foo=bar', - ], - [ - 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', - 'http://localhost/something?foo=bar', - ], - [ - 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', - 'https://localhost/something?foo=bar', - ], - [ - 'http://localhost/something?state=0000&foo=bar&error=abcd', - 'http://localhost/something?foo=bar', - ], - [ - 'https://localhost/something?state=0000&foo=bar&error=abcd', - 'https://localhost/something?foo=bar', - ], - [ - 'https://localhost:1337/something?state=0000&foo=bar&error=abcd', - 'https://localhost:1337/something?foo=bar', - ], - [ - 'https://localhost:1337/something?state=0000&code=foo', - 'https://localhost:1337/something', - ], - [ - 'https://localhost/something/?state=0000&code=foo&foo=bar', - 'https://localhost/something/?foo=bar', - ], - [ - 'https://localhost/something/?state=0000&code=foo', - 'https://localhost/something/', - ], - ]; - } - - public function testGracefullyHandlesUrlAppending() - { - $params = []; - $url = 'https://www.foo.com/'; - $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/', $processed_url); - - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/'; - $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); - - $params = [ - 'access_token' => 'foo', - 'bar' => 'baz', - ]; - $url = 'https://www.foo.com/?foo=bar'; - $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); - - $params = [ - 'access_token' => 'foo', - ]; - $url = 'https://www.foo.com/?foo=bar&access_token=bar'; - $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); - $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); - } - - public function testSlashesAreProperlyPrepended() - { - $slashTestOne = FacebookUrlManipulator::forceSlashPrefix('foo'); - $slashTestTwo = FacebookUrlManipulator::forceSlashPrefix('/foo'); - $slashTestThree = FacebookUrlManipulator::forceSlashPrefix('foo/bar'); - $slashTestFour = FacebookUrlManipulator::forceSlashPrefix('/foo/bar'); - $slashTestFive = FacebookUrlManipulator::forceSlashPrefix(null); - $slashTestSix = FacebookUrlManipulator::forceSlashPrefix(''); - - $this->assertEquals('/foo', $slashTestOne); - $this->assertEquals('/foo', $slashTestTwo); - $this->assertEquals('/foo/bar', $slashTestThree); - $this->assertEquals('/foo/bar', $slashTestFour); - $this->assertEquals(null, $slashTestFive); - $this->assertEquals('', $slashTestSix); - } - - public function testParamsCanBeReturnedAsArray() - { - $paramsOne = FacebookUrlManipulator::getParamsAsArray('/foo'); - $paramsTwo = FacebookUrlManipulator::getParamsAsArray('/foo?one=1&two=2'); - $paramsThree = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com'); - $paramsFour = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?'); - $paramsFive = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?foo=bar'); - - $this->assertEquals([], $paramsOne); - $this->assertEquals(['one' => '1', 'two' => '2'], $paramsTwo); - $this->assertEquals([], $paramsThree); - $this->assertEquals([], $paramsFour); - $this->assertEquals(['foo' => 'bar'], $paramsFive); - } - - /** - * @dataProvider provideMergableEndpoints - */ - public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) - { - $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); - - $this->assertEquals($result, $expected); - } - - public function provideMergableEndpoints() - { - return [ - [ - 'https://www.foo.com/?foo=ignore_foo&dance=fun', - '/me?foo=keep_foo', - '/me?dance=fun&foo=keep_foo', - ], - [ - 'https://www.bar.com?', - 'https://foo.com?foo=bar', - 'https://foo.com?foo=bar', - ], - [ - 'you', - 'me', - 'me', - ], - [ - '/1234?swing=fun', - '/1337?bar=baz&west=coast', - '/1337?bar=baz&swing=fun&west=coast', - ], - ]; - } - - public function testGraphUrlsCanBeTrimmed() - { - $fullGraphUrl = 'https://graph.facebook.com/'; - $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); - $this->assertEquals('/', $baseGraphUrl); - - $fullGraphUrl = 'https://graph.facebook.com/v1.0/'; - $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); - $this->assertEquals('/', $baseGraphUrl); - - $fullGraphUrl = 'https://graph.facebook.com/me'; - $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); - $this->assertEquals('/me', $baseGraphUrl); - - $fullGraphUrl = 'https://graph.beta.facebook.com/me'; - $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); - $this->assertEquals('/me', $baseGraphUrl); - - $fullGraphUrl = 'https://whatever-they-want.facebook.com/v2.1/me'; - $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); - $this->assertEquals('/me', $baseGraphUrl); - - $fullGraphUrl = 'https://graph.facebook.com/v5.301/1233?foo=bar'; - $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); - $this->assertEquals('/1233?foo=bar', $baseGraphUrl); - } - + /** + * @dataProvider provideUris + */ + public function testParamsGetRemovedFromAUrl($dirtyUrl, $expectedCleanUrl) + { + $removeParams = [ + 'state', + 'code', + 'error', + 'error_reason', + 'error_description', + 'error_code', + ]; + $currentUri = FacebookUrlManipulator::removeParamsFromUrl($dirtyUrl, $removeParams); + $this->assertEquals($expectedCleanUrl, $currentUri); + } + + public function provideUris() + { + return [ + [ + 'http://localhost/something?state=0000&foo=bar&code=abcd', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&code=abcd', + 'https://localhost/something?foo=bar', + ], + [ + 'http://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&error=abcd&error_reason=abcd&error_description=abcd&error_code=1', + 'https://localhost/something?foo=bar', + ], + [ + 'http://localhost/something?state=0000&foo=bar&error=abcd', + 'http://localhost/something?foo=bar', + ], + [ + 'https://localhost/something?state=0000&foo=bar&error=abcd', + 'https://localhost/something?foo=bar', + ], + [ + 'https://localhost:1337/something?state=0000&foo=bar&error=abcd', + 'https://localhost:1337/something?foo=bar', + ], + [ + 'https://localhost:1337/something?state=0000&code=foo', + 'https://localhost:1337/something', + ], + [ + 'https://localhost/something/?state=0000&code=foo&foo=bar', + 'https://localhost/something/?foo=bar', + ], + [ + 'https://localhost/something/?state=0000&code=foo', + 'https://localhost/something/', + ], + ]; + } + + public function testGracefullyHandlesUrlAppending() + { + $params = []; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo', $processed_url); + + $params = [ + 'access_token' => 'foo', + 'bar' => 'baz', + ]; + $url = 'https://www.foo.com/?foo=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=foo&bar=baz&foo=bar', $processed_url); + + $params = [ + 'access_token' => 'foo', + ]; + $url = 'https://www.foo.com/?foo=bar&access_token=bar'; + $processed_url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + $this->assertEquals('https://www.foo.com/?access_token=bar&foo=bar', $processed_url); + } + + public function testSlashesAreProperlyPrepended() + { + $slashTestOne = FacebookUrlManipulator::forceSlashPrefix('foo'); + $slashTestTwo = FacebookUrlManipulator::forceSlashPrefix('/foo'); + $slashTestThree = FacebookUrlManipulator::forceSlashPrefix('foo/bar'); + $slashTestFour = FacebookUrlManipulator::forceSlashPrefix('/foo/bar'); + $slashTestFive = FacebookUrlManipulator::forceSlashPrefix(null); + $slashTestSix = FacebookUrlManipulator::forceSlashPrefix(''); + + $this->assertEquals('/foo', $slashTestOne); + $this->assertEquals('/foo', $slashTestTwo); + $this->assertEquals('/foo/bar', $slashTestThree); + $this->assertEquals('/foo/bar', $slashTestFour); + $this->assertEquals(null, $slashTestFive); + $this->assertEquals('', $slashTestSix); + } + + public function testParamsCanBeReturnedAsArray() + { + $paramsOne = FacebookUrlManipulator::getParamsAsArray('/foo'); + $paramsTwo = FacebookUrlManipulator::getParamsAsArray('/foo?one=1&two=2'); + $paramsThree = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com'); + $paramsFour = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?'); + $paramsFive = FacebookUrlManipulator::getParamsAsArray('https://www.foo.com/?foo=bar'); + + $this->assertEquals([], $paramsOne); + $this->assertEquals(['one' => '1', 'two' => '2'], $paramsTwo); + $this->assertEquals([], $paramsThree); + $this->assertEquals([], $paramsFour); + $this->assertEquals(['foo' => 'bar'], $paramsFive); + } + + /** + * @dataProvider provideMergableEndpoints + */ + public function testParamsCanBeMergedOntoUrlProperly($urlOne, $urlTwo, $expected) + { + $result = FacebookUrlManipulator::mergeUrlParams($urlOne, $urlTwo); + + $this->assertEquals($result, $expected); + } + + public function provideMergableEndpoints() + { + return [ + [ + 'https://www.foo.com/?foo=ignore_foo&dance=fun', + '/me?foo=keep_foo', + '/me?dance=fun&foo=keep_foo', + ], + [ + 'https://www.bar.com?', + 'https://foo.com?foo=bar', + 'https://foo.com?foo=bar', + ], + [ + 'you', + 'me', + 'me', + ], + [ + '/1234?swing=fun', + '/1337?bar=baz&west=coast', + '/1337?bar=baz&swing=fun&west=coast', + ], + ]; + } + + public function testGraphUrlsCanBeTrimmed() + { + $fullGraphUrl = 'https://graph.facebook.com/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v1.0/'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.beta.facebook.com/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://whatever-they-want.facebook.com/v2.1/me'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/me', $baseGraphUrl); + + $fullGraphUrl = 'https://graph.facebook.com/v5.301/1233?foo=bar'; + $baseGraphUrl = FacebookUrlManipulator::baseGraphUrlEndpoint($fullGraphUrl); + $this->assertEquals('/1233?foo=bar', $baseGraphUrl); + } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index dfc4c4da2..4b048361e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -28,7 +28,6 @@ use Facebook\FacebookClient; // Delete the temp test user after all tests have fired -register_shutdown_function(function () -{ - //echo "\nTotal requests made to Graph: " . FacebookClient::$requestCount . "\n\n"; +register_shutdown_function(function () { + //echo "\nTotal requests made to Graph: " . FacebookClient::$requestCount . "\n\n"; }); From f8e445db49d2ba10049396944068433da5b3e9fb Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 18 Feb 2015 17:05:54 -0600 Subject: [PATCH 126/407] Finished up docs --- CHANGELOG.md | 2 +- README.md | 60 +++---- docs/AccessToken.fbmd | 2 +- docs/Facebook.fbmd | 2 +- docs/FacebookBatchRequest.fbmd | 23 +-- docs/FacebookCanvasHelper.fbmd | 44 ++--- docs/FacebookClient.fbmd | 7 +- docs/FacebookJavaScriptHelper.fbmd | 46 ++---- docs/FacebookPageTabHelper.fbmd | 60 +++++++ docs/FacebookResponseException.fbmd | 73 +++++++-- docs/GraphList.fbmd | 2 +- docs/SignedRequest.fbmd | 4 +- docs/example_access_token_from_canvas.fbmd | 45 ++++++ .../example_access_token_from_javascript.fbmd | 90 +++++++++++ docs/example_access_token_from_page_tab.fbmd | 51 ++++++ docs/example_batch_request.fbmd | 152 ++++++++++++++++++ docs/example_batch_upload.fbmd | 66 ++++++++ docs/example_facebook_login.fbmd | 105 ++++++++++++ docs/example_pagination_basic.fbmd | 48 ++++++ docs/example_post_links.fbmd | 3 +- docs/example_retrieve_user_profile.fbmd | 4 +- docs/example_upload_photo.fbmd | 10 +- docs/example_upload_video.fbmd | 45 ++++++ docs/sdk_landing_page.fbmd | 20 +-- docs/sdk_reference.fbmd | 34 +--- 25 files changed, 816 insertions(+), 182 deletions(-) create mode 100644 docs/example_access_token_from_canvas.fbmd create mode 100644 docs/example_access_token_from_javascript.fbmd create mode 100644 docs/example_access_token_from_page_tab.fbmd create mode 100644 docs/example_batch_request.fbmd create mode 100644 docs/example_batch_upload.fbmd create mode 100644 docs/example_facebook_login.fbmd create mode 100644 docs/example_pagination_basic.fbmd create mode 100644 docs/example_upload_video.fbmd diff --git a/CHANGELOG.md b/CHANGELOG.md index 0689188d3..1b4663877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -As you may have already noticed, the Facebook SDK v4 does not follow strict [semver](http://semver.org/). The versioning format used for this SDK is more like `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions are squashed together but there shouldn't be any breaking changes between `MINOR|PATCH` releases. +As you may have already noticed, the Facebook SDK v4 does not follow strict [semver](http://semver.org/). The versioning format used for this SDK follows `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions are squashed together but there shouldn't be any breaking changes between `MINOR|PATCH` releases. ## 4.1.x diff --git a/README.md b/README.md index 1599d347b..d2d859172 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,26 @@ -Facebook SDK for PHP -==================== +# Facebook SDK for PHP [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Development Version](https://img.shields.io/badge/Development%20Version-4.1.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) -This repository contains the open source PHP SDK that allows you to access Facebook -Platform from your PHP app. +This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. -Usage ------ +## Installation + +The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). Add the Facebook PHP SDK package to your `composer.json` file. + +```json +{ + "require": { + "facebook/php-sdk-v4": "~4.1.0" + } +} +``` + + +## Usage > **Note:** This version of the Facebook SDK for PHP requires PHP 5.4 or greater. @@ -20,10 +30,11 @@ Simple GET example of a user's profile. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', //'default_access_token' => '{access-token}', // optional ]); -// Use one of the helper classes to get a Facebook\AccessToken entity. +// Use one of the helper classes to get a Facebook\Authentication\AccessToken entity. // $helper = $fb->getRedirectLoginHelper(); // $helper = $fb->getJavaScriptHelper(); // $helper = $fb->getCanvasHelper(); @@ -47,38 +58,31 @@ $me = $response->getGraphUser(); echo 'Logged in as ' . $me->getName(); ``` -Complete documentation, installation instructions, and examples are available at: -[https://developers.facebook.com/docs/php](https://developers.facebook.com/docs/php) - +Complete documentation, installation instructions, and examples are available at: [https://developers.facebook.com/docs/php](https://developers.facebook.com/docs/php) -Tests ------ -1) [Composer](https://getcomposer.org/) is a prerequisite for running the tests. +## Tests -Install composer globally, then run `composer install` to install required files. +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) 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. +```bash +$ ./vendor/bin/phpunit +``` -3) The tests can be executed by running this command from the root directory: +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 +$ ./vendor/bin/phpunit --exclude-group integration ``` -Contributing ------------- +## Contributing -For us to accept contributions you will have to first have signed the -[Contributor License Agreement](https://developers.facebook.com/opensource/cla). +For us to accept contributions you will have to first have signed the [Contributor License Agreement](https://developers.facebook.com/opensource/cla). Please see [CONTRIBUTING](https://github.com/facebook/facebook-php-sdk-v4/blob/master/CONTRIBUTING.md) for details. -When committing, keep all lines to less than 80 characters, and try to -follow the existing style. -Before creating a pull request, squash your commits into a single commit. +## License -Add the comments where needed, and provide ample explanation in the -commit message. +Please see the [license file](https://github.com/facebook/facebook-php-sdk-v4/blob/master/LICENSE) for more information. diff --git a/docs/AccessToken.fbmd b/docs/AccessToken.fbmd index 0ba0696d4..ff7f1abfc 100644 --- a/docs/AccessToken.fbmd +++ b/docs/AccessToken.fbmd @@ -1,7 +1,7 @@ # 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. +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. diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index e0cb2fe76..84c396a5e 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -466,7 +466,7 @@ if (count($photosList) > 0) { do { echo '

Likes:

' . "\n\n"; var_dump($likes->asArray()); - } while ($likes = $fqb->next($likes)); + } while ($likes = $fb->next($likes)); } $pageCount++; } while ($pageCount < $maxPages && $photosList = $fb->next($photosList)); diff --git a/docs/FacebookBatchRequest.fbmd b/docs/FacebookBatchRequest.fbmd index 8c56ba257..b20020d82 100644 --- a/docs/FacebookBatchRequest.fbmd +++ b/docs/FacebookBatchRequest.fbmd @@ -27,29 +27,8 @@ The `FacebookBatchRequest` entity does not actually make any calls to the Graph Usage: ~~~~ -$fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); -$requests = [ - new Facebook\FacebookRequest(/* */), - new Facebook\FacebookRequest(/* */), -]; -$batchRequest = new Facebook\FacebookBatchRequest($fbApp, $requests, '{access-token}'); - -// Send the batch request to Graph -try { - $batchResponse = $fb->getClient()->sendBatchRequest($batchRequest); -} 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; -} - -// OR - $fb = new Facebook\Facebook(/* . . . */); + $requests = [ $fb->request('GET', '/me'), $fb->request('POST', '/me/feed', [/* */]), diff --git a/docs/FacebookCanvasHelper.fbmd b/docs/FacebookCanvasHelper.fbmd index 2bb13957d..969a9a696 100644 --- a/docs/FacebookCanvasHelper.fbmd +++ b/docs/FacebookCanvasHelper.fbmd @@ -14,15 +14,8 @@ Facebook\Helpers\FacebookCanvasHelper( Facebook\FacebookApp $facebookApp ) 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. ~~~ -use Facebook\Helpers\FacebookCanvasHelper; - -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - ]); -$facebookApp = $fb->getApp(); - -$canvasHelper = new FacebookCanvasHelper($facebookApp); +$fb = new Facebook\Facebook([/* */]); +$canvasHelper = $fb->getCanvasHelper(); $signedRequest = $canvasHelper->getSignedRequest(); if ($signedRequest) { @@ -34,24 +27,15 @@ if ($signedRequest) { If a user has already authenticated your app, you can also obtain an access token. ~~~ -use Facebook\Helpers\FacebookCanvasHelper; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; - -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - ]); -$facebookApp = $fb->getApp(); -$facebookClient = $fb->getClient(); +$fb = new Facebook\Facebook([/* */]); +$canvasHelper = $fb->getCanvasHelper(); try { - $canvasHelper = new FacebookCanvasHelper($facebookApp); - $accessToken = $canvasHelper->getAccessToken($facebookClient); -} catch(FacebookResponseException $e) { + $accessToken = $canvasHelper->getAccessToken(); +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { +} catch(Facebook\Exceptions\FacebookSDKException $e) { // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e->getMessage(); } @@ -60,6 +44,8 @@ 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.
@@ -67,7 +53,7 @@ if (isset($accessToken)) { ### __construct() {#construct} ~~~~ -public FacebookCanvasHelper __construct( Facebook\FacebookApp $app ) +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. @@ -75,7 +61,7 @@ Upon instantiation, `FacebookCanvasHelper` validates and decrypts the signed req ### getAccessToken() {#get-access-token} ~~~ -public Facebook\AccessToken|null getAccessToken( Facebook\FacebookClient $client ) +public Facebook\AccessToken|null getAccessToken() ~~~ Checks the signed request for authentication data and tries to obtain an access token access token. @@ -121,7 +107,7 @@ Gets the value that is set in the `app_data` property if present. ~~~ public Facebook\SignedRequest|null getSignedRequest() ~~~ -Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedRequest) entity if present. +Returns the signed request as an instance of [`Facebook\SignedRequest`](/docs/php/SignedRequest) if present. @@ -129,7 +115,5 @@ Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedReque ~~~ public string|null getRawSignedRequest() ~~~ -Gets the raw, unencrypted signed request that was sent via POST if present. - -Returns a an encrypted signed request as a `string` or `null`. - \ No newline at end of file +Returns the raw encoded signed request as a `string` if present in the POST variables or `null`. + diff --git a/docs/FacebookClient.fbmd b/docs/FacebookClient.fbmd index a4f0dc781..9e9304cd4 100644 --- a/docs/FacebookClient.fbmd +++ b/docs/FacebookClient.fbmd @@ -12,18 +12,17 @@ You most likely won't be working with the `Facebook\FacebookClient` service dire You can grab an instance of a `Facebook\FacebookClient` service, from the `Facebook\Facebook` super service class. ~~~~ -$fb = new Facebook\Facebook(/* */); +$fb = new Facebook\Facebook([/* */]); $fbClient = $fb->getClient(); ~~~~ Alternatively you could instantiate a new `Facebook\FacebookClient` service directly. ~~~~ -$fbApp = new Facebook\FacebookApp('{app_id}', '{app_secret}'); -$fbClient = new Facebook\FacebookClient($fbApp, $enableBeta = false); +$fbClient = new Facebook\FacebookClient($httpClientHandler, $enableBeta = false); ~~~~ -The Graph API has a number of different base URL's based on what request you're trying 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 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. diff --git a/docs/FacebookJavaScriptHelper.fbmd b/docs/FacebookJavaScriptHelper.fbmd index 112ed8a19..d6f02ccb4 100644 --- a/docs/FacebookJavaScriptHelper.fbmd +++ b/docs/FacebookJavaScriptHelper.fbmd @@ -7,18 +7,11 @@ If you're using the [JavaScript SDK](https://developers.facebook.com/docs/javasc ## Usage {#usage} -This helper will handle validating and decrypting the signed request from the cookie set by the JavaScript SDK. +This helper will handle validating and decode the signed request from the cookie set by the JavaScript SDK. ~~~ -use Facebook\Helpers\FacebookJavaScriptHelper; - -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - ]); -$facebookApp = $fb->getApp(); - -$jsHelper = new FacebookJavaScriptHelper($facebookApp); +$fb = new Facebook\Facebook([/* */]); +$jsHelper = $fb->getJavaScriptHelper(); $signedRequest = $jsHelper->getSignedRequest(); if ($signedRequest) { @@ -30,24 +23,15 @@ if ($signedRequest) { If a user has already authenticated your app, you can also obtain an access token. ~~~ -use Facebook\Helpers\FacebookJavaScriptHelper; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookSDKException; - -$fb = new Facebook\Facebook([ - 'app_id' => '{app-id}', - 'app_secret' => '{app-secret}', - ]); -$facebookApp = $fb->getApp(); -$facebookClient = $fb->getClient(); +$fb = new Facebook\Facebook([/* */]); +$jsHelper = $fb->getJavaScriptHelper(); try { - $jsHelper = new FacebookJavaScriptHelper($facebookApp); - $accessToken = $jsHelper->getAccessToken($facebookClient); -} catch(FacebookResponseException $e) { + $accessToken = $jsHelper->getAccessToken(); +} catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); -} catch(FacebookSDKException $e) { +} catch(Facebook\Exceptions\FacebookSDKException $e) { // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e->getMessage(); } @@ -57,7 +41,7 @@ if (isset($accessToken)) { } ~~~ -It's important to note that on first access, or if a session has since expired, these methods will operate on data that is one request-cycle stale. 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] +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) @@ -65,9 +49,9 @@ It's important to note that on first access, or if a session has since expired, ### __construct() {#construct} ~~~~ -public FacebookJavaScriptHelper __construct( Facebook\FacebookApp $app ) +public FacebookJavaScriptHelper __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) ~~~~ -Upon instantiation, `FacebookJavaScriptHelper` validates and decrypts the signed request that exists in the cookie set by the JavaScript SDK if present. +Upon instantiation, `FacebookJavaScriptHelper` validates and decodes the signed request that exists in the cookie set by the JavaScript SDK if present. @@ -83,7 +67,7 @@ Checks the signed request for authentication data and tries to obtain an access ~~~ 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. +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. ~~~ $userId = $jsHelper->getUserId(); @@ -119,7 +103,5 @@ Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedReque ~~~ public string|null getRawSignedRequest() ~~~ -Gets the raw, unencrypted signed request that was sent via POST if present. - -Returns a an encrypted signed request as a `string` or `null`. - \ No newline at end of file +Returns the raw encoded signed request as a `string` or `null`. + diff --git a/docs/FacebookPageTabHelper.fbmd b/docs/FacebookPageTabHelper.fbmd index 0b5d6cdfe..6ae23e900 100644 --- a/docs/FacebookPageTabHelper.fbmd +++ b/docs/FacebookPageTabHelper.fbmd @@ -6,4 +6,64 @@ Page tabs are similar to the context to app canvases but are treated slightly di ## Usage {#usage} + +The usage of the `FacebookPageTabHelper` is exactly the same as [`FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) with additional methods to obtain the `page` data from the signed request. + +~~~ +$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. + +~~~ +$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 {#instance-methods} + +### getPageData() {#get-page-data} +~~~ +public string|null getPageData($key, $default = null) +~~~ +Gets a value from the `page` property if present. + + + +### isAdmin() {#is-admin} +~~~ +public boolean isAdmin() +~~~ +Returns `true` is the user has authenticated your app and is an admin of the parent page. + + + +### getPageId() {#get-page-id} +~~~ +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/FacebookResponseException.fbmd b/docs/FacebookResponseException.fbmd index c3fc98b56..c7778dbf1 100644 --- a/docs/FacebookResponseException.fbmd +++ b/docs/FacebookResponseException.fbmd @@ -1,23 +1,56 @@ # FacebookResponseException for the Facebook SDK for PHP -Represents an exception thrown by executing a Facebook request. +Represents an error response from the Graph API. -## Facebook\FacebookResponseException {#overview} +## Facebook\Exceptions\FacebookResponseException {#overview} -This base class has several subclasses: +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. -`FacebookAuthenticationException` -`FacebookClientException` -`FacebookAuthorizationException` -`FacebookServerException` -`FacebookThrottleException` -`FacebookOtherException` +```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; +} +``` -Whenever a FacebookResponseException is thrown, it will be one of these types. -They are derived from the error information here: https://developers.facebook.com/docs/graph-api/using-graph-api/#errors +FB(devsite:markdown-wiki:table { + columns: ['Class name','Description',], + rows: [ + [ + '`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). @@ -28,16 +61,24 @@ They are derived from the error information here: https://developers.facebook.co ### getHttpStatusCode {#gethttpstatus} `getHttpStatusCode()` Returns the HTTP status code returned with this exception. + ### getSubErrorCode {#getsuberrorcode} `getSubErrorCode()` -Returns the numeric sub-error code returned from Facebook. +Returns the numeric sub-error code returned from the Graph API. + ### getErrorType {#geterrortype} `getErrorType()` Returns the type of error as a string. -### getResponse {#getresponse} -`getResponse()` -Returns the decoded response used to create the exception. + +### getResponseData {#getresponsedata} +`getResponseData()` +Returns the decoded response body used to create the exception as an array. + ### getRawResponse {#getrawresponse} `getRawResponse()` -Returns the raw response used to create the exception. +Returns the raw response body used to create the exception as a string. + +### getResponse {#getresponse} +`getResponse()` +Returns the `FacebookResponse` entity which represents the HTTP response. \ No newline at end of file diff --git a/docs/GraphList.fbmd b/docs/GraphList.fbmd index 3283c586e..217cc2d16 100644 --- a/docs/GraphList.fbmd +++ b/docs/GraphList.fbmd @@ -54,7 +54,7 @@ $maxPages = 5; $pageCount = 0; do { - echo '

Page #' . $page_count . ':

' . "\n\n"; + echo '

Page #' . $pageCount . ':

' . "\n\n"; foreach ($listOfPages as $page) { var_dump($page->asArray()); diff --git a/docs/SignedRequest.fbmd b/docs/SignedRequest.fbmd index 7dddcea1c..06e593dad 100644 --- a/docs/SignedRequest.fbmd +++ b/docs/SignedRequest.fbmd @@ -42,7 +42,7 @@ $signedRequest = $helper->getSignedRequest(); ~~~~ public string|null getRawSignedRequest() ~~~~ -Returns the original raw signed request in the form of a string. +Returns the original raw encoded signed request in the form of a string. @@ -58,7 +58,7 @@ Returns the [signed request payload](https://developers.facebook.com/docs/refere ~~~~ public string|null get(string $key, string|null $default) ~~~~ -Returns a field from the signed request payload or `$default` if the value does not exist. +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. diff --git a/docs/example_access_token_from_canvas.fbmd b/docs/example_access_token_from_canvas.fbmd new file mode 100644 index 000000000..a4571e2ac --- /dev/null +++ b/docs/example_access_token_from_canvas.fbmd @@ -0,0 +1,45 @@ + +# 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 {#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. + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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/example_access_token_from_javascript.fbmd b/docs/example_access_token_from_javascript.fbmd new file mode 100644 index 000000000..9fa2b8aca --- /dev/null +++ b/docs/example_access_token_from_javascript.fbmd @@ -0,0 +1,90 @@ + +# 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 {#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. + +~~~~ + + + +

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. + +~~~~ +# /js-login.php +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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/example_access_token_from_page_tab.fbmd b/docs/example_access_token_from_page_tab.fbmd new file mode 100644 index 000000000..447463335 --- /dev/null +++ b/docs/example_access_token_from_page_tab.fbmd @@ -0,0 +1,51 @@ + +# 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 {#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. + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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/example_batch_request.fbmd b/docs/example_batch_request.fbmd new file mode 100644 index 000000000..1d31684c5 --- /dev/null +++ b/docs/example_batch_request.fbmd @@ -0,0 +1,152 @@ + +# Batch Request Example + +This example covers sending a batch request with the Facebook SDK for PHP. + + + +## Example {#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). + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +// 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. + +%FB(devsite:markdown-wiki:info-card { + content: "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).", + type: 'warning', +}) +
+ + +## Multiple User 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. + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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/example_batch_upload.fbmd b/docs/example_batch_upload.fbmd new file mode 100644 index 000000000..14ac292fa --- /dev/null +++ b/docs/example_batch_upload.fbmd @@ -0,0 +1,66 @@ + +# Batch File Upload Example + +This example covers uploading files in a batch request with the Facebook SDK for PHP. + + + +## Example {#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. + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +// 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/example_facebook_login.fbmd b/docs/example_facebook_login.fbmd new file mode 100644 index 000000000..44d2cde3b --- /dev/null +++ b/docs/example_facebook_login.fbmd @@ -0,0 +1,105 @@ + +# Facebook Login Example + +This example covers Facebook Login with the Facebook SDK for PHP. + + + +## Example {#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 redirect the user to after the app authentication dialog is called `/fb-callback.php`. + +~~~~ +# /login.php + +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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 + +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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\n"; + echo "

Error Code: " . $helper->getErrorCode() . "

\n\n"; + echo "

Error Reason: " . $helper->getErrorReason() . "

\n\n"; + echo "

Error Description: " . $helper->getErrorDescription() . "

\n\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: " . $helper->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/example_pagination_basic.fbmd b/docs/example_pagination_basic.fbmd new file mode 100644 index 000000000..b2276da53 --- /dev/null +++ b/docs/example_pagination_basic.fbmd @@ -0,0 +1,48 @@ + +# Pagination Example + +This example covers basic cursor pagination with the Facebook SDK for PHP. + + + +## Example {#example} + +The Graph API supports [several methods to paginate over response data](https://developers.facebook.com/docs/graph-api/using-graph-api/v2.2#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. + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +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 +$feed = $response->getGraphList(); + +foreach ($feed as $status) { + var_dump($status->asArray()); +} + +// Page 2 (next 5 results) +$nextFeed = $fb->next($feed); + +foreach ($nextFeed as $status) { + var_dump($status->asArray()); +} +~~~~ + diff --git a/docs/example_post_links.fbmd b/docs/example_post_links.fbmd index 52fb5fb13..cf716b00d 100644 --- a/docs/example_post_links.fbmd +++ b/docs/example_post_links.fbmd @@ -5,7 +5,7 @@ This example covers posting a link to the current user's timeline using the Grap It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException).
@@ -15,6 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', ]); $linkData = [ diff --git a/docs/example_retrieve_user_profile.fbmd b/docs/example_retrieve_user_profile.fbmd index 7f7431a81..422676833 100644 --- a/docs/example_retrieve_user_profile.fbmd +++ b/docs/example_retrieve_user_profile.fbmd @@ -5,8 +5,7 @@ This example covers getting profile information for the current user and printin It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). - +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). @@ -16,6 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', ]); try { diff --git a/docs/example_upload_photo.fbmd b/docs/example_upload_photo.fbmd index 99e72bba8..a192da870 100644 --- a/docs/example_upload_photo.fbmd +++ b/docs/example_upload_photo.fbmd @@ -5,14 +5,18 @@ This example covers uploading a photo to the current User's profile using the Gr It assumes that you've already acquired an access token using one of the helper classes found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). ## Example {#example} ~~~~ -$fb = new Facebook\Facebook(/* . . . */); +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); $data = [ 'message' => 'My awesome photo upload example.', @@ -21,7 +25,7 @@ $data = [ try { // Returns a `Facebook\FacebookResponse` object - $response = $fb->post('/me/photos', $data); + $response = $fb->post('/me/photos', $data, '{access-token}'); } catch(Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph returned an error: ' . $e->getMessage(); exit; diff --git a/docs/example_upload_video.fbmd b/docs/example_upload_video.fbmd new file mode 100644 index 000000000..c9330df8c --- /dev/null +++ b/docs/example_upload_video.fbmd @@ -0,0 +1,45 @@ + +# Video Upload Example + +This example covers uploading & posting a video to a user's timeline with the Facebook SDK for PHP. + + + +## Example {#example} + +%FB(devsite:markdown-wiki:info-card { + content: "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.", + type: 'warning', +}) + +~~~~ +$fb = new Facebook\Facebook([ + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.2', + ]); + +$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; +} + +$graphObject = $response->getGraphObject(); +var_dump($graphObject); + +echo 'Video ID: ' . $graphObject['id']; +~~~~ + diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd index fee95cda2..51fe8552a 100644 --- a/docs/sdk_landing_page.fbmd +++ b/docs/sdk_landing_page.fbmd @@ -5,28 +5,30 @@ The Facebook SDK for PHP is a library with powerful features that enable PHP dev Whether you're developing a website with Facebook login, creating a Facebook Canvas app or Page tab, the Facebook PHP SDK does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. -Take a look through our guide, [Getting Started with the Facebook SDK for PHP](/docs/php/gettingstarted), and then check out some of the examples below. +For installation & implementation instructions, look through the [Getting Started with the Facebook SDK for PHP](/docs/php/gettingstarted) guide, and then check out some of the examples below. ## Examples {#examples} -For more complete examples, check out the [examples from the official repo on GitHub](). @todo +The following examples demonstrate how you would accomplish common tasks with the Facebook PHP SDK. - **Authentication & Signed Requests** - - [Facebook Login (OAuth 2.0)](/docs/php/howto/example_facebook_login) @todo - - [Obtaining an access token from the JavaScript SDK](/docs/php/howto/example_access_token_from_javascript) @todo - - [Obtaining an access token within a Facebook Canvas context](/docs/php/howto/example_access_token_from_canvas) @todo - - [Obtaining an access token within a Facebook Page tab context](/docs/php/howto/example_access_token_from_page_tab) @todo + - [Facebook Login (OAuth 2.0)](/docs/php/howto/example_facebook_login) + - [Obtaining an access token from the JavaScript SDK](/docs/php/howto/example_access_token_from_javascript) + - [Obtaining an access token within a Facebook Canvas context](/docs/php/howto/example_access_token_from_canvas) + - [Obtaining an access token within a Facebook Page tab context](/docs/php/howto/example_access_token_from_page_tab) - **User profile** - [Retrieve a user's profile](/docs/php/howto/example_retrieve_user_profile) - [Post a link to a user's feed](/docs/php/howto/example_post_links) - **File Uploads** - [Upload a photo to a user's profile](/docs/php/howto/example_upload_photo) - - [Upload a video to a user's profile](/docs/php/howto/example_upload_video) @todo + - [Upload a video to a user's profile](/docs/php/howto/example_upload_video) - **Batch Requests** - - [Sending requests in a batch](/docs/php/howto/example_batch_request) @todo - - [Uploading files in a batch](/docs/php/howto/example_batch_upload) @todo + - [Sending requests in a batch](/docs/php/howto/example_batch_request) + - [Uploading files in a batch](/docs/php/howto/example_batch_upload) +- **Pagination** + - [Basic pagination](/docs/php/howto/example_pagination_basic) diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 596f403fc..63c30660e 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -41,11 +41,11 @@ FB(devsite:markdown-wiki:table { 'An entity that represents an access token.', ], [ - '[`Facebook\Authentication\AccessTokenMetadata`](/docs/php/AccessTokenMetadata)', + '`Facebook\Authentication\AccessTokenMetadata`', 'An entity that represents metadata from an access token.', ], [ - '[`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client)', + '`Facebook\Authentication\OAuth2Client`', 'An OAuth 2.0 client that sends and receives HTTP requests related to user authentication.', ], ], @@ -78,7 +78,7 @@ FB(devsite:markdown-wiki:table { ], [ '[`Facebook\FacebookClient`](/docs/php/FacebookClient)', - 'A service object to send HTTP requests and receive HTTP responses to and from the Graph API.', + 'A service object that sends HTTP requests and receives HTTP responses to and from the Graph API.', ], ], }) @@ -196,30 +196,6 @@ FB(devsite:markdown-wiki:table { }) - -# HTTP Clients {#http-clients} - -Various HTTP clients that can be implemented to send and receive HTTP requests to and HTTP responses from Graph. - -FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\HttpClients\FacebookStreamHttpClient`](/docs/php/FacebookStreamHttpClient)', - 'The stream wrapper HTTP client implementation.', - ], - [ - '[`Facebook\HttpClients\FacebookHttpCurlClient`](/docs/php/FacebookHttpCurlClient)', - 'The cURL HTTP client implementation.', - ], - [ - '[`Facebook\HttpClients\FacebookGuzzleHttpClient`](/docs/php/FacebookGuzzleHttpClient)', - 'The Guzzle HTTP client implementation. (Requires installing Guzzle with Composer.)', - ], - ], -}) - - # Extensibility {#extensibility} @@ -229,11 +205,11 @@ FB(devsite:markdown-wiki:table { columns: ['Interface name','Description',], rows: [ [ - '[`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface)', + '`Facebook\HttpClients\FacebookHttpClientInterface`', 'An interface to code your own HTTP client implementation.', ], [ - '[`Facebook\Http\GraphRawResponse`](/docs/php/GraphRawResponse)', + '`Facebook\Http\GraphRawResponse`', 'An entity that is returned from an instance of a `FacebookHttpClientInterface` that represents a raw HTTP response from the Graph API.', ], [ From 821ea26cab07e14a5c022be9915f96dc4918d862 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 19 Feb 2015 14:43:38 -0600 Subject: [PATCH 127/407] - Remove PHP Code Sniffer from composer require-dev. - Add Scrutinizer badge to README. - Add instructions on installing PHP Code Sniffer globally. --- CONTRIBUTING.md | 10 +++++++++- README.md | 1 + composer.json | 1 - 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ee390bf32..bb79c4f67 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,8 +37,16 @@ $ ./vendor/bin/phpunit ## Running PHP Code Sniffer +You can install [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) globally with composer. + +``` bash +$ composer global require squizlabs/php_codesniffer +``` + +Then you can `cd` into the Facebook PHP SDK folder and run Code Sniffer against the `src/` directory. + ``` bash -$ ./vendor/bin/phpcs src --standard=psr2 -sp +$ ~/.composer/vendor/bin/phpcs src --standard=psr2 -sp ``` **Happy coding**! diff --git a/README.md b/README.md index 1599d347b..f01e596c8 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Facebook SDK for PHP ==================== [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) [![Development Version](https://img.shields.io/badge/Development%20Version-4.1.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) diff --git a/composer.json b/composer.json index b7f47052d..63de9a546 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,6 @@ "require-dev": { "phpunit/phpunit": "~4.0", "mockery/mockery": "~0.8", - "squizlabs/php_codesniffer": "~2.0", "guzzlehttp/guzzle": "~5.0" }, "suggest": { From e8950e0e9c973a0dc511234338a0b0bab448f0f8 Mon Sep 17 00:00:00 2001 From: Niraj Shah Date: Fri, 20 Feb 2015 16:56:54 +0000 Subject: [PATCH 128/407] Fixed auto-load prefix --- src/Facebook/autoload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 9a707e816..637593059 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -44,7 +44,7 @@ */ spl_autoload_register(function ($class) { // project-specific namespace prefix - $prefix = '\Facebook\\'; + $prefix = 'Facebook\\'; // base directory for the namespace prefix $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/'; From b5a54d4d772e10a088bd1d631958f53e2de759ce Mon Sep 17 00:00:00 2001 From: Scott Arciszewski Date: Tue, 24 Feb 2015 16:03:03 -0500 Subject: [PATCH 129/407] Update UrandomPseudoRandomStringGenerator.php Prevent `fread()` from wastefully buffering 8192 bytes from `/dev/urandom`. --- .../PseudoRandomString/UrandomPseudoRandomStringGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php index ae4e9e6e9..4f7728184 100644 --- a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php @@ -69,6 +69,7 @@ public function getPseudoRandomString($length) 'Unable to open stream to /dev/urandom.' ); } + stream_set_read_buffer($stream, 0); $binaryString = fread($stream, $length); fclose($stream); From 975d401e2bd288911e640691ceeb289b52aad66a Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Sun, 1 Mar 2015 17:07:31 -0800 Subject: [PATCH 130/407] Updated FacebookRedirectLoginHelper to use constant time CSRF check. --- .gitignore | 1 + .../Helpers/FacebookRedirectLoginHelper.php | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0c2e885a4..d94b3735b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ vendor/ composer.lock tests/FacebookTestCredentials.php +.idea/ diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index d22c8b740..295b31449 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -269,7 +269,19 @@ protected function validateCsrf() throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.'); } - if ($state !== $savedState) { + $savedLen = mb_strlen($savedState); + $givenLen = mb_strlen($state); + + if ($savedLen !== $givenLen) { + throw new FacebookSDKException('Cross-site request forgery validation failed. Invalid "state" param provided.'); + } + + $result = 0; + for ($i = 0; $i < $savedLen; $i++) { + $result |= ord($state[$i]) ^ ord($savedState[$i]); + } + + if ($result !== 0) { throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } } From 72fe2861f75542e1d27dff2e9060af469a93970d Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Mon, 2 Mar 2015 11:57:51 -0800 Subject: [PATCH 131/407] Updates per review. --- .gitignore | 1 - src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index d94b3735b..0c2e885a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ vendor/ composer.lock tests/FacebookTestCredentials.php -.idea/ diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 295b31449..144a5b454 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -269,16 +269,16 @@ protected function validateCsrf() throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.'); } - $savedLen = mb_strlen($savedState); - $givenLen = mb_strlen($state); + $savedLen = strlen($savedState); + $givenLen = strlen($state); if ($savedLen !== $givenLen) { - throw new FacebookSDKException('Cross-site request forgery validation failed. Invalid "state" param provided.'); + throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } $result = 0; for ($i = 0; $i < $savedLen; $i++) { - $result |= ord($state[$i]) ^ ord($savedState[$i]); + $result |= ord($state[$i]) ^ ord($savedState[$i]); } if ($result !== 0) { From 18665ca1a2f2ced6fc3597f5d89c9166e236178c Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 4 Mar 2015 23:28:41 -0600 Subject: [PATCH 132/407] Fix HHVM bug --- .../UrandomPseudoRandomStringGenerator.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php index 4f7728184..0f9cacd42 100644 --- a/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php +++ b/src/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php @@ -69,7 +69,10 @@ public function getPseudoRandomString($length) 'Unable to open stream to /dev/urandom.' ); } - stream_set_read_buffer($stream, 0); + + if (!defined('HHVM_VERSION')) { + stream_set_read_buffer($stream, 0); + } $binaryString = fread($stream, $length); fclose($stream); From 3d5235ae71b97c05477e7a29076ed5095bd6334d Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 4 Mar 2015 23:33:09 -0600 Subject: [PATCH 133/407] Add Travis-CI check for PHP 7.0. Remove "allow_failures" for HHVM. Add "travis_retry" wrapper to composer commands. --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5a7c5c971..c3082dfd5 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,20 +4,21 @@ php: - 5.4 - 5.5 - 5.6 + - 7.0 - hhvm sudo: false before_install: - - composer self-update + - travis_retry composer self-update install: - - composer install --prefer-source --no-interaction + - travis_retry composer install --prefer-source --no-interaction script: - vendor/bin/phpunit --coverage-text --exclude-group integration matrix: allow_failures: - - php: hhvm + - php: 7.0 fast_finish: true From 588adb3d3406f9459861dd2ed70977531abcd074 Mon Sep 17 00:00:00 2001 From: Thilo Frommeyer Date: Mon, 23 Mar 2015 22:03:32 +0100 Subject: [PATCH 134/407] Updated delete method to support parameters - #379 The Graph API supports parameters for DELETE Requests. For example: Unblocking a user from a page requires a parameter "user" which the current version of the SDK doesn't implement. Docs were updated also. --- docs/Facebook.fbmd | 5 +++-- src/Facebook/Facebook.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 84c396a5e..1d5e3b401 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -295,6 +295,7 @@ $response = $fb->post('/me/feed', ['message' => 'Foo message']); ~~~~ public Facebook\FacebookResponse delete( string $endpoint, + array $params, string|AccessToken|null $accessToken, string|null $eTag, string|null $graphVersion @@ -303,10 +304,10 @@ public Facebook\FacebookResponse delete( Sends a DELETE request to Graph and returns a `Facebook\FacebookResponse`. -The arguments are the same as `get()` above. +The arguments are the same as `post()` above. ~~~~ -$response = $fb->delete('/{node-id}'); +$response = $fb->delete('/{node-id}', ['object' => '1234']); ~~~~ diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 3ccdf10ba..4ad247545 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -405,6 +405,7 @@ public function post($endpoint, array $params = [], $accessToken = null, $eTag = * Sends a DELETE request to Graph and returns the result. * * @param string $endpoint + * @param array $params * @param AccessToken|string|null $accessToken * @param string|null $eTag * @param string|null $graphVersion @@ -413,12 +414,12 @@ public function post($endpoint, array $params = [], $accessToken = null, $eTag = * * @throws FacebookSDKException */ - public function delete($endpoint, $accessToken = null, $eTag = null, $graphVersion = null) + public function delete($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) { return $this->sendRequest( 'DELETE', $endpoint, - $params = [], + $params, $accessToken, $eTag, $graphVersion From 6ed76ba4cadd89133a988c37eca10a7556212414 Mon Sep 17 00:00:00 2001 From: Thilo Frommeyer Date: Tue, 24 Mar 2015 22:03:57 +0100 Subject: [PATCH 135/407] Fixed spaces indentation --- src/Facebook/Facebook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 4ad247545..6fba1f96d 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -405,7 +405,7 @@ public function post($endpoint, array $params = [], $accessToken = null, $eTag = * Sends a DELETE request to Graph and returns the result. * * @param string $endpoint - * @param array $params + * @param array $params * @param AccessToken|string|null $accessToken * @param string|null $eTag * @param string|null $graphVersion From a50e83c2b356d258b69d7bd7234db159094d38bb Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 1 Apr 2015 15:02:45 -0500 Subject: [PATCH 136/407] Graph version bump to v2.3 --- src/Facebook/Facebook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 6fba1f96d..8e98b03c8 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -62,7 +62,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.2'; + const DEFAULT_GRAPH_VERSION = 'v2.3'; /** * @const string The name of the environment variable that contains the app ID. From 623a2a651f33721a979cfe726a71d74c2f30fd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Crnkovi=C4=87?= Date: Thu, 2 Apr 2015 13:53:48 +0200 Subject: [PATCH 137/407] Support setting base directory with or without the trailing slash These both work the same ``` php define('FACEBOOK_SDK_V4_SRC_DIR', 'path/to/Facebook/'); // OR define('FACEBOOK_SDK_V4_SRC_DIR', 'path/to/Facebook'); ``` --- src/Facebook/autoload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 637593059..01f4d76a4 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -62,7 +62,7 @@ // replace the namespace prefix with the base directory, replace namespace // separators with directory separators in the relative class name, append // with .php - $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; + $file = rtrim($base_dir, '/') . '/' . str_replace('\\', '/', $relative_class) . '.php'; // if the file exists, require it if (file_exists($file)) { From 85c0288021b3cfbf0242376f2f43338f91afd956 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 2 Apr 2015 14:27:05 -0500 Subject: [PATCH 138/407] Add support for nested params for multipart requests --- src/Facebook/Http/RequestBodyMultipart.php | 30 +++++++++++++-- tests/Http/RequestBodyMultipartTest.php | 44 ++++++++++++++++++++++ tests/Http/RequestUrlEncodedTest.php | 24 ++++++++++++ 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/Facebook/Http/RequestBodyMultipart.php b/src/Facebook/Http/RequestBodyMultipart.php index 34152bf59..82f1438e2 100644 --- a/src/Facebook/Http/RequestBodyMultipart.php +++ b/src/Facebook/Http/RequestBodyMultipart.php @@ -39,17 +39,17 @@ class RequestBodyMultipart implements RequestBodyInterface /** * @var string The boundary. */ - protected $boundary; + private $boundary; /** * @var array The parameters to send with this request. */ - protected $params = []; + private $params; /** * @var array The files to send with this request. */ - protected $files = []; + private $files = []; /** * @param array $params The parameters to send with this request. @@ -71,7 +71,8 @@ public function getBody() $body = ''; // Compile normal params - foreach ($this->params as $k => $v) { + $params = $this->getNestedParams($this->params); + foreach ($params as $k => $v) { $body .= $this->getParamString($k, $v); } @@ -134,6 +135,27 @@ private function getParamString($name, $value) ); } + /** + * Returns the params as an array of nested params. + * + * @param array $params + * + * @return array + */ + private function getNestedParams(array $params) + { + $query = http_build_query($params, null, '&'); + $params = explode('&', $query); + $result = []; + + foreach ($params as $param) { + list($key, $value) = explode('=', $param, 2); + $result[urldecode($key)] = urldecode($value); + } + + return $result; + } + /** * Get the headers needed before transferring the content of a POST file. * diff --git a/tests/Http/RequestBodyMultipartTest.php b/tests/Http/RequestBodyMultipartTest.php index e344ea2cb..267cc4995 100644 --- a/tests/Http/RequestBodyMultipartTest.php +++ b/tests/Http/RequestBodyMultipartTest.php @@ -64,4 +64,48 @@ public function testCanProperlyEncodeFilesAndParams() $this->assertEquals($expectedBody, $body); } + + public function testSupportsMultidimensionalParams() + { + $message = new RequestBodyMultipart([ + 'foo' => 'bar', + 'faz' => [1,2,3], + 'targeting' => [ + 'countries' => 'US,GB', + 'age_min' => 13, + ], + 'call_to_action' => [ + 'type' => 'LEARN_MORE', + 'value' => [ + 'link' => 'http://example.com', + 'sponsorship' => [ + 'image' => 'http://example.com/bar.jpg', + ], + ], + ], + ], [], 'foo_boundary'); + $body = $message->getBody(); + + $expectedBody = "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"faz[0]\"\r\n\r\n1\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"faz[1]\"\r\n\r\n2\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"faz[2]\"\r\n\r\n3\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"targeting[countries]\"\r\n\r\nUS,GB\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"targeting[age_min]\"\r\n\r\n13\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"call_to_action[type]\"\r\n\r\nLEARN_MORE\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"call_to_action[value][link]\"\r\n\r\nhttp://example.com\r\n"; + $expectedBody .= "--foo_boundary\r\n"; + $expectedBody .= "Content-Disposition: form-data; name=\"call_to_action[value][sponsorship][image]\"\r\n\r\nhttp://example.com/bar.jpg\r\n"; + $expectedBody .= "--foo_boundary--\r\n"; + + $this->assertEquals($expectedBody, $body); + } } diff --git a/tests/Http/RequestUrlEncodedTest.php b/tests/Http/RequestUrlEncodedTest.php index 595cdc78f..3e2291269 100644 --- a/tests/Http/RequestUrlEncodedTest.php +++ b/tests/Http/RequestUrlEncodedTest.php @@ -37,4 +37,28 @@ public function testCanProperlyEncodeAnArrayOfParams() $this->assertEquals('foo=bar&scawy_vawues=%40FooBar+is+a+real+twitter+handle.', $body); } + + public function testSupportsMultidimensionalParams() + { + $message = new RequestBodyUrlEncoded([ + 'foo' => 'bar', + 'faz' => [1,2,3], + 'targeting' => [ + 'countries' => 'US,GB', + 'age_min' => 13, + ], + 'call_to_action' => [ + 'type' => 'LEARN_MORE', + 'value' => [ + 'link' => 'http://example.com', + 'sponsorship' => [ + 'image' => 'http://example.com/bar.jpg', + ], + ], + ], + ]); + $body = $message->getBody(); + + $this->assertEquals('foo=bar&faz%5B0%5D=1&faz%5B1%5D=2&faz%5B2%5D=3&targeting%5Bcountries%5D=US%2CGB&targeting%5Bage_min%5D=13&call_to_action%5Btype%5D=LEARN_MORE&call_to_action%5Bvalue%5D%5Blink%5D=http%3A%2F%2Fexample.com&call_to_action%5Bvalue%5D%5Bsponsorship%5D%5Bimage%5D=http%3A%2F%2Fexample.com%2Fbar.jpg', $body); + } } From cf8ed9d68705e890ce69ac8f12efa11074ab95bc Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 24 Apr 2015 09:17:19 -0500 Subject: [PATCH 139/407] Permission fix per #403 --- .travis.yml | 0 src/Facebook/FacebookBatchRequest.php | 0 src/Facebook/FacebookBatchResponse.php | 0 src/Facebook/FacebookRequest.php | 0 src/Facebook/FacebookResponse.php | 0 src/Facebook/FileUpload/FacebookFile.php | 0 src/Facebook/FileUpload/FacebookVideo.php | 0 src/Facebook/Http/GraphRawResponse.php | 0 src/Facebook/Http/RequestBodyInterface.php | 0 .../PseudoRandomString/PseudoRandomStringGeneratorInterface.php | 0 src/Facebook/Url/FacebookUrlDetectionHandler.php | 0 src/Facebook/Url/FacebookUrlManipulator.php | 0 src/Facebook/Url/UrlDetectionInterface.php | 0 13 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 .travis.yml mode change 100755 => 100644 src/Facebook/FacebookBatchRequest.php mode change 100755 => 100644 src/Facebook/FacebookBatchResponse.php mode change 100755 => 100644 src/Facebook/FacebookRequest.php mode change 100755 => 100644 src/Facebook/FacebookResponse.php mode change 100755 => 100644 src/Facebook/FileUpload/FacebookFile.php mode change 100755 => 100644 src/Facebook/FileUpload/FacebookVideo.php mode change 100755 => 100644 src/Facebook/Http/GraphRawResponse.php mode change 100755 => 100644 src/Facebook/Http/RequestBodyInterface.php mode change 100755 => 100644 src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php mode change 100755 => 100644 src/Facebook/Url/FacebookUrlDetectionHandler.php mode change 100755 => 100644 src/Facebook/Url/FacebookUrlManipulator.php mode change 100755 => 100644 src/Facebook/Url/UrlDetectionInterface.php diff --git a/.travis.yml b/.travis.yml old mode 100755 new mode 100644 diff --git a/src/Facebook/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php old mode 100755 new mode 100644 diff --git a/src/Facebook/FacebookBatchResponse.php b/src/Facebook/FacebookBatchResponse.php old mode 100755 new mode 100644 diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php old mode 100755 new mode 100644 diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php old mode 100755 new mode 100644 diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php old mode 100755 new mode 100644 diff --git a/src/Facebook/FileUpload/FacebookVideo.php b/src/Facebook/FileUpload/FacebookVideo.php old mode 100755 new mode 100644 diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php old mode 100755 new mode 100644 diff --git a/src/Facebook/Http/RequestBodyInterface.php b/src/Facebook/Http/RequestBodyInterface.php old mode 100755 new mode 100644 diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorInterface.php old mode 100755 new mode 100644 diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php old mode 100755 new mode 100644 diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php old mode 100755 new mode 100644 diff --git a/src/Facebook/Url/UrlDetectionInterface.php b/src/Facebook/Url/UrlDetectionInterface.php old mode 100755 new mode 100644 From 1d7e3c81b2a962ccdfc08cd6c68b3457c0ad227f Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 24 Apr 2015 09:27:50 -0500 Subject: [PATCH 140/407] Add scrutinizer config for PSR-2 checks --- .scrutinizer.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .scrutinizer.yml diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 000000000..663201362 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,8 @@ +filter: + paths: + - 'src/*' + +tools: + php_code_sniffer: + config: + standard: PSR2 From fc1c49a7ec61972c1f1dc1b1eb0566d95c585d80 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 12:38:25 -0500 Subject: [PATCH 141/407] Add branch alias for PHP SDK v5. :monkey: --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 63de9a546..31e70cd4e 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ }, "extra": { "branch-alias": { - "dev-master": "4.1.x-dev" + "dev-master": "5.x-dev" } } } From cce152936f051ff8ece92c3631b5d343e7cf22dc Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:08:08 -0500 Subject: [PATCH 142/407] Update 4.1 docs to refer to version 5 --- CHANGELOG.md | 104 ++++++++++++++++++++++++++-------- CONTRIBUTING.md | 2 + README.md | 6 +- docs/sdk_downloads.fbmd | 2 +- docs/sdk_getting_started.fbmd | 22 +++---- docs/sdk_landing_page.fbmd | 2 +- docs/sdk_reference.fbmd | 2 +- phpunit.xml.dist | 2 +- src/Facebook/Facebook.php | 2 +- src/Facebook/autoload.php | 2 +- 10 files changed, 102 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b4663877..b904f75cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,37 +1,93 @@ # CHANGELOG -As you may have already noticed, the Facebook SDK v4 does not follow strict [semver](http://semver.org/). The versioning format used for this SDK follows `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions are squashed together but there shouldn't be any breaking changes between `MINOR|PATCH` releases. +Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org/). -## 4.1.x +## 5.0.x -- 4.1.0 (2015-??-??) - - Added batch support - - Added `graph.beta.facebook.com` support - - Moved exception classes to `Exception\*` directory - - Moved response collection objects to `GraphNodes\*` directory - - Moved helpers to `Helpers\*` directory - - Moved `FacebookRequest` and `FacebookResponse` to `Entities\*` directory - - Killed `FacebookSession` in favor of `Facebook\AccessToken` - - Added `FacebookClient` service - - Renamed `FacebookRequestException` to `FacebookResponseException` - - Renamed `FacebookHttpable` to `FacebookHttpClientInterface` - - Updated the API for the helpers. - - Refactored request/response handling - - Added support for "rerequest" authorization - - [`AccessToken`] Added serialization support - - Added `ext-mbstring` to composer require - - Added `Facebook\FacebookApp` entity - - Namespaced tests - - Grouped functional tests under `functional` group - - Added `Facebook\Facebook` super service - - Added this CHANGELOG. Hi! :) +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.0 (2015-??-??) + - 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 `GraphList` 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 + - 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` ## 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. + +- 4.0.23 (2015-04-03) + - 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`** +- 4.0.21 (2015-03-31) + - 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 +- 4.0.19 (2015-03-02) + - 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 +- 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` +- 4.0.16 (2015-02-03) + - [`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 +- 4.0.14 (2014-12-29) + - [`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 - 4.0.12 (2014-10-30) - - Added Graph v2.2 support + - **Updated default fallback Graph version to `v2.2`** - Fixed potential duplicate `type` param in URL's - [`FacebookRedirectLoginHelper`] Added `getReRequestUrl()` - [`GraphUser`] Added `getEmail()` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bb79c4f67..e3c16c4a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,6 +17,8 @@ We accept contributions via Pull Requests on [Github](https://github.com/faceboo - **Document any change in behaviour** - Make sure the README and the [documentation](https://github.com/facebook/facebook-php-sdk-v4/tree/master/docs) are kept up-to-date. +- **Consider our release cycle** - As of version 5.0.0, we try to follow [SemVer](http://semver.org/). Randomly breaking public APIs is not an option. + - **Create topic branches** - Don't ask us to pull from your master branch. - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. diff --git a/README.md b/README.md index 5ae61f348..3971cb3e1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Development Version](https://img.shields.io/badge/Development%20Version-4.1.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Development Version](https://img.shields.io/badge/Development%20Version-5.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. @@ -15,7 +15,7 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). ```json { "require": { - "facebook/php-sdk-v4": "~4.1.0" + "facebook/php-sdk-v4": "~5.0@dev" } } ``` @@ -31,7 +31,7 @@ Simple GET example of a user's profile. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.3', //'default_access_token' => '{access-token}', // optional ]); diff --git a/docs/sdk_downloads.fbmd b/docs/sdk_downloads.fbmd index 30ff20cd2..cf10f37b7 100644 --- a/docs/sdk_downloads.fbmd +++ b/docs/sdk_downloads.fbmd @@ -1,5 +1,5 @@ -# Downloads for the Facebook SDK 4.x for PHP +# Downloads for the Facebook PHP SDK For full details on what changed between each version release, see the [CHANGELOG](https://github.com/facebook/facebook-php-sdk-v4/blob/master/CHANGELOG.md). diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 149abf2d5..592bcb25e 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -7,7 +7,7 @@ Whether you're developing a website with Facebook login, creating a Facebook Can ## Autoloading & namespaces {#psr-4} -The Facebook PHP SDK v4.x 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. +The Facebook PHP SDK 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. @@ -34,14 +34,14 @@ There are two methods to install the Facebook PHP SDK. The recommended installat ~~~ { "require" : { - "facebook/php-sdk-v4" : "~4.1.0" + "facebook/php-sdk-v4" : "~5.0" } } ~~~ %FB(devsite:markdown-wiki:info-card { - content: "The Facebook SDK v4 does not follow [SemVer](http://semver.org/). The versioning format used for the SDK is `4.MAJOR.(MINOR|PATCH)`. The `MINOR` and `PATCH` versions are squashed together but there shouldn't be any breaking changes between `MINOR|PATCH` releases. That's why it is important to use all three version numbers in composer when using the `~` operator, e.g. `~4.1.0`. This will ensure you don't inadvertently download a version with breaking changes in it.", - type: 'warning', + content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", + type: 'info', }) Then run `composer install` from the command line, and composer will download the latest version of the SDK and put it in the `/vendor/` directory. @@ -59,8 +59,8 @@ require_once __DIR__ . '/vendor/autoload.php'; First, download the source code and unzip it wherever you like in your project. %FB(devsite:markdown-wiki:button { - text: 'Download the PHP SDK v4.1', - href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/4.1-dev.zip', + text: 'Download the PHP SDK v5.0', + href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/5.0-dev.zip', size: 'large', use: 'special', }) @@ -85,21 +85,21 @@ The source code includes myriad files that aren't necessary for use in a product 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 3rd-party code. For this example we'll rename the `Facebook` directory to `facebook-sdk-v4.1`. +Move the folder `src/Facebook` to the root of your website installation or where ever you like to put 3rd-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-v4.1` and inside will also be the `autolaoder.php` file. +The path the the core SDK files should now be located in `/var/html/facebook-sdk-v5` and inside will also be the `autolaoder.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. ~~~ -require_once __DIR__ . '/facebook-sdk-v4.1/autoload.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. ~~~ -define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v4.1/'); -require_once __DIR__ . '/facebook-sdk-v4.1/autoload.php'; +define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v5/'); +require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; ~~~ diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd index 51fe8552a..4d231600a 100644 --- a/docs/sdk_landing_page.fbmd +++ b/docs/sdk_landing_page.fbmd @@ -1,5 +1,5 @@ -# Facebook SDK v4.1 for PHP +# Facebook SDK v5 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](/docs/reference/javascript/) to give the front-end user the best possible user experience. But it doesn't end there, the Facebook PHP SDK makes it easy to upload photos and videos and send batch requests to the Graph API among other things. And PHP SDK has many extensibility points giving PHP developers full control of how the PHP SDK interacts with their specific hosting environment and web framework. diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 63c30660e..52a47c19b 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -1,5 +1,5 @@ -# Facebook SDK for PHP Reference (v4.1) +# Facebook SDK for PHP Reference (v5) Below is the API reference for the Facebook PHP SDK. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 370a34f10..f6707bdb7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -7,7 +7,7 @@ stopOnFailure="false" bootstrap="tests/bootstrap.php"> - + ./tests diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 8e98b03c8..9895deec9 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -57,7 +57,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '4.1.0-dev'; + const VERSION = '5.0.0'; /** * @const string Default Graph API version for requests. diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 01f4d76a4..e1b055197 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -29,7 +29,7 @@ */ if (version_compare(PHP_VERSION, '5.4.0', '<')) { - throw new Exception('The Facebook SDK v4 requires PHP version 5.4 or higher.'); + throw new Exception('The Facebook SDK requires PHP version 5.4 or higher.'); } /** From f96948373336f2c6672fdea4e87f2ccb065e69f8 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:17:23 -0500 Subject: [PATCH 143/407] Update autoloader custom constant name with backwards support --- src/Facebook/autoload.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 01f4d76a4..a0a221b60 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -46,8 +46,16 @@ // project-specific namespace prefix $prefix = 'Facebook\\'; + // For backwards compatibility + $customBaseDir = ''; + // @todo v6: Remove support for 'FACEBOOK_SDK_V4_SRC_DIR' + if (defined('FACEBOOK_SDK_V4_SRC_DIR')) { + $customBaseDir = FACEBOOK_SDK_V4_SRC_DIR; + } elseif (defined('FACEBOOK_SDK_SRC_DIR')) { + $customBaseDir = FACEBOOK_SDK_SRC_DIR; + } // base directory for the namespace prefix - $base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/'; + $baseDir = $customBaseDir ?: __DIR__ . '/'; // does the class use the namespace prefix? $len = strlen($prefix); @@ -57,12 +65,12 @@ } // get the relative class name - $relative_class = substr($class, $len); + $relativeClass = substr($class, $len); // replace the namespace prefix with the base directory, replace namespace // separators with directory separators in the relative class name, append // with .php - $file = rtrim($base_dir, '/') . '/' . str_replace('\\', '/', $relative_class) . '.php'; + $file = rtrim($baseDir, '/') . '/' . str_replace('\\', '/', $relativeClass) . '.php'; // if the file exists, require it if (file_exists($file)) { From d245f8ee606c97c706eade28ff3817595bebcc50 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:19:41 -0500 Subject: [PATCH 144/407] Add TODO note to force default_graph_version option in v6 --- src/Facebook/Facebook.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 8e98b03c8..d30ba30c1 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -199,6 +199,7 @@ public function __construct(array $config = []) if (isset($config['default_graph_version'])) { $this->defaultGraphVersion = $config['default_graph_version']; } else { + // @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set $this->defaultGraphVersion = static::DEFAULT_GRAPH_VERSION; } } From 054c3bc3a887d8e2db7e4afc75964f2b75bdd37e Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:37:55 -0500 Subject: [PATCH 145/407] Rename GraphObject to GraphNode --- src/Facebook/FacebookResponse.php | 2 +- src/Facebook/GraphNodes/GraphAchievement.php | 2 +- src/Facebook/GraphNodes/GraphAlbum.php | 2 +- src/Facebook/GraphNodes/GraphApplication.php | 2 +- src/Facebook/GraphNodes/GraphLocation.php | 2 +- .../{GraphObject.php => GraphNode.php} | 2 +- .../GraphNodes/GraphObjectFactory.php | 46 +++--- src/Facebook/GraphNodes/GraphPage.php | 2 +- src/Facebook/GraphNodes/GraphPicture.php | 2 +- src/Facebook/GraphNodes/GraphSessionInfo.php | 2 +- src/Facebook/GraphNodes/GraphUser.php | 2 +- tests/FacebookBatchResponseTest.php | 6 +- tests/FacebookResponseTest.php | 6 +- tests/GraphNodes/AbstractGraphNode.php | 51 +++++++ tests/GraphNodes/GraphAchievementTest.php | 2 +- tests/GraphNodes/GraphNodeTest.php | 119 +++++++++++++-- tests/GraphNodes/GraphObjectFactoryTest.php | 40 ++--- tests/GraphNodes/GraphObjectTest.php | 138 ------------------ 18 files changed, 214 insertions(+), 214 deletions(-) rename src/Facebook/GraphNodes/{GraphObject.php => GraphNode.php} (99%) create mode 100644 tests/GraphNodes/AbstractGraphNode.php delete mode 100644 tests/GraphNodes/GraphObjectTest.php diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 344f0af88..0a4b77af7 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -261,7 +261,7 @@ public function decodeBody() * * @param string|null $subclassName The GraphObject sub class to cast to. * - * @return \Facebook\GraphNodes\GraphObject + * @return \Facebook\GraphNodes\GraphNode * * @throws FacebookSDKException */ diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php index ad8afe248..c6d400b96 100644 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -29,7 +29,7 @@ * @package Facebook */ -class GraphAchievement extends GraphObject +class GraphAchievement extends GraphNode { /** * @var array Maps object key names to Graph object types. diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index f2de63199..730f4b7e6 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -29,7 +29,7 @@ * @package Facebook */ -class GraphAlbum extends GraphObject +class GraphAlbum extends GraphNode { /** * @var array Maps object key names to Graph object types. diff --git a/src/Facebook/GraphNodes/GraphApplication.php b/src/Facebook/GraphNodes/GraphApplication.php index d22002073..a8b048895 100644 --- a/src/Facebook/GraphNodes/GraphApplication.php +++ b/src/Facebook/GraphNodes/GraphApplication.php @@ -29,7 +29,7 @@ * @package Facebook */ -class GraphApplication extends GraphObject +class GraphApplication extends GraphNode { /** * Returns the ID for the application. diff --git a/src/Facebook/GraphNodes/GraphLocation.php b/src/Facebook/GraphNodes/GraphLocation.php index 45f6d7763..b6b03f885 100644 --- a/src/Facebook/GraphNodes/GraphLocation.php +++ b/src/Facebook/GraphNodes/GraphLocation.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphLocation extends GraphObject +class GraphLocation extends GraphNode { /** * Returns the street component of the location diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphNode.php similarity index 99% rename from src/Facebook/GraphNodes/GraphObject.php rename to src/Facebook/GraphNodes/GraphNode.php index 923b06c90..cabc4bf02 100644 --- a/src/Facebook/GraphNodes/GraphObject.php +++ b/src/Facebook/GraphNodes/GraphNode.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphObject extends Collection +class GraphNode extends Collection { /** * @var array Maps object key names to Graph object types. diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index fa3a143cf..c7bccec26 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -33,12 +33,12 @@ * * ## Assumptions ## * GraphList - is ALWAYS a numeric array - * GraphList - is ALWAYS an array of GraphObject types - * GraphObject - is ALWAYS an associative array - * GraphObject - MAY contain GraphObject's "recurrable" - * GraphObject - MAY contain GraphList's "recurrable" - * GraphObject - MAY contain DateTime's "primitives" - * GraphObject - MAY contain string's "primitives" + * GraphList - is ALWAYS an array of GraphNode types + * GraphNode - is ALWAYS an associative array + * GraphNode - MAY contain GraphNode's "recurrable" + * GraphNode - MAY contain GraphList's "recurrable" + * GraphNode - MAY contain DateTime's "primitives" + * GraphNode - MAY contain string's "primitives" */ class GraphObjectFactory { @@ -46,7 +46,7 @@ class GraphObjectFactory /** * @const string The base graph object class. */ - const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; + const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphNode'; /** * @const string The graph object prefix. @@ -75,11 +75,11 @@ public function __construct(FacebookResponse $response) } /** - * Tries to convert a FacebookResponse entity into a GraphObject. + * Tries to convert a FacebookResponse entity into a GraphNode. * - * @param string|null $subclassName The GraphObject sub class to cast to. + * @param string|null $subclassName The GraphNode sub class to cast to. * - * @return GraphObject + * @return GraphNode * * @throws FacebookSDKException */ @@ -154,7 +154,7 @@ public function makeGraphUser() /** * Tries to convert a FacebookResponse entity into a GraphList. * - * @param string|null $subclassName The GraphObject sub class to cast the list items to. + * @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 GraphList @@ -186,7 +186,7 @@ public function validateResponseAsArray() } /** - * Validates that the return data can be cast as a GraphObject. + * Validates that the return data can be cast as a GraphNode. * * @throws FacebookSDKException */ @@ -194,7 +194,7 @@ public function validateResponseCastableAsGraphObject() { if (isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data'])) { throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphObject because the response looks like a GraphList. Try using GraphObjectFactory::makeGraphList() instead.', + 'Unable to convert response from Graph to a GraphNode because the response looks like a GraphList. Try using GraphObjectFactory::makeGraphList() instead.', 620 ); } @@ -216,12 +216,12 @@ public function validateResponseCastableAsGraphList() } /** - * Safely instantiates a GraphObject of $subclassName. + * Safely instantiates a GraphNode of $subclassName. * * @param array $data The array of data to iterate over. * @param string|null $subclassName The subclass to cast this collection to. * - * @return GraphObject + * @return GraphNode * * @throws FacebookSDKException */ @@ -246,7 +246,7 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) ? $graphObjectMap[$k] : null; - // Could be a GraphList or GraphObject + // Could be a GraphList or GraphNode $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); } else { $items[$k] = $v; @@ -264,7 +264,7 @@ public function safelyMakeGraphObject(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 GraphObject|GraphList + * @return GraphNode|GraphList * * @throws FacebookSDKException */ @@ -275,19 +275,19 @@ public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, if (static::isCastableAsGraphList($data['data'])) { return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); } - // Sometimes Graph is a weirdo and returns a GraphObject under the "data" key + // Sometimes Graph is a weirdo and returns a GraphNode under the "data" key $data = $data['data']; } - // Create GraphObject + // Create GraphNode return $this->safelyMakeGraphObject($data, $subclassName); } /** - * Return an array of GraphObject's. + * Return an array of GraphNode's. * * @param array $data The array of data to iterate over. - * @param string|null $subclassName The GraphObject subclass to cast each item in the list to. + * @param string|null $subclassName The GraphNode subclass to cast each item in the list to. * @param string|null $parentKey The key of this data (Graph edge). * @param string|null $parentNodeId The parent Graph node ID. * @@ -348,7 +348,7 @@ public static function isCastableAsGraphList(array $data) /** * Ensures that the subclass in question is valid. * - * @param string $subclassName The GraphObject subclass to validate. + * @param string $subclassName The GraphNode subclass to validate. * * @throws FacebookSDKException */ @@ -358,6 +358,6 @@ public static function validateSubclass($subclassName) return; } - throw new FacebookSDKException('The given subclass "' . $subclassName . '" is not valid. Cannot cast to an object that is not a GraphObject subclass.', 620); + throw new FacebookSDKException('The given subclass "' . $subclassName . '" is not valid. Cannot cast to an object that is not a GraphNode subclass.', 620); } } diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index 4c709a0f2..69346e229 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphPage extends GraphObject +class GraphPage extends GraphNode { /** * @var array Maps object key names to Graph object types. diff --git a/src/Facebook/GraphNodes/GraphPicture.php b/src/Facebook/GraphNodes/GraphPicture.php index 22a66ca76..8852d6aa9 100644 --- a/src/Facebook/GraphNodes/GraphPicture.php +++ b/src/Facebook/GraphNodes/GraphPicture.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphPicture extends GraphObject +class GraphPicture extends GraphNode { /** * Returns true if user picture is silhouette. diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index 976d0ab9a..b962de1ec 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphSessionInfo extends GraphObject +class GraphSessionInfo extends GraphNode { /** * Returns the application id the token was issued for. diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 3bab2a3c7..11ffb0b19 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphUser extends GraphObject +class GraphUser extends GraphNode { /** * @var array Maps object key names to Graph object types. diff --git a/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index b633e25e5..4b2e3b422 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -80,12 +80,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\GraphObject', $decodedResponses[0]->getGraphObject()); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $decodedResponses[0]->getGraphObject()); // Paginated list of Graph objects. $this->assertFalse($decodedResponses[1]->isError(), 'Did not expect Response to return an error for paginated list of Graph objects.'); $graphList = $decodedResponses[1]->getGraphList(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphList[1]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphList[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphList[1]); } public function testABatchResponseCanBeIteratedOver() diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index eece6d8d9..0802be6ad 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -79,7 +79,7 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() 'id' => '123', 'name' => 'Foo', ], $decodedResponse); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObject); } public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() @@ -90,8 +90,8 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() $graphObjectList = $response->getGraphList(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObjectList[1]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObjectList[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObjectList[1]); } public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() diff --git a/tests/GraphNodes/AbstractGraphNode.php b/tests/GraphNodes/AbstractGraphNode.php new file mode 100644 index 000000000..6d52acdf0 --- /dev/null +++ b/tests/GraphNodes/AbstractGraphNode.php @@ -0,0 +1,51 @@ +responseMock = m::mock('\Facebook\FacebookResponse'); + } + + protected function makeFactoryWithData($data) + { + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($data); + + return new GraphObjectFactory($this->responseMock); + } +} diff --git a/tests/GraphNodes/GraphAchievementTest.php b/tests/GraphNodes/GraphAchievementTest.php index bfd9f2096..787d9fc8c 100644 --- a/tests/GraphNodes/GraphAchievementTest.php +++ b/tests/GraphNodes/GraphAchievementTest.php @@ -23,7 +23,7 @@ */ namespace Facebook\Tests\GraphNodes; -class GraphAchievementTest extends GraphNodeTest +class GraphAchievementTest extends AbstractGraphNode { public function testIdIsString() diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php index 17036c856..031484f34 100644 --- a/tests/GraphNodes/GraphNodeTest.php +++ b/tests/GraphNodes/GraphNodeTest.php @@ -23,29 +23,116 @@ */ namespace Facebook\Tests\GraphNodes; -use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNode; -abstract class GraphNodeTest extends \PHPUnit_Framework_TestCase +class GraphNodeTest extends \PHPUnit_Framework_TestCase { - /** - * @var \Facebook\FacebookResponse|\Mockery\MockInterface - */ - protected $responseMock; + public function testAnEmptyBaseGraphObjectCanInstantiate() + { + $graphObject = new GraphNode(); + $backingData = $graphObject->asArray(); + + $this->assertEquals([], $backingData); + } + + public function testAGraphObjectCanInstantiateWithData() + { + $graphObject = new GraphNode(['foo' => 'bar']); + $backingData = $graphObject->asArray(); + + $this->assertEquals(['foo' => 'bar'], $backingData); + } + + public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() + { + $graphObject = new GraphNode(); + + // Should pass + $shouldPass = $graphObject->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 = $graphObject->isIso8601DateString('1999-12-31'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); + + $shouldPass = $graphObject->isIso8601DateString('2009-05-19T14:39Z'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + $shouldPass = $graphObject->isIso8601DateString('2014-W36'); + $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); + + // Should fail + $shouldFail = $graphObject->isIso8601DateString('2009-05-19T14a39r'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + + $shouldFail = $graphObject->isIso8601DateString('foo_time'); + $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); + } - public function setUp() + public function testATimeStampCanBeConvertedToADateTimeObject() { - parent::setUp(); - $this->responseMock = m::mock('\Facebook\FacebookResponse'); + $someTimeStampFromGraph = 1405547020; + $graphObject = new GraphNode(); + $dateTime = $graphObject->castToDateTime($someTimeStampFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); + + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); + $this->assertEquals(1405547020, $timeStamp); + } + + public function testAGraphDateStringCanBeConvertedToADateTimeObject() + { + $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; + $graphObject = new GraphNode(); + $dateTime = $graphObject->castToDateTime($someDateStringFromGraph); + $prettyDate = $dateTime->format(\DateTime::RFC1036); + $timeStamp = $dateTime->getTimestamp(); + + $this->assertInstanceOf('DateTime', $dateTime); + $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); + $this->assertEquals(1405395893, $timeStamp); + } + + public function testUncastingAGraphObjectWillUncastTheDateTimeObject() + { + $collectionOne = new GraphNode(['foo', 'bar']); + $collectionTwo = new GraphNode([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + 'some_collection' => $collectionOne, + ]); + + $uncastArray = $collectionTwo->uncastItems(); + + $this->assertEquals([ + 'id' => '123', + 'date' => '2014-07-15T03:44:53+0000', + 'some_collection' => ['foo', 'bar'], + ], $uncastArray); + } + + public function testGettingGraphObjectAsAnArrayWillNotUncastTheDateTimeObject() + { + $collection = new GraphNode([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsArray = $collection->asArray(); + + $this->assertInstanceOf('DateTime', $collectionAsArray['date']); } - protected function makeFactoryWithData($data) + public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() { - $this->responseMock - ->shouldReceive('getDecodedBody') - ->once() - ->andReturn($data); + $collection = new GraphNode([ + 'id' => '123', + 'date' => new \DateTime('2014-07-15T03:44:53+0000'), + ]); + + $collectionAsString = $collection->asJson(); - return new GraphObjectFactory($this->responseMock); + $this->assertEquals('{"id":"123","date":"2014-07-15T03:44:53+0000"}', $collectionAsString); } } diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index 8a397eefd..c06f6a0bc 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -27,16 +27,16 @@ use Facebook\FacebookRequest; use Facebook\FacebookResponse; use Facebook\GraphNodes\GraphObjectFactory; -use Facebook\GraphNodes\GraphObject; +use Facebook\GraphNodes\GraphNode; -class MyFooSubClassGraphObject extends GraphObject +class MyFooSubClassGraphNode extends GraphNode { } -class MyFooGraphObject extends GraphObject +class MyFooGraphNode extends GraphNode { protected static $graphObjectMap = [ - 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', + 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', ]; } @@ -124,9 +124,9 @@ public function testInvalidSubClassesWillThrow() public function testValidSubClassesWillNotThrow() { - GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphNode'); GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); - GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphNode'); } public function testCastingAsASubClassObjectWillInstantiateTheSubClass() @@ -135,9 +135,9 @@ public function testCastingAsASubClassObjectWillInstantiateTheSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); } public function testASubClassMappingWillAutomaticallyInstantiateSubClass() @@ -146,11 +146,11 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $fooObject = $mySubClassObject->getProperty('foo_object'); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphObject', $fooObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', $fooObject); } public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() @@ -167,12 +167,12 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() $factory = new GraphObjectFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphObject'); + $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $unknownObject = $mySubClassObject->getProperty('unknown_object'); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $mySubClassObject); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $unknownObject); - $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphObject', $unknownObject); + $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $unknownObject); } public function testAListFromGraphWillBeCastAsAGraphList() @@ -227,7 +227,7 @@ public function testAGraphObjectWillBeCastAsAGraphObject() $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -251,7 +251,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphObject); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -349,20 +349,20 @@ public function testAGraphListWillBeCastRecursively() // Story $storyObject = $graphObject[0]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $storyObject['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $storyObject['from']); $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); // Story Comments $storyComments = $storyObject['comments']; $firstStoryComment = $storyComments[0]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $firstStoryComment['from']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $firstStoryComment['from']); // Message $messageObject = $graphObject[1]; $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); $toUsers = $messageObject['to']; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphObject', $toUsers[0]); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $toUsers[0]); } public function testAGraphListWillGenerateTheProperParentGraphEdges() diff --git a/tests/GraphNodes/GraphObjectTest.php b/tests/GraphNodes/GraphObjectTest.php deleted file mode 100644 index 9ef900bba..000000000 --- a/tests/GraphNodes/GraphObjectTest.php +++ /dev/null @@ -1,138 +0,0 @@ -asArray(); - - $this->assertEquals([], $backingData); - } - - public function testAGraphObjectCanInstantiateWithData() - { - $graphObject = new GraphObject(['foo' => 'bar']); - $backingData = $graphObject->asArray(); - - $this->assertEquals(['foo' => 'bar'], $backingData); - } - - public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() - { - $graphObject = new GraphObject(); - - // Should pass - $shouldPass = $graphObject->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 = $graphObject->isIso8601DateString('1999-12-31'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); - - $shouldPass = $graphObject->isIso8601DateString('2009-05-19T14:39Z'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - - $shouldPass = $graphObject->isIso8601DateString('2014-W36'); - $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - - // Should fail - $shouldFail = $graphObject->isIso8601DateString('2009-05-19T14a39r'); - $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); - - $shouldFail = $graphObject->isIso8601DateString('foo_time'); - $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); - } - - public function testATimeStampCanBeConvertedToADateTimeObject() - { - $someTimeStampFromGraph = 1405547020; - $graphObject = new GraphObject(); - $dateTime = $graphObject->castToDateTime($someTimeStampFromGraph); - $prettyDate = $dateTime->format(\DateTime::RFC1036); - $timeStamp = $dateTime->getTimestamp(); - - $this->assertInstanceOf('DateTime', $dateTime); - $this->assertEquals('Wed, 16 Jul 14 23:43:40 +0200', $prettyDate); - $this->assertEquals(1405547020, $timeStamp); - } - - public function testAGraphDateStringCanBeConvertedToADateTimeObject() - { - $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; - $graphObject = new GraphObject(); - $dateTime = $graphObject->castToDateTime($someDateStringFromGraph); - $prettyDate = $dateTime->format(\DateTime::RFC1036); - $timeStamp = $dateTime->getTimestamp(); - - $this->assertInstanceOf('DateTime', $dateTime); - $this->assertEquals('Tue, 15 Jul 14 03:44:53 +0000', $prettyDate); - $this->assertEquals(1405395893, $timeStamp); - } - - public function testUncastingAGraphObjectWillUncastTheDateTimeObject() - { - $collectionOne = new GraphObject(['foo', 'bar']); - $collectionTwo = new GraphObject([ - 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), - 'some_collection' => $collectionOne, - ]); - - $uncastArray = $collectionTwo->uncastItems(); - - $this->assertEquals([ - 'id' => '123', - 'date' => '2014-07-15T03:44:53+0000', - 'some_collection' => ['foo', 'bar'], - ], $uncastArray); - } - - public function testGettingGraphObjectAsAnArrayWillNotUncastTheDateTimeObject() - { - $collection = new GraphObject([ - 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), - ]); - - $collectionAsArray = $collection->asArray(); - - $this->assertInstanceOf('DateTime', $collectionAsArray['date']); - } - - public function testReturningACollectionAsJasonWillSafelyRepresentDateTimes() - { - $collection = new GraphObject([ - 'id' => '123', - 'date' => new \DateTime('2014-07-15T03:44:53+0000'), - ]); - - $collectionAsString = $collection->asJson(); - - $this->assertEquals('{"id":"123","date":"2014-07-15T03:44:53+0000"}', $collectionAsString); - } -} From 541e33479ac56d5b9f9b0521d07b08e0de9b0c57 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:39:43 -0500 Subject: [PATCH 146/407] Rename GraphObjectFactory to GraphNodeFactory --- ...ObjectFactory.php => GraphNodeFactory.php} | 2 +- ...ctoryTest.php => GraphNodeFactoryTest.php} | 42 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) rename src/Facebook/GraphNodes/{GraphObjectFactory.php => GraphNodeFactory.php} (99%) rename tests/GraphNodes/{GraphObjectFactoryTest.php => GraphNodeFactoryTest.php} (91%) diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php similarity index 99% rename from src/Facebook/GraphNodes/GraphObjectFactory.php rename to src/Facebook/GraphNodes/GraphNodeFactory.php index c7bccec26..3d60d085a 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -40,7 +40,7 @@ * GraphNode - MAY contain DateTime's "primitives" * GraphNode - MAY contain string's "primitives" */ -class GraphObjectFactory +class GraphNodeFactory { /** diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php similarity index 91% rename from tests/GraphNodes/GraphObjectFactoryTest.php rename to tests/GraphNodes/GraphNodeFactoryTest.php index c06f6a0bc..dd702dec2 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -26,7 +26,7 @@ use Facebook\FacebookApp; use Facebook\FacebookRequest; use Facebook\FacebookResponse; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; use Facebook\GraphNodes\GraphNode; class MyFooSubClassGraphNode extends GraphNode @@ -40,7 +40,7 @@ class MyFooGraphNode extends GraphNode ]; } -class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase +class GraphNodeFactoryTest extends \PHPUnit_Framework_TestCase { /** * @var \Facebook\FacebookRequest @@ -66,7 +66,7 @@ public function testAValidGraphObjectResponseWillNotThrow() $data = '{"id":"123","name":"foo"}'; $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $factory->validateResponseCastableAsGraphObject(); } @@ -78,7 +78,7 @@ public function testANonGraphObjectResponseWillThrow() $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $factory->validateResponseCastableAsGraphObject(); } @@ -87,7 +87,7 @@ public function testAValidGraphListResponseWillNotThrow() $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $factory->validateResponseCastableAsGraphList(); } @@ -99,15 +99,15 @@ public function testANonGraphListResponseWillThrow() $data = '{"id":"123","name":"foo"}'; $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $factory->validateResponseCastableAsGraphList(); } public function testOnlyNumericArraysAreCastableAsAGraphList() { - $shouldPassOne = GraphObjectFactory::isCastableAsGraphList([]); - $shouldPassTwo = GraphObjectFactory::isCastableAsGraphList(['foo', 'bar']); - $shouldFail = GraphObjectFactory::isCastableAsGraphList(['faz' => 'baz']); + $shouldPassOne = GraphNodeFactory::isCastableAsGraphList([]); + $shouldPassTwo = GraphNodeFactory::isCastableAsGraphList(['foo', 'bar']); + $shouldFail = GraphNodeFactory::isCastableAsGraphList(['faz' => 'baz']); $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphList.'); $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphList.'); @@ -119,14 +119,14 @@ public function testOnlyNumericArraysAreCastableAsAGraphList() */ public function testInvalidSubClassesWillThrow() { - GraphObjectFactory::validateSubclass('FooSubClass'); + GraphNodeFactory::validateSubclass('FooSubClass'); } public function testValidSubClassesWillNotThrow() { - GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphNode'); - GraphObjectFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); - GraphObjectFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphNode'); + GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); + GraphNodeFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphNode'); } public function testCastingAsASubClassObjectWillInstantiateTheSubClass() @@ -134,7 +134,7 @@ public function testCastingAsASubClassObjectWillInstantiateTheSubClass() $data = '{"id":"123","name":"foo"}'; $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); @@ -145,7 +145,7 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $data = '{"id":"123","name":"Foo Name","foo_object":{"id":"1337","name":"Should be sub classed!"}}'; $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $fooObject = $mySubClassObject->getProperty('foo_object'); @@ -165,7 +165,7 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() ]); $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $unknownObject = $mySubClassObject->getProperty('unknown_object'); @@ -197,7 +197,7 @@ public function testAListFromGraphWillBeCastAsAGraphList() ]); $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $graphList = $factory->makeGraphList(); $graphData = $graphList->asArray(); @@ -223,7 +223,7 @@ public function testAGraphObjectWillBeCastAsAGraphObject() ]); $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); @@ -247,7 +247,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $graphObject = $factory->makeGraphObject(); $graphData = $graphObject->asArray(); @@ -343,7 +343,7 @@ public function testAGraphListWillBeCastRecursively() $data = json_encode($dataFromGraph); $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $graphObject = $factory->makeGraphList(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); @@ -420,7 +420,7 @@ public function testAGraphListWillGenerateTheProperParentGraphEdges() ]); $res = new FacebookResponse($this->request, $data); - $factory = new GraphObjectFactory($res); + $factory = new GraphNodeFactory($res); $graphList = $factory->makeGraphList(); $topGraphEdge = $graphList->getParentGraphEdge(); $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); From f511b5ca87ed59a74ab551e4c82c977479f45a51 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:39:55 -0500 Subject: [PATCH 147/407] Rename GraphObjectFactory to GraphNodeFactory --- src/Facebook/FacebookResponse.php | 14 +++++++------- tests/GraphNodes/AbstractGraphNode.php | 4 ++-- tests/GraphNodes/GraphAlbumTest.php | 8 ++++---- tests/GraphNodes/GraphPageTest.php | 6 +++--- tests/GraphNodes/GraphSessionInfoTest.php | 4 ++-- tests/GraphNodes/GraphUserTest.php | 10 +++++----- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 0a4b77af7..8d51e798a 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -23,7 +23,7 @@ */ namespace Facebook; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; @@ -267,7 +267,7 @@ public function decodeBody() */ public function getGraphObject($subclassName = null) { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphObject($subclassName); } @@ -281,7 +281,7 @@ public function getGraphObject($subclassName = null) */ public function getGraphAlbum() { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphAlbum(); } @@ -295,7 +295,7 @@ public function getGraphAlbum() */ public function getGraphPage() { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphPage(); } @@ -309,7 +309,7 @@ public function getGraphPage() */ public function getGraphSessionInfo() { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphSessionInfo(); } @@ -323,7 +323,7 @@ public function getGraphSessionInfo() */ public function getGraphUser() { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphUser(); } @@ -340,7 +340,7 @@ public function getGraphUser() */ public function getGraphList($subclassName = null, $auto_prefix = true) { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphList($subclassName, $auto_prefix); } diff --git a/tests/GraphNodes/AbstractGraphNode.php b/tests/GraphNodes/AbstractGraphNode.php index 6d52acdf0..1c4ce15a0 100644 --- a/tests/GraphNodes/AbstractGraphNode.php +++ b/tests/GraphNodes/AbstractGraphNode.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\GraphNodes; use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; abstract class AbstractGraphNode extends \PHPUnit_Framework_TestCase { @@ -46,6 +46,6 @@ protected function makeFactoryWithData($data) ->once() ->andReturn($data); - return new GraphObjectFactory($this->responseMock); + return new GraphNodeFactory($this->responseMock); } } diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 50484c4e3..a5d28a9cb 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\GraphNodes; use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; class GraphAlbumTest extends \PHPUnit_Framework_TestCase { @@ -52,7 +52,7 @@ public function testDatesGetCastToDateTime() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphAlbum(); $createdTime = $graphObject->getCreatedTime(); @@ -76,7 +76,7 @@ public function testFromGetsCastAsGraphUser() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphAlbum(); $from = $graphObject->getFrom(); @@ -99,7 +99,7 @@ public function testPlacePropertyWillGetCastAsGraphPageObject() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphAlbum(); $place = $graphObject->getPlace(); diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php index f6861a23f..1bfabc8a3 100644 --- a/tests/GraphNodes/GraphPageTest.php +++ b/tests/GraphNodes/GraphPageTest.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\GraphNodes; use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; class GraphPageTest extends \PHPUnit_Framework_TestCase { @@ -57,7 +57,7 @@ public function testPagePropertiesReturnGraphPageObjects() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphPage(); $bestPage = $graphObject->getBestPage(); @@ -85,7 +85,7 @@ public function testLocationPropertyWillGetCastAsGraphLocationObject() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphPage(); $location = $graphObject->getLocation(); diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index 51322be25..f273a880d 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -24,7 +24,7 @@ namespace Facebook\Tests\GraphNodes; use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase { @@ -49,7 +49,7 @@ public function testDatesGetCastToDateTime() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphSessionInfo(); diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index 5de8119c3..aa7981506 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -25,7 +25,7 @@ use Facebook\FacebookResponse; use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; class GraphUserTest extends \PHPUnit_Framework_TestCase { @@ -49,7 +49,7 @@ public function testDatesGetCastToDateTime() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphUser(); $birthday = $graphObject->getBirthday(); @@ -76,7 +76,7 @@ public function testPagePropertiesWillGetCastAsGraphPageObjects() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphUser(); $hometown = $graphObject->getHometown(); @@ -101,7 +101,7 @@ public function testUserPropertiesWillGetCastAsGraphUserObjects() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphUser(); $significantOther = $graphObject->getSignificantOther(); @@ -126,7 +126,7 @@ public function testPicturePropertiesWillGetCastAsGraphPictureObjects() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphUser(); $Picture = $graphObject->getPicture(); From 334a5618f1cc5e8815fa7d10b6647c45db80c72f Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:50:54 -0500 Subject: [PATCH 148/407] Rename GraphList to GraphEdge --- src/Facebook/Facebook.php | 20 ++++----- src/Facebook/FacebookResponse.php | 4 +- .../{GraphList.php => GraphEdge.php} | 6 +-- src/Facebook/GraphNodes/GraphNodeFactory.php | 34 +++++++------- tests/FacebookTest.php | 6 +-- .../{GraphListTest.php => GraphEdgeTest.php} | 26 +++++------ tests/GraphNodes/GraphNodeFactoryTest.php | 44 +++++++++---------- 7 files changed, 70 insertions(+), 70 deletions(-) rename src/Facebook/GraphNodes/{GraphList.php => GraphEdge.php} (98%) rename tests/GraphNodes/{GraphListTest.php => GraphEdgeTest.php} (86%) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 8e98b03c8..4754ea073 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -27,7 +27,7 @@ use Facebook\Authentication\OAuth2Client; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; -use Facebook\GraphNodes\GraphList; +use Facebook\GraphNodes\GraphEdge; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; @@ -429,13 +429,13 @@ public function delete($endpoint, array $params = [], $accessToken = null, $eTag /** * Sends a request to Graph for the next page of results. * - * @param GraphList $graphList The GraphList to paginate over. + * @param GraphEdge $graphList The GraphEdge to paginate over. * - * @return GraphList|null + * @return GraphEdge|null * * @throws FacebookSDKException */ - public function next(GraphList $graphList) + public function next(GraphEdge $graphList) { return $this->getPaginationResults($graphList, 'next'); } @@ -443,13 +443,13 @@ public function next(GraphList $graphList) /** * Sends a request to Graph for the previous page of results. * - * @param GraphList $graphList The GraphList to paginate over. + * @param GraphEdge $graphList The GraphEdge to paginate over. * - * @return GraphList|null + * @return GraphEdge|null * * @throws FacebookSDKException */ - public function previous(GraphList $graphList) + public function previous(GraphEdge $graphList) { return $this->getPaginationResults($graphList, 'previous'); } @@ -457,14 +457,14 @@ public function previous(GraphList $graphList) /** * Sends a request to Graph for the next page of results. * - * @param GraphList $graphList The GraphList to paginate over. + * @param GraphEdge $graphList The GraphEdge to paginate over. * @param string $direction The direction of the pagination: next|previous. * - * @return GraphList|null + * @return GraphEdge|null * * @throws FacebookSDKException */ - public function getPaginationResults(GraphList $graphList, $direction) + public function getPaginationResults(GraphEdge $graphList, $direction) { $paginationRequest = $graphList->getPaginationRequest($direction); if (!$paginationRequest) { diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 8d51e798a..d117d5dce 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -329,12 +329,12 @@ public function getGraphUser() } /** - * Instantiate a new GraphList from response. + * Instantiate a new GraphEdge from response. * * @param string|null $subclassName The GraphObject sub class to cast list items to. * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. * - * @return \Facebook\GraphNodes\GraphList + * @return \Facebook\GraphNodes\GraphEdge * * @throws FacebookSDKException */ diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphEdge.php similarity index 98% rename from src/Facebook/GraphNodes/GraphList.php rename to src/Facebook/GraphNodes/GraphEdge.php index 8bc2b15db..46a4499be 100644 --- a/src/Facebook/GraphNodes/GraphList.php +++ b/src/Facebook/GraphNodes/GraphEdge.php @@ -28,11 +28,11 @@ use Facebook\Exceptions\FacebookSDKException; /** - * Class GraphList + * Class GraphEdge * * @package Facebook */ -class GraphList extends Collection +class GraphEdge extends Collection { /** * @var FacebookRequest The original request that generated this data. @@ -94,7 +94,7 @@ public function getSubClassName() } /** - * Returns the raw meta data associated with this GraphList. + * Returns the raw meta data associated with this GraphEdge. * * @return array */ diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index 3d60d085a..e4322280b 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -32,11 +32,11 @@ * @package Facebook * * ## Assumptions ## - * GraphList - is ALWAYS a numeric array - * GraphList - is ALWAYS an array of GraphNode types + * GraphEdge - is ALWAYS a numeric array + * GraphEdge - is ALWAYS an array of GraphNode types * GraphNode - is ALWAYS an associative array * GraphNode - MAY contain GraphNode's "recurrable" - * GraphNode - MAY contain GraphList's "recurrable" + * GraphNode - MAY contain GraphEdge's "recurrable" * GraphNode - MAY contain DateTime's "primitives" * GraphNode - MAY contain string's "primitives" */ @@ -152,12 +152,12 @@ public function makeGraphUser() } /** - * Tries to convert a FacebookResponse entity into a GraphList. + * 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 GraphList + * @return GraphEdge * * @throws FacebookSDKException */ @@ -194,14 +194,14 @@ public function validateResponseCastableAsGraphObject() { if (isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data'])) { throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphNode because the response looks like a GraphList. Try using GraphObjectFactory::makeGraphList() instead.', + 'Unable to convert response from Graph to a GraphNode because the response looks like a GraphEdge. Try using GraphObjectFactory::makeGraphList() instead.', 620 ); } } /** - * Validates that the return data can be cast as a GraphList. + * Validates that the return data can be cast as a GraphEdge. * * @throws FacebookSDKException */ @@ -209,7 +209,7 @@ public function validateResponseCastableAsGraphList() { if (!(isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data']))) { throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphList because the response does not look like a GraphList. Try using GraphObjectFactory::makeGraphObject() instead.', + 'Unable to convert response from Graph to a GraphEdge because the response does not look like a GraphEdge. Try using GraphObjectFactory::makeGraphObject() instead.', 620 ); } @@ -246,7 +246,7 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) ? $graphObjectMap[$k] : null; - // Could be a GraphList or GraphNode + // Could be a GraphEdge or GraphNode $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); } else { $items[$k] = $v; @@ -264,14 +264,14 @@ public function safelyMakeGraphObject(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|GraphList + * @return GraphNode|GraphEdge * * @throws FacebookSDKException */ public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (isset($data['data'])) { - // Create GraphList + // Create GraphEdge if (static::isCastableAsGraphList($data['data'])) { return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); } @@ -291,14 +291,14 @@ public function castAsGraphObjectOrGraphList(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 GraphList + * @return GraphEdge * * @throws FacebookSDKException */ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (!isset($data['data'])) { - throw new FacebookSDKException('Cannot cast data to GraphList. Expected a "data" key.', 620); + throw new FacebookSDKException('Cannot cast data to GraphEdge. Expected a "data" key.', 620); } $dataList = []; @@ -308,10 +308,10 @@ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKe $metaData = $this->getMetaData($data); - // We'll need to make an edge endpoint for this in case it's a GraphList (for cursor pagination) + // 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; - return new GraphList($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + return new GraphEdge($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); } /** @@ -329,7 +329,7 @@ public function getMetaData(array $data) } /** - * Determines whether or not the data should be cast as a GraphList. + * Determines whether or not the data should be cast as a GraphEdge. * * @param array $data * @@ -341,7 +341,7 @@ public static function isCastableAsGraphList(array $data) return true; } - // Checks for a sequential numeric array which would be a GraphList + // Checks for a sequential numeric array which would be a GraphEdge return array_keys($data) === range(0, count($data) - 1); } diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 160af574e..d4a4de338 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -32,7 +32,7 @@ use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; use Facebook\FacebookRequest; use Facebook\Authentication\AccessToken; -use Facebook\GraphNodes\GraphList; +use Facebook\GraphNodes\GraphEdge; class FooClientInterface implements FacebookHttpClientInterface { @@ -354,7 +354,7 @@ public function testPaginationReturnsProperResponse() $fb = new Facebook($config); $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); - $graphList = new GraphList( + $graphList = new GraphEdge( $request, [], [ @@ -370,7 +370,7 @@ public function testPaginationReturnsProperResponse() ); $nextPage = $fb->next($graphList); - $this->assertInstanceOf('Facebook\GraphNodes\GraphList', $nextPage); + $this->assertInstanceOf('Facebook\GraphNodes\GraphEdge', $nextPage); $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); $this->assertEquals('Foo', $nextPage[0]['name']); diff --git a/tests/GraphNodes/GraphListTest.php b/tests/GraphNodes/GraphEdgeTest.php similarity index 86% rename from tests/GraphNodes/GraphListTest.php rename to tests/GraphNodes/GraphEdgeTest.php index f048aae49..4e70f523a 100644 --- a/tests/GraphNodes/GraphListTest.php +++ b/tests/GraphNodes/GraphEdgeTest.php @@ -25,9 +25,9 @@ use Facebook\FacebookApp; use Facebook\FacebookRequest; -use Facebook\GraphNodes\GraphList; +use Facebook\GraphNodes\GraphEdge; -class GraphListTest extends \PHPUnit_Framework_TestCase +class GraphEdgeTest extends \PHPUnit_Framework_TestCase { /** @@ -66,19 +66,19 @@ public function setUp() public function testNonGetRequestsWillThrow() { $this->request->setMethod('POST'); - $graphList = new GraphList($this->request); - $graphList->validateForPagination(); + $graphEdge = new GraphEdge($this->request); + $graphEdge->validateForPagination(); } public function testCanReturnGraphGeneratedPaginationEndpoints() { - $graphList = new GraphList( + $graphEdge = new GraphEdge( $this->request, [], ['paging' => $this->basePagination] ); - $nextPage = $graphList->getPaginationUrl('next'); - $prevPage = $graphList->getPaginationUrl('previous'); + $nextPage = $graphEdge->getPaginationUrl('next'); + $prevPage = $graphEdge->getPaginationUrl('previous'); $this->assertEquals('/998899/photos?pretty=0&limit=25&after=foo_after_cursor', $nextPage); $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); @@ -86,14 +86,14 @@ public function testCanReturnGraphGeneratedPaginationEndpoints() public function testCanGeneratePaginationEndpointsFromACursor() { - $graphList = new GraphList( + $graphEdge = new GraphEdge( $this->request, [], ['paging' => $this->cursorPagination], '/1234567890/likes' ); - $nextPage = $graphList->getPaginationUrl('next'); - $prevPage = $graphList->getPaginationUrl('previous'); + $nextPage = $graphEdge->getPaginationUrl('next'); + $prevPage = $graphEdge->getPaginationUrl('previous'); $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); @@ -101,14 +101,14 @@ public function testCanGeneratePaginationEndpointsFromACursor() public function testCanInstantiateNewPaginationRequest() { - $graphList = new GraphList( + $graphEdge = new GraphEdge( $this->request, [], ['paging' => $this->cursorPagination], '/1234567890/likes' ); - $nextPage = $graphList->getNextPageRequest(); - $prevPage = $graphList->getPreviousPageRequest(); + $nextPage = $graphEdge->getNextPageRequest(); + $prevPage = $graphEdge->getPreviousPageRequest(); $this->assertInstanceOf('Facebook\FacebookRequest', $nextPage); $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index dd702dec2..56c329948 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -82,7 +82,7 @@ public function testANonGraphObjectResponseWillThrow() $factory->validateResponseCastableAsGraphObject(); } - public function testAValidGraphListResponseWillNotThrow() + public function testAValidGraphEdgeResponseWillNotThrow() { $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; $res = new FacebookResponse($this->request, $data); @@ -94,7 +94,7 @@ public function testAValidGraphListResponseWillNotThrow() /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ - public function testANonGraphListResponseWillThrow() + public function testANonGraphEdgeResponseWillThrow() { $data = '{"id":"123","name":"foo"}'; $res = new FacebookResponse($this->request, $data); @@ -103,15 +103,15 @@ public function testANonGraphListResponseWillThrow() $factory->validateResponseCastableAsGraphList(); } - public function testOnlyNumericArraysAreCastableAsAGraphList() + public function testOnlyNumericArraysAreCastableAsAGraphEdge() { $shouldPassOne = GraphNodeFactory::isCastableAsGraphList([]); $shouldPassTwo = GraphNodeFactory::isCastableAsGraphList(['foo', 'bar']); $shouldFail = GraphNodeFactory::isCastableAsGraphList(['faz' => 'baz']); - $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphList.'); - $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphList.'); - $this->assertFalse($shouldFail, 'Expected the given array to not be castable as a GraphList.'); + $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphEdge.'); + $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphEdge.'); + $this->assertFalse($shouldFail, 'Expected the given array to not be castable as a GraphEdge.'); } /** @@ -175,7 +175,7 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $unknownObject); } - public function testAListFromGraphWillBeCastAsAGraphList() + public function testAListFromGraphWillBeCastAsAGraphEdge() { $data = json_encode([ 'data' => [ @@ -198,10 +198,10 @@ public function testAListFromGraphWillBeCastAsAGraphList() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphList = $factory->makeGraphList(); - $graphData = $graphList->asArray(); + $graphEdge = $factory->makeGraphList(); + $graphData = $graphEdge->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphEdge); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -259,7 +259,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() ], $graphData); } - public function testAGraphListWillBeCastRecursively() + public function testAGraphEdgeWillBeCastRecursively() { $someUser = [ 'id' => '123', @@ -345,13 +345,13 @@ public function testAGraphListWillBeCastRecursively() $factory = new GraphNodeFactory($res); $graphObject = $factory->makeGraphList(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphObject); // Story $storyObject = $graphObject[0]; $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $storyObject['from']); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['likes']); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $storyObject['comments']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['likes']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['comments']); // Story Comments $storyComments = $storyObject['comments']; @@ -360,12 +360,12 @@ public function testAGraphListWillBeCastRecursively() // Message $messageObject = $graphObject[1]; - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $messageObject['to']); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $messageObject['to']); $toUsers = $messageObject['to']; $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $toUsers[0]); } - public function testAGraphListWillGenerateTheProperParentGraphEdges() + public function testAGraphEdgeWillGenerateTheProperParentGraphEdges() { $likesList = [ 'data' => [ @@ -421,12 +421,12 @@ public function testAGraphListWillGenerateTheProperParentGraphEdges() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphList = $factory->makeGraphList(); - $topGraphEdge = $graphList->getParentGraphEdge(); - $childGraphEdgeOne = $graphList[0]['likes']->getParentGraphEdge(); - $childGraphEdgeTwo = $graphList[1]['likes']->getParentGraphEdge(); - $childGraphEdgeThree = $graphList[1]['photos']->getParentGraphEdge(); - $childGraphEdgeFour = $graphList[1]['photos'][0]['likes']->getParentGraphEdge(); + $graphEdge = $factory->makeGraphList(); + $topGraphEdge = $graphEdge->getParentGraphEdge(); + $childGraphEdgeOne = $graphEdge[0]['likes']->getParentGraphEdge(); + $childGraphEdgeTwo = $graphEdge[1]['likes']->getParentGraphEdge(); + $childGraphEdgeThree = $graphEdge[1]['photos']->getParentGraphEdge(); + $childGraphEdgeFour = $graphEdge[1]['photos'][0]['likes']->getParentGraphEdge(); $this->assertNull($topGraphEdge); $this->assertEquals('/111/likes', $childGraphEdgeOne); From f0bdc1b0e80812d56da2f78d7d409d15a347ab08 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 15:57:18 -0500 Subject: [PATCH 149/407] Rename methods on Graph node factory --- src/Facebook/FacebookResponse.php | 4 +- src/Facebook/GraphNodes/GraphNode.php | 2 +- src/Facebook/GraphNodes/GraphNodeFactory.php | 54 ++++++++++---------- tests/GraphNodes/GraphNodeFactoryTest.php | 30 +++++------ 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index d117d5dce..0d26e68a2 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -269,7 +269,7 @@ public function getGraphObject($subclassName = null) { $factory = new GraphNodeFactory($this); - return $factory->makeGraphObject($subclassName); + return $factory->makeGraphNode($subclassName); } /** @@ -342,6 +342,6 @@ public function getGraphList($subclassName = null, $auto_prefix = true) { $factory = new GraphNodeFactory($this); - return $factory->makeGraphList($subclassName, $auto_prefix); + return $factory->makeGraphEdge($subclassName, $auto_prefix); } } diff --git a/src/Facebook/GraphNodes/GraphNode.php b/src/Facebook/GraphNodes/GraphNode.php index cabc4bf02..0d2f504c1 100644 --- a/src/Facebook/GraphNodes/GraphNode.php +++ b/src/Facebook/GraphNodes/GraphNode.php @@ -24,7 +24,7 @@ namespace Facebook\GraphNodes; /** - * Class GraphObject + * Class GraphNode * * @package Facebook */ diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index e4322280b..ccdd7fd81 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -27,7 +27,7 @@ use Facebook\Exceptions\FacebookSDKException; /** - * Class GraphObjectFactory + * Class GraphNodeFactory * * @package Facebook * @@ -83,12 +83,12 @@ public function __construct(FacebookResponse $response) * * @throws FacebookSDKException */ - public function makeGraphObject($subclassName = null) + public function makeGraphNode($subclassName = null) { $this->validateResponseAsArray(); - $this->validateResponseCastableAsGraphObject(); + $this->validateResponseCastableAsGraphNode(); - return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); + return $this->castAsGraphNodeOrGraphEdge($this->decodedBody, $subclassName); } /** @@ -100,7 +100,7 @@ public function makeGraphObject($subclassName = null) */ public function makeGraphAchievement() { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); } /** @@ -112,7 +112,7 @@ public function makeGraphAchievement() */ public function makeGraphAlbum() { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); } /** @@ -124,7 +124,7 @@ public function makeGraphAlbum() */ public function makeGraphPage() { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); } /** @@ -136,7 +136,7 @@ public function makeGraphPage() */ public function makeGraphSessionInfo() { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); } /** @@ -148,7 +148,7 @@ public function makeGraphSessionInfo() */ public function makeGraphUser() { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); } /** @@ -161,16 +161,16 @@ public function makeGraphUser() * * @throws FacebookSDKException */ - public function makeGraphList($subclassName = null, $auto_prefix = true) + public function makeGraphEdge($subclassName = null, $auto_prefix = true) { $this->validateResponseAsArray(); - $this->validateResponseCastableAsGraphList(); + $this->validateResponseCastableAsGraphEdge(); if ($subclassName && $auto_prefix) { $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; } - return $this->castAsGraphObjectOrGraphList($this->decodedBody, $subclassName); + return $this->castAsGraphNodeOrGraphEdge($this->decodedBody, $subclassName); } /** @@ -190,11 +190,11 @@ public function validateResponseAsArray() * * @throws FacebookSDKException */ - public function validateResponseCastableAsGraphObject() + public function validateResponseCastableAsGraphNode() { - if (isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data'])) { + if (isset($this->decodedBody['data']) && static::isCastableAsGraphEdge($this->decodedBody['data'])) { throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphNode because the response looks like a GraphEdge. Try using GraphObjectFactory::makeGraphList() instead.', + 'Unable to convert response from Graph to a GraphNode because the response looks like a GraphEdge. Try using GraphNodeFactory::makeGraphEdge() instead.', 620 ); } @@ -205,11 +205,11 @@ public function validateResponseCastableAsGraphObject() * * @throws FacebookSDKException */ - public function validateResponseCastableAsGraphList() + public function validateResponseCastableAsGraphEdge() { - if (!(isset($this->decodedBody['data']) && static::isCastableAsGraphList($this->decodedBody['data']))) { + if (!(isset($this->decodedBody['data']) && static::isCastableAsGraphEdge($this->decodedBody['data']))) { throw new FacebookSDKException( - 'Unable to convert response from Graph to a GraphEdge because the response does not look like a GraphEdge. Try using GraphObjectFactory::makeGraphObject() instead.', + 'Unable to convert response from Graph to a GraphEdge because the response does not look like a GraphEdge. Try using GraphNodeFactory::makeGraphNode() instead.', 620 ); } @@ -225,7 +225,7 @@ public function validateResponseCastableAsGraphList() * * @throws FacebookSDKException */ - public function safelyMakeGraphObject(array $data, $subclassName = null) + public function safelyMakeGraphNode(array $data, $subclassName = null) { $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; static::validateSubclass($subclassName); @@ -247,7 +247,7 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) : null; // Could be a GraphEdge or GraphNode - $items[$k] = $this->castAsGraphObjectOrGraphList($v, $objectSubClass, $k, $parentNodeId); + $items[$k] = $this->castAsGraphNodeOrGraphEdge($v, $objectSubClass, $k, $parentNodeId); } else { $items[$k] = $v; } @@ -268,19 +268,19 @@ public function safelyMakeGraphObject(array $data, $subclassName = null) * * @throws FacebookSDKException */ - public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + public function castAsGraphNodeOrGraphEdge(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (isset($data['data'])) { // Create GraphEdge - if (static::isCastableAsGraphList($data['data'])) { - return $this->safelyMakeGraphList($data, $subclassName, $parentKey, $parentNodeId); + if (static::isCastableAsGraphEdge($data['data'])) { + return $this->safelyMakeGraphEdge($data, $subclassName, $parentKey, $parentNodeId); } // Sometimes Graph is a weirdo and returns a GraphNode under the "data" key $data = $data['data']; } // Create GraphNode - return $this->safelyMakeGraphObject($data, $subclassName); + return $this->safelyMakeGraphNode($data, $subclassName); } /** @@ -295,7 +295,7 @@ public function castAsGraphObjectOrGraphList(array $data, $subclassName = null, * * @throws FacebookSDKException */ - public function safelyMakeGraphList(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) { if (!isset($data['data'])) { throw new FacebookSDKException('Cannot cast data to GraphEdge. Expected a "data" key.', 620); @@ -303,7 +303,7 @@ public function safelyMakeGraphList(array $data, $subclassName = null, $parentKe $dataList = []; foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphObject($graphNode, $subclassName, $parentKey, $parentNodeId); + $dataList[] = $this->safelyMakeGraphNode($graphNode, $subclassName, $parentKey, $parentNodeId); } $metaData = $this->getMetaData($data); @@ -335,7 +335,7 @@ public function getMetaData(array $data) * * @return boolean */ - public static function isCastableAsGraphList(array $data) + public static function isCastableAsGraphEdge(array $data) { if ($data === []) { return true; diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 56c329948..6e7a2fa5f 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -67,7 +67,7 @@ public function testAValidGraphObjectResponseWillNotThrow() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $factory->validateResponseCastableAsGraphObject(); + $factory->validateResponseCastableAsGraphNode(); } /** @@ -79,7 +79,7 @@ public function testANonGraphObjectResponseWillThrow() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $factory->validateResponseCastableAsGraphObject(); + $factory->validateResponseCastableAsGraphNode(); } public function testAValidGraphEdgeResponseWillNotThrow() @@ -88,7 +88,7 @@ public function testAValidGraphEdgeResponseWillNotThrow() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $factory->validateResponseCastableAsGraphList(); + $factory->validateResponseCastableAsGraphEdge(); } /** @@ -100,14 +100,14 @@ public function testANonGraphEdgeResponseWillThrow() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $factory->validateResponseCastableAsGraphList(); + $factory->validateResponseCastableAsGraphEdge(); } public function testOnlyNumericArraysAreCastableAsAGraphEdge() { - $shouldPassOne = GraphNodeFactory::isCastableAsGraphList([]); - $shouldPassTwo = GraphNodeFactory::isCastableAsGraphList(['foo', 'bar']); - $shouldFail = GraphNodeFactory::isCastableAsGraphList(['faz' => 'baz']); + $shouldPassOne = GraphNodeFactory::isCastableAsGraphEdge([]); + $shouldPassTwo = GraphNodeFactory::isCastableAsGraphEdge(['foo', 'bar']); + $shouldFail = GraphNodeFactory::isCastableAsGraphEdge(['faz' => 'baz']); $this->assertTrue($shouldPassOne, 'Expected the given array to be castable as a GraphEdge.'); $this->assertTrue($shouldPassTwo, 'Expected the given array to be castable as a GraphEdge.'); @@ -135,7 +135,7 @@ public function testCastingAsASubClassObjectWillInstantiateTheSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); } @@ -146,7 +146,7 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $fooObject = $mySubClassObject->getProperty('foo_object'); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); @@ -167,7 +167,7 @@ public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphObject('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); $unknownObject = $mySubClassObject->getProperty('unknown_object'); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); @@ -198,7 +198,7 @@ public function testAListFromGraphWillBeCastAsAGraphEdge() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphEdge = $factory->makeGraphList(); + $graphEdge = $factory->makeGraphEdge(); $graphData = $graphEdge->asArray(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphEdge); @@ -224,7 +224,7 @@ public function testAGraphObjectWillBeCastAsAGraphObject() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphObject = $factory->makeGraphObject(); + $graphObject = $factory->makeGraphNode(); $graphData = $graphObject->asArray(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphObject); @@ -248,7 +248,7 @@ public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphObject = $factory->makeGraphObject(); + $graphObject = $factory->makeGraphNode(); $graphData = $graphObject->asArray(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphObject); @@ -344,7 +344,7 @@ public function testAGraphEdgeWillBeCastRecursively() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphObject = $factory->makeGraphList(); + $graphObject = $factory->makeGraphEdge(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphObject); // Story @@ -421,7 +421,7 @@ public function testAGraphEdgeWillGenerateTheProperParentGraphEdges() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphEdge = $factory->makeGraphList(); + $graphEdge = $factory->makeGraphEdge(); $topGraphEdge = $graphEdge->getParentGraphEdge(); $childGraphEdgeOne = $graphEdge[0]['likes']->getParentGraphEdge(); $childGraphEdgeTwo = $graphEdge[1]['likes']->getParentGraphEdge(); From 86eaced2561abe0371d5acc496c543e3cdcf799e Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 16:02:06 -0500 Subject: [PATCH 150/407] Clean up references to GraphObject & GraphList --- src/Facebook/Facebook.php | 2 +- src/Facebook/FacebookResponse.php | 6 +++--- src/Facebook/GraphNodes/GraphEdge.php | 10 +++++----- src/Facebook/GraphNodes/GraphNodeFactory.php | 2 +- tests/FacebookClientTest.php | 2 +- tests/FacebookResponseTest.php | 2 +- tests/GraphNodes/GraphNodeFactoryTest.php | 10 +++++----- tests/GraphNodes/GraphNodeTest.php | 8 ++++---- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 4754ea073..060c19ee4 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -473,7 +473,7 @@ public function getPaginationResults(GraphEdge $graphList, $direction) $this->lastResponse = $this->client->sendRequest($paginationRequest); - // Keep the same GraphObject subclass + // Keep the same GraphNode subclass $subClassName = $graphList->getSubClassName(); $graphList = $this->lastResponse->getGraphList($subClassName, false); diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 0d26e68a2..08d82e75f 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -257,9 +257,9 @@ public function decodeBody() } /** - * Instantiate a new GraphObject from response. + * Instantiate a new GraphNode from response. * - * @param string|null $subclassName The GraphObject sub class to cast to. + * @param string|null $subclassName The GraphNode sub class to cast to. * * @return \Facebook\GraphNodes\GraphNode * @@ -331,7 +331,7 @@ public function getGraphUser() /** * Instantiate a new GraphEdge from response. * - * @param string|null $subclassName The GraphObject sub class to cast list items to. + * @param string|null $subclassName The GraphNode sub class to cast list items to. * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. * * @return \Facebook\GraphNodes\GraphEdge diff --git a/src/Facebook/GraphNodes/GraphEdge.php b/src/Facebook/GraphNodes/GraphEdge.php index 46a4499be..95f32849a 100644 --- a/src/Facebook/GraphNodes/GraphEdge.php +++ b/src/Facebook/GraphNodes/GraphEdge.php @@ -50,18 +50,18 @@ class GraphEdge extends Collection protected $parentEdgeEndpoint; /** - * @var string|null The subclass of the child GraphObject's. + * @var string|null The subclass of the child GraphNode's. */ protected $subclassName; /** - * Init this collection of GraphObject's. + * Init this collection of GraphNode's. * * @param FacebookRequest $request The original request that generated this data. - * @param array $data An array of GraphObject's. + * @param array $data An array of GraphNode's. * @param array $metaData An array of Graph meta data like pagination, etc. * @param string|null $parentEdgeEndpoint The parent Graph edge endpoint that generated the list. - * @param string|null $subclassName The subclass of the child GraphObject's. + * @param string|null $subclassName The subclass of the child GraphNode's. */ public function __construct(FacebookRequest $request, array $data = [], array $metaData = [], $parentEdgeEndpoint = null, $subclassName = null) { @@ -84,7 +84,7 @@ public function getParentGraphEdge() } /** - * Gets the subclass name that the child GraphObject's are cast as. + * Gets the subclass name that the child GraphNode's are cast as. * * @return string|null */ diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index ccdd7fd81..911295417 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -239,7 +239,7 @@ public function safelyMakeGraphNode(array $data, $subclassName = null) // Array means could be recurable if (is_array($v)) { // Detect any smart-casting from the $graphObjectMap array. - // This is always empty on the GraphObject collection, but subclasses can define + // 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]) diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index bd2ce2ae4..d51dd2cbd 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -255,7 +255,7 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() ); $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphObject', $graphObject); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObject); $this->assertNotNull($graphObject->getProperty('id')); $this->assertEquals('Foo Phpunit User', $graphObject->getProperty('name')); diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index 0802be6ad..c16b477f7 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -66,7 +66,7 @@ public function testAProperAppSecretProofCanBeGenerated() $this->assertEquals('df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', $appSecretProof); } - public function testASuccessfulJsonResponseWillBeDecodedToAGraphObject() + public function testASuccessfulJsonResponseWillBeDecodedToAGraphNode() { $graphResponseJson = '{"id":"123","name":"Foo"}'; $response = new FacebookResponse($this->request, $graphResponseJson, 200); diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 6e7a2fa5f..564773053 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -61,7 +61,7 @@ public function setUp() ); } - public function testAValidGraphObjectResponseWillNotThrow() + public function testAValidGraphNodeResponseWillNotThrow() { $data = '{"id":"123","name":"foo"}'; $res = new FacebookResponse($this->request, $data); @@ -73,7 +73,7 @@ public function testAValidGraphObjectResponseWillNotThrow() /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ - public function testANonGraphObjectResponseWillThrow() + public function testANonGraphNodeResponseWillThrow() { $data = '{"data":[{"id":"123","name":"foo"},{"id":"1337","name":"bar"}]}'; $res = new FacebookResponse($this->request, $data); @@ -153,7 +153,7 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', $fooObject); } - public function testAnUnknownGraphObjectWillBeCastAsAGenericGraphObject() + public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() { $data = json_encode([ 'id' => '123', @@ -214,7 +214,7 @@ public function testAListFromGraphWillBeCastAsAGraphEdge() ], $graphData[1]); } - public function testAGraphObjectWillBeCastAsAGraphObject() + public function testAGraphNodeWillBeCastAsAGraphNode() { $data = json_encode([ 'id' => '123', @@ -235,7 +235,7 @@ public function testAGraphObjectWillBeCastAsAGraphObject() ], $graphData); } - public function testAGraphObjectWithARootDataKeyWillBeCastAsAGraphObject() + public function testAGraphNodeWithARootDataKeyWillBeCastAsAGraphNode() { $data = json_encode([ 'data' => [ diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php index 031484f34..6acb8029b 100644 --- a/tests/GraphNodes/GraphNodeTest.php +++ b/tests/GraphNodes/GraphNodeTest.php @@ -27,7 +27,7 @@ class GraphNodeTest extends \PHPUnit_Framework_TestCase { - public function testAnEmptyBaseGraphObjectCanInstantiate() + public function testAnEmptyBaseGraphNodeCanInstantiate() { $graphObject = new GraphNode(); $backingData = $graphObject->asArray(); @@ -35,7 +35,7 @@ public function testAnEmptyBaseGraphObjectCanInstantiate() $this->assertEquals([], $backingData); } - public function testAGraphObjectCanInstantiateWithData() + public function testAGraphNodeCanInstantiateWithData() { $graphObject = new GraphNode(['foo' => 'bar']); $backingData = $graphObject->asArray(); @@ -94,7 +94,7 @@ public function testAGraphDateStringCanBeConvertedToADateTimeObject() $this->assertEquals(1405395893, $timeStamp); } - public function testUncastingAGraphObjectWillUncastTheDateTimeObject() + public function testUncastingAGraphNodeWillUncastTheDateTimeObject() { $collectionOne = new GraphNode(['foo', 'bar']); $collectionTwo = new GraphNode([ @@ -112,7 +112,7 @@ public function testUncastingAGraphObjectWillUncastTheDateTimeObject() ], $uncastArray); } - public function testGettingGraphObjectAsAnArrayWillNotUncastTheDateTimeObject() + public function testGettingGraphNodeAsAnArrayWillNotUncastTheDateTimeObject() { $collection = new GraphNode([ 'id' => '123', From 5bc84b4144b5d85ca8731fe81e4e85c9dec9eb19 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 6 May 2015 16:25:38 -0500 Subject: [PATCH 151/407] Add BC for GraphObject & GraphList & depricated them --- src/Facebook/FacebookResponse.php | 39 +++++- src/Facebook/GraphNodes/GraphList.php | 36 ++++++ src/Facebook/GraphNodes/GraphNodeFactory.php | 9 +- src/Facebook/GraphNodes/GraphObject.php | 36 ++++++ .../GraphNodes/GraphObjectFactory.php | 74 ++++++++++++ tests/FacebookBatchResponseTest.php | 2 +- tests/FacebookClientTest.php | 6 +- tests/FacebookResponseTest.php | 2 +- tests/GraphNodes/GraphObjectFactoryTest.php | 114 ++++++++++++++++++ 9 files changed, 309 insertions(+), 9 deletions(-) create mode 100644 src/Facebook/GraphNodes/GraphList.php create mode 100644 src/Facebook/GraphNodes/GraphObject.php create mode 100644 src/Facebook/GraphNodes/GraphObjectFactory.php create mode 100644 tests/GraphNodes/GraphObjectFactoryTest.php diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 08d82e75f..bb2f82687 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -256,6 +256,23 @@ public function decodeBody() } } + /** + * Instantiate a new GraphObject from response. + * + * @param string|null $subclassName The GraphNode sub class 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. * @@ -265,7 +282,7 @@ public function decodeBody() * * @throws FacebookSDKException */ - public function getGraphObject($subclassName = null) + public function getGraphNode($subclassName = null) { $factory = new GraphNodeFactory($this); @@ -328,6 +345,24 @@ public function getGraphUser() return $factory->makeGraphUser(); } + /** + * Instantiate a new GraphList from response. + * + * @param string|null $subclassName The GraphNode sub class 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. * @@ -338,7 +373,7 @@ public function getGraphUser() * * @throws FacebookSDKException */ - public function getGraphList($subclassName = null, $auto_prefix = true) + public function getGraphEdge($subclassName = null, $auto_prefix = true) { $factory = new GraphNodeFactory($this); diff --git a/src/Facebook/GraphNodes/GraphList.php b/src/Facebook/GraphNodes/GraphList.php new file mode 100644 index 000000000..a60a07a7e --- /dev/null +++ b/src/Facebook/GraphNodes/GraphList.php @@ -0,0 +1,36 @@ +response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + return new $className($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); } /** diff --git a/src/Facebook/GraphNodes/GraphObject.php b/src/Facebook/GraphNodes/GraphObject.php new file mode 100644 index 000000000..bb8f8e40c --- /dev/null +++ b/src/Facebook/GraphNodes/GraphObject.php @@ -0,0 +1,36 @@ +makeGraphNode($subclassName); + } + + /** + * 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/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index 4b2e3b422..a4c37a94f 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -80,7 +80,7 @@ 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]->getGraphObject()); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $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.'); $graphList = $decodedResponses[1]->getGraphList(); diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index d51dd2cbd..3b1429d88 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -241,7 +241,7 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() $testUserPath, $params ); - $response = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + $response = static::$testFacebookClient->sendRequest($request)->getGraphNode(); $testUserId = $response->getProperty('id'); $testUserAccessToken = $response->getProperty('access_token'); @@ -253,7 +253,7 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() 'GET', '/me' ); - $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphNode(); $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObject); $this->assertNotNull($graphObject->getProperty('id')); @@ -266,7 +266,7 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() 'DELETE', '/' . $testUserId ); - $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphObject(); + $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphNode(); $this->assertTrue($graphObject->getProperty('success')); } diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index c16b477f7..96f3ce567 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -72,7 +72,7 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphNode() $response = new FacebookResponse($this->request, $graphResponseJson, 200); $decodedResponse = $response->getDecodedBody(); - $graphObject = $response->getGraphObject(); + $graphObject = $response->getGraphNode(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); $this->assertEquals([ diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php new file mode 100644 index 000000000..dbc5e771d --- /dev/null +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -0,0 +1,114 @@ +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); + $graphEdge = $factory->makeGraphList(); + $graphData = $graphEdge->asArray(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphEdge); + $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]); + } +} From 69529d02421fe31da9da8055c4df435fe02a6880 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 8 May 2015 08:58:09 -0500 Subject: [PATCH 152/407] Updated docs to refer to GraphNode --- docs/Facebook.fbmd | 8 ++-- docs/FacebookFile.fbmd | 4 +- docs/FacebookRequest.fbmd | 4 +- docs/FacebookResponse.fbmd | 14 +++---- docs/FacebookVideo.fbmd | 4 +- docs/GraphList.fbmd | 4 +- docs/{GraphObject.fbmd => GraphNode.fbmd} | 48 +++++++++++------------ docs/example_post_links.fbmd | 6 +-- docs/example_retrieve_user_profile.fbmd | 2 +- docs/example_upload_photo.fbmd | 6 +-- docs/example_upload_video.fbmd | 6 +-- docs/sdk_getting_started.fbmd | 2 +- docs/sdk_reference.fbmd | 16 ++++---- 13 files changed, 62 insertions(+), 62 deletions(-) rename docs/{GraphObject.fbmd => GraphNode.fbmd} (86%) diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 1d5e3b401..64f658fe6 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -506,9 +506,9 @@ try { exit; } -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); -echo 'Photo ID: ' . $graphObject['id']; +echo 'Photo ID: ' . $graphNode['id']; ~~~~ @@ -535,8 +535,8 @@ try { exit; } -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); -echo 'Video ID: ' . $graphObject['id']; +echo 'Video ID: ' . $graphNode['id']; ~~~~ diff --git a/docs/FacebookFile.fbmd b/docs/FacebookFile.fbmd index 7efcf5958..b4ef44cd1 100644 --- a/docs/FacebookFile.fbmd +++ b/docs/FacebookFile.fbmd @@ -47,9 +47,9 @@ try { exit; } -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); -echo 'Photo ID: ' . $graphObject['id']; +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. diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index 9d4ba56ef..54998809e 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -51,9 +51,9 @@ try { exit; } -$object = $response->getGraphObject(); +$node = $response->getGraphNode(); -echo 'User name: ' . $object['name']; +echo 'User name: ' . $node['name']; ~~~~ diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index f013d528a..b58443b8d 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -139,11 +139,11 @@ Returns the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/Facebook -### getGraphObject() {#get-graph-object} +### getGraphNode() {#get-graph-node} ~~~~ -public Facebook\GraphNodes\GraphObject getGraphObject() +public Facebook\GraphNodes\GraphNode getGraphNode() ~~~~ -Returns the response data in the form of a [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode) collection. @@ -151,7 +151,7 @@ Returns the response data in the form of a [`Facebook\GraphNodes\GraphObject`](/ ~~~~ public Facebook\GraphNodes\GraphAlbum getGraphAlbum() ~~~~ -Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphObject#album-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) collection. @@ -159,7 +159,7 @@ Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/d ~~~~ public Facebook\GraphNodes\GraphPage getGraphPage() ~~~~ -Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphObject#page-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods) collection. @@ -167,7 +167,7 @@ Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/do ~~~~ public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() ~~~~ -Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphObject#sessioninfo-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphNode#sessioninfo-instance-methods) collection. @@ -175,7 +175,7 @@ Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInf ~~~~ public Facebook\GraphNodes\GraphUser getGraphUser() ~~~~ -Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods) collection. diff --git a/docs/FacebookVideo.fbmd b/docs/FacebookVideo.fbmd index 85616f070..24614aaf2 100644 --- a/docs/FacebookVideo.fbmd +++ b/docs/FacebookVideo.fbmd @@ -46,8 +46,8 @@ try { exit; } -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); -echo 'Video ID: ' . $graphObject['id']; +echo 'Video ID: ' . $graphNode['id']; ~~~~ diff --git a/docs/GraphList.fbmd b/docs/GraphList.fbmd index 217cc2d16..9963e999b 100644 --- a/docs/GraphList.fbmd +++ b/docs/GraphList.fbmd @@ -16,8 +16,8 @@ $graphList = $request->getGraphList(); Usage: ~~~~ -// Iterate over all the GraphObject in the list -foreach ($graphList as $graphObject) { +// Iterate over all the GraphNode's returned from the edge +foreach ($graphList as $graphNode) { // . . . } ~~~~ diff --git a/docs/GraphObject.fbmd b/docs/GraphNode.fbmd similarity index 86% rename from docs/GraphObject.fbmd rename to docs/GraphNode.fbmd index 3b5e9ec63..c68bbdfc9 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphNode.fbmd @@ -1,11 +1,11 @@ -# GraphObject for the Facebook SDK for PHP +# GraphNode for the Facebook SDK for PHP -A `Facebook\GraphNodes\GraphObject` is a collection that represents a node returned by the Graph API. +A `Facebook\GraphNodes\GraphNode` is a collection that represents a node returned by the Graph API. -## Facebook\GraphNodes\GraphObject {#overview} +## Facebook\GraphNodes\GraphNode {#overview} This base class has several subclasses: @@ -16,7 +16,7 @@ This base class has several subclasses: [__GraphPicture__](#picture-instance-methods) [__GraphAchievement__](#achievement-instance-methods) -`GraphObject`'s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents an HTTP response from the Graph API. +`GraphNode`'s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents an HTTP response from the Graph API. Usage: @@ -25,8 +25,8 @@ $fb = new Facebook\Facebook(\* *\); // Returns a `Facebook\FacebookResponse` object $response = $fb->get('/something'); -// Get the base class GraphObject from the response -$node = $response->getGraphObject(); +// Get the base class GraphNode from the response +$node = $response->getGraphNode(); // Get the response typed as a GraphUser $user = $response->getGraphUser()); @@ -35,11 +35,11 @@ $user = $response->getGraphUser()); $page = $response->getGraphPage(); // User example -echo $node->getProperty('name'); // From GraphObject +echo $node->getProperty('name'); // From GraphNode echo $user->getName(); // From GraphUser // Location example -echo $node->getProperty('country'); // From GraphObject +echo $node->getProperty('country'); // From GraphNode echo $location->getCountry(); // From GraphLocation ~~~~ @@ -47,29 +47,29 @@ echo $location->getCountry(); // From GraphLocation ## SPL Libraries {#spl} -The `GraphObject` 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`. +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 `GraphObject`. +All of the following operations are possible on a `GraphNode`. ~~~~ -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); // Array access -$id = $graphObject['id']; +$id = $graphNode['id']; // Iteration -foreach ($graphObject as $key => $value) { +foreach ($graphNode as $key => $value) { // . . . } // Counting -$total = count($graphObject); +$total = count($graphNode); ~~~~ -## GraphObject Instance Methods {#instance-methods} +## GraphNode Instance Methods {#instance-methods} ### asArray {#as-array} @@ -84,7 +84,7 @@ Returns the data as a JSON string. ### getProperty {#get-property} `getProperty(string $name, string $default = 'foo')` -Gets the value of a named key for this graph object. 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 GraphObject. +Gets the value of a named key for this graph object. 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 property doesn't exist. @@ -106,10 +106,10 @@ The `GraphUser` collection represents a [User](https://developers.facebook.com/d ### Auto-cast properties {#user-auto-casting} -The following properties on the `GraphUser` collection will get automatically cast as `GraphObject` subtypes: +The following properties on the `GraphUser` collection will get automatically cast as `GraphNode` subtypes: FB(devsite:markdown-wiki:table { - columns: ['Property','GraphObject subtype',], + columns: ['Property','GraphNode subtype',], rows: [ [ '`hometown`', @@ -196,10 +196,10 @@ The `GraphPage` collection represents a [Page](https://developers.facebook.com/d ### Auto-cast properties {#page-auto-casting} -The following properties on the `GraphPage` collection will get automatically cast as `GraphObject` subtypes: +The following properties on the `GraphPage` collection will get automatically cast as `GraphNode` subtypes: FB(devsite:markdown-wiki:table { - columns: ['Property','GraphObject subtype',], + columns: ['Property','GraphNode subtype',], rows: [ [ '`best_page`', @@ -274,10 +274,10 @@ The `GraphAlbum` collection represents an [Album](https://developers.facebook.co ### Auto-cast properties {#album-auto-casting} -The following properties on the `GraphAlbum` collection will get automatically cast as `GraphObject` subtypes: +The following properties on the `GraphAlbum` collection will get automatically cast as `GraphNode` subtypes: FB(devsite:markdown-wiki:table { - columns: ['Property','GraphObject subtype',], + columns: ['Property','GraphNode subtype',], rows: [ [ '`from`', @@ -360,9 +360,9 @@ Returns the `link` property for the album as a string if present. ### getLocation() {#album-getlocation} ~~~~ -public Facebook\GraphNodes\GraphObject|string|null getLocation() +public Facebook\GraphNodes\GraphNode|string|null getLocation() ~~~~ -Returns the `location` property for the album as a `Facebook\GraphNodes\GraphObject` or string if present. +Returns the `location` property for the album as a `Facebook\GraphNodes\GraphNode` or string if present. ### getPrivacy() {#album-getprivacy} ~~~~ diff --git a/docs/example_post_links.fbmd b/docs/example_post_links.fbmd index cf716b00d..164d5196a 100644 --- a/docs/example_post_links.fbmd +++ b/docs/example_post_links.fbmd @@ -5,7 +5,7 @@ This example covers posting a link to the current user's timeline using the Grap It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). @@ -34,9 +34,9 @@ try { exit; } -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); -echo 'Posted with id: ' . $graphObject['id']; +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/example_retrieve_user_profile.fbmd b/docs/example_retrieve_user_profile.fbmd index 422676833..a11f3126c 100644 --- a/docs/example_retrieve_user_profile.fbmd +++ b/docs/example_retrieve_user_profile.fbmd @@ -5,7 +5,7 @@ This example covers getting profile information for the current user and printin It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). diff --git a/docs/example_upload_photo.fbmd b/docs/example_upload_photo.fbmd index a192da870..a88945afb 100644 --- a/docs/example_upload_photo.fbmd +++ b/docs/example_upload_photo.fbmd @@ -5,7 +5,7 @@ This example covers uploading a photo to the current User's profile using the Gr It assumes that you've already acquired an access token using one of the helper classes found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. -For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). +For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). @@ -34,9 +34,9 @@ try { exit; } -$graphObject = $response->getGraphObject(); +$graphNode = $response->getGraphNode(); -echo 'Photo ID: ' . $graphObject['id']; +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/example_upload_video.fbmd b/docs/example_upload_video.fbmd index c9330df8c..375cac1a7 100644 --- a/docs/example_upload_video.fbmd +++ b/docs/example_upload_video.fbmd @@ -37,9 +37,9 @@ try { exit; } -$graphObject = $response->getGraphObject(); -var_dump($graphObject); +$graphNode = $response->getGraphNode(); +var_dump($graphNode); -echo 'Video ID: ' . $graphObject['id']; +echo 'Video ID: ' . $graphNode['id']; ~~~~ diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 592bcb25e..8a5a5e963 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -309,7 +309,7 @@ echo 'Logged in as ' . $userNode->getName(); The `get()` method will return a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) 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`](/docs/php/GraphObject#user-instance-methods) entity which represents a user node. +To get the response in the form of a nifty collection, we call `getGraphUser()` which returns a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-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. diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 52a47c19b..ffc0ab1db 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -141,35 +141,35 @@ FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\GraphNodes\GraphObject`](/docs/php/GraphObject)', + '[`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode)', 'The base collection object that represents a generic node.', ], [ '[`Facebook\GraphNodes\GraphList`](/docs/php/GraphList)', - 'A collection of GraphObject's with special methods to help paginate over the edge.', + 'A collection of GraphNode's with special methods to help paginate over the edge.', ], [ - '[`Facebook\GraphNodes\GraphAchievement`](/docs/php/GraphObject#achievement-instance-methods)', + '[`Facebook\GraphNodes\GraphAchievement`](/docs/php/GraphNode#achievement-instance-methods)', 'A collection that represents an Achievement node.', ], [ - '[`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphObject#album-instance-methods)', + '[`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods)', 'A collection that represents an Album node.', ], [ - '[`Facebook\GraphNodes\GraphLocation`](/docs/php/GraphObject#location-instance-methods)', + '[`Facebook\GraphNodes\GraphLocation`](/docs/php/GraphNode#location-instance-methods)', 'A collection that represents a Location node.', ], [ - '[`Facebook\GraphNodes\GraphPage`](/docs/php/GraphObject#page-instance-methods)', + '[`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods)', 'A collection that represents a Page node.', ], [ - '[`Facebook\GraphNodes\GraphPicture`](/docs/php/GraphObject#picture-instance-methods)', + '[`Facebook\GraphNodes\GraphPicture`](/docs/php/GraphNode#picture-instance-methods)', 'A collection that represents a Picture node.', ], [ - '[`Facebook\GraphNodes\GraphUser`](/docs/php/GraphObject#user-instance-methods)', + '[`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods)', 'A collection that represents a User node.', ], ], From 1ce6c6f20e790d3c0f3c0d6a2cbf6e71091f3c1e Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 8 May 2015 09:03:47 -0500 Subject: [PATCH 153/407] Remove references to a Graph object from tests --- tests/FacebookClientTest.php | 12 ++++----- tests/FacebookResponseTest.php | 10 ++++---- tests/GraphNodes/CollectionTest.php | 16 ++++++------ tests/GraphNodes/GraphAchievementTest.php | 24 +++++++++--------- tests/GraphNodes/GraphAlbumTest.php | 14 +++++------ tests/GraphNodes/GraphNodeFactoryTest.php | 20 +++++++-------- tests/GraphNodes/GraphNodeTest.php | 30 +++++++++++------------ tests/GraphNodes/GraphPageTest.php | 10 ++++---- tests/GraphNodes/GraphSessionInfoTest.php | 6 ++--- tests/GraphNodes/GraphUserTest.php | 18 +++++++------- 10 files changed, 80 insertions(+), 80 deletions(-) diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 3b1429d88..e45367538 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -253,11 +253,11 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() 'GET', '/me' ); - $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphNode(); + $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObject); - $this->assertNotNull($graphObject->getProperty('id')); - $this->assertEquals('Foo Phpunit User', $graphObject->getProperty('name')); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); + $this->assertNotNull($graphNode->getProperty('id')); + $this->assertEquals('Foo Phpunit User', $graphNode->getProperty('name')); // Delete test user $request = new FacebookRequest( @@ -266,9 +266,9 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() 'DELETE', '/' . $testUserId ); - $graphObject = static::$testFacebookClient->sendRequest($request)->getGraphNode(); + $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - $this->assertTrue($graphObject->getProperty('success')); + $this->assertTrue($graphNode->getProperty('success')); } public function initializeTestApp() diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index 96f3ce567..f9b55d725 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -72,14 +72,14 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphNode() $response = new FacebookResponse($this->request, $graphResponseJson, 200); $decodedResponse = $response->getDecodedBody(); - $graphObject = $response->getGraphNode(); + $graphNode = $response->getGraphNode(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); $this->assertEquals([ 'id' => '123', 'name' => 'Foo', ], $decodedResponse); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObject); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); } public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() @@ -87,11 +87,11 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; $response = new FacebookResponse($this->request, $graphResponseJson, 200); - $graphObjectList = $response->getGraphList(); + $graphEdge = $response->getGraphList(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObjectList[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphObjectList[1]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[1]); } public function testASuccessfulUrlEncodedKeyValuePairResponseWillBeDecoded() diff --git a/tests/GraphNodes/CollectionTest.php b/tests/GraphNodes/CollectionTest.php index cce1a3974..a5e33df56 100755 --- a/tests/GraphNodes/CollectionTest.php +++ b/tests/GraphNodes/CollectionTest.php @@ -30,36 +30,36 @@ class CollectionTest extends \PHPUnit_Framework_TestCase public function testAnExistingPropertyCanBeAccessed() { - $graphObject = new Collection(['foo' => 'bar']); - $property = $graphObject->getProperty('foo'); + $graphNode = new Collection(['foo' => 'bar']); + $property = $graphNode->getProperty('foo'); $this->assertEquals('bar', $property); } public function testAMissingPropertyWillReturnNull() { - $graphObject = new Collection(['foo' => 'bar']); - $property = $graphObject->getProperty('baz'); + $graphNode = new Collection(['foo' => 'bar']); + $property = $graphNode->getProperty('baz'); $this->assertNull($property, 'Expected the property to return null.'); } public function testAMissingPropertyWillReturnTheDefault() { - $graphObject = new Collection(['foo' => 'bar']); - $property = $graphObject->getProperty('baz', 'faz'); + $graphNode = new Collection(['foo' => 'bar']); + $property = $graphNode->getProperty('baz', 'faz'); $this->assertEquals('faz', $property); } public function testTheKeysFromTheCollectionCanBeReturned() { - $graphObject = new Collection([ + $graphNode = new Collection([ 'key1' => 'foo', 'key2' => 'bar', 'key3' => 'baz', ]); - $propertyKeys = $graphObject->getPropertyNames(); + $propertyKeys = $graphNode->getPropertyNames(); $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); } diff --git a/tests/GraphNodes/GraphAchievementTest.php b/tests/GraphNodes/GraphAchievementTest.php index 787d9fc8c..d5e276e57 100644 --- a/tests/GraphNodes/GraphAchievementTest.php +++ b/tests/GraphNodes/GraphAchievementTest.php @@ -33,9 +33,9 @@ public function testIdIsString() ]; $factory = $this->makeFactoryWithData($dataFromGraph); - $graphObject = $factory->makeGraphAchievement(); + $graphNode = $factory->makeGraphAchievement(); - $id = $graphObject->getId(); + $id = $graphNode->getId(); $this->assertEquals($dataFromGraph['id'], $id); } @@ -47,9 +47,9 @@ public function testTypeIsAlwaysString() ]; $factory = $this->makeFactoryWithData($dataFromGraph); - $graphObject = $factory->makeGraphAchievement(); + $graphNode = $factory->makeGraphAchievement(); - $type = $graphObject->getType(); + $type = $graphNode->getType(); $this->assertEquals('game.achievement', $type); } @@ -61,9 +61,9 @@ public function testNoFeedStoryIsBoolean() ]; $factory = $this->makeFactoryWithData($dataFromGraph); - $graphObject = $factory->makeGraphAchievement(); + $graphNode = $factory->makeGraphAchievement(); - $isNoFeedStory = $graphObject->isNoFeedStory(); + $isNoFeedStory = $graphNode->isNoFeedStory(); $this->assertTrue(is_bool($isNoFeedStory)); } @@ -75,9 +75,9 @@ public function testDatesGetCastToDateTime() ]; $factory = $this->makeFactoryWithData($dataFromGraph); - $graphObject = $factory->makeGraphAchievement(); + $graphNode = $factory->makeGraphAchievement(); - $publishTime = $graphObject->getPublishTime(); + $publishTime = $graphNode->getPublishTime(); $this->assertInstanceOf('DateTime', $publishTime); } @@ -92,9 +92,9 @@ public function testFromGetsCastAsGraphUser() ]; $factory = $this->makeFactoryWithData($dataFromGraph); - $graphObject = $factory->makeGraphAchievement(); + $graphNode = $factory->makeGraphAchievement(); - $from = $graphObject->getFrom(); + $from = $graphNode->getFrom(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphUser', $from); } @@ -108,9 +108,9 @@ public function testApplicationGetsCastAsGraphApplication() ]; $factory = $this->makeFactoryWithData($dataFromGraph); - $graphObject = $factory->makeGraphAchievement(); + $graphNode = $factory->makeGraphAchievement(); - $app = $graphObject->getApplication(); + $app = $graphNode->getApplication(); $this->assertInstanceOf('\Facebook\GraphNodes\GraphApplication', $app); } diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index a5d28a9cb..f7a552130 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -53,10 +53,10 @@ public function testDatesGetCastToDateTime() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphAlbum(); + $graphNode = $factory->makeGraphAlbum(); - $createdTime = $graphObject->getCreatedTime(); - $updatedTime = $graphObject->getUpdatedTime(); + $createdTime = $graphNode->getCreatedTime(); + $updatedTime = $graphNode->getUpdatedTime(); $this->assertInstanceOf('DateTime', $createdTime); $this->assertInstanceOf('DateTime', $updatedTime); @@ -77,9 +77,9 @@ public function testFromGetsCastAsGraphUser() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphAlbum(); + $graphNode = $factory->makeGraphAlbum(); - $from = $graphObject->getFrom(); + $from = $graphNode->getFrom(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $from); } @@ -100,9 +100,9 @@ public function testPlacePropertyWillGetCastAsGraphPageObject() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphAlbum(); + $graphNode = $factory->makeGraphAlbum(); - $place = $graphObject->getPlace(); + $place = $graphNode->getPlace(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $place); } diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 564773053..6099284c6 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -224,10 +224,10 @@ public function testAGraphNodeWillBeCastAsAGraphNode() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphObject = $factory->makeGraphNode(); - $graphData = $graphObject->asArray(); + $graphNode = $factory->makeGraphNode(); + $graphData = $graphNode->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -248,10 +248,10 @@ public function testAGraphNodeWithARootDataKeyWillBeCastAsAGraphNode() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphObject = $factory->makeGraphNode(); - $graphData = $graphObject->asArray(); + $graphNode = $factory->makeGraphNode(); + $graphData = $graphNode->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphObject); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', @@ -344,11 +344,11 @@ public function testAGraphEdgeWillBeCastRecursively() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $graphObject = $factory->makeGraphEdge(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphObject); + $graphNode = $factory->makeGraphEdge(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $graphNode); // Story - $storyObject = $graphObject[0]; + $storyObject = $graphNode[0]; $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $storyObject['from']); $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['likes']); $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $storyObject['comments']); @@ -359,7 +359,7 @@ public function testAGraphEdgeWillBeCastRecursively() $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $firstStoryComment['from']); // Message - $messageObject = $graphObject[1]; + $messageObject = $graphNode[1]; $this->assertInstanceOf('\Facebook\GraphNodes\GraphEdge', $messageObject['to']); $toUsers = $messageObject['to']; $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $toUsers[0]); diff --git a/tests/GraphNodes/GraphNodeTest.php b/tests/GraphNodes/GraphNodeTest.php index 6acb8029b..50f58aea5 100644 --- a/tests/GraphNodes/GraphNodeTest.php +++ b/tests/GraphNodes/GraphNodeTest.php @@ -29,50 +29,50 @@ class GraphNodeTest extends \PHPUnit_Framework_TestCase { public function testAnEmptyBaseGraphNodeCanInstantiate() { - $graphObject = new GraphNode(); - $backingData = $graphObject->asArray(); + $graphNode = new GraphNode(); + $backingData = $graphNode->asArray(); $this->assertEquals([], $backingData); } public function testAGraphNodeCanInstantiateWithData() { - $graphObject = new GraphNode(['foo' => 'bar']); - $backingData = $graphObject->asArray(); + $graphNode = new GraphNode(['foo' => 'bar']); + $backingData = $graphNode->asArray(); $this->assertEquals(['foo' => 'bar'], $backingData); } public function testDatesThatShouldBeCastAsDateTimeObjectsAreDetected() { - $graphObject = new GraphNode(); + $graphNode = new GraphNode(); // Should pass - $shouldPass = $graphObject->isIso8601DateString('1985-10-26T01:21:00+0000'); + $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 = $graphObject->isIso8601DateString('1999-12-31'); + $shouldPass = $graphNode->isIso8601DateString('1999-12-31'); $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to party like it\'s 1999.'); - $shouldPass = $graphObject->isIso8601DateString('2009-05-19T14:39Z'); + $shouldPass = $graphNode->isIso8601DateString('2009-05-19T14:39Z'); $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); - $shouldPass = $graphObject->isIso8601DateString('2014-W36'); + $shouldPass = $graphNode->isIso8601DateString('2014-W36'); $this->assertTrue($shouldPass, 'Expected the valid ISO 8601 formatted date to pass.'); // Should fail - $shouldFail = $graphObject->isIso8601DateString('2009-05-19T14a39r'); + $shouldFail = $graphNode->isIso8601DateString('2009-05-19T14a39r'); $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); - $shouldFail = $graphObject->isIso8601DateString('foo_time'); + $shouldFail = $graphNode->isIso8601DateString('foo_time'); $this->assertFalse($shouldFail, 'Expected the invalid ISO 8601 format to fail.'); } public function testATimeStampCanBeConvertedToADateTimeObject() { $someTimeStampFromGraph = 1405547020; - $graphObject = new GraphNode(); - $dateTime = $graphObject->castToDateTime($someTimeStampFromGraph); + $graphNode = new GraphNode(); + $dateTime = $graphNode->castToDateTime($someTimeStampFromGraph); $prettyDate = $dateTime->format(\DateTime::RFC1036); $timeStamp = $dateTime->getTimestamp(); @@ -84,8 +84,8 @@ public function testATimeStampCanBeConvertedToADateTimeObject() public function testAGraphDateStringCanBeConvertedToADateTimeObject() { $someDateStringFromGraph = '2014-07-15T03:44:53+0000'; - $graphObject = new GraphNode(); - $dateTime = $graphObject->castToDateTime($someDateStringFromGraph); + $graphNode = new GraphNode(); + $dateTime = $graphNode->castToDateTime($someDateStringFromGraph); $prettyDate = $dateTime->format(\DateTime::RFC1036); $timeStamp = $dateTime->getTimestamp(); diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php index 1bfabc8a3..a3a88e93e 100644 --- a/tests/GraphNodes/GraphPageTest.php +++ b/tests/GraphNodes/GraphPageTest.php @@ -58,10 +58,10 @@ public function testPagePropertiesReturnGraphPageObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphPage(); + $graphNode = $factory->makeGraphPage(); - $bestPage = $graphObject->getBestPage(); - $globalBrandParentPage = $graphObject->getGlobalBrandParentPage(); + $bestPage = $graphNode->getBestPage(); + $globalBrandParentPage = $graphNode->getGlobalBrandParentPage(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $bestPage); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $globalBrandParentPage); @@ -86,9 +86,9 @@ public function testLocationPropertyWillGetCastAsGraphLocationObject() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphPage(); + $graphNode = $factory->makeGraphPage(); - $location = $graphObject->getLocation(); + $location = $graphNode->getLocation(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphLocation', $location); } diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index f273a880d..2960c28cb 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -51,10 +51,10 @@ public function testDatesGetCastToDateTime() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphSessionInfo(); + $graphNode = $factory->makeGraphSessionInfo(); - $expires = $graphObject->getExpiresAt(); - $issuedAt = $graphObject->getIssuedAt(); + $expires = $graphNode->getExpiresAt(); + $issuedAt = $graphNode->getIssuedAt(); $this->assertInstanceOf('DateTime', $expires); $this->assertInstanceOf('DateTime', $issuedAt); diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index aa7981506..ca7557392 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -50,9 +50,9 @@ public function testDatesGetCastToDateTime() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); + $graphNode = $factory->makeGraphUser(); - $birthday = $graphObject->getBirthday(); + $birthday = $graphNode->getBirthday(); $this->assertInstanceOf('DateTime', $birthday); } @@ -77,10 +77,10 @@ public function testPagePropertiesWillGetCastAsGraphPageObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); + $graphNode = $factory->makeGraphUser(); - $hometown = $graphObject->getHometown(); - $location = $graphObject->getLocation(); + $hometown = $graphNode->getHometown(); + $location = $graphNode->getLocation(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $hometown); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPage', $location); @@ -102,9 +102,9 @@ public function testUserPropertiesWillGetCastAsGraphUserObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); + $graphNode = $factory->makeGraphUser(); - $significantOther = $graphObject->getSignificantOther(); + $significantOther = $graphNode->getSignificantOther(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphUser', $significantOther); } @@ -127,9 +127,9 @@ public function testPicturePropertiesWillGetCastAsGraphPictureObjects() ->once() ->andReturn($dataFromGraph); $factory = new GraphNodeFactory($this->responseMock); - $graphObject = $factory->makeGraphUser(); + $graphNode = $factory->makeGraphUser(); - $Picture = $graphObject->getPicture(); + $Picture = $graphNode->getPicture(); $this->assertInstanceOf('\\Facebook\\GraphNodes\\GraphPicture', $Picture); $this->assertTrue($Picture->isSilhouette()); From 1e5b501ca8c959a193b08e2b8271c4f17a46c3ec Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 8 May 2015 09:05:48 -0500 Subject: [PATCH 154/407] Rename constant to reflect node DSL --- src/Facebook/GraphNodes/GraphNodeFactory.php | 6 +++--- src/Facebook/GraphNodes/GraphObjectFactory.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index c8014a4b6..3bea66122 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -45,7 +45,7 @@ class GraphNodeFactory /** * @const string The base graph object class. */ - const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphNode'; + const BASE_GRAPH_NODE_CLASS = '\Facebook\GraphNodes\GraphNode'; /** * @const string The base graph edge class. @@ -231,7 +231,7 @@ public function validateResponseCastableAsGraphEdge() */ public function safelyMakeGraphNode(array $data, $subclassName = null) { - $subclassName = $subclassName ?: static::BASE_GRAPH_OBJECT_CLASS; + $subclassName = $subclassName ?: static::BASE_GRAPH_NODE_CLASS; static::validateSubclass($subclassName); // Remember the parent node ID @@ -359,7 +359,7 @@ public static function isCastableAsGraphEdge(array $data) */ public static function validateSubclass($subclassName) { - if ($subclassName == static::BASE_GRAPH_OBJECT_CLASS || is_subclass_of($subclassName, static::BASE_GRAPH_OBJECT_CLASS)) { + if ($subclassName == static::BASE_GRAPH_NODE_CLASS || is_subclass_of($subclassName, static::BASE_GRAPH_NODE_CLASS)) { return; } diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index e1e900d8a..3c8e977d9 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -36,7 +36,7 @@ class GraphObjectFactory extends GraphNodeFactory /** * @const string The base graph object class. */ - const BASE_GRAPH_OBJECT_CLASS = '\Facebook\GraphNodes\GraphObject'; + const BASE_GRAPH_NODE_CLASS = '\Facebook\GraphNodes\GraphObject'; /** * @const string The base graph edge class. From 9504664891279305d9f1653520bfae7ba49782c4 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 8 May 2015 09:14:35 -0500 Subject: [PATCH 155/407] Update docs to refernce GraphEdge --- docs/Facebook.fbmd | 24 +++++++-------- docs/FacebookResponse.fbmd | 6 ++-- docs/{GraphList.fbmd => GraphEdge.fbmd} | 40 ++++++++++++------------- docs/example_pagination_basic.fbmd | 2 +- docs/sdk_reference.fbmd | 2 +- 5 files changed, 37 insertions(+), 37 deletions(-) rename docs/{GraphList.fbmd => GraphEdge.fbmd} (66%) diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 64f658fe6..103b87cf3 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -13,7 +13,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.3', // . . . ]); ~~~~ @@ -53,7 +53,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.3', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), @@ -442,27 +442,27 @@ $helper = $fb->getPageTabHelper(); ### next() {#next} ~~~~ -public Facebook\GraphNodes\GraphList|null next(Facebook\GraphNodes\GraphList $graphList) +public Facebook\GraphNodes\GraphEdge|null next(Facebook\GraphNodes\GraphEdge $graphEdge) ~~~~ -Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) collection. If the next page returns no results, `null` will be returned. +Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. If the next page returns no results, `null` will be returned. ~~~~ // Iterate over 5 pages max $maxPages = 5; -// Get a list of photo objects +// Get a list of photo nodes from the /photos edge $response = $fb->get('/me/photos?fields=id,source,likes&limit=5'); -$photosList = $response->getGraphList(); +$photosEdge = $response->getGraphEdge(); -if (count($photosList) > 0) { +if (count($photosEdge) > 0) { $pageCount = 0; do { - foreach ($photosList as $photo) { + foreach ($photosEdge as $photo) { var_dump($photo->asArray()); - // Deep pagination is supported on child GraphList's + // Deep pagination is supported on child GraphEdge's $likes = $photo['likes']; do { echo '

Likes:

' . "\n\n"; @@ -470,7 +470,7 @@ if (count($photosList) > 0) { } while ($likes = $fb->next($likes)); } $pageCount++; - } while ($pageCount < $maxPages && $photosList = $fb->next($photosList)); + } while ($pageCount < $maxPages && $photosEdge = $fb->next($photosEdge)); } ~~~~
@@ -478,10 +478,10 @@ if (count($photosList) > 0) { ### previous() {#previous} ~~~~ -public Facebook\GraphNodes\GraphList|null previous(Facebook\GraphNodes\GraphList $graphList) +public Facebook\GraphNodes\GraphEdge|null previous(Facebook\GraphNodes\GraphEdge $graphEdge) ~~~~ -Requests and returns the previous page of results in a `Facebook\GraphNodes\GraphList` collection. Functions just like `next()` above, but in the opposite direction of pagination. +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. diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index b58443b8d..55946a253 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -179,9 +179,9 @@ Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/do -### getGraphList() {#get-graph-list} +### getGraphEdge() {#get-graph-edge} ~~~~ -public Facebook\GraphNodes\GraphList getGraphList() +public Facebook\GraphNodes\GraphEdge getGraphEdge() ~~~~ -Returns the response data in the form of a [`Facebook\GraphNodes\GraphList`](/docs/php/GraphList) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. diff --git a/docs/GraphList.fbmd b/docs/GraphEdge.fbmd similarity index 66% rename from docs/GraphList.fbmd rename to docs/GraphEdge.fbmd index 9963e999b..4f451d18d 100644 --- a/docs/GraphList.fbmd +++ b/docs/GraphEdge.fbmd @@ -1,23 +1,23 @@ -# GraphList for the Facebook SDK for PHP +# GraphEdge for the Facebook SDK for PHP -When a list of nodes is returned from a Graph request, it can be cast as a `GraphList` which provides convenient ways of interacting with the data which includes pagination. +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\GraphList {#overview} +## Facebook\GraphNodes\GraphEdge {#overview} -You can grab a `GraphList` from a response from Graph. +You can grab a `GraphEdge` from a response from Graph. ~~~~ -$graphList = $request->getGraphList(); +$graphEdge = $request->getGraphEdge(); ~~~~ Usage: ~~~~ // Iterate over all the GraphNode's returned from the edge -foreach ($graphList as $graphNode) { +foreach ($graphEdge as $graphNode) { // . . . } ~~~~ @@ -26,13 +26,13 @@ foreach ($graphList as $graphNode) { ## Pagination {#pagination} -With the help of the `Facebook\Facebook` super service class, the `GraphList` collection can grab the next and previous sets of data. +With the help of the `Facebook\Facebook` super service class, the `GraphEdge` collection can grab the next and previous sets of data. ~~~~ -$listOfAlbums = $response->getGraphList(); +$albumsEdge = $response->getGraphEdge(); // Get the next page of results -$nextPageOfAlbums = $fb->next($listOfAlbums); +$nextPageOfAlbums = $fb->next($albumsEdge); // Or the previous page of results $previousPageOfAlbums = $fb->previous($previousOfAlbums); ~~~~ @@ -43,12 +43,12 @@ When the next or previous page returns no results, `$fb->next()` will return `nu ## Deep Pagination {#deep-pagination} -Sometimes Graph will return a list of nodes within a node. Paginating on these sub lists can be non-trivial. Fortunately, the `GraphList` collection takes the guesswork out and allows you to paginate deeply within a `GraphList`. +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. ~~~~ -$listOfPages = $response->getGraphList(); +$pagesEdge = $response->getGraphEdge(); // Only grab 5 pages $maxPages = 5; $pageCount = 0; @@ -56,7 +56,7 @@ $pageCount = 0; do { echo '

Page #' . $pageCount . ':

' . "\n\n"; - foreach ($listOfPages as $page) { + foreach ($pagesEdge as $page) { var_dump($page->asArray()); $likes = $page['likes']; @@ -66,7 +66,7 @@ do { } while ($likes = $fb->next($likes)); } $pageCount++; -} while ($pageCount < $maxPages && $listOfPages = $fb->next($listOfPages)); +} while ($pageCount < $maxPages && $pagesEdge = $fb->next($pagesEdge)); ~~~~
@@ -78,10 +78,10 @@ do { public array getMetaData() ~~~~ -Sometimes Graph will return additional data associated with a list of Graph nodes. You can access this raw data as an array with `getMetaData()`. +Sometimes Graph will return additional data associated with an edge. You can access this raw data as an array with `getMetaData()`. ~~~~ -$metaData = $graphList->getMetaData(); +$metaData = $graphEdge->getMetaData(); ~~~~ ### getNextCursor() {#get-next-cursor} @@ -89,10 +89,10 @@ $metaData = $graphList->getMetaData(); 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 a list of Graph nodes, it is sometimes handy to store the last cursor used so that you can revisit the exact position at a later time. +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. ~~~~ -$nextCursor = $graphList->getNextCursor(); +$nextCursor = $graphEdge->getNextCursor(); // Returns: MMAyDDM5NjA0OTEyMDc0OTM= ~~~~ @@ -104,7 +104,7 @@ public string|null getPreviousCursor() Returns the `$.paging.cursors.before` value if it exists or `null` if it does not exist. ~~~~ -$previousCursor = $graphList->getPreviousCursor(); +$previousCursor = $graphEdge->getPreviousCursor(); // Returns: ODOxMTUzMjQzNTg5zzU5 ~~~~ @@ -117,8 +117,8 @@ Some endpoints and edges of Graph support a summary of data. If the `summary=tru ~~~~ $response = $fb->get('/{post-id}/likes?summary=true'); -$listOfLikes = $response->getGraphList(); -$totalCount = $listOfLikes->getTotalCount(); +$likesEdge = $response->getGraphEdge(); +$totalCount = $likesEdge->getTotalCount(); // Returns: 10 ~~~~
diff --git a/docs/example_pagination_basic.fbmd b/docs/example_pagination_basic.fbmd index b2276da53..ae5c80591 100644 --- a/docs/example_pagination_basic.fbmd +++ b/docs/example_pagination_basic.fbmd @@ -32,7 +32,7 @@ try { } // Page 1 -$feed = $response->getGraphList(); +$feed = $response->getGraphEdge(); foreach ($feed as $status) { var_dump($status->asArray()); diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index ffc0ab1db..390c9f292 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -145,7 +145,7 @@ FB(devsite:markdown-wiki:table { 'The base collection object that represents a generic node.', ], [ - '[`Facebook\GraphNodes\GraphList`](/docs/php/GraphList)', + '[`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge)', 'A collection of GraphNode's with special methods to help paginate over the edge.', ], [ From 1e7d07a237d80ae1a7d6b0b2962d784f912dbfb5 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 8 May 2015 09:19:03 -0500 Subject: [PATCH 156/407] Remove references to Graph list from tests --- CHANGELOG.md | 2 +- src/Facebook/Facebook.php | 24 ++++++++++++------------ tests/FacebookBatchResponseTest.php | 6 +++--- tests/FacebookResponseTest.php | 4 ++-- tests/FacebookTest.php | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b904f75cb..aeb629e10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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 `GraphList` to obtain all the metadata associated with a list of Graph nodes + - 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 diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index b625d8079..3938b1746 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -430,44 +430,44 @@ public function delete($endpoint, array $params = [], $accessToken = null, $eTag /** * Sends a request to Graph for the next page of results. * - * @param GraphEdge $graphList The GraphEdge to paginate over. + * @param GraphEdge $graphEdge The GraphEdge to paginate over. * * @return GraphEdge|null * * @throws FacebookSDKException */ - public function next(GraphEdge $graphList) + public function next(GraphEdge $graphEdge) { - return $this->getPaginationResults($graphList, 'next'); + return $this->getPaginationResults($graphEdge, 'next'); } /** * Sends a request to Graph for the previous page of results. * - * @param GraphEdge $graphList The GraphEdge to paginate over. + * @param GraphEdge $graphEdge The GraphEdge to paginate over. * * @return GraphEdge|null * * @throws FacebookSDKException */ - public function previous(GraphEdge $graphList) + public function previous(GraphEdge $graphEdge) { - return $this->getPaginationResults($graphList, 'previous'); + return $this->getPaginationResults($graphEdge, 'previous'); } /** * Sends a request to Graph for the next page of results. * - * @param GraphEdge $graphList The GraphEdge to paginate over. + * @param GraphEdge $graphEdge The GraphEdge to paginate over. * @param string $direction The direction of the pagination: next|previous. * * @return GraphEdge|null * * @throws FacebookSDKException */ - public function getPaginationResults(GraphEdge $graphList, $direction) + public function getPaginationResults(GraphEdge $graphEdge, $direction) { - $paginationRequest = $graphList->getPaginationRequest($direction); + $paginationRequest = $graphEdge->getPaginationRequest($direction); if (!$paginationRequest) { return null; } @@ -475,10 +475,10 @@ public function getPaginationResults(GraphEdge $graphList, $direction) $this->lastResponse = $this->client->sendRequest($paginationRequest); // Keep the same GraphNode subclass - $subClassName = $graphList->getSubClassName(); - $graphList = $this->lastResponse->getGraphList($subClassName, false); + $subClassName = $graphEdge->getSubClassName(); + $graphEdge = $this->lastResponse->getGraphEdge($subClassName, false); - return count($graphList) > 0 ? $graphList : null; + return count($graphEdge) > 0 ? $graphEdge : null; } /** diff --git a/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index a4c37a94f..dec92a190 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -83,9 +83,9 @@ public function testASuccessfulJsonBatchResponseWillBeDecoded() $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $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.'); - $graphList = $decodedResponses[1]->getGraphList(); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphList[0]); - $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphList[1]); + $graphEdge = $decodedResponses[1]->getGraphEdge(); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); + $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[1]); } public function testABatchResponseCanBeIteratedOver() diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index f9b55d725..21f90ae0d 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -82,12 +82,12 @@ public function testASuccessfulJsonResponseWillBeDecodedToAGraphNode() $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); } - public function testASuccessfulJsonResponseWillBeDecodedToAGraphList() + public function testASuccessfulJsonResponseWillBeDecodedToAGraphEdge() { $graphResponseJson = '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}'; $response = new FacebookResponse($this->request, $graphResponseJson, 200); - $graphEdge = $response->getGraphList(); + $graphEdge = $response->getGraphEdge(); $this->assertFalse($response->isError(), 'Did not expect Response to return an error.'); $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphEdge[0]); diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index d4a4de338..36486655b 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -354,7 +354,7 @@ public function testPaginationReturnsProperResponse() $fb = new Facebook($config); $request = new FacebookRequest($fb->getApp(), 'foo_token', 'GET'); - $graphList = new GraphEdge( + $graphEdge = new GraphEdge( $request, [], [ @@ -369,7 +369,7 @@ public function testPaginationReturnsProperResponse() '\Facebook\GraphNodes\GraphUser' ); - $nextPage = $fb->next($graphList); + $nextPage = $fb->next($graphEdge); $this->assertInstanceOf('Facebook\GraphNodes\GraphEdge', $nextPage); $this->assertInstanceOf('Facebook\GraphNodes\GraphUser', $nextPage[0]); $this->assertEquals('Foo', $nextPage[0]['name']); From acb46b24ee9b47c318275a60bf84dfc2e53fba45 Mon Sep 17 00:00:00 2001 From: Unit One ICT Date: Sat, 2 May 2015 09:10:49 +0300 Subject: [PATCH 157/407] Add GraphEvent and GraphCoverPhoto support based on #401 --- docs/GraphObject.fbmd | 107 ++++++++ src/Facebook/FacebookResponse.php | 14 + src/Facebook/GraphNodes/GraphCoverPhoto.php | 72 ++++++ src/Facebook/GraphNodes/GraphEvent.php | 243 ++++++++++++++++++ .../GraphNodes/GraphObjectFactory.php | 12 + tests/GraphNodes/GraphEventTest.php | 115 +++++++++ 6 files changed, 563 insertions(+) create mode 100644 src/Facebook/GraphNodes/GraphCoverPhoto.php create mode 100644 src/Facebook/GraphNodes/GraphEvent.php create mode 100644 tests/GraphNodes/GraphEventTest.php diff --git a/docs/GraphObject.fbmd b/docs/GraphObject.fbmd index 3b5e9ec63..38f21c7be 100644 --- a/docs/GraphObject.fbmd +++ b/docs/GraphObject.fbmd @@ -442,3 +442,110 @@ public string|null getId() ~~~~ Returns the `id` property for the achievement as a string if present.
+ + +## GraphEvent Instance Methods {#event-instance-methods} + +All getter methods return `null` if the property does not exist on the node. + + +### getId() {#event-id} +~~~~ +public string|null getId()~~~~ +Returns the `id` property (The event ID) for the event as a string if present. + +### getCover() {#event-cover} +~~~~ +public GraphCoverPhoto|null getCover()~~~~ +Returns the `cover` property (Cover picture) for the event as a GraphCoverPhoto if present. + +### getDescription() {#event-description} +~~~~ +public string|null getDescription()~~~~ +Returns the `description` property (Long-form description) for the event as a string if present. + +### getEndTime() {#event-end_time} +~~~~ +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() {#event-is_date_only} +~~~~ +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() {#event-name} +~~~~ +public string|null getName()~~~~ +Returns the `name` property (Event name) for the event as a string if present. + +### getOwner() {#event-owner} +~~~~ +public GraphObject|null getOwner()~~~~ +Returns the `owner` property (The profile that created the event) for the event as a GraphObject if present. + +### getParentGroup() {#event-parent_group} +~~~~ +public GraphObject|null getParentGroup()~~~~ +Returns the `parent_group` property (The group the event belongs to) for the event as a GraphObject if present. + +### getPlace() {#event-place} +~~~~ +public GraphPage|null getPlace()~~~~ +Returns the `place` property (Event Place information) for the event as a GraphPage if present. + +### getPrivacy() {#event-privacy} +~~~~ +public string|null getPrivacy()~~~~ +Returns the `privacy` property (Who can see the event) for the event as a string if present. + +### getStartTime() {#event-start_time} +~~~~ +public DateTime|null getStartTime()~~~~ +Returns the `start_time` property (Start time) for the event as a DateTime if present. + +### getTicketUri() {#event-ticket_uri} +~~~~ +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() {#event-timezone} +~~~~ +public string|null getTimezone()~~~~ +Returns the `timezone` property (Timezone) for the event as a string if present. + +### getUpdatedTime() {#event-updated_time} +~~~~ +public DateTime|null getUpdatedTime()~~~~ +Returns the `updated_time` property (Last update time) for the event as a DateTime if present. + +### getPicture() {#event-picture} +~~~~ +public GraphPicture|null getPicture()~~~~ +Returns the `picture` property (Event picture) for the event as a GraphPicture if present. + +### getAttendingCount() {#event-attending_count} +~~~~ +public int|null getAttendingCount()~~~~ +Returns the `attending_count` property (Number of people attending the event) for the event as a int if present. + +### getDeclinedCount() {#event-declined_count} +~~~~ +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() {#event-maybe_count} +~~~~ +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() {#event-noreply_count} +~~~~ +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() {#event-invited_count} +~~~~ +public int|null getInvitedCount()~~~~ +Returns the `invited_count` property (Number of people invited to the event) for the event as a int if present. + diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 344f0af88..6b82c20bb 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -328,6 +328,20 @@ public function getGraphUser() return $factory->makeGraphUser(); } + /** + * Convenience method for creating a GraphEvent collection. + * + * @return \Facebook\GraphNodes\GraphEvent + * + * @throws FacebookSDKException + */ + public function getGraphEvent() + { + $factory = new GraphObjectFactory($this); + + return $factory->makeGraphEvent(); + } + /** * Instantiate a new GraphList from response. * diff --git a/src/Facebook/GraphNodes/GraphCoverPhoto.php b/src/Facebook/GraphNodes/GraphCoverPhoto.php new file mode 100644 index 000000000..f6e91c3c4 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphCoverPhoto.php @@ -0,0 +1,72 @@ +getProperty('id'); + } + + /** + * Returns the source of cover if it exists + * + * @return string|null + */ + public function getSource() + { + return $this->getProperty('source'); + } + + /** + * Returns the offset_x of cover if it exists + * + * @return int|null + */ + public function getOffsetX() + { + return $this->getProperty('offset_x'); + } + + /** + * Returns the offset_y of cover if it exists + * + * @return int|null + */ + public function getOffsetY() + { + return $this->getProperty('offset_y'); + } +} diff --git a/src/Facebook/GraphNodes/GraphEvent.php b/src/Facebook/GraphNodes/GraphEvent.php new file mode 100644 index 000000000..1930a4e7b --- /dev/null +++ b/src/Facebook/GraphNodes/GraphEvent.php @@ -0,0 +1,243 @@ + '\Facebook\GraphNodes\GraphCoverPhoto', + 'place' => '\Facebook\GraphNodes\GraphPage', + 'picture' => '\Facebook\GraphNodes\GraphPicture', + // @todo parent_group must be cast to GraphGroup once supported + // 'parent_group' => '\Facebook\GraphNodes\GraphGroup', + ]; + + /** + * Returns the `id` (The event ID) as string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getProperty('id'); + } + + /** + * Returns the `cover` (Cover picture) as GraphCoverPhoto if present. + * + * @return GraphCoverPhoto|null + */ + public function getCover() + { + return $this->getProperty('cover'); + } + + /** + * Returns the `description` (Long-form description) as string if present. + * + * @return string|null + */ + public function getDescription() + { + return $this->getProperty('description'); + } + + /** + * Returns the `end_time` (End time, if one has been set) as DateTime if present. + * + * @return DateTime|null + */ + public function getEndTime() + { + return $this->getProperty('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() + { + return $this->getProperty('is_date_only'); + } + + /** + * Returns the `name` (Event name) as string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getProperty('name'); + } + + /** + * Returns the `owner` (The profile that created the event) as GraphObject if present. + * + * @return GraphObject|null + */ + public function getOwner() + { + return $this->getProperty('owner'); + } + + /** + * Returns the `parent_group` (The group the event belongs to) as GraphObject if present. + * + * @return GraphObject|null + */ + public function getParentGroup() + { + return $this->getProperty('parent_group'); + } + + /** + * Returns the `place` (Event Place information) as GraphPage if present. + * + * @return GraphPage|null + */ + public function getPlace() + { + return $this->getProperty('place'); + } + + /** + * Returns the `privacy` (Who can see the event) as string if present. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getProperty('privacy'); + } + + /** + * Returns the `start_time` (Start time) as DateTime if present. + * + * @return DateTime|null + */ + public function getStartTime() + { + return $this->getProperty('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() + { + return $this->getProperty('ticket_uri'); + } + + /** + * Returns the `timezone` (Timezone) as string if present. + * + * @return string|null + */ + public function getTimezone() + { + return $this->getProperty('timezone'); + } + + /** + * Returns the `updated_time` (Last update time) as DateTime if present. + * + * @return DateTime|null + */ + public function getUpdatedTime() + { + return $this->getProperty('updated_time'); + } + + /** + * Returns the `picture` (Event picture) as GraphPicture if present. + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getProperty('picture'); + } + + /** + * Returns the `attending_count` (Number of people attending the event) as int if present. + * + * @return int|null + */ + public function getAttendingCount() + { + return $this->getProperty('attending_count'); + } + + /** + * Returns the `declined_count` (Number of people who declined the event) as int if present. + * + * @return int|null + */ + public function getDeclinedCount() + { + return $this->getProperty('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() + { + return $this->getProperty('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() + { + return $this->getProperty('noreply_count'); + } + + /** + * Returns the `invited_count` (Number of people invited to the event) as int if present. + * + * @return int|null + */ + public function getInvitedCount() + { + return $this->getProperty('invited_count'); + } +} diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index fa3a143cf..1c95cf383 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -150,6 +150,18 @@ public function makeGraphUser() { return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); } + + /** + * Convenience method for creating a GraphEvent collection. + * + * @return GraphEvent + * + * @throws FacebookSDKException + */ + public function makeGraphEvent() + { + return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); + } /** * Tries to convert a FacebookResponse entity into a GraphList. diff --git a/tests/GraphNodes/GraphEventTest.php b/tests/GraphNodes/GraphEventTest.php new file mode 100644 index 000000000..bbfabc5f5 --- /dev/null +++ b/tests/GraphNodes/GraphEventTest.php @@ -0,0 +1,115 @@ +responseMock = m::mock('\Facebook\FacebookResponse'); + } + + public function testDatesGetCastToDateTime() + { + $dataFromGraph = [ + 'end_time' => '2015-04-14T11:00:00+0300', + 'start_time' => '2015-04-14T11:00:00+0300', + 'updated_time' => '2015-04-14T11:00:00+0300', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $end_time = $graphObject->getEndTime(); + $this->assertInstanceOf('DateTime', $end_time); + $start_time = $graphObject->getStartTime(); + $this->assertInstanceOf('DateTime', $start_time); + $updated_time = $graphObject->getUpdatedTime(); + $this->assertInstanceOf('DateTime', $updated_time); + } + + public function testCoverGetsCastAsGraphCoverPhoto() + { + $dataFromGraph = [ + 'cover' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $cover = $graphObject->getCover(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); + } + + public function testPlaceGetsCastAsGraphPage() + { + $dataFromGraph = [ + 'place' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $place = $graphObject->getPlace(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphPage', $place); + } + + public function testPictureGetsCastAsGraphPicture() + { + $dataFromGraph = [ + 'picture' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphObjectFactory($this->responseMock); + $graphObject = $factory->makeGraphEvent(); + + $picture = $graphObject->getPicture(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphPicture', $picture); + } +} From 86749457f526058ffdecd3bcfb12c31cbb5abab7 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 12 May 2015 22:53:55 -0500 Subject: [PATCH 158/407] Make compatibile with PR #405 --- src/Facebook/FacebookResponse.php | 2 +- src/Facebook/GraphNodes/GraphCoverPhoto.php | 2 +- src/Facebook/GraphNodes/GraphEvent.php | 12 ++++++------ src/Facebook/GraphNodes/GraphNodeFactory.php | 12 ++++++++++++ tests/GraphNodes/GraphEventTest.php | 10 +++++----- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 69eb0a5c5..7ef86d7b7 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -354,7 +354,7 @@ public function getGraphUser() */ public function getGraphEvent() { - $factory = new GraphObjectFactory($this); + $factory = new GraphNodeFactory($this); return $factory->makeGraphEvent(); } diff --git a/src/Facebook/GraphNodes/GraphCoverPhoto.php b/src/Facebook/GraphNodes/GraphCoverPhoto.php index f6e91c3c4..e28143dd2 100644 --- a/src/Facebook/GraphNodes/GraphCoverPhoto.php +++ b/src/Facebook/GraphNodes/GraphCoverPhoto.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphCoverPhoto extends GraphObject +class GraphCoverPhoto extends GraphNode { /** * Returns the id of cover if it exists diff --git a/src/Facebook/GraphNodes/GraphEvent.php b/src/Facebook/GraphNodes/GraphEvent.php index 1930a4e7b..f1601fbf1 100644 --- a/src/Facebook/GraphNodes/GraphEvent.php +++ b/src/Facebook/GraphNodes/GraphEvent.php @@ -28,7 +28,7 @@ * * @package Facebook */ -class GraphEvent extends GraphObject +class GraphEvent extends GraphNode { /** * @var array Maps object key names to Graph object types. @@ -74,7 +74,7 @@ public function getDescription() /** * Returns the `end_time` (End time, if one has been set) as DateTime if present. * - * @return DateTime|null + * @return \DateTime|null */ public function getEndTime() { @@ -104,7 +104,7 @@ public function getName() /** * Returns the `owner` (The profile that created the event) as GraphObject if present. * - * @return GraphObject|null + * @return GraphNode|null */ public function getOwner() { @@ -114,7 +114,7 @@ public function getOwner() /** * Returns the `parent_group` (The group the event belongs to) as GraphObject if present. * - * @return GraphObject|null + * @return GraphNode|null */ public function getParentGroup() { @@ -144,7 +144,7 @@ public function getPrivacy() /** * Returns the `start_time` (Start time) as DateTime if present. * - * @return DateTime|null + * @return \DateTime|null */ public function getStartTime() { @@ -174,7 +174,7 @@ public function getTimezone() /** * Returns the `updated_time` (Last update time) as DateTime if present. * - * @return DateTime|null + * @return \DateTime|null */ public function getUpdatedTime() { diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index 3bea66122..e20ddf714 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -155,6 +155,18 @@ 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'); + } + /** * Tries to convert a FacebookResponse entity into a GraphEdge. * diff --git a/tests/GraphNodes/GraphEventTest.php b/tests/GraphNodes/GraphEventTest.php index bbfabc5f5..b6ed0d11d 100644 --- a/tests/GraphNodes/GraphEventTest.php +++ b/tests/GraphNodes/GraphEventTest.php @@ -25,7 +25,7 @@ use Facebook\FacebookResponse; use Mockery as m; -use Facebook\GraphNodes\GraphObjectFactory; +use Facebook\GraphNodes\GraphNodeFactory; class GraphEventTest extends \PHPUnit_Framework_TestCase { @@ -51,7 +51,7 @@ public function testDatesGetCastToDateTime() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); $end_time = $graphObject->getEndTime(); @@ -72,7 +72,7 @@ public function testCoverGetsCastAsGraphCoverPhoto() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); $cover = $graphObject->getCover(); @@ -89,7 +89,7 @@ public function testPlaceGetsCastAsGraphPage() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); $place = $graphObject->getPlace(); @@ -106,7 +106,7 @@ public function testPictureGetsCastAsGraphPicture() ->shouldReceive('getDecodedBody') ->once() ->andReturn($dataFromGraph); - $factory = new GraphObjectFactory($this->responseMock); + $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); $picture = $graphObject->getPicture(); From b400e5cf79f4fa304ea4a611c851853049947dc0 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 13 May 2015 12:25:08 -0500 Subject: [PATCH 159/407] Tweak per feedback from @yguedidi --- docs/FacebookRequest.fbmd | 4 ++-- docs/GraphNode.fbmd | 6 +++--- docs/example_pagination_basic.fbmd | 6 +++--- tests/GraphNodes/GraphObjectFactoryTest.php | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index 54998809e..da487b357 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -51,9 +51,9 @@ try { exit; } -$node = $response->getGraphNode(); +$graphNode = $response->getGraphNode(); -echo 'User name: ' . $node['name']; +echo 'User name: ' . $graphNode['name']; ~~~~ diff --git a/docs/GraphNode.fbmd b/docs/GraphNode.fbmd index 10309b0b3..3f140b481 100644 --- a/docs/GraphNode.fbmd +++ b/docs/GraphNode.fbmd @@ -26,7 +26,7 @@ $fb = new Facebook\Facebook(\* *\); $response = $fb->get('/something'); // Get the base class GraphNode from the response -$node = $response->getGraphNode(); +$graphNode = $response->getGraphNode(); // Get the response typed as a GraphUser $user = $response->getGraphUser()); @@ -35,11 +35,11 @@ $user = $response->getGraphUser()); $page = $response->getGraphPage(); // User example -echo $node->getProperty('name'); // From GraphNode +echo $graphNode->getProperty('name'); // From GraphNode echo $user->getName(); // From GraphUser // Location example -echo $node->getProperty('country'); // From GraphNode +echo $graphNode->getProperty('country'); // From GraphNode echo $location->getCountry(); // From GraphLocation ~~~~ diff --git a/docs/example_pagination_basic.fbmd b/docs/example_pagination_basic.fbmd index ae5c80591..41894b698 100644 --- a/docs/example_pagination_basic.fbmd +++ b/docs/example_pagination_basic.fbmd @@ -32,14 +32,14 @@ try { } // Page 1 -$feed = $response->getGraphEdge(); +$feedEdge = $response->getGraphEdge(); -foreach ($feed as $status) { +foreach ($feedEdge as $status) { var_dump($status->asArray()); } // Page 2 (next 5 results) -$nextFeed = $fb->next($feed); +$nextFeed = $fb->next($feedEdge); foreach ($nextFeed as $status) { var_dump($status->asArray()); diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index dbc5e771d..764503ab8 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -96,10 +96,10 @@ public function testAListFromGraphWillBeCastAsAGraphEdge() $res = new FacebookResponse($this->request, $data); $factory = new GraphObjectFactory($res); - $graphEdge = $factory->makeGraphList(); - $graphData = $graphEdge->asArray(); + $graphList = $factory->makeGraphList(); + $graphData = $graphList->asArray(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphEdge); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphList', $graphList); $this->assertEquals([ 'id' => '123', 'name' => 'Foo McBar', From fb6c29133c47c039b31fa9acbf19e0d0b0648199 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 13 May 2015 13:00:56 -0500 Subject: [PATCH 160/407] Rename getProperty() to getField() and depricate getProperty() --- docs/GraphNode.fbmd | 28 ++++++------- .../Authentication/AccessTokenMetadata.php | 38 +++++++++++++----- src/Facebook/GraphNodes/Collection.php | 39 +++++++++++++++--- src/Facebook/GraphNodes/GraphAchievement.php | 12 +++--- src/Facebook/GraphNodes/GraphAlbum.php | 28 ++++++------- src/Facebook/GraphNodes/GraphApplication.php | 2 +- src/Facebook/GraphNodes/GraphCoverPhoto.php | 8 ++-- src/Facebook/GraphNodes/GraphEvent.php | 40 +++++++++---------- src/Facebook/GraphNodes/GraphLocation.php | 14 +++---- src/Facebook/GraphNodes/GraphPage.php | 16 ++++---- src/Facebook/GraphNodes/GraphPicture.php | 8 ++-- src/Facebook/GraphNodes/GraphSessionInfo.php | 14 +++---- src/Facebook/GraphNodes/GraphUser.php | 24 +++++------ tests/FacebookClientTest.php | 10 ++--- tests/GraphNodes/CollectionTest.php | 24 ++++++++--- tests/GraphNodes/GraphNodeFactoryTest.php | 4 +- 16 files changed, 183 insertions(+), 126 deletions(-) diff --git a/docs/GraphNode.fbmd b/docs/GraphNode.fbmd index 3f140b481..18388221b 100644 --- a/docs/GraphNode.fbmd +++ b/docs/GraphNode.fbmd @@ -35,11 +35,11 @@ $user = $response->getGraphUser()); $page = $response->getGraphPage(); // User example -echo $graphNode->getProperty('name'); // From GraphNode +echo $graphNode->getField('name'); // From GraphNode echo $user->getName(); // From GraphUser // Location example -echo $graphNode->getProperty('country'); // From GraphNode +echo $graphNode->getField('country'); // From GraphNode echo $location->getCountry(); // From GraphLocation ~~~~ @@ -74,7 +74,7 @@ $total = count($graphNode); ### asArray {#as-array} `asArray()` -Returns the raw representation (associative arrays, nested) of this objects underlying data. +Returns the raw representation (associative arrays, nested) of the node's underlying data. ### asJson {#as-json} @@ -82,16 +82,16 @@ Returns the raw representation (associative arrays, nested) of this objects unde Returns the data as a JSON string. -### getProperty {#get-property} -`getProperty(string $name, string $default = 'foo')` -Gets the value of a named key for this graph object. 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. +### getField {#get-field} +`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 property doesn't exist. +The second argument lets you define a default value to return if the field doesn't exist. -### getPropertyNames {#get-property-names} -`getPropertyNames()` -Returns an array with the names of all properties present on this graph object. +### getFieldNames {#get-field-names} +`getFieldNames()` +Returns an array with the names of all fields present on the graph node. ### map {#map} @@ -481,13 +481,13 @@ Returns the `name` property (Event name) for the event as a string if present. ### getOwner() {#event-owner} ~~~~ -public GraphObject|null getOwner()~~~~ -Returns the `owner` property (The profile that created the event) for the event as a GraphObject if present. +public GraphNode|null getOwner()~~~~ +Returns the `owner` property (The profile that created the event) for the event as a GraphNode if present. ### getParentGroup() {#event-parent_group} ~~~~ -public GraphObject|null getParentGroup()~~~~ -Returns the `parent_group` property (The group the event belongs to) for the event as a GraphObject if present. +public GraphNode|null getParentGroup()~~~~ +Returns the `parent_group` property (The group the event belongs to) for the event as a GraphNode if present. ### getPlace() {#event-place} ~~~~ diff --git a/src/Facebook/Authentication/AccessTokenMetadata.php b/src/Facebook/Authentication/AccessTokenMetadata.php index 17e5bbf5e..f302a6d2f 100644 --- a/src/Facebook/Authentication/AccessTokenMetadata.php +++ b/src/Facebook/Authentication/AccessTokenMetadata.php @@ -73,7 +73,7 @@ public function __construct(array $metadata) * * @return mixed */ - public function getProperty($field, $default = null) + public function getField($field, $default = null) { if (isset($this->metadata[$field])) { return $this->metadata[$field]; @@ -82,6 +82,22 @@ public function getProperty($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. * @@ -137,7 +153,7 @@ public function getMetadataProperty($field, $default = null) */ public function getAppId() { - return $this->getProperty('app_id'); + return $this->getField('app_id'); } /** @@ -147,7 +163,7 @@ public function getAppId() */ public function getApplication() { - return $this->getProperty('application'); + return $this->getField('application'); } /** @@ -158,7 +174,7 @@ public function getApplication() */ public function isError() { - return $this->getProperty('error') !== null; + return $this->getField('error') !== null; } /** @@ -198,7 +214,7 @@ public function getErrorSubcode() */ public function getExpiresAt() { - return $this->getProperty('expires_at'); + return $this->getField('expires_at'); } /** @@ -208,7 +224,7 @@ public function getExpiresAt() */ public function getIsValid() { - return $this->getProperty('is_valid'); + return $this->getField('is_valid'); } /** @@ -223,7 +239,7 @@ public function getIsValid() */ public function getIssuedAt() { - return $this->getProperty('issued_at'); + return $this->getField('issued_at'); } /** @@ -234,7 +250,7 @@ public function getIssuedAt() */ public function getMetadata() { - return $this->getProperty('metadata'); + return $this->getField('metadata'); } /** @@ -275,7 +291,7 @@ public function getAuthNonce() */ public function getProfileId() { - return $this->getProperty('profile_id'); + return $this->getField('profile_id'); } /** @@ -286,7 +302,7 @@ public function getProfileId() */ public function getScopes() { - return $this->getProperty('scopes'); + return $this->getField('scopes'); } /** @@ -296,7 +312,7 @@ public function getScopes() */ public function getUserId() { - return $this->getProperty('user_id'); + return $this->getField('user_id'); } /** diff --git a/src/Facebook/GraphNodes/Collection.php b/src/Facebook/GraphNodes/Collection.php index 620b9a1dc..cac010ba3 100644 --- a/src/Facebook/GraphNodes/Collection.php +++ b/src/Facebook/GraphNodes/Collection.php @@ -56,14 +56,14 @@ public function __construct(array $items = []) } /** - * Gets the value of the named property for this graph object. + * Gets the value of a field from the Graph node. * - * @param string $name The property to retrieve. - * @param mixed $default The default to return if the property doesn't exist. + * @param string $name The field to retrieve. + * @param mixed $default The default to return if the field doesn't exist. * * @return mixed */ - public function getProperty($name, $default = null) + public function getField($name, $default = null) { if (isset($this->items[$name])) { return $this->items[$name]; @@ -72,14 +72,43 @@ public function getProperty($name, $default = null) return $default ?: null; } + /** + * 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() + { + 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 array_keys($this->items); + return $this->getFieldNames(); } /** diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php index c6d400b96..3fba815c9 100644 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -46,7 +46,7 @@ class GraphAchievement extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } /** @@ -56,7 +56,7 @@ public function getId() */ public function getFrom() { - return $this->getProperty('from'); + return $this->getField('from'); } /** @@ -66,7 +66,7 @@ public function getFrom() */ public function getPublishTime() { - return $this->getProperty('publish_time'); + return $this->getField('publish_time'); } /** @@ -76,7 +76,7 @@ public function getPublishTime() */ public function getApplication() { - return $this->getProperty('application'); + return $this->getField('application'); } /** @@ -86,7 +86,7 @@ public function getApplication() */ public function getData() { - return $this->getProperty('data'); + return $this->getField('data'); } /** @@ -108,6 +108,6 @@ public function getType() */ public function isNoFeedStory() { - return $this->getProperty('no_feed_story'); + return $this->getField('no_feed_story'); } } diff --git a/src/Facebook/GraphNodes/GraphAlbum.php b/src/Facebook/GraphNodes/GraphAlbum.php index 730f4b7e6..50d1f2c37 100644 --- a/src/Facebook/GraphNodes/GraphAlbum.php +++ b/src/Facebook/GraphNodes/GraphAlbum.php @@ -46,7 +46,7 @@ class GraphAlbum extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } /** @@ -56,7 +56,7 @@ public function getId() */ public function getCanUpload() { - return $this->getProperty('can_upload'); + return $this->getField('can_upload'); } /** @@ -66,7 +66,7 @@ public function getCanUpload() */ public function getCount() { - return $this->getProperty('count'); + return $this->getField('count'); } /** @@ -76,7 +76,7 @@ public function getCount() */ public function getCoverPhoto() { - return $this->getProperty('cover_photo'); + return $this->getField('cover_photo'); } /** @@ -86,7 +86,7 @@ public function getCoverPhoto() */ public function getCreatedTime() { - return $this->getProperty('created_time'); + return $this->getField('created_time'); } /** @@ -96,7 +96,7 @@ public function getCreatedTime() */ public function getUpdatedTime() { - return $this->getProperty('updated_time'); + return $this->getField('updated_time'); } /** @@ -106,7 +106,7 @@ public function getUpdatedTime() */ public function getDescription() { - return $this->getProperty('description'); + return $this->getField('description'); } /** @@ -116,7 +116,7 @@ public function getDescription() */ public function getFrom() { - return $this->getProperty('from'); + return $this->getField('from'); } /** @@ -126,7 +126,7 @@ public function getFrom() */ public function getPlace() { - return $this->getProperty('place'); + return $this->getField('place'); } /** @@ -136,7 +136,7 @@ public function getPlace() */ public function getLink() { - return $this->getProperty('link'); + return $this->getField('link'); } /** @@ -146,7 +146,7 @@ public function getLink() */ public function getLocation() { - return $this->getProperty('location'); + return $this->getField('location'); } /** @@ -156,7 +156,7 @@ public function getLocation() */ public function getName() { - return $this->getProperty('name'); + return $this->getField('name'); } /** @@ -166,7 +166,7 @@ public function getName() */ public function getPrivacy() { - return $this->getProperty('privacy'); + return $this->getField('privacy'); } /** @@ -178,6 +178,6 @@ public function getPrivacy() */ public function getType() { - return $this->getProperty('type'); + return $this->getField('type'); } } diff --git a/src/Facebook/GraphNodes/GraphApplication.php b/src/Facebook/GraphNodes/GraphApplication.php index a8b048895..69b09bb57 100644 --- a/src/Facebook/GraphNodes/GraphApplication.php +++ b/src/Facebook/GraphNodes/GraphApplication.php @@ -38,6 +38,6 @@ class GraphApplication extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } } diff --git a/src/Facebook/GraphNodes/GraphCoverPhoto.php b/src/Facebook/GraphNodes/GraphCoverPhoto.php index e28143dd2..ee6075075 100644 --- a/src/Facebook/GraphNodes/GraphCoverPhoto.php +++ b/src/Facebook/GraphNodes/GraphCoverPhoto.php @@ -37,7 +37,7 @@ class GraphCoverPhoto extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } /** @@ -47,7 +47,7 @@ public function getId() */ public function getSource() { - return $this->getProperty('source'); + return $this->getField('source'); } /** @@ -57,7 +57,7 @@ public function getSource() */ public function getOffsetX() { - return $this->getProperty('offset_x'); + return $this->getField('offset_x'); } /** @@ -67,6 +67,6 @@ public function getOffsetX() */ public function getOffsetY() { - return $this->getProperty('offset_y'); + return $this->getField('offset_y'); } } diff --git a/src/Facebook/GraphNodes/GraphEvent.php b/src/Facebook/GraphNodes/GraphEvent.php index f1601fbf1..b90d41846 100644 --- a/src/Facebook/GraphNodes/GraphEvent.php +++ b/src/Facebook/GraphNodes/GraphEvent.php @@ -48,7 +48,7 @@ class GraphEvent extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } /** @@ -58,7 +58,7 @@ public function getId() */ public function getCover() { - return $this->getProperty('cover'); + return $this->getField('cover'); } /** @@ -68,7 +68,7 @@ public function getCover() */ public function getDescription() { - return $this->getProperty('description'); + return $this->getField('description'); } /** @@ -78,7 +78,7 @@ public function getDescription() */ public function getEndTime() { - return $this->getProperty('end_time'); + return $this->getField('end_time'); } /** @@ -88,7 +88,7 @@ public function getEndTime() */ public function getIsDateOnly() { - return $this->getProperty('is_date_only'); + return $this->getField('is_date_only'); } /** @@ -98,7 +98,7 @@ public function getIsDateOnly() */ public function getName() { - return $this->getProperty('name'); + return $this->getField('name'); } /** @@ -108,7 +108,7 @@ public function getName() */ public function getOwner() { - return $this->getProperty('owner'); + return $this->getField('owner'); } /** @@ -118,7 +118,7 @@ public function getOwner() */ public function getParentGroup() { - return $this->getProperty('parent_group'); + return $this->getField('parent_group'); } /** @@ -128,7 +128,7 @@ public function getParentGroup() */ public function getPlace() { - return $this->getProperty('place'); + return $this->getField('place'); } /** @@ -138,7 +138,7 @@ public function getPlace() */ public function getPrivacy() { - return $this->getProperty('privacy'); + return $this->getField('privacy'); } /** @@ -148,7 +148,7 @@ public function getPrivacy() */ public function getStartTime() { - return $this->getProperty('start_time'); + return $this->getField('start_time'); } /** @@ -158,7 +158,7 @@ public function getStartTime() */ public function getTicketUri() { - return $this->getProperty('ticket_uri'); + return $this->getField('ticket_uri'); } /** @@ -168,7 +168,7 @@ public function getTicketUri() */ public function getTimezone() { - return $this->getProperty('timezone'); + return $this->getField('timezone'); } /** @@ -178,7 +178,7 @@ public function getTimezone() */ public function getUpdatedTime() { - return $this->getProperty('updated_time'); + return $this->getField('updated_time'); } /** @@ -188,7 +188,7 @@ public function getUpdatedTime() */ public function getPicture() { - return $this->getProperty('picture'); + return $this->getField('picture'); } /** @@ -198,7 +198,7 @@ public function getPicture() */ public function getAttendingCount() { - return $this->getProperty('attending_count'); + return $this->getField('attending_count'); } /** @@ -208,7 +208,7 @@ public function getAttendingCount() */ public function getDeclinedCount() { - return $this->getProperty('declined_count'); + return $this->getField('declined_count'); } /** @@ -218,7 +218,7 @@ public function getDeclinedCount() */ public function getMaybeCount() { - return $this->getProperty('maybe_count'); + return $this->getField('maybe_count'); } /** @@ -228,7 +228,7 @@ public function getMaybeCount() */ public function getNoreplyCount() { - return $this->getProperty('noreply_count'); + return $this->getField('noreply_count'); } /** @@ -238,6 +238,6 @@ public function getNoreplyCount() */ public function getInvitedCount() { - return $this->getProperty('invited_count'); + return $this->getField('invited_count'); } } diff --git a/src/Facebook/GraphNodes/GraphLocation.php b/src/Facebook/GraphNodes/GraphLocation.php index b6b03f885..187a399a1 100644 --- a/src/Facebook/GraphNodes/GraphLocation.php +++ b/src/Facebook/GraphNodes/GraphLocation.php @@ -37,7 +37,7 @@ class GraphLocation extends GraphNode */ public function getStreet() { - return $this->getProperty('street'); + return $this->getField('street'); } /** @@ -47,7 +47,7 @@ public function getStreet() */ public function getCity() { - return $this->getProperty('city'); + return $this->getField('city'); } /** @@ -57,7 +57,7 @@ public function getCity() */ public function getState() { - return $this->getProperty('state'); + return $this->getField('state'); } /** @@ -67,7 +67,7 @@ public function getState() */ public function getCountry() { - return $this->getProperty('country'); + return $this->getField('country'); } /** @@ -77,7 +77,7 @@ public function getCountry() */ public function getZip() { - return $this->getProperty('zip'); + return $this->getField('zip'); } /** @@ -87,7 +87,7 @@ public function getZip() */ public function getLatitude() { - return $this->getProperty('latitude'); + return $this->getField('latitude'); } /** @@ -97,6 +97,6 @@ public function getLatitude() */ public function getLongitude() { - return $this->getProperty('longitude'); + return $this->getField('longitude'); } } diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index 69346e229..ab8e31a6c 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -46,7 +46,7 @@ class GraphPage extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } /** @@ -56,7 +56,7 @@ public function getId() */ public function getCategory() { - return $this->getProperty('category'); + return $this->getField('category'); } /** @@ -66,7 +66,7 @@ public function getCategory() */ public function getName() { - return $this->getProperty('name'); + return $this->getField('name'); } /** @@ -76,7 +76,7 @@ public function getName() */ public function getBestPage() { - return $this->getProperty('best_page'); + return $this->getField('best_page'); } /** @@ -86,7 +86,7 @@ public function getBestPage() */ public function getGlobalBrandParentPage() { - return $this->getProperty('global_brand_parent_page'); + return $this->getField('global_brand_parent_page'); } /** @@ -96,7 +96,7 @@ public function getGlobalBrandParentPage() */ public function getLocation() { - return $this->getProperty('location'); + return $this->getField('location'); } /** @@ -108,7 +108,7 @@ public function getLocation() */ public function getAccessToken() { - return $this->getProperty('access_token'); + return $this->getField('access_token'); } /** @@ -120,6 +120,6 @@ public function getAccessToken() */ public function getPerms() { - return $this->getProperty('perms'); + return $this->getField('perms'); } } diff --git a/src/Facebook/GraphNodes/GraphPicture.php b/src/Facebook/GraphNodes/GraphPicture.php index 8852d6aa9..bfd37fabc 100644 --- a/src/Facebook/GraphNodes/GraphPicture.php +++ b/src/Facebook/GraphNodes/GraphPicture.php @@ -37,7 +37,7 @@ class GraphPicture extends GraphNode */ public function isSilhouette() { - return $this->getProperty('is_silhouette'); + return $this->getField('is_silhouette'); } /** @@ -47,7 +47,7 @@ public function isSilhouette() */ public function getUrl() { - return $this->getProperty('url'); + return $this->getField('url'); } /** @@ -57,7 +57,7 @@ public function getUrl() */ public function getWidth() { - return $this->getProperty('width'); + return $this->getField('width'); } /** @@ -67,6 +67,6 @@ public function getWidth() */ public function getHeight() { - return $this->getProperty('height'); + return $this->getField('height'); } } diff --git a/src/Facebook/GraphNodes/GraphSessionInfo.php b/src/Facebook/GraphNodes/GraphSessionInfo.php index b962de1ec..3c9e2ff48 100644 --- a/src/Facebook/GraphNodes/GraphSessionInfo.php +++ b/src/Facebook/GraphNodes/GraphSessionInfo.php @@ -37,7 +37,7 @@ class GraphSessionInfo extends GraphNode */ public function getAppId() { - return $this->getProperty('app_id'); + return $this->getField('app_id'); } /** @@ -47,7 +47,7 @@ public function getAppId() */ public function getApplication() { - return $this->getProperty('application'); + return $this->getField('application'); } /** @@ -57,7 +57,7 @@ public function getApplication() */ public function getExpiresAt() { - return $this->getProperty('expires_at'); + return $this->getField('expires_at'); } /** @@ -67,7 +67,7 @@ public function getExpiresAt() */ public function getIsValid() { - return $this->getProperty('is_valid'); + return $this->getField('is_valid'); } /** @@ -77,7 +77,7 @@ public function getIsValid() */ public function getIssuedAt() { - return $this->getProperty('issued_at'); + return $this->getField('issued_at'); } /** @@ -87,7 +87,7 @@ public function getIssuedAt() */ public function getScopes() { - return $this->getProperty('scopes'); + return $this->getField('scopes'); } /** @@ -97,6 +97,6 @@ public function getScopes() */ public function getUserId() { - return $this->getProperty('user_id'); + return $this->getField('user_id'); } } diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index 11ffb0b19..cb9ddbb5d 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -47,7 +47,7 @@ class GraphUser extends GraphNode */ public function getId() { - return $this->getProperty('id'); + return $this->getField('id'); } /** @@ -57,7 +57,7 @@ public function getId() */ public function getName() { - return $this->getProperty('name'); + return $this->getField('name'); } /** @@ -67,7 +67,7 @@ public function getName() */ public function getFirstName() { - return $this->getProperty('first_name'); + return $this->getField('first_name'); } /** @@ -77,7 +77,7 @@ public function getFirstName() */ public function getMiddleName() { - return $this->getProperty('middle_name'); + return $this->getField('middle_name'); } /** @@ -87,7 +87,7 @@ public function getMiddleName() */ public function getLastName() { - return $this->getProperty('last_name'); + return $this->getField('last_name'); } /** @@ -97,7 +97,7 @@ public function getLastName() */ public function getGender() { - return $this->getProperty('gender'); + return $this->getField('gender'); } /** @@ -107,7 +107,7 @@ public function getGender() */ public function getLink() { - return $this->getProperty('link'); + return $this->getField('link'); } /** @@ -117,7 +117,7 @@ public function getLink() */ public function getBirthday() { - return $this->getProperty('birthday'); + return $this->getField('birthday'); } /** @@ -127,7 +127,7 @@ public function getBirthday() */ public function getLocation() { - return $this->getProperty('location'); + return $this->getField('location'); } /** @@ -137,7 +137,7 @@ public function getLocation() */ public function getHometown() { - return $this->getProperty('hometown'); + return $this->getField('hometown'); } /** @@ -147,7 +147,7 @@ public function getHometown() */ public function getSignificantOther() { - return $this->getProperty('significant_other'); + return $this->getField('significant_other'); } /** @@ -157,6 +157,6 @@ public function getSignificantOther() */ public function getPicture() { - return $this->getProperty('picture'); + return $this->getField('picture'); } } diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index e45367538..6e9bb6cf5 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -243,8 +243,8 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() ); $response = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - $testUserId = $response->getProperty('id'); - $testUserAccessToken = $response->getProperty('access_token'); + $testUserId = $response->getField('id'); + $testUserAccessToken = $response->getField('access_token'); // Get the test user's profile $request = new FacebookRequest( @@ -256,8 +256,8 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); $this->assertInstanceOf('Facebook\GraphNodes\GraphNode', $graphNode); - $this->assertNotNull($graphNode->getProperty('id')); - $this->assertEquals('Foo Phpunit User', $graphNode->getProperty('name')); + $this->assertNotNull($graphNode->getField('id')); + $this->assertEquals('Foo Phpunit User', $graphNode->getField('name')); // Delete test user $request = new FacebookRequest( @@ -268,7 +268,7 @@ public function testCanCreateATestUserAndGetTheProfileAndThenDeleteTheTestUser() ); $graphNode = static::$testFacebookClient->sendRequest($request)->getGraphNode(); - $this->assertTrue($graphNode->getProperty('success')); + $this->assertTrue($graphNode->getField('success')); } public function initializeTestApp() diff --git a/tests/GraphNodes/CollectionTest.php b/tests/GraphNodes/CollectionTest.php index a5e33df56..af3eba8c5 100755 --- a/tests/GraphNodes/CollectionTest.php +++ b/tests/GraphNodes/CollectionTest.php @@ -31,24 +31,32 @@ class CollectionTest extends \PHPUnit_Framework_TestCase public function testAnExistingPropertyCanBeAccessed() { $graphNode = new Collection(['foo' => 'bar']); - $property = $graphNode->getProperty('foo'); + $field = $graphNode->getField('foo'); + $this->assertEquals('bar', $field); + + // @todo v6: Remove this assertion + $property = $graphNode->getProperty('foo'); $this->assertEquals('bar', $property); } public function testAMissingPropertyWillReturnNull() { $graphNode = new Collection(['foo' => 'bar']); - $property = $graphNode->getProperty('baz'); + $field = $graphNode->getField('baz'); - $this->assertNull($property, 'Expected the property to return null.'); + $this->assertNull($field, 'Expected the property to return null.'); } public function testAMissingPropertyWillReturnTheDefault() { $graphNode = new Collection(['foo' => 'bar']); - $property = $graphNode->getProperty('baz', 'faz'); + $field = $graphNode->getField('baz', 'faz'); + $this->assertEquals('faz', $field); + + // @todo v6: Remove this assertion + $property = $graphNode->getProperty('baz', 'faz'); $this->assertEquals('faz', $property); } @@ -59,9 +67,13 @@ public function testTheKeysFromTheCollectionCanBeReturned() 'key2' => 'bar', 'key3' => 'baz', ]); - $propertyKeys = $graphNode->getPropertyNames(); - $this->assertEquals(['key1', 'key2', 'key3'], $propertyKeys); + $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() diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 6099284c6..7d2f02372 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -147,7 +147,7 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $factory = new GraphNodeFactory($res); $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); - $fooObject = $mySubClassObject->getProperty('foo_object'); + $fooObject = $mySubClassObject->getField('foo_object'); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', $fooObject); @@ -168,7 +168,7 @@ public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() $factory = new GraphNodeFactory($res); $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); - $unknownObject = $mySubClassObject->getProperty('unknown_object'); + $unknownObject = $mySubClassObject->getField('unknown_object'); $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $unknownObject); From 7df37128ad715dda2badff5ce4279c6b77bcb810 Mon Sep 17 00:00:00 2001 From: Unit One ICT Date: Thu, 14 May 2015 23:32:38 +0300 Subject: [PATCH 161/407] Add GraphGroup support including the docs and the test class --- docs/GraphNode.fbmd | 64 ++++++- src/Facebook/FacebookResponse.php | 14 ++ src/Facebook/GraphNodes/GraphEvent.php | 11 +- src/Facebook/GraphNodes/GraphGroup.php | 171 +++++++++++++++++++ src/Facebook/GraphNodes/GraphNodeFactory.php | 12 ++ tests/GraphNodes/GraphEventTest.php | 38 ++--- tests/GraphNodes/GraphGroupTest.php | 75 ++++++++ 7 files changed, 355 insertions(+), 30 deletions(-) create mode 100644 src/Facebook/GraphNodes/GraphGroup.php create mode 100644 tests/GraphNodes/GraphGroupTest.php diff --git a/docs/GraphNode.fbmd b/docs/GraphNode.fbmd index 18388221b..6be7676af 100644 --- a/docs/GraphNode.fbmd +++ b/docs/GraphNode.fbmd @@ -486,8 +486,8 @@ Returns the `owner` property (The profile that created the event) for the event ### getParentGroup() {#event-parent_group} ~~~~ -public GraphNode|null getParentGroup()~~~~ -Returns the `parent_group` property (The group the event belongs to) for the event as a GraphNode if present. +public GraphGroup|null getParentGroup()~~~~ +Returns the `parent_group` property (The group the event belongs to) for the event as a GraphGroup if present. ### getPlace() {#event-place} ~~~~ @@ -549,3 +549,63 @@ Returns the `noreply_count` property (Number of people who did not reply to the 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 {#group-instance-methods} + +All getter methods return `null` if the field does not exist on the node. + +### getId() {#group-id} +~~~~ +public string|null getId()~~~~ +Returns the `id` field (The Group ID) for the group as a string if present. +### getCover() {#group-cover} +~~~~ +public GraphCoverPhoto|null getCover()~~~~ +Returns the `cover` field (The cover photo of the Group) for the group as a GraphCoverPhoto if present. +### getDescription() {#group-description} +~~~~ +public string|null getDescription()~~~~ +Returns the `description` field (A brief description of the Group) for the group as a string if present. +### getEmail() {#group-email} +~~~~ +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() {#group-icon} +~~~~ +public string|null getIcon()~~~~ +Returns the `icon` field (The URL for the Group's icon) for the group as a string if present. +### getLink() {#group-link} +~~~~ +public string|null getLink()~~~~ +Returns the `link` field (The Group's website) for the group as a string if present. +### getName() {#group-name} +~~~~ +public string|null getName()~~~~ +Returns the `name` field (The name of the Group) for the group as a string if present. +### getMemberRequestCount() {#group-member_request_count} +~~~~ +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() {#group-owner} +~~~~ +public GraphNode|null getOwner()~~~~ +Returns the `owner` field (The profile that created this Group) for the group as a GraphNode if present. +### getParent() {#group-parent} +~~~~ +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() {#group-privacy} +~~~~ +public string|null getPrivacy()~~~~ +Returns the `privacy` field (The privacy setting of the Group) for the group as a string if present. +### getUpdatedTime() {#group-updated_time} +~~~~ +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() {#group-venue} +~~~~ +public GraphLocation|null getVenue()~~~~ +Returns the `venue` field (The location for the Group) for the group as a GraphLocation if present. + diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 7ef86d7b7..ce55b1433 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -359,6 +359,20 @@ public function getGraphEvent() 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. * diff --git a/src/Facebook/GraphNodes/GraphEvent.php b/src/Facebook/GraphNodes/GraphEvent.php index b90d41846..19ff2fb4a 100644 --- a/src/Facebook/GraphNodes/GraphEvent.php +++ b/src/Facebook/GraphNodes/GraphEvent.php @@ -31,14 +31,13 @@ class GraphEvent extends GraphNode { /** - * @var array Maps object key names to Graph object types. + * @var array Maps object key names to GraphNode types. */ protected static $graphObjectMap = [ 'cover' => '\Facebook\GraphNodes\GraphCoverPhoto', 'place' => '\Facebook\GraphNodes\GraphPage', 'picture' => '\Facebook\GraphNodes\GraphPicture', - // @todo parent_group must be cast to GraphGroup once supported - // 'parent_group' => '\Facebook\GraphNodes\GraphGroup', + 'parent_group' => '\Facebook\GraphNodes\GraphGroup', ]; /** @@ -102,7 +101,7 @@ public function getName() } /** - * Returns the `owner` (The profile that created the event) as GraphObject if present. + * Returns the `owner` (The profile that created the event) as GraphNode if present. * * @return GraphNode|null */ @@ -112,9 +111,9 @@ public function getOwner() } /** - * Returns the `parent_group` (The group the event belongs to) as GraphObject if present. + * Returns the `parent_group` (The group the event belongs to) as GraphGroup if present. * - * @return GraphNode|null + * @return GraphGroup|null */ public function getParentGroup() { diff --git a/src/Facebook/GraphNodes/GraphGroup.php b/src/Facebook/GraphNodes/GraphGroup.php new file mode 100644 index 000000000..07a4dbd75 --- /dev/null +++ b/src/Facebook/GraphNodes/GraphGroup.php @@ -0,0 +1,171 @@ + '\Facebook\GraphNodes\GraphCoverPhoto', + 'venue' => '\Facebook\GraphNodes\GraphLocation', + ]; + + /** + * Returns the `id` (The Group ID) as string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns the `cover` (The cover photo of the Group) as GraphCoverPhoto if present. + * + * @return GraphCoverPhoto|null + */ + public function getCover() + { + return $this->getField('cover'); + } + + /** + * Returns the `description` (A brief description of the Group) as string if present. + * + * @return string|null + */ + public function getDescription() + { + 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() + { + return $this->getField('email'); + } + + /** + * Returns the `icon` (The URL for the Group's icon) as string if present. + * + * @return string|null + */ + public function getIcon() + { + return $this->getField('icon'); + } + + /** + * Returns the `link` (The Group's website) as string if present. + * + * @return string|null + */ + public function getLink() + { + return $this->getField('link'); + } + + /** + * Returns the `name` (The name of the Group) as string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getField('name'); + } + + /** + * Returns the `member_request_count` (Number of people asking to join the group.) as int if present. + * + * @return int|null + */ + public function getMemberRequestCount() + { + return $this->getField('member_request_count'); + } + + /** + * Returns the `owner` (The profile that created this Group) as GraphNode if present. + * + * @return GraphNode|null + */ + public function getOwner() + { + 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() + { + return $this->getField('parent'); + } + + /** + * Returns the `privacy` (The privacy setting of the Group) as string if present. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getField('privacy'); + } + + /** + * 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() + { + return $this->getField('updated_time'); + } + + /** + * Returns the `venue` (The location for the Group) as GraphLocation if present. + * + * @return GraphLocation|null + */ + public function getVenue() + { + return $this->getField('venue'); + } + +} diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index e20ddf714..e1bedd910 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -167,6 +167,18 @@ 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. * diff --git a/tests/GraphNodes/GraphEventTest.php b/tests/GraphNodes/GraphEventTest.php index b6ed0d11d..98ccd8565 100644 --- a/tests/GraphNodes/GraphEventTest.php +++ b/tests/GraphNodes/GraphEventTest.php @@ -39,12 +39,10 @@ public function setUp() $this->responseMock = m::mock('\Facebook\FacebookResponse'); } - public function testDatesGetCastToDateTime() + public function testCoverGetsCastAsGraphCoverPhoto() { $dataFromGraph = [ - 'end_time' => '2015-04-14T11:00:00+0300', - 'start_time' => '2015-04-14T11:00:00+0300', - 'updated_time' => '2015-04-14T11:00:00+0300', + 'cover' => ['id' => '1337'] ]; $this->responseMock @@ -54,18 +52,14 @@ public function testDatesGetCastToDateTime() $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); - $end_time = $graphObject->getEndTime(); - $this->assertInstanceOf('DateTime', $end_time); - $start_time = $graphObject->getStartTime(); - $this->assertInstanceOf('DateTime', $start_time); - $updated_time = $graphObject->getUpdatedTime(); - $this->assertInstanceOf('DateTime', $updated_time); + $cover = $graphObject->getCover(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); } - public function testCoverGetsCastAsGraphCoverPhoto() + public function testPlaceGetsCastAsGraphPage() { $dataFromGraph = [ - 'cover' => ['id' => '1337'] + 'place' => ['id' => '1337'] ]; $this->responseMock @@ -75,14 +69,14 @@ public function testCoverGetsCastAsGraphCoverPhoto() $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); - $cover = $graphObject->getCover(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); + $place = $graphObject->getPlace(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphPage', $place); } - public function testPlaceGetsCastAsGraphPage() + public function testPictureGetsCastAsGraphPicture() { $dataFromGraph = [ - 'place' => ['id' => '1337'] + 'picture' => ['id' => '1337'] ]; $this->responseMock @@ -92,14 +86,14 @@ public function testPlaceGetsCastAsGraphPage() $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); - $place = $graphObject->getPlace(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphPage', $place); + $picture = $graphObject->getPicture(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphPicture', $picture); } - public function testPictureGetsCastAsGraphPicture() + public function testParentGroupGetsCastAsGraphGroup() { $dataFromGraph = [ - 'picture' => ['id' => '1337'] + 'parent_group' => ['id' => '1337'] ]; $this->responseMock @@ -109,7 +103,7 @@ public function testPictureGetsCastAsGraphPicture() $factory = new GraphNodeFactory($this->responseMock); $graphObject = $factory->makeGraphEvent(); - $picture = $graphObject->getPicture(); - $this->assertInstanceOf('\Facebook\GraphNodes\GraphPicture', $picture); + $parentGroup = $graphObject->getParentGroup(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphGroup', $parentGroup); } } diff --git a/tests/GraphNodes/GraphGroupTest.php b/tests/GraphNodes/GraphGroupTest.php new file mode 100644 index 000000000..21893b54a --- /dev/null +++ b/tests/GraphNodes/GraphGroupTest.php @@ -0,0 +1,75 @@ +responseMock = m::mock('\Facebook\FacebookResponse'); + } + + public function testCoverGetsCastAsGraphCoverPhoto() + { + $dataFromGraph = [ + 'cover' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphGroup(); + + $cover = $graphNode->getCover(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphCoverPhoto', $cover); + } + + public function testVenueGetsCastAsGraphLocation() + { + $dataFromGraph = [ + 'venue' => ['id' => '1337'] + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphGroup(); + + $venue = $graphNode->getVenue(); + $this->assertInstanceOf('\Facebook\GraphNodes\GraphLocation', $venue); + } +} From 8ed147b9c2a94db75b04512828cd154bab8f2467 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 16 Jun 2015 15:19:30 -0700 Subject: [PATCH 162/407] Doc updates during loading. --- docs/Facebook.fbmd | 28 ++++++------ docs/FacebookApp.fbmd | 4 +- docs/sdk_downloads.fbmd | 65 ++++++++++++++++++++++++-- docs/sdk_getting_started.fbmd | 32 ++++++------- docs/sdk_landing_page.fbmd | 8 ++-- docs/sdk_reference.fbmd | 86 +++++++++++++++++------------------ 6 files changed, 139 insertions(+), 84 deletions(-) diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 103b87cf3..8bf5deab6 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -61,22 +61,22 @@ $fb = new Facebook\Facebook([ ]); ~~~~ -### `app_id` +### `app_id` {#appid} The ID of your Facebook app (required). -### `app_secret` +### `app_secret` {#appsecret} The secret of your Facebook app (required). -### `default_access_token` +### `default_access_token` {#defaulttoken} 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/support/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`. +### `enable_beta_mode` {#enablebeta} +Enable [beta mode](/docs/support/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` +### `default_graph_version` {#defaultversion} 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.0`. Defaults to the latest version of Graph. -### `http_client_handler` +### `http_client_handler` {#httpclient} 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`. @@ -93,7 +93,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -### `persistent_data_handler` +### `persistent_data_handler` {#datahandler} 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`. @@ -108,7 +108,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -### `url_detection_handler` +### `url_detection_handler` {#urlhandler} 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](/docs/php/UrlDetectionInterface)` and set the value of `url_detection_handler` to an instance of your custom URL detector. @@ -121,7 +121,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -### `pseudo_random_string_generator` +### `pseudo_random_string_generator` {#prsg} 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. @@ -260,7 +260,7 @@ $fb->get('/me'); 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/reference/ads-api/etags-reference/). Set this to the eTag from a previous request to get a `304 Not Modified` response if the data has not changed. +[Graph supports eTags](/docs/reference/ads-api/etags-reference/). 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. @@ -373,7 +373,7 @@ 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/#operations). +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](/docs/graph-api/making-multiple-requests/#operations). ~~~~ $requests = [ @@ -406,7 +406,7 @@ $helper = $fb->getRedirectLoginHelper(); public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() ~~~~ -Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) which is used to access the signed request stored in the cookie set by the JavaScript SDK. +Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) which is used to access the signed request stored in the cookie set by the SDK for JavaScript. ~~~~ $helper = $fb->getJavaScriptHelper(); @@ -518,7 +518,7 @@ echo 'Photo ID: ' . $graphNode['id']; 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 PHP SDK will automatically point the request to the `graph-video.facebook.com` host name for you. +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. ~~~~ // Upload a video for a user diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index 65e73b589..64f3f5207 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -1,7 +1,7 @@ # 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. +In order to make requests to the Graph API, you need to [create a Facebook app](/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. %FB(devsite:markdown-wiki:info-card { content: "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.", @@ -25,7 +25,7 @@ $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 PHP SDK. But this entity plays an important role in the internal workings of the PHP SDK. +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. diff --git a/docs/sdk_downloads.fbmd b/docs/sdk_downloads.fbmd index cf10f37b7..93b3f91e8 100644 --- a/docs/sdk_downloads.fbmd +++ b/docs/sdk_downloads.fbmd @@ -3,13 +3,68 @@ For full details on what changed between each version release, see the [CHANGELOG](https://github.com/facebook/facebook-php-sdk-v4/blob/master/CHANGELOG.md). -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Package','Date','Change Summary',], rows: [ [ - '[Facebook SDK 4.1.0](https://github.com/facebook/facebook-php-sdk-v4/archive/4.1.0.zip)', - 'TBD', - 'New API, removed statics', + '[Facebook SDK 5.0.0](https://github.com/facebook/facebook-php-sdk-v4/archive/5.0.0.zip)', + 'July 1, 2015', + 'New API, a major refactoring driven by the community, removed statics', + ], + [ + '[Facebook SDK 4.0.23](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.23.zip)', + 'April 3, 2015', + 'Redirect login helper response handling updates', + ], + [ + '[Facebook SDK 4.0.22](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.22.zip)', + 'April 2, 2015', + 'Graph v2.3 support, array handling updates', + ], + [ + '[Facebook SDK 4.0.21](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.21.zip)', + 'March 31, 2015', + 'Added FacebookPermissions enum', + ], + [ + '[Facebook SDK 4.0.20](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.20.zip)', + 'March 2, 2015', + 'Bug fixes', + ], + [ + '[Facebook SDK 4.0.19](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.19.zip)', + 'March 2, 2015', + 'Updated CSRF validation to use constant-time evaluation', + ], + [ + '[Facebook SDK 4.0.18](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.18.zip)', + 'February 24, 2015', + 'Revert unintended breaking change in 4.0.17', + ], + [ + '[Facebook SDK 4.0.17](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.17.zip)', + 'February 19, 2015', + 'Graph video support, bug fixes', + ], + [ + '[Facebook SDK 4.0.16](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.16.zip)', + 'February 3, 2015', + 'Reauthentication and curl updates', + ], + [ + '[Facebook SDK 4.0.15](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.15.zip)', + 'January 6, 2015', + 'Prevent generating a logout URL for app access tokens', + ], + [ + '[Facebook SDK 4.0.14](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.14.zip)', + 'December 29, 2014', + 'Updates to GraphUser/GraphAlbum, expanded CSRF protection', + ], + [ + '[Facebook SDK 4.0.13](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.13.zip)', + 'December 12, 2014', + 'Updated certificate handling, composer details, bug fixes', ], [ '[Facebook SDK 4.0.12](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.12.zip)', @@ -39,7 +94,7 @@ FB(devsite:markdown-wiki:table { [ '[Facebook SDK 4.0.7](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.7.zip)', 'May 31, 2014', - 'Added `FacebookPageTabHelper`', + 'Added FacebookPageTabHelper', ], [ '[Facebook SDK 4.0.6](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.6.zip)', diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 8a5a5e963..ebb7e2c0d 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -1,13 +1,13 @@ # 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 PHP SDK does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. +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 {#psr-4} -The Facebook PHP SDK 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. +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. @@ -23,7 +23,7 @@ It would be advantageous to familiarize yourself with the concepts of [namespaci ## Installing the Facebook SDK for PHP {#installation} -There are two methods to install the Facebook PHP SDK. The recommended installation method is by using [Composer](#install-composer). If are unable to use Composer for your project, you can still [install the SDK manually](#install-manually) by downloading the source files and including the autoloader. +There are two methods to install the Facebook SDK for PHP. The recommended installation method is by using [Composer](#install-composer). If are unable to use Composer for your project, you can still [install the SDK manually](#install-manually) by downloading the source files and including the autoloader. @@ -59,7 +59,7 @@ require_once __DIR__ . '/vendor/autoload.php'; First, download the source code and unzip it wherever you like in your project. %FB(devsite:markdown-wiki:button { - text: 'Download the PHP SDK v5.0', + text: 'Download the SDK for PHP v5.0', href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/5.0-dev.zip', size: 'large', use: 'special', @@ -74,7 +74,7 @@ require_once __DIR__ . '/path/to/facebook-php-sdk-v4/src/Facebook/autoload.php'; The autoloader should be able to auto-detect the proper location of the source code. -### Keeping things tidy +### Keeping things tidy {#tidy-up} 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. @@ -85,7 +85,7 @@ The source code includes myriad files that aren't necessary for use in a product 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 3rd-party code. For this example we'll rename the `Facebook` directory to `facebook-sdk-v5`. +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 `autolaoder.php` file. @@ -107,7 +107,7 @@ require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; ## Configuration and setup {#setup} %FB(devsite:markdown-wiki:info-card { - content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](http://developers.facebook.com/apps).", + content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](/apps).", type: 'warning', }) @@ -121,14 +121,14 @@ $fb = new Facebook\Facebook([ ]); ~~~ -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](http://developers.facebook.com/apps). +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](/apps). %FB(devsite:markdown-wiki:info-card { - content: "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 PHP SDK will choose one for you and it might not be one that is compatible with your app.", + content: "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.", type: 'warning', }) -The `Facebook\Facebook` service ties all the components of the PHP SDK together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). +The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). @@ -196,7 +196,7 @@ if (isset($accessToken)) { If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) to get an [`AccessToken`](/docs/php/AccessToken) entity for the user. %FB(devsite:markdown-wiki:info-card { - content: "The `FacebookCanvasHelper` will detect a [signed request](https://developers.facebook.com/docs/reference/login/signed-request) 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](#authentication-redirect) or by using the [JavaScript SDK](https://developers.facebook.com/docs/javascript) and then use the PHP SDK to [obtain the access token from the cookie](#authentication-javascript) the JavaScript SDK set.", + content: "The `FacebookCanvasHelper` will detect a [signed request](/docs/reference/login/signed-request) 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](#authentication-redirect) or by using the [SDK for JavaScript](/docs/javascript) and then use the SDK for PHP to [obtain the access token from the cookie](#authentication-javascript) the SDK for JavaScript set.", type: 'warning', }) @@ -228,7 +228,7 @@ if (isset($accessToken)) { }) -### Obtaining an access token from the JavaScript SDK {#authentication-javascript} +### Obtaining an access token from the SDK for JavaScript {#authentication-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](/docs/php/FacebookJavaScriptHelper). The `getAccessToken()` method will return an [`AccessToken`](/docs/php/AccessToken) entity. @@ -255,7 +255,7 @@ if (isset($accessToken)) { ~~~ %FB(devsite:markdown-wiki:info-card { - content: "Make sure you set the `{cookie:true}` option when you [initialize the JavaScript SDK](https://developers.facebook.com/docs/javascript/reference/FB.init). This will make the JavaScript SDK set a cookie on your domain containing information about the user in the form of a signed request.", + content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](/docs/javascript/reference/FB.init). 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.", type: 'warning', }) @@ -275,7 +275,7 @@ $oAuth2Client = $fb->getOAuth2Client(); $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken('{access-token}'); ~~~ -[See more about long-lived and short-lived access tokens](https://developers.facebook.com/docs/facebook-login/access-tokens#extending). +[See more about long-lived and short-lived access tokens](/docs/facebook-login/access-tokens#extending). @@ -283,7 +283,7 @@ $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken('{access-token}') 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. +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](/docs/graph-api/reference/user) that references the user or Page making the request. ~~~ $fb = new Facebook\Facebook([/* . . . */]); @@ -324,5 +324,5 @@ try { $plainOldArray = $response->getDecodedBody(); ~~~ -For a full list of all of the components that make up the PHP SDK, see the [PHP SDK reference page](/docs/php/reference). +For a full list of all of the components that make up the SDK for PHP, see the [SDK for PHP reference page](/docs/php/reference). diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd index 4d231600a..d59701e43 100644 --- a/docs/sdk_landing_page.fbmd +++ b/docs/sdk_landing_page.fbmd @@ -1,9 +1,9 @@ # Facebook SDK v5 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](/docs/reference/javascript/) to give the front-end user the best possible user experience. But it doesn't end there, the Facebook PHP SDK makes it easy to upload photos and videos and send batch requests to the Graph API among other things. And PHP SDK has many extensibility points giving PHP developers full control of how the PHP SDK interacts with their specific hosting environment and web framework. +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](/docs/reference/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 PHP SDK does all the heavy lifting for you making it as easy as possible to deeply integrate into the Facebook platform. +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](/docs/php/gettingstarted) guide, and then check out some of the examples below. @@ -11,11 +11,11 @@ For installation & implementation instructions, look through the [Getting Starte ## Examples {#examples} -The following examples demonstrate how you would accomplish common tasks with the Facebook PHP SDK. +The following examples demonstrate how you would accomplish common tasks with the Facebook SDK for PHP. - **Authentication & Signed Requests** - [Facebook Login (OAuth 2.0)](/docs/php/howto/example_facebook_login) - - [Obtaining an access token from the JavaScript SDK](/docs/php/howto/example_access_token_from_javascript) + - [Obtaining an access token from the SDK for JavaScript](/docs/php/howto/example_access_token_from_javascript) - [Obtaining an access token within a Facebook Canvas context](/docs/php/howto/example_access_token_from_canvas) - [Obtaining an access token within a Facebook Page tab context](/docs/php/howto/example_access_token_from_page_tab) - **User profile** diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 390c9f292..2ab60bb16 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -1,23 +1,23 @@ # Facebook SDK for PHP Reference (v5) -Below is the API reference for the Facebook PHP SDK. +Below is the API reference for the Facebook SDK for PHP. # Core API {#core-api} -These classes are at the core of the Facebook PHP SDK. +These classes are at the core of the Facebook SDK for PHP. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\Facebook`](/docs/php/Facebook)', + '[`Facebook\\Facebook`](/docs/php/Facebook)', 'The main service object that helps tie all the SDK components together.', ], [ - '[`Facebook\FacebookApp`](/docs/php/FacebookApp)', + '[`Facebook\\FacebookApp`](/docs/php/FacebookApp)', 'An entity that represents a Facebook app and is required to send requests to Graph.', ], ], @@ -29,23 +29,23 @@ FB(devsite:markdown-wiki:table { These classes facilitate authenticating a Facebook user with OAuth 2.0. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper)', + '[`Facebook\\Helpers\\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper)', 'An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link.', ], [ - '[`Facebook\Authentication\AccessToken`](/docs/php/AccessToken)', + '[`Facebook\\Authentication\\AccessToken`](/docs/php/AccessToken)', 'An entity that represents an access token.', ], [ - '`Facebook\Authentication\AccessTokenMetadata`', + '`Facebook\\Authentication\\AccessTokenMetadata`', 'An entity that represents metadata from an access token.', ], [ - '`Facebook\Authentication\OAuth2Client`', + '`Facebook\\Authentication\\OAuth2Client`', 'An OAuth 2.0 client that sends and receives HTTP requests related to user authentication.', ], ], @@ -57,27 +57,27 @@ FB(devsite:markdown-wiki:table { These classes are used in a Graph API request/response cycle. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\FacebookRequest`](/docs/php/FacebookRequest)', + '[`Facebook\\FacebookRequest`](/docs/php/FacebookRequest)', 'An entity that represents an HTTP request to be sent to Graph.', ], [ - '[`Facebook\FacebookResponse`](/docs/php/FacebookResponse)', + '[`Facebook\\FacebookResponse`](/docs/php/FacebookResponse)', 'An entity that represents an HTTP response from Graph.', ], [ - '[`Facebook\FacebookBatchRequest`](/docs/php/FacebookBatchRequest)', + '[`Facebook\\FacebookBatchRequest`](/docs/php/FacebookBatchRequest)', 'An entity that represents an HTTP batch request to be sent to Graph.', ], [ - '[`Facebook\FacebookBatchResponse`](/docs/php/FacebookBatchResponse)', + '[`Facebook\\FacebookBatchResponse`](/docs/php/FacebookBatchResponse)', 'An entity that represents an HTTP response from Graph after sending a batch request.', ], [ - '[`Facebook\FacebookClient`](/docs/php/FacebookClient)', + '[`Facebook\\FacebookClient`](/docs/php/FacebookClient)', 'A service object that sends HTTP requests and receives HTTP responses to and from the Graph API.', ], ], @@ -89,23 +89,23 @@ FB(devsite:markdown-wiki:table { Classes to help obtain and manage signed requests. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper)', + '[`Facebook\\Helpers\\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper)', 'Used to obtain an access token or signed request from the cookie set by the JavaScript SDK.', ], [ - '[`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper)', + '[`Facebook\\Helpers\\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper)', 'Used to obtain an access token or signed request from within the context of an app canvas.', ], [ - '[`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper)', + '[`Facebook\\Helpers\\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper)', 'Used to obtain an access token or signed request from within the context of a page tab.', ], [ - '[`Facebook\SignedRequest`](/docs/php/SignedRequest)', + '[`Facebook\\SignedRequest`](/docs/php/SignedRequest)', 'An entity that represents a signed request.', ], ], @@ -117,15 +117,15 @@ FB(devsite:markdown-wiki:table { These are the core exceptions that the SDK will throw when an error occurs. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException)', + '[`Facebook\\Exceptions\\FacebookSDKException`](/docs/php/FacebookSDKException)', 'The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error.', ], [ - '[`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException)', + '[`Facebook\\Exceptions\\FacebookResponseException`](/docs/php/FacebookResponseException)', 'The base exception to all Graph error responses. This exception is never thrown directly.', ], ], @@ -137,39 +137,39 @@ FB(devsite:markdown-wiki:table { 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. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode)', + '[`Facebook\\GraphNodes\\GraphNode`](/docs/php/GraphNode)', 'The base collection object that represents a generic node.', ], [ - '[`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge)', - 'A collection of GraphNode's with special methods to help paginate over the edge.', + '[`Facebook\\GraphNodes\\GraphEdge`](/docs/php/GraphEdge)', + 'A collection of GraphNode\'s with special methods to help paginate over the edge.', ], [ - '[`Facebook\GraphNodes\GraphAchievement`](/docs/php/GraphNode#achievement-instance-methods)', + '[`Facebook\\GraphNodes\\GraphAchievement`](/docs/php/GraphNode#achievement-instance-methods)', 'A collection that represents an Achievement node.', ], [ - '[`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods)', + '[`Facebook\\GraphNodes\\GraphAlbum`](/docs/php/GraphNode#album-instance-methods)', 'A collection that represents an Album node.', ], [ - '[`Facebook\GraphNodes\GraphLocation`](/docs/php/GraphNode#location-instance-methods)', + '[`Facebook\\GraphNodes\\GraphLocation`](/docs/php/GraphNode#location-instance-methods)', 'A collection that represents a Location node.', ], [ - '[`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPage`](/docs/php/GraphNode#page-instance-methods)', 'A collection that represents a Page node.', ], [ - '[`Facebook\GraphNodes\GraphPicture`](/docs/php/GraphNode#picture-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPicture`](/docs/php/GraphNode#picture-instance-methods)', 'A collection that represents a Picture node.', ], [ - '[`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods)', + '[`Facebook\\GraphNodes\\GraphUser`](/docs/php/GraphNode#user-instance-methods)', 'A collection that represents a User node.', ], ], @@ -181,15 +181,15 @@ FB(devsite:markdown-wiki:table { These are entities that represent files to be uploaded with a Graph request. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '[`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile)', + '[`Facebook\\FileUpload\\FacebookFile`](/docs/php/FacebookFile)', 'Represents a generic file to be uploaded to the Graph API.', ], [ - '[`Facebook\FileUpload\FacebookVideo`](/docs/php/FacebookVideo)', + '[`Facebook\\FileUpload\\FacebookVideo`](/docs/php/FacebookVideo)', 'Represents a video file to be uploaded to the Graph API.', ], ], @@ -201,27 +201,27 @@ FB(devsite:markdown-wiki:table { You can overwrite certain functionality of the SDK by coding to an interface and injecting an instance of your custom functionality. -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Interface name','Description',], rows: [ [ - '`Facebook\HttpClients\FacebookHttpClientInterface`', + '`Facebook\\HttpClients\\ FacebookHttpClientInterface`', 'An interface to code your own HTTP client implementation.', ], [ - '`Facebook\Http\GraphRawResponse`', + '`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`](/docs/php/PersistentDataInterface)', + '[`Facebook\\PersistentData\\PersistentDataInterface`](/docs/php/PersistentDataInterface)', 'An interface to code your own persistent data storage implementation.', ], [ - '[`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface)', + '[`Facebook\\Url\\UrlDetectionInterface`](/docs/php/UrlDetectionInterface)', 'An interface to code your own URL detection logic.', ], [ - '[`Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface`](/docs/php/PseudoRandomStringGeneratorInterface)', + '[`Facebook\\PseudoRandomString\\ PseudoRandomStringGeneratorInterface`](/docs/php/PseudoRandomStringGeneratorInterface)', 'An interface to code your own cryptographically secure pseudo-random string generator.', ], ], From ebeced494db65aca0e33c4219fad2e17c17f4002 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 7 Jul 2015 23:26:40 -0700 Subject: [PATCH 163/407] Updates made while loading to dev site. --- docs/Facebook.fbmd | 90 +++++-------------- docs/FacebookApp.fbmd | 16 +--- docs/FacebookFile.fbmd | 2 +- docs/FacebookRedirectLoginHelper.fbmd | 2 +- docs/FacebookResponseException.fbmd | 20 ++--- docs/FacebookVideo.fbmd | 2 +- docs/GraphNode.fbmd | 121 ++++++++++++++++---------- docs/PersistentDataInterface.fbmd | 2 +- docs/example_facebook_login.fbmd | 22 +++-- 9 files changed, 131 insertions(+), 146 deletions(-) diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 8bf5deab6..f50b1df75 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -158,62 +158,48 @@ $fb = new Facebook\Facebook(); -## Instance Methods {#instance-methods} +# Instance Methods {#instance-methods} -### getApp() {#get-app} +## getApp() {#get-app} ~~~~ public FacebookApp getApp() ~~~~ Returns the instance of `Facebook\FacebookApp` for the instantiated service. - - -### getClient() {#get-client} +## getClient() {#get-client} ~~~~ public Facebook\FacebookClient getClient() ~~~~ Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) for the instantiated service. - - -### getOAuth2Client() {#get-oauth2-client} +## getOAuth2Client() {#get-oauth2-client} ~~~~ public Facebook\Authentication\OAuth2Client getOAuth2Client() ~~~~ Returns an instance of [`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client). - - -### getLastResponse() {#get-last-response} +## getLastResponse() {#get-last-response} ~~~~ 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() {#get-url-detection-handler} +## getUrlDetectionHandler() {#get-url-detection-handler} ~~~~ public Facebook\Url\UrlDetectionInterface getUrlDetectionHandler() ~~~~ Returns an instance of [`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface). - - -### getDefaultAccessToken() {#get-default-access-token} +## getDefaultAccessToken() {#get-default-access-token} ~~~~ public Facebook\Authentication\AccessToken|null getDefaultAccessToken() ~~~~ - Returns the default fallback [`AccessToken`](/docs/php/AccessToken) 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() {#set-default-access-token} +## setDefaultAccessToken() {#set-default-access-token} ~~~~ 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`](/docs/php/AccessToken). ~~~~ @@ -226,18 +212,14 @@ $fb->setDefaultAccessToken($accessToken); ~~~~ This setting will overwrite the value from `default_access_token` option if it was passed to the `Facebook\Facebook` constructor. - - -### getDefaultGraphVersion() {#get-default-graph-version} +## getDefaultGraphVersion() {#get-default-graph-version} ~~~~ 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() {#get} +## get() {#get} ~~~~ public Facebook\FacebookResponse get( string $endpoint, @@ -264,10 +246,8 @@ The access token (as a string or `AccessToken` entity) to use for the request. I `$graphVersion` This will overwrite the Graph version that was set in the `default_graph_version` configuration option. - - -### post() {#post} +## post() {#post} ~~~~ public Facebook\FacebookResponse post( string $endpoint, @@ -288,10 +268,8 @@ The associative array of params you want to send in the body of the POST request ~~~~ $response = $fb->post('/me/feed', ['message' => 'Foo message']); ~~~~ - - -### delete() {#delete} +## delete() {#delete} ~~~~ public Facebook\FacebookResponse delete( string $endpoint, @@ -309,10 +287,8 @@ The arguments are the same as `post()` above. ~~~~ $response = $fb->delete('/{node-id}', ['object' => '1234']); ~~~~ - - -### request() {#request} +## request() {#request} ~~~~ public Facebook\FacebookRequest request( string $method, @@ -334,10 +310,8 @@ The HTTP request verb to use for this request. This can be set to any verb that ~~~~ $request = $fb->request('GET', '/{node-id}'); ~~~~ - - -### sendRequest() {#send-request} +## sendRequest() {#send-request} ~~~~ public Facebook\FacebookResponse sendRequest( string $method, @@ -354,10 +328,8 @@ Sends a request to the Graph API. ~~~~ $response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.2'); ~~~~ - - -### sendBatchRequest() {#send-batch-request} +## sendBatchRequest() {#send-batch-request} ~~~~ public Facebook\FacebookBatchResponse sendBatchRequest( array $requests, @@ -385,10 +357,8 @@ $batchResponse = $fb->sendBatchRequest($requests); ~~~~ [See a full batch example](/docs/php/howto/example_batch_request). - - -### getRedirectLoginHelper() {#get-redirect-login-helper} +## getRedirectLoginHelper() {#get-redirect-login-helper} ~~~~ public Facebook\Helpers\FacebookRedirectLoginHelper getRedirectLoginHelper() ~~~~ @@ -398,10 +368,8 @@ Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRed ~~~~ $helper = $fb->getRedirectLoginHelper(); ~~~~ - - -### getJavaScriptHelper() {#get-javascript-helper} +## getJavaScriptHelper() {#get-javascript-helper} ~~~~ public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() ~~~~ @@ -411,10 +379,8 @@ Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaSc ~~~~ $helper = $fb->getJavaScriptHelper(); ~~~~ - - -### getCanvasHelper() {#get-canvas-helper} +## getCanvasHelper() {#get-canvas-helper} ~~~~ public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() ~~~~ @@ -424,10 +390,8 @@ Returns a [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelp ~~~~ $helper = $fb->getCanvasHelper(); ~~~~ - - -### getPageTabHelper() {#get-page-tab-helper} +## getPageTabHelper() {#get-page-tab-helper} ~~~~ public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() ~~~~ @@ -437,10 +401,8 @@ Returns a [`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHe ~~~~ $helper = $fb->getPageTabHelper(); ~~~~ - - -### next() {#next} +## next() {#next} ~~~~ public Facebook\GraphNodes\GraphEdge|null next(Facebook\GraphNodes\GraphEdge $graphEdge) ~~~~ @@ -473,19 +435,15 @@ if (count($photosEdge) > 0) { } while ($pageCount < $maxPages && $photosEdge = $fb->next($photosEdge)); } ~~~~ - - -### previous() {#previous} +## previous() {#previous} ~~~~ 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() {#file-to-upload} +## fileToUpload() {#file-to-upload} ~~~~ public Facebook\FileUpload\FacebookFile fileToUpload(string $pathToFile) ~~~~ @@ -510,10 +468,8 @@ $graphNode = $response->getGraphNode(); echo 'Photo ID: ' . $graphNode['id']; ~~~~ - - -### videoToUpload() {#video-to-upload} +## videoToUpload() {#video-to-upload} ~~~~ public Facebook\FileUpload\FacebookVideo videoToUpload(string $pathToVideoFile) ~~~~ diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index 64f3f5207..e17b09a24 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -4,7 +4,7 @@ In order to make requests to the Graph API, you need to [create a Facebook app](/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. %FB(devsite:markdown-wiki:info-card { - content: "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.", + content: "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.", type: 'warning', }) @@ -26,35 +26,27 @@ $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 {#instance-methods} -### getAccessToken() {#get-access-token} +## getAccessToken() {#get-access-token} ~~~~ public Facebook\Authentication\AccessToken getAccessToken() ~~~~ Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessToken) entity. - - -### getId() {#get-id} +## getId() {#get-id} ~~~~ public string getId() ~~~~ Returns an the app id. - - -### getSecret() {#get-secret} +## getSecret() {#get-secret} ~~~~ public string getSecret() ~~~~ Returns an the app secret. - - ## Serialization {#serialization} The `Facebook\FacebookApp` entity can be serialized and unserialized. diff --git a/docs/FacebookFile.fbmd b/docs/FacebookFile.fbmd index b4ef44cd1..3242b8a7a 100644 --- a/docs/FacebookFile.fbmd +++ b/docs/FacebookFile.fbmd @@ -1,7 +1,7 @@ # File Uploading with the Facebook SDK for PHP -Uploading files to the Graph API is made a breeze with the PHP SDK. +Uploading files to the Graph API is made a breeze with the Facebook SDK for PHP. diff --git a/docs/FacebookRedirectLoginHelper.fbmd b/docs/FacebookRedirectLoginHelper.fbmd index 249c1627a..97bd57d8d 100644 --- a/docs/FacebookRedirectLoginHelper.fbmd +++ b/docs/FacebookRedirectLoginHelper.fbmd @@ -7,7 +7,7 @@ The most commonly used helper is the `FacebookRedirectLoginHelper` which allows ## Usage {#usage} -Facebook Login is achieved via OAuth 2.0. But you don't really have to know much about OAuth 2.0 since the PHP SDK does all the heavy lifting for you. +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 diff --git a/docs/FacebookResponseException.fbmd b/docs/FacebookResponseException.fbmd index c7778dbf1..a0eda9217 100644 --- a/docs/FacebookResponseException.fbmd +++ b/docs/FacebookResponseException.fbmd @@ -9,7 +9,7 @@ Represents an error response from the Graph API. 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) { @@ -18,39 +18,39 @@ try { // Do some further processing on $previousException exit; } -``` +~~~~ -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], rows: [ [ - '`Facebook\Exceptions\FacebookAuthenticationException`', + '`Facebook\\Exceptions\\FacebookAuthenticationException`', 'Thrown when Graph returns an authentication error.', ], [ - '`Facebook\Exceptions\FacebookAuthorizationException`', + '`Facebook\\Exceptions\\FacebookAuthorizationException`', 'Thrown when Graph returns a user permissions error.', ], [ - '`Facebook\Exceptions\FacebookClientException`', + '`Facebook\\Exceptions\\FacebookClientException`', 'Thrown when Graph returns a duplicate post error.', ], [ - '`Facebook\Exceptions\FacebookOtherException`', + '`Facebook\\Exceptions\\FacebookOtherException`', 'Thrown when Graph returns an error that is unknown to the SDK.', ], [ - '`Facebook\Exceptions\FacebookServerException`', + '`Facebook\\Exceptions\\FacebookServerException`', 'Thrown when Graph returns a server error.', ], [ - '`Facebook\Exceptions\FacebookThrottleException`', + '`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). +These exceptions are derived from the [error responses from the Graph API](/docs/graph-api/using-graph-api/#errors). diff --git a/docs/FacebookVideo.fbmd b/docs/FacebookVideo.fbmd index 24614aaf2..f24242b77 100644 --- a/docs/FacebookVideo.fbmd +++ b/docs/FacebookVideo.fbmd @@ -1,7 +1,7 @@ # Video Uploading with the Facebook SDK for PHP -Uploading video files to the Graph API is made a breeze with the PHP SDK. +Uploading video files to the Graph API is made a breeze with the SDK for PHP. diff --git a/docs/GraphNode.fbmd b/docs/GraphNode.fbmd index 6be7676af..66ca76aae 100644 --- a/docs/GraphNode.fbmd +++ b/docs/GraphNode.fbmd @@ -108,20 +108,20 @@ The `GraphUser` collection represents a [User](https://developers.facebook.com/d The following properties on the `GraphUser` collection will get automatically cast as `GraphNode` subtypes: -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Property','GraphNode subtype',], rows: [ [ '`hometown`', - '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', ], [ '`location`', - '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', ], [ '`significant_other`', - '[`Facebook\GraphNodes\GraphUser`](#user-instance-methods)', + '[`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods)', ], ], }) @@ -198,20 +198,20 @@ The `GraphPage` collection represents a [Page](https://developers.facebook.com/d The following properties on the `GraphPage` collection will get automatically cast as `GraphNode` subtypes: -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Property','GraphNode subtype',], rows: [ [ '`best_page`', - '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', ], [ '`global_brand_parent_page`', - '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', ], [ '`location`', - '[`Facebook\GraphNodes\GraphLocation`](#location-instance-methods)', + '[`Facebook\\GraphNodes\\GraphLocation`](#location-instance-methods)', ], ], }) @@ -276,16 +276,16 @@ The `GraphAlbum` collection represents an [Album](https://developers.facebook.co The following properties on the `GraphAlbum` collection will get automatically cast as `GraphNode` subtypes: -FB(devsite:markdown-wiki:table { +%FB(devsite:markdown-wiki:table { columns: ['Property','GraphNode subtype',], rows: [ [ '`from`', - '[`Facebook\GraphNodes\GraphUser`](#user-instance-methods)', + '[`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods)', ], [ '`place`', - '[`Facebook\GraphNodes\GraphPage`](#page-instance-methods)', + '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', ], ], }) @@ -451,102 +451,122 @@ All getter methods return `null` if the property does not exist on the node. ### getId() {#event-id} ~~~~ -public string|null getId()~~~~ +public string|null getId() +~~~~ Returns the `id` property (The event ID) for the event as a string if present. ### getCover() {#event-cover} ~~~~ -public GraphCoverPhoto|null getCover()~~~~ +public GraphCoverPhoto|null getCover() +~~~~ Returns the `cover` property (Cover picture) for the event as a GraphCoverPhoto if present. ### getDescription() {#event-description} ~~~~ -public string|null getDescription()~~~~ +public string|null getDescription() +~~~~ Returns the `description` property (Long-form description) for the event as a string if present. ### getEndTime() {#event-end_time} ~~~~ -public DateTime|null getEndTime()~~~~ +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() {#event-is_date_only} ~~~~ -public bool|null getIsDateOnly()~~~~ +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() {#event-name} ~~~~ -public string|null getName()~~~~ +public string|null getName() +~~~~ Returns the `name` property (Event name) for the event as a string if present. ### getOwner() {#event-owner} ~~~~ -public GraphNode|null getOwner()~~~~ +public GraphNode|null getOwner() +~~~~ Returns the `owner` property (The profile that created the event) for the event as a GraphNode if present. ### getParentGroup() {#event-parent_group} ~~~~ -public GraphGroup|null getParentGroup()~~~~ +public GraphGroup|null getParentGroup() +~~~~ Returns the `parent_group` property (The group the event belongs to) for the event as a GraphGroup if present. ### getPlace() {#event-place} ~~~~ -public GraphPage|null getPlace()~~~~ +public GraphPage|null getPlace() +~~~~ Returns the `place` property (Event Place information) for the event as a GraphPage if present. ### getPrivacy() {#event-privacy} ~~~~ -public string|null getPrivacy()~~~~ +public string|null getPrivacy() +~~~~ Returns the `privacy` property (Who can see the event) for the event as a string if present. ### getStartTime() {#event-start_time} ~~~~ -public DateTime|null getStartTime()~~~~ +public DateTime|null getStartTime() +~~~~ Returns the `start_time` property (Start time) for the event as a DateTime if present. ### getTicketUri() {#event-ticket_uri} ~~~~ -public string|null getTicketUri()~~~~ +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() {#event-timezone} ~~~~ -public string|null getTimezone()~~~~ +public string|null getTimezone() +~~~~ Returns the `timezone` property (Timezone) for the event as a string if present. ### getUpdatedTime() {#event-updated_time} ~~~~ -public DateTime|null getUpdatedTime()~~~~ +public DateTime|null getUpdatedTime() +~~~~ Returns the `updated_time` property (Last update time) for the event as a DateTime if present. ### getPicture() {#event-picture} ~~~~ -public GraphPicture|null getPicture()~~~~ +public GraphPicture|null getPicture() +~~~~ Returns the `picture` property (Event picture) for the event as a GraphPicture if present. ### getAttendingCount() {#event-attending_count} ~~~~ -public int|null getAttendingCount()~~~~ +public int|null getAttendingCount() +~~~~ Returns the `attending_count` property (Number of people attending the event) for the event as a int if present. ### getDeclinedCount() {#event-declined_count} ~~~~ -public int|null getDeclinedCount()~~~~ +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() {#event-maybe_count} ~~~~ -public int|null getMaybeCount()~~~~ +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() {#event-noreply_count} ~~~~ -public int|null getNoreplyCount()~~~~ +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() {#event-invited_count} ~~~~ -public int|null getInvitedCount()~~~~ +public int|null getInvitedCount() +~~~~ Returns the `invited_count` property (Number of people invited to the event) for the event as a int if present. @@ -558,54 +578,67 @@ All getter methods return `null` if the field does not exist on the node. ### getId() {#group-id} ~~~~ -public string|null getId()~~~~ +public string|null getId() +~~~~ Returns the `id` field (The Group ID) for the group as a string if present. ### getCover() {#group-cover} ~~~~ -public GraphCoverPhoto|null getCover()~~~~ +public GraphCoverPhoto|null getCover() +~~~~ Returns the `cover` field (The cover photo of the Group) for the group as a GraphCoverPhoto if present. ### getDescription() {#group-description} ~~~~ -public string|null getDescription()~~~~ +public string|null getDescription() +~~~~ Returns the `description` field (A brief description of the Group) for the group as a string if present. ### getEmail() {#group-email} ~~~~ -public string|null getEmail()~~~~ +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() {#group-icon} ~~~~ -public string|null getIcon()~~~~ +public string|null getIcon() +~~~~ Returns the `icon` field (The URL for the Group's icon) for the group as a string if present. ### getLink() {#group-link} ~~~~ -public string|null getLink()~~~~ +public string|null getLink() +~~~~ Returns the `link` field (The Group's website) for the group as a string if present. ### getName() {#group-name} ~~~~ -public string|null getName()~~~~ +public string|null getName() +~~~~ Returns the `name` field (The name of the Group) for the group as a string if present. ### getMemberRequestCount() {#group-member_request_count} ~~~~ -public int|null getMemberRequestCount()~~~~ +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() {#group-owner} ~~~~ -public GraphNode|null getOwner()~~~~ +public GraphNode|null getOwner() +~~~~ Returns the `owner` field (The profile that created this Group) for the group as a GraphNode if present. ### getParent() {#group-parent} ~~~~ -public GraphNode|null getParent()~~~~ +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() {#group-privacy} ~~~~ -public string|null getPrivacy()~~~~ +public string|null getPrivacy() +~~~~ Returns the `privacy` field (The privacy setting of the Group) for the group as a string if present. ### getUpdatedTime() {#group-updated_time} ~~~~ -public DateTime|null getUpdatedTime()~~~~ +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() {#group-venue} ~~~~ -public GraphLocation|null getVenue()~~~~ +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/PersistentDataInterface.fbmd b/docs/PersistentDataInterface.fbmd index 8dbb605f1..f6fb4c083 100644 --- a/docs/PersistentDataInterface.fbmd +++ b/docs/PersistentDataInterface.fbmd @@ -1,7 +1,7 @@ # 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 PHP SDK uses native PHP sessions to store the persistent data. You can overwrite this behavior by coding to the `Facebook\PersistentData\PersistentDataInterface`. +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`. diff --git a/docs/example_facebook_login.fbmd b/docs/example_facebook_login.fbmd index 44d2cde3b..58473596c 100644 --- a/docs/example_facebook_login.fbmd +++ b/docs/example_facebook_login.fbmd @@ -9,11 +9,13 @@ This example covers Facebook Login with the Facebook SDK for PHP. 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 redirect the user to after the app authentication dialog is called `/fb-callback.php`. +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 + +## /login.php {#login} +~~~~ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -27,10 +29,12 @@ $loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permiss echo 'Log in with Facebook!'; ~~~~ + -~~~~ -# /fb-callback.php + +## /fb-callback.php {#fbcallback} +~~~~ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -54,10 +58,10 @@ try { if (! isset($accessToken)) { if ($helper->getError()) { header('HTTP/1.0 401 Unauthorized'); - echo "

Error: " . $helper->getError() . "

\n\n"; - echo "

Error Code: " . $helper->getErrorCode() . "

\n\n"; - echo "

Error Reason: " . $helper->getErrorReason() . "

\n\n"; - echo "

Error Description: " . $helper->getErrorDescription() . "

\n\n"; + 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'; From a662544b702ec8f735cc2038899648c7f84a2709 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 8 Jul 2015 13:44:04 -0500 Subject: [PATCH 164/407] Upgrade references to Graph v2.4 --- README.md | 2 +- docs/Facebook.fbmd | 4 ++-- src/Facebook/Facebook.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3971cb3e1..938622a4d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Simple GET example of a user's profile. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.3', + 'default_graph_version' => 'v2.4', //'default_access_token' => '{access-token}', // optional ]); diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index f50b1df75..7286a3f10 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -13,7 +13,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.3', + 'default_graph_version' => 'v2.4', // . . . ]); ~~~~ @@ -53,7 +53,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.3', + 'default_graph_version' => 'v2.4', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 3938b1746..227a16667 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -62,7 +62,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.3'; + const DEFAULT_GRAPH_VERSION = 'v2.4'; /** * @const string The name of the environment variable that contains the app ID. From b5d7e5c8b85419f9031b08a161e9030dca35f5a1 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Wed, 8 Jul 2015 12:08:57 -0700 Subject: [PATCH 165/407] Update for 5.0 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 938622a4d..7d60e6e87 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Development Version](https://img.shields.io/badge/Development%20Version-5.0-orange.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.0.0-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. @@ -15,7 +15,7 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). ```json { "require": { - "facebook/php-sdk-v4": "~5.0@dev" + "facebook/php-sdk-v4": "~5.0" } } ``` From 4a8ce9aaacb56889a505a42669db9cb09cb41879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Fri, 10 Jul 2015 18:24:35 -0400 Subject: [PATCH 166/407] Fix: Add missing import --- src/Facebook/GraphNodes/GraphObjectFactory.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 94963a023..8615990dc 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -23,6 +23,8 @@ */ namespace Facebook\GraphNodes; +use Facebook\Exceptions\FacebookSDKException; + /** * Class GraphObjectFactory * @@ -56,7 +58,7 @@ public function makeGraphObject($subclassName = null) { return $this->makeGraphNode($subclassName); } - + /** * Convenience method for creating a GraphEvent collection. * From 98a528389b2294c2443a2066c0e74cfe3e34fb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Fri, 10 Jul 2015 18:26:43 -0400 Subject: [PATCH 167/407] Fix: Method accepts only two arguments, not four --- src/Facebook/GraphNodes/GraphNodeFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index e1bedd910..0d7bca252 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -331,7 +331,7 @@ public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKe $dataList = []; foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphNode($graphNode, $subclassName, $parentKey, $parentNodeId); + $dataList[] = $this->safelyMakeGraphNode($graphNode, $subclassName); } $metaData = $this->getMetaData($data); From a0c196c15e20d9a82fd998f4cc2b9a2f1cc29645 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Mon, 20 Jul 2015 10:58:59 -0700 Subject: [PATCH 168/407] Update sdk_getting_started.fbmd --- docs/sdk_getting_started.fbmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index ebb7e2c0d..71dba1e6f 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -87,7 +87,7 @@ After downloading the source code with the button above, extract the files in a 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 `autolaoder.php` file. +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. From ebc78351f7297c3737cfffc1f6f262f54e6b81c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Fri, 10 Jul 2015 18:26:43 -0400 Subject: [PATCH 169/407] Fix: Method accepts only two arguments, not four --- src/Facebook/GraphNodes/GraphNodeFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index e1bedd910..0d7bca252 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -331,7 +331,7 @@ public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKe $dataList = []; foreach ($data['data'] as $graphNode) { - $dataList[] = $this->safelyMakeGraphNode($graphNode, $subclassName, $parentKey, $parentNodeId); + $dataList[] = $this->safelyMakeGraphNode($graphNode, $subclassName); } $metaData = $this->getMetaData($data); From 34402e325e71b7101b6ee0749276034c16d92b92 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 4 Aug 2015 17:17:38 -0500 Subject: [PATCH 170/407] Make default field value return exact value --- src/Facebook/GraphNodes/Collection.php | 2 +- tests/GraphNodes/CollectionTest.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/Collection.php b/src/Facebook/GraphNodes/Collection.php index cac010ba3..e1fea7819 100644 --- a/src/Facebook/GraphNodes/Collection.php +++ b/src/Facebook/GraphNodes/Collection.php @@ -69,7 +69,7 @@ public function getField($name, $default = null) return $this->items[$name]; } - return $default ?: null; + return $default; } /** diff --git a/tests/GraphNodes/CollectionTest.php b/tests/GraphNodes/CollectionTest.php index af3eba8c5..0985328a1 100755 --- a/tests/GraphNodes/CollectionTest.php +++ b/tests/GraphNodes/CollectionTest.php @@ -60,6 +60,20 @@ public function testAMissingPropertyWillReturnTheDefault() $this->assertEquals('faz', $property); } + public function testFalseDefaultsWillReturnSameType() + { + $graphNode = new Collection(['foo' => 'bar']); + + $field = $graphNode->getField('baz', ''); + $this->assertSame('', $field); + + $field = $graphNode->getField('baz', 0); + $this->assertSame(0, $field); + + $field = $graphNode->getField('baz', false); + $this->assertSame(false, $field); + } + public function testTheKeysFromTheCollectionCanBeReturned() { $graphNode = new Collection([ From 4424728aa2392f44c3ea07fe9b32ab8a0a4370fe Mon Sep 17 00:00:00 2001 From: Michael Beckwith Date: Mon, 17 Aug 2015 13:31:53 -0500 Subject: [PATCH 171/407] fix typo in docblock --- src/Facebook/FacebookResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index ce55b1433..033c9b886 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -225,7 +225,7 @@ public function getThrownException() * * Graph will return 2 types of responses: * - JSON(P) - * Most responses from Grpah are JSON(P) + * Most responses from Graph are JSON(P) * - application/x-www-form-urlencoded key/value pairs * Happens on the `/oauth/access_token` endpoint when exchanging * a short-lived access token for a long-lived access token From 5b6a85a5b52c7e7277852316fc29ad2e08496c2f Mon Sep 17 00:00:00 2001 From: Demi Chen Date: Sun, 16 Aug 2015 23:38:05 -0700 Subject: [PATCH 172/407] Video Resumable uploader --- .../Exceptions/FacebookResponseException.php | 7 + .../FacebookResumableUploadException.php | 57 +++++ src/Facebook/Facebook.php | 71 ++++++ src/Facebook/FileUpload/FacebookFile.php | 10 + .../FileUpload/FacebookResumableUploader.php | 201 ++++++++++++++++ .../FileUpload/FacebookResumeContext.php | 98 ++++++++ .../FileUpload/FacebookTransferChunk.php | 116 +++++++++ .../FacebookResumableUploaderTest.php | 222 ++++++++++++++++++ tests/foo.mp4 | Bin 0 -> 2087 bytes 9 files changed, 782 insertions(+) create mode 100644 src/Facebook/Exceptions/FacebookResumableUploadException.php create mode 100644 src/Facebook/FileUpload/FacebookResumableUploader.php create mode 100644 src/Facebook/FileUpload/FacebookResumeContext.php create mode 100644 src/Facebook/FileUpload/FacebookTransferChunk.php create mode 100644 tests/FileUpload/FacebookResumableUploaderTest.php create mode 100644 tests/foo.mp4 diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index c1b19f907..4aea23908 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -89,6 +89,13 @@ public static function create(FacebookResponse $response) case 464: case 467: return new static($response, new FacebookAuthenticationException($message, $code)); + // Video upload resumable error + case 1363019: + case 1363037: + case 1363033: + case 1363021: + case 1363041: + return new static($response, new FacebookResumableUploadException($message, $code)); } } diff --git a/src/Facebook/Exceptions/FacebookResumableUploadException.php b/src/Facebook/Exceptions/FacebookResumableUploadException.php new file mode 100644 index 000000000..431f97de3 --- /dev/null +++ b/src/Facebook/Exceptions/FacebookResumableUploadException.php @@ -0,0 +1,57 @@ +resumeContext; + } + + /** + * @param FacebookResumeContext $resumeContext + */ + public function setResumeContext(FacebookResumeContext $resumeContext) + { + $this->resumeContext = $resumeContext; + } + +} diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 3938b1746..f34393911 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -26,6 +26,7 @@ use Facebook\Authentication\AccessToken; use Facebook\Authentication\OAuth2Client; use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookResumableUploader; use Facebook\FileUpload\FacebookVideo; use Facebook\GraphNodes\GraphEdge; use Facebook\Url\UrlDetectionInterface; @@ -45,8 +46,10 @@ use Facebook\Helpers\FacebookJavaScriptHelper; use Facebook\Helpers\FacebookPageTabHelper; use Facebook\Helpers\FacebookRedirectLoginHelper; +use Facebook\Exceptions\FacebookResumableUploadException; use Facebook\Exceptions\FacebookSDKException; + /** * Class Facebook * @@ -586,4 +589,72 @@ public function videoToUpload($pathToFile) { return new FacebookVideo($pathToFile); } + + /** + * Upload video + * + * @param int $target + * @param string $pathToFile + * @param string $accessToken + * @param int $maxTransferTries + * + * @return array + * + * @throws FacebookSDKException + */ + public function uploadVideo($target, $pathToFile, $accessToken, $maxTransferTries = 5) + { + $uploader = $this->getResumableUploader($accessToken, $maxTransferTries); + $endpoint = '/'.$target.'/videos'; + $chunk = $uploader->start($endpoint, $pathToFile); + + do { + $chunk = $uploader->transfer($endpoint, $chunk); + } while(!$chunk->isLastChunk()); + + return [ + 'videoId' => $chunk->getVideoId(), + 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId()), + ]; + } + + /** + * Instantiates a new video uploader + * + * @param string $accessToken + * @param int $maxTransferTries + * + * @return FacebookResumableUploader + */ + protected function getResumableUploader($accessToken, $maxTransferTries = 5) + { + return new FacebookResumableUploader($this->app, $this->client, $accessToken, $maxTransferTries); + } + + /** + * Resume upload given a resumable upload exception + * + * @param FacebookResumableUploadException $exception + * + * @return array + * + * @throws FacebookSDKException + */ + public function resumeUpload(FacebookResumableUploadException $exception) + { + $resumeContext = $exception->getResumeContext(); + + $uploader = $this->getResumableUploader($resumeContext->getAccessToken(), $resumeContext->getMaxTransferTries()); + $chunk = $resumeContext->getChunk(); + $endpoint = $resumeContext->getEndpoint(); + + do { + $chunk = $uploader->transfer($endpoint, $chunk); + } while(!$chunk->isLastChunk()); + + return [ + 'videoId' => $chunk->getVideoId(), + 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId()), + ]; + } } diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php index f8b990548..bb0abea99 100644 --- a/src/Facebook/FileUpload/FacebookFile.php +++ b/src/Facebook/FileUpload/FacebookFile.php @@ -111,6 +111,16 @@ public function getFileName() return basename($this->path); } + /** + * Return the path of the file. + * + * @return string + */ + public function getFilePath() + { + return $this->path; + } + /** * Return the mimetype of the file. * diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php new file mode 100644 index 000000000..925c30a60 --- /dev/null +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -0,0 +1,201 @@ +app = $app; + $this->client = $client; + $this->accessToken = $accessToken; + $this->maxTransferTries = $maxTransferTries; + } + + /** + * Upload - phase start + * + * @param $endpoint + * @param $filePath + * @return FacebookTransferChunk + * + * @throws FacebookSDKException + */ + public function start($endpoint, $filePath) + { + $fileSize = filesize($filePath); + + $startReqParams = [ + 'upload_phase' => 'start', + 'file_size' => $fileSize, + ]; + + $request = new FacebookRequest( + $this->app, + $this->accessToken, + 'POST', + $endpoint, + $startReqParams + ); + + $res= $this->client->sendRequest($request)->getDecodedBody(); + + $firstTransferChunk = new FacebookTransferChunk( + $filePath, + $res['upload_session_id'], + $res['video_id'], + $res['start_offset'], + $res['end_offset'] - $res['start_offset'] + ); + + return $firstTransferChunk; + } + + /** + * Upload - phase transfer + * + * @param $endpoint + * @param FacebookTransferChunk $chunk + * @return FacebookTransferChunk + * + * @throws FacebookResumableUploadException + * @throws FacebookSDKException + */ + public function transfer($endpoint, FacebookTransferChunk $chunk) + { + $transReqParams = [ + 'upload_phase' => 'transfer', + 'upload_session_id' => $chunk->getUploadSessionId(), + 'start_offset' => $chunk->getStartOffset(), + 'video_file_chunk' => $chunk, + ]; + + $maxTransferTries = $this->maxTransferTries; + + $request = new FacebookRequest( + $this->app, + $this->accessToken, + 'POST', + $endpoint, + $transReqParams + ); + + while ($maxTransferTries > 0) { + try { + $res= $this->client->sendRequest($request)->getDecodedBody(); + + $nextTransferChunk = new FacebookTransferChunk( + $chunk->getFilePath(), + $chunk->getUploadSessionId(), + $chunk->getVideoId(), + $res['start_offset'], + $res['end_offset'] - $res['start_offset'] + ); + + return $nextTransferChunk; + } catch (FacebookSDKException $e) { + $preException = $e->getPrevious(); + if ($preException instanceof FacebookResumableUploadException) { + if (--$maxTransferTries <= 0) { + $resumeContext = new FacebookResumeContext( + $endpoint, + $this->accessToken, + $chunk + ); + $preException->setResumeContext($resumeContext); + throw $e; + } + } else { + throw $e; + } + continue; + } + } + } + + /** + * Upload - phase finish + * + * @param $endpoint + * @param $uploadSessionId + * @return boolean + * + * @throws FacebookSDKException + */ + public function finish($endpoint, $uploadSessionId) + { + $finishReqParams = [ + 'upload_phase' => 'finish', + 'upload_session_id' => $uploadSessionId, + ]; + + $request = new FacebookRequest( + $this->app, + $this->accessToken, + 'POST', + $endpoint, + $finishReqParams + ); + + $res = $this->client->sendRequest($request)->getDecodedBody(); + return $res['success']; + } +} diff --git a/src/Facebook/FileUpload/FacebookResumeContext.php b/src/Facebook/FileUpload/FacebookResumeContext.php new file mode 100644 index 000000000..490739535 --- /dev/null +++ b/src/Facebook/FileUpload/FacebookResumeContext.php @@ -0,0 +1,98 @@ +accessToken = $accessToken; + $this->chunk = $chunk; + $this->endpoint = $endpoint; + $this->maxTransferTries = $maxTransferTries; + } + + /** + * @return string + */ + public function getEndpoint() + { + return $this->endpoint; + } + + /** + * @return FacebookTransferChunk + */ + public function getChunk() + { + return $this->chunk; + } + + /** + * @return string + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * @return int + */ + public function getMaxTransferTries() + { + return $this->maxTransferTries; + } +} diff --git a/src/Facebook/FileUpload/FacebookTransferChunk.php b/src/Facebook/FileUpload/FacebookTransferChunk.php new file mode 100644 index 000000000..fa0158bac --- /dev/null +++ b/src/Facebook/FileUpload/FacebookTransferChunk.php @@ -0,0 +1,116 @@ +uploadSessionId = $uploadSessionId; + $this->startOffset = $startOffset; + $this->maxLen = $maxLen; + $this->videoId = $videoId; + } + + /** + * Return the contents of the file. + * + * @return string + */ + public function getContents() + { + return stream_get_contents($this->stream, $this->maxLen, $this->startOffset); + } + + /** + * Return upload session Id + * + * @return int + */ + public function getUploadSessionId() + { + return $this->uploadSessionId; + } + + /** + * Check whether is the last chunk + * + * @return bool + */ + public function isLastChunk() + { + return $this->maxLen === 0; + } + + /** + * @return int + */ + public function getStartOffset() + { + return $this->startOffset; + } + + /** + * Get uploaded video Id + * + * @return int + */ + public function getVideoId() + { + return $this->videoId; + } +} diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php new file mode 100644 index 000000000..aaa0992cd --- /dev/null +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -0,0 +1,222 @@ +mockStart(); + } + + if (preg_split("/=/", explode('&', $body)[0])[1] == 'finish') { + return $this->mockFinish(); + } + + return $this->mockTransfer(); + } + + public function mockStart() + { + $header = [ + "Content-Type" => "application/json; charset=UTF-8", + "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", + "facebook-api-version" => "v2.3", + ]; + + $body = '{"video_id":"162719974059555","start_offset":"0","end_offset":"2087",' . + '"upload_session_id":"162719977392888"}'; + + return new GraphRawResponse($header, $body, 200); + } + + public function mockTransfer() + { + $header = [ + "Content-Type" => "application/json; charset=UTF-8", + "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", + "facebook-api-version" => "v2.3", + ]; + + $body = '{"start_offset":"2087","end_offset":"2087"}'; + + return new GraphRawResponse($header, $body, 200); + } + + public function mockFinish() + { + $header = [ + "Content-Type" => "application/json; charset=UTF-8", + "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", + "facebook-api-version" => "v2.3", + ]; + + $body = '{"success":true}'; + + return new GraphRawResponse($header, $body, 200); + } +} + +class VideoUploadClientHandlerFail implements FacebookHttpClientInterface +{ + public function send($url, $method, $body, array $headers, $timeOut) + { + if (preg_split("/=/", explode('&', $body)[0])[1] == 'start') { + return $this->mockStart(); + } + + if (preg_split("/=/", explode('&', $body)[0])[1] == 'finish') { + return $this->mockFinish(); + } + + return $this->mockTransfer(); + } + + public function mockStart() + { + $header = [ + "Content-Type" => "application/json; charset=UTF-8", + "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", + "facebook-api-version" => "v2.3", + "WWW-Authenticate" => 'OAuth "Facebook Platform" "invalid_token" "Error validating access token', + ]; + + $body = '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . + '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . + '"type":"OAuthException","code":190,"error_subcode":463}}'; + + return new GraphRawResponse($header, $body, 400); + } + + public function mockTransfer() + { + $header = [ + "Content-Type" => "application/json; charset=UTF-8", + "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", + "facebook-api-version" => "v2.3", + "WWW-Authenticate" => 'OAuth "Facebook Platform" "invalid_token" "Error validating access token', + ]; + + $body = '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . + '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . + '"type":"OAuthException","code":190,"error_subcode":1363033}}'; + + return new GraphRawResponse($header, $body, 400); + } + + public function mockFinish() + { + $header = [ + "Content-Type" => "application/json; charset=UTF-8", + "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", + "facebook-api-version" => "v2.3", + ]; + + $body = '{"success":true}'; + + return new GraphRawResponse($header, $body, 200); + } +} + + +class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FacebookApp + */ + private $fbApp; + /** + * @var FacebookClient + */ + private $fbSuccessClient; + /** + * @var FacebookClient + */ + private $fbFailClient; + + public function setUp() + { + $this->fbApp = new FacebookApp('app_id', 'app_secret'); + $this->fbSuccessClient = new FacebookClient(new VideoUploadClientHandlerSuccess()); + $this->fbFailClient = new FacebookClient(new VideoUploadClientHandlerFail()); + } + + public function testSuccess() + { + $fileUploader = new FacebookResumableUploader($this->fbApp, $this->fbSuccessClient, 'access_token'); + $endpoint = '/113582528973300/videos'; + $filePath = __DIR__ . '/../foo.mp4'; + $chunk = $fileUploader->start($endpoint, $filePath); + $this->assertInstanceOf('Facebook\FileUpload\FacebookTransferChunk', $chunk); + $this->assertEquals('162719977392888', $chunk->getUploadSessionId()); + $this->assertEquals('162719974059555', $chunk->getVideoId()); + + $chunk = $fileUploader->transfer($endpoint, $chunk); + $this->assertEquals(2087, $chunk->getStartOffset()); + + $this->assertTrue($fileUploader->finish($endpoint, $chunk->getUploadSessionId())); + } + + public function testFail() + { + $fileUploader = new FacebookResumableUploader($this->fbApp, $this->fbFailClient, 'access_token'); + $endpoint = '/113582528973300/videos'; + $filePath = __DIR__ . '/../foo.mp4'; + + $catchResException = false; + try { + $chunk = $fileUploader->start($endpoint, $filePath); + } catch (FacebookSDKException $e) { + $catchResException = true; + } + $this->assertTrue($catchResException); + + // get file chunk + $catchResumableException = false; + $successUploader = new FacebookResumableUploader($this->fbApp, $this->fbSuccessClient, 'access_token'); + $chunk = $successUploader->start($endpoint, $filePath); + try { + $chunk = $fileUploader->transfer($endpoint, $chunk); + } catch (FacebookSDKException $e) { + if ($e->getPrevious() instanceof FacebookResumableUploadException) { + $catchResumableException = true; + $this->assertInstanceOf('Facebook\FileUpload\FacebookResumeContext', + $e->getPrevious()->getResumeContext()); + } + } + $this->assertTrue($catchResumableException); + } + +} \ No newline at end of file diff --git a/tests/foo.mp4 b/tests/foo.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..b5df99c881ccaabca1481c3fd301ea29c24b3ca4 GIT binary patch literal 2087 zcmb7EeQXp(6rbxC2NGy#gEbV`Qi>(^?sl)oL8}{D8$zQ;gpWiDLKVf*_08Ug1^maC%)HDN~5uvh?zR%(m=p$@sTrHU1HEOMzsUzIt*`V&z@>HGwtXl>_g;wBnEEqbVTrBB^ z#aNxj^IExV1F|4;V54N=>EHee&{=5N2`kbO6eKO41BFEaCos`fa8@e0kRV~=W7{T+ zp#XsFuxuqA+4giHX3G^cOnitC``CI-qGH(gwr=<(z*}`gPh1G`Sw}7nG?9@xV@w(R z>`H)S5qZ`l#{awLm?j)tkhQ}0YIKa*kDjjq-J90@i7gWz27+x=%Wu*F4#-e%i9UiK@ssd~R=D|>*sEra17?hi)iydy7A%Q`|P)l8|hK2?w zd5em~g`A33<05&TK|_|nM^Oz?3F)O2&-po?r73uCY%wKZzohWBEK^FC(i9isq(&XH zbOg>3hG8ffvq2o8^m;#_*_5g`vJBaMn!qwn8iHV>WHEvTAIV4}d>R+3!7SsY_@Ji9 zoDV`7%FwVRi8`P;kvRfyKnr}G47-3ip-Bm0*3A?_#Q>)pK2@(3Rd9_bs8fAPAfRJ| zb+{=bs6hlIa#NC`)N(;M`I021OCk@=BnX-cX;u+llsSVmB8CjCNgOx<@0aQ|uF=OU zvdUR4!HnQrB!(abIBFd6322;*bwCYRtO*(_pjzArX0|wieDEKKaq2t{VZPpAJv6DK zabzeO)`JkD@xElgBv9j7UJFpNA0|Wkf&+}eNmF&C8}EdfF|u*!NU zQH3$XmBKAREv^o3klY7qf#=cmSE_coj3TGy0cT|Y6c@X^4x$F8?l zo@zQ~4&JLk8MnHZc+|NadopuYE#fzHKi-6vRn5lv&mFkp70w(?yKLWYH%=TbEor?l z;hQ~ak(1_EJp*?-YW%kRpE~Gsm6IZl%?o}#-u!3I!VrDCVaDV8DPMoKw;^GHyhR&yQWx zd9dox%GxF6dS7R8@$km8Kkw`{w_Gheyt$*RWQ*sE9a~Lv{Jot+;}=S=b*)=$-d%}O zvX^t8&NhFUI`olUISwC!jPmw5FMkM^L(tN3*Qx=fm$z3pOp1XP3xI7`-pMFXfTBs% smq6Q55>W+lzwKp7RGmaEGZWTbNfdP?xV{8xM@*b+r)DKk8GADN51|1xg8%>k literal 0 HcmV?d00001 From 5e7e69122536d052982fe9a99d19edfe54a171b4 Mon Sep 17 00:00:00 2001 From: Leo Hochberg Date: Fri, 21 Aug 2015 00:33:33 -0700 Subject: [PATCH 173/407] adding a getEmail() method for GraphUser objects --- src/Facebook/GraphNodes/GraphUser.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index cb9ddbb5d..a53005b53 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -90,6 +90,16 @@ public function getLastName() return $this->getField('last_name'); } + /** + * Returns the email for the user as a string if present. + * + * @return string|null + */ + public function getEmail() + { + return $this->getField('email'); + } + /** * Returns the gender for the user as a string if present. * From 371e9d6c0b69e2f6575434945793069467b0e01c Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Fri, 4 Sep 2015 12:46:45 +0200 Subject: [PATCH 174/407] Fix: Deep Pagination does not append extra parameters anymore --- src/Facebook/GraphNodes/GraphEdge.php | 28 +++--------------------- tests/FacebookTest.php | 2 ++ tests/GraphNodes/GraphEdgeTest.php | 31 +++++---------------------- 3 files changed, 10 insertions(+), 51 deletions(-) diff --git a/src/Facebook/GraphNodes/GraphEdge.php b/src/Facebook/GraphNodes/GraphEdge.php index 95f32849a..086e2df42 100644 --- a/src/Facebook/GraphNodes/GraphEdge.php +++ b/src/Facebook/GraphNodes/GraphEdge.php @@ -153,35 +153,13 @@ public function getPaginationUrl($direction) $this->validateForPagination(); // Do we have a paging URL? - if (isset($this->metaData['paging'][$direction])) { - // Graph returns the full URL with all the original params. - // We just want the endpoint though. - $pageUrl = $this->metaData['paging'][$direction]; - - return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); - } - - // Do we have a cursor to work with? - $cursorDirection = $direction === 'next' ? 'after' : 'before'; - $cursor = $this->getCursor($cursorDirection); - if (!$cursor) { + if (!isset($this->metaData['paging'][$direction])) { return null; } - // If we don't know the ID of the parent node, this ain't gonna work. - if (!$this->parentEdgeEndpoint) { - return null; - } - - // We have the parent node ID, paging cursor & original request. - // These were the ingredients chosen to create the perfect little URL. - $pageUrl = $this->parentEdgeEndpoint . '?' . $cursorDirection . '=' . urlencode($cursor); - - // Pull in the original params - $originalUrl = $this->request->getUrl(); - $pageUrl = FacebookUrlManipulator::mergeUrlParams($originalUrl, $pageUrl); + $pageUrl = $this->metaData['paging'][$direction]; - return FacebookUrlManipulator::forceSlashPrefix($pageUrl); + return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); } /** diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 36486655b..a5f7836f6 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -363,6 +363,8 @@ public function testPaginationReturnsProperResponse() 'after' => 'bar_after_cursor', 'before' => 'bar_before_cursor', ], + 'previous' => 'previous_url', + 'next' => 'next_url', ] ], '/1337/photos', diff --git a/tests/GraphNodes/GraphEdgeTest.php b/tests/GraphNodes/GraphEdgeTest.php index 4e70f523a..0336c157e 100644 --- a/tests/GraphNodes/GraphEdgeTest.php +++ b/tests/GraphNodes/GraphEdgeTest.php @@ -35,16 +35,10 @@ class GraphEdgeTest extends \PHPUnit_Framework_TestCase */ protected $request; - protected $basePagination = [ + protected $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', ]; - protected $cursorPagination = [ - 'cursors' => [ - 'after' => 'bar_after_cursor', - 'before' => 'bar_before_cursor', - ], - ]; public function setUp() { @@ -75,7 +69,7 @@ public function testCanReturnGraphGeneratedPaginationEndpoints() $graphEdge = new GraphEdge( $this->request, [], - ['paging' => $this->basePagination] + ['paging' => $this->pagination] ); $nextPage = $graphEdge->getPaginationUrl('next'); $prevPage = $graphEdge->getPaginationUrl('previous'); @@ -84,27 +78,12 @@ public function testCanReturnGraphGeneratedPaginationEndpoints() $this->assertEquals('/998899/photos?pretty=0&limit=25&before=foo_before_cursor', $prevPage); } - public function testCanGeneratePaginationEndpointsFromACursor() - { - $graphEdge = new GraphEdge( - $this->request, - [], - ['paging' => $this->cursorPagination], - '/1234567890/likes' - ); - $nextPage = $graphEdge->getPaginationUrl('next'); - $prevPage = $graphEdge->getPaginationUrl('previous'); - - $this->assertEquals('/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage); - $this->assertEquals('/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage); - } - public function testCanInstantiateNewPaginationRequest() { $graphEdge = new GraphEdge( $this->request, [], - ['paging' => $this->cursorPagination], + ['paging' => $this->pagination], '/1234567890/likes' ); $nextPage = $graphEdge->getNextPageRequest(); @@ -114,7 +93,7 @@ public function testCanInstantiateNewPaginationRequest() $this->assertInstanceOf('Facebook\FacebookRequest', $prevPage); $this->assertNotSame($this->request, $nextPage); $this->assertNotSame($this->request, $prevPage); - $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&after=bar_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&keep=me', $nextPage->getUrl()); - $this->assertEquals('/v1337/1234567890/likes?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=bar_before_cursor&foo=bar&keep=me', $prevPage->getUrl()); + $this->assertEquals('/v1337/998899/photos?access_token=foo_token&after=foo_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&limit=25&pretty=0', $nextPage->getUrl()); + $this->assertEquals('/v1337/998899/photos?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=foo_before_cursor&foo=bar&limit=25&pretty=0', $prevPage->getUrl()); } } From f4f2757ff9ebcc6f15c2a1f5124786bc39379a42 Mon Sep 17 00:00:00 2001 From: Guido Lodetti Date: Fri, 4 Sep 2015 16:15:51 +0200 Subject: [PATCH 175/407] Improved the getGraphEdge() function documentation --- docs/FacebookResponse.fbmd | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index 55946a253..6826ec764 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -181,7 +181,23 @@ Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/do ### getGraphEdge() {#get-graph-edge} ~~~~ -public Facebook\GraphNodes\GraphEdge getGraphEdge() +public Facebook\GraphNodes\GraphEdge getGraphEdge( + string|null $subclassName, + boolean $auto_prefix) ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. + +`$subclassName` +The `Facebook\GraphNodes\GraphNode` sub class 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`. + +~~~~ +$res = $fb->get('/{facebook-page}/events', '{access-token}'); +$events = $res->getGraphEdge("GraphEvent"); +foreach($events : $event){ + // . . . +} +~~~~ From 4032e88f9023e764933ad0ad2598cb2c4b2c4809 Mon Sep 17 00:00:00 2001 From: Guido Lodetti Date: Mon, 7 Sep 2015 20:21:25 +0200 Subject: [PATCH 176/407] Fix typos --- docs/FacebookResponse.fbmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/FacebookResponse.fbmd b/docs/FacebookResponse.fbmd index 6826ec764..30b694194 100644 --- a/docs/FacebookResponse.fbmd +++ b/docs/FacebookResponse.fbmd @@ -188,7 +188,7 @@ public Facebook\GraphNodes\GraphEdge getGraphEdge( Returns the response data in the form of a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. `$subclassName` -The `Facebook\GraphNodes\GraphNode` sub class to cast list items to. If none is provided, default is `Facebook\GraphNodes\GraphNode`. +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`. @@ -196,7 +196,7 @@ Toggle to auto-prefix the subclass name. If none is provided, default is `true`. ~~~~ $res = $fb->get('/{facebook-page}/events', '{access-token}'); $events = $res->getGraphEdge("GraphEvent"); -foreach($events : $event){ +foreach ($events as $event) { // . . . } ~~~~ From 3aa9fe8b066dea2e3f17770c87341c8b0bd9b9be Mon Sep 17 00:00:00 2001 From: Guido Lodetti Date: Mon, 7 Sep 2015 20:22:34 +0200 Subject: [PATCH 177/407] Fixed some "sub class" to "subclass" --- src/Facebook/FacebookResponse.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 033c9b886..b3d36a6d0 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -259,7 +259,7 @@ public function decodeBody() /** * Instantiate a new GraphObject from response. * - * @param string|null $subclassName The GraphNode sub class to cast to. + * @param string|null $subclassName The GraphNode subclass to cast to. * * @return \Facebook\GraphNodes\GraphObject * @@ -276,7 +276,7 @@ public function getGraphObject($subclassName = null) /** * Instantiate a new GraphNode from response. * - * @param string|null $subclassName The GraphNode sub class to cast to. + * @param string|null $subclassName The GraphNode subclass to cast to. * * @return \Facebook\GraphNodes\GraphNode * @@ -376,7 +376,7 @@ public function getGraphGroup() /** * Instantiate a new GraphList from response. * - * @param string|null $subclassName The GraphNode sub class to cast list items to. + * @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 @@ -394,7 +394,7 @@ public function getGraphList($subclassName = null, $auto_prefix = true) /** * Instantiate a new GraphEdge from response. * - * @param string|null $subclassName The GraphNode sub class to cast list items to. + * @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 From 1f169788a77d7f433ef4947ff0d6c80362223987 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 22 Sep 2015 10:33:57 -0500 Subject: [PATCH 178/407] Make changes based on feedback --- .../FacebookResumableUploadException.php | 2 - src/Facebook/Facebook.php | 15 ++-- .../FileUpload/FacebookResumableUploader.php | 70 +++++++++++-------- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/src/Facebook/Exceptions/FacebookResumableUploadException.php b/src/Facebook/Exceptions/FacebookResumableUploadException.php index 431f97de3..8e07a7ffb 100644 --- a/src/Facebook/Exceptions/FacebookResumableUploadException.php +++ b/src/Facebook/Exceptions/FacebookResumableUploadException.php @@ -23,7 +23,6 @@ */ namespace Facebook\Exceptions; -use Facebook\FacebookResponse; use Facebook\FileUpload\FacebookResumeContext; /** @@ -53,5 +52,4 @@ public function setResumeContext(FacebookResumeContext $resumeContext) { $this->resumeContext = $resumeContext; } - } diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index c6ba10bc8..989d9e90d 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -49,7 +49,6 @@ use Facebook\Exceptions\FacebookResumableUploadException; use Facebook\Exceptions\FacebookSDKException; - /** * Class Facebook * @@ -597,14 +596,16 @@ public function videoToUpload($pathToFile) * @param string $pathToFile * @param string $accessToken * @param int $maxTransferTries + * @param string $graphVersion * * @return array * * @throws FacebookSDKException */ - public function uploadVideo($target, $pathToFile, $accessToken, $maxTransferTries = 5) + public function uploadVideo($target, $pathToFile, $accessToken, $maxTransferTries = 5, $graphVersion = null) { - $uploader = $this->getResumableUploader($accessToken, $maxTransferTries); + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $uploader = $this->getResumableUploader($accessToken, $maxTransferTries, $graphVersion); $endpoint = '/'.$target.'/videos'; $chunk = $uploader->start($endpoint, $pathToFile); @@ -623,12 +624,15 @@ public function uploadVideo($target, $pathToFile, $accessToken, $maxTransferTrie * * @param string $accessToken * @param int $maxTransferTries + * @param string $graphVersion * * @return FacebookResumableUploader */ - protected function getResumableUploader($accessToken, $maxTransferTries = 5) + private function getResumableUploader($accessToken, $maxTransferTries = 5, $graphVersion = null) { - return new FacebookResumableUploader($this->app, $this->client, $accessToken, $maxTransferTries); + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + + return new FacebookResumableUploader($this->app, $this->client, $accessToken, $maxTransferTries, $graphVersion); } /** @@ -642,6 +646,7 @@ protected function getResumableUploader($accessToken, $maxTransferTries = 5) */ public function resumeUpload(FacebookResumableUploadException $exception) { + // @TODO properly handle Graph version $resumeContext = $exception->getResumeContext(); $uploader = $this->getResumableUploader($resumeContext->getAccessToken(), $resumeContext->getMaxTransferTries()); diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 925c30a60..62f3a751b 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -56,18 +56,25 @@ class FacebookResumableUploader */ protected $maxTransferTries; + /** + * @var string Graph version to use for this request. + */ + protected $graphVersion; + /** * @param FacebookApp $app * @param FacebookClient $client * @param string $accessToken * @param int $maxTransferTries + * @param string|null $graphVersion */ - public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $maxTransferTries = 5) + public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $maxTransferTries = 5, $graphVersion = null) { $this->app = $app; $this->client = $client; $this->accessToken = $accessToken; $this->maxTransferTries = $maxTransferTries; + $this->graphVersion = $graphVersion; } /** @@ -93,17 +100,19 @@ public function start($endpoint, $filePath) $this->accessToken, 'POST', $endpoint, - $startReqParams + $startReqParams, + null, + $this->graphVersion ); - $res= $this->client->sendRequest($request)->getDecodedBody(); + $response = $this->client->sendRequest($request)->getDecodedBody(); $firstTransferChunk = new FacebookTransferChunk( $filePath, - $res['upload_session_id'], - $res['video_id'], - $res['start_offset'], - $res['end_offset'] - $res['start_offset'] + $response['upload_session_id'], + $response['video_id'], + $response['start_offset'], + $response['end_offset'] - $response['start_offset'] ); return $firstTransferChunk; @@ -135,38 +144,38 @@ public function transfer($endpoint, FacebookTransferChunk $chunk) $this->accessToken, 'POST', $endpoint, - $transReqParams + $transReqParams, + null, + $this->graphVersion ); while ($maxTransferTries > 0) { try { - $res= $this->client->sendRequest($request)->getDecodedBody(); + $response = $this->client->sendRequest($request)->getDecodedBody(); - $nextTransferChunk = new FacebookTransferChunk( + return new FacebookTransferChunk( $chunk->getFilePath(), $chunk->getUploadSessionId(), $chunk->getVideoId(), - $res['start_offset'], - $res['end_offset'] - $res['start_offset'] + $response['start_offset'], + $response['end_offset'] - $response['start_offset'] ); - - return $nextTransferChunk; } catch (FacebookSDKException $e) { $preException = $e->getPrevious(); - if ($preException instanceof FacebookResumableUploadException) { - if (--$maxTransferTries <= 0) { - $resumeContext = new FacebookResumeContext( - $endpoint, - $this->accessToken, - $chunk - ); - $preException->setResumeContext($resumeContext); - throw $e; - } - } else { + if (!$preException instanceof FacebookResumableUploadException) { + throw $e; + } + + if (--$maxTransferTries <= 0) { + $resumeContext = new FacebookResumeContext( + $endpoint, + $this->accessToken, + $chunk + ); + $preException->setResumeContext($resumeContext); + throw $e; } - continue; } } } @@ -192,10 +201,13 @@ public function finish($endpoint, $uploadSessionId) $this->accessToken, 'POST', $endpoint, - $finishReqParams + $finishReqParams, + null, + $this->graphVersion ); - $res = $this->client->sendRequest($request)->getDecodedBody(); - return $res['success']; + $response = $this->client->sendRequest($request)->getDecodedBody(); + + return $response['success']; } } From 4dcc0a4167cd5c34ed0965828bbf22e90a128df0 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 23 Sep 2015 21:49:23 -0500 Subject: [PATCH 179/407] Refactor upload by chunks --- .../FacebookResumableUploadException.php | 22 -- src/Facebook/Facebook.php | 75 ++---- src/Facebook/FileUpload/FacebookFile.php | 28 ++- .../FileUpload/FacebookResumableUploader.php | 181 ++++++-------- .../FileUpload/FacebookResumeContext.php | 98 -------- .../FileUpload/FacebookTransferChunk.php | 51 ++-- tests/FileUpload/FacebookFileTest.php | 9 +- .../FacebookResumableUploaderTest.php | 233 +++++++----------- 8 files changed, 256 insertions(+), 441 deletions(-) delete mode 100644 src/Facebook/FileUpload/FacebookResumeContext.php diff --git a/src/Facebook/Exceptions/FacebookResumableUploadException.php b/src/Facebook/Exceptions/FacebookResumableUploadException.php index 8e07a7ffb..2f04b38f3 100644 --- a/src/Facebook/Exceptions/FacebookResumableUploadException.php +++ b/src/Facebook/Exceptions/FacebookResumableUploadException.php @@ -23,8 +23,6 @@ */ namespace Facebook\Exceptions; -use Facebook\FileUpload\FacebookResumeContext; - /** * Class FacebookResumableUploadException * @@ -32,24 +30,4 @@ */ class FacebookResumableUploadException extends FacebookSDKException { - /** - * @var FacebookResumeContext - */ - private $resumeContext; - - /** - * @return FacebookResumeContext - */ - public function getResumeContext() - { - return $this->resumeContext; - } - - /** - * @param FacebookResumeContext $resumeContext - */ - public function setResumeContext(FacebookResumeContext $resumeContext) - { - $this->resumeContext = $resumeContext; - } } diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 989d9e90d..253fcf319 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -46,7 +46,6 @@ use Facebook\Helpers\FacebookJavaScriptHelper; use Facebook\Helpers\FacebookPageTabHelper; use Facebook\Helpers\FacebookRedirectLoginHelper; -use Facebook\Exceptions\FacebookResumableUploadException; use Facebook\Exceptions\FacebookSDKException; /** @@ -590,76 +589,36 @@ public function videoToUpload($pathToFile) } /** - * Upload video + * Upload a video in chunks. * - * @param int $target - * @param string $pathToFile - * @param string $accessToken - * @param int $maxTransferTries - * @param string $graphVersion + * @param int $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, $accessToken, $maxTransferTries = 5, $graphVersion = null) + public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = null, $maxTransferTries = 5, $graphVersion = null) { + $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; - $uploader = $this->getResumableUploader($accessToken, $maxTransferTries, $graphVersion); - $endpoint = '/'.$target.'/videos'; - $chunk = $uploader->start($endpoint, $pathToFile); - - do { - $chunk = $uploader->transfer($endpoint, $chunk); - } while(!$chunk->isLastChunk()); - - return [ - 'videoId' => $chunk->getVideoId(), - 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId()), - ]; - } - /** - * Instantiates a new video uploader - * - * @param string $accessToken - * @param int $maxTransferTries - * @param string $graphVersion - * - * @return FacebookResumableUploader - */ - private function getResumableUploader($accessToken, $maxTransferTries = 5, $graphVersion = null) - { - $graphVersion = $graphVersion ?: $this->defaultGraphVersion; - - return new FacebookResumableUploader($this->app, $this->client, $accessToken, $maxTransferTries, $graphVersion); - } - - /** - * Resume upload given a resumable upload exception - * - * @param FacebookResumableUploadException $exception - * - * @return array - * - * @throws FacebookSDKException - */ - public function resumeUpload(FacebookResumableUploadException $exception) - { - // @TODO properly handle Graph version - $resumeContext = $exception->getResumeContext(); - - $uploader = $this->getResumableUploader($resumeContext->getAccessToken(), $resumeContext->getMaxTransferTries()); - $chunk = $resumeContext->getChunk(); - $endpoint = $resumeContext->getEndpoint(); + $uploader = new FacebookResumableUploader($this->app, $this->client, $accessToken, $graphVersion); + $endpoint = '/'.$target.'/videos'; + $file = $this->videoToUpload($pathToFile); + $chunk = $uploader->start($endpoint, $file); do { - $chunk = $uploader->transfer($endpoint, $chunk); - } while(!$chunk->isLastChunk()); + $chunk = $uploader->maxTriesTransfer($endpoint, $chunk, $maxTransferTries); + } while (!$chunk->isLastChunk()); return [ - 'videoId' => $chunk->getVideoId(), - 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId()), + 'video_id' => $chunk->getVideoId(), + 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId(), $metadata), ]; } } diff --git a/src/Facebook/FileUpload/FacebookFile.php b/src/Facebook/FileUpload/FacebookFile.php index bb0abea99..f1754a971 100644 --- a/src/Facebook/FileUpload/FacebookFile.php +++ b/src/Facebook/FileUpload/FacebookFile.php @@ -37,6 +37,16 @@ class FacebookFile */ protected $path; + /** + * @var int The maximum bytes to read. Defaults to -1 (read all the remaining buffer). + */ + private $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; + /** * @var resource The stream pointing to the file. */ @@ -46,12 +56,16 @@ class FacebookFile * Creates a new FacebookFile entity. * * @param string $filePath + * @param int $maxLength + * @param int $offset * * @throws FacebookSDKException */ - public function __construct($filePath) + public function __construct($filePath, $maxLength = -1, $offset = -1) { $this->path = $filePath; + $this->maxLength = $maxLength; + $this->offset = $offset; $this->open(); } @@ -98,7 +112,7 @@ public function close() */ public function getContents() { - return stream_get_contents($this->stream); + return stream_get_contents($this->stream, $this->maxLength, $this->offset); } /** @@ -121,6 +135,16 @@ public function getFilePath() return $this->path; } + /** + * Return the size of the file. + * + * @return int + */ + public function getSize() + { + return filesize($this->path); + } + /** * Return the mimetype of the file. * diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 62f3a751b..caa7c4c0a 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -24,6 +24,7 @@ namespace Facebook\FileUpload; use Facebook\Exceptions\FacebookResumableUploadException; +use Facebook\Exceptions\FacebookResponseException; use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookApp; use Facebook\FacebookClient; @@ -51,11 +52,6 @@ class FacebookResumableUploader */ protected $client; - /** - * @var int Max retry times - */ - protected $maxTransferTries; - /** * @var string Graph version to use for this request. */ @@ -65,149 +61,136 @@ class FacebookResumableUploader * @param FacebookApp $app * @param FacebookClient $client * @param string $accessToken - * @param int $maxTransferTries - * @param string|null $graphVersion + * @param string $graphVersion */ - public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $maxTransferTries = 5, $graphVersion = null) + public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $graphVersion) { $this->app = $app; $this->client = $client; $this->accessToken = $accessToken; - $this->maxTransferTries = $maxTransferTries; $this->graphVersion = $graphVersion; } /** - * Upload - phase start + * Upload by chunks - start phase + * + * @param string $endpoint + * @param FacebookFile $file * - * @param $endpoint - * @param $filePath * @return FacebookTransferChunk * * @throws FacebookSDKException */ - public function start($endpoint, $filePath) + public function start($endpoint, FacebookFile $file) { - $fileSize = filesize($filePath); - - $startReqParams = [ + $params = [ 'upload_phase' => 'start', - 'file_size' => $fileSize, + 'file_size' => $file->getSize(), ]; - - $request = new FacebookRequest( - $this->app, - $this->accessToken, - 'POST', - $endpoint, - $startReqParams, - null, - $this->graphVersion - ); + $request = $this->makeUploadRequest($endpoint, $params); $response = $this->client->sendRequest($request)->getDecodedBody(); - $firstTransferChunk = new FacebookTransferChunk( - $filePath, - $response['upload_session_id'], - $response['video_id'], - $response['start_offset'], - $response['end_offset'] - $response['start_offset'] - ); - - return $firstTransferChunk; + return new FacebookTransferChunk($file, $response['upload_session_id'], $response['video_id'], $response['start_offset'], $response['end_offset']); } /** - * Upload - phase transfer + * Upload by chunks - transfer phase * - * @param $endpoint + * @param string $endpoint * @param FacebookTransferChunk $chunk + * @param boolean $allowToThrow + * * @return FacebookTransferChunk * - * @throws FacebookResumableUploadException - * @throws FacebookSDKException + * @throws FacebookResponseException */ - public function transfer($endpoint, FacebookTransferChunk $chunk) + public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow = false) { - $transReqParams = [ + $params = [ 'upload_phase' => 'transfer', 'upload_session_id' => $chunk->getUploadSessionId(), 'start_offset' => $chunk->getStartOffset(), - 'video_file_chunk' => $chunk, + 'video_file_chunk' => $chunk->getPartialFile(), ]; - - $maxTransferTries = $this->maxTransferTries; - - $request = new FacebookRequest( - $this->app, - $this->accessToken, - 'POST', - $endpoint, - $transReqParams, - null, - $this->graphVersion - ); - - while ($maxTransferTries > 0) { - try { - $response = $this->client->sendRequest($request)->getDecodedBody(); - - return new FacebookTransferChunk( - $chunk->getFilePath(), - $chunk->getUploadSessionId(), - $chunk->getVideoId(), - $response['start_offset'], - $response['end_offset'] - $response['start_offset'] - ); - } catch (FacebookSDKException $e) { - $preException = $e->getPrevious(); - if (!$preException instanceof FacebookResumableUploadException) { - throw $e; - } - - if (--$maxTransferTries <= 0) { - $resumeContext = new FacebookResumeContext( - $endpoint, - $this->accessToken, - $chunk - ); - $preException->setResumeContext($resumeContext); - - throw $e; - } + $request = $this->makeUploadRequest($endpoint, $params); + + try { + $response = $this->client->sendRequest($request)->getDecodedBody(); + } catch (FacebookResponseException $e) { + $preException = $e->getPrevious(); + if ($allowToThrow || !$preException instanceof FacebookResumableUploadException) { + throw $e; } + + // Return the same chunk entity so it can be retried. + return $chunk; } + + return new FacebookTransferChunk($chunk->getFile(), $chunk->getUploadSessionId(), $chunk->getVideoId(), $response['start_offset'], $response['end_offset']); } /** - * Upload - phase finish + * Attempts to upload a chunk of a file in $retryCountdown tries. + * + * @param string $endpoint + * @param FacebookTransferChunk $chunk + * @param int $retryCountdown + * + * @return FacebookTransferChunk + * + * @throws FacebookResponseException + */ + public function maxTriesTransfer($endpoint, FacebookTransferChunk $chunk, $retryCountdown) + { + $allowToThrow = $retryCountdown < 1; + + $newChunk = $this->transfer($endpoint, $chunk, $allowToThrow); + + if ($newChunk !== $chunk) { + return $newChunk; + } + + $retryCountdown--; + + // If transfer() returned the same chunk entity, the transfer failed but is resumable. + return $this->maxTriesTransfer($endpoint, $chunk, $retryCountdown); + } + + /** + * Upload by chunks - finish phase + * + * @param string $endpoint + * @param string $uploadSessionId + * @param array $metadata The metadata associated with the file. * - * @param $endpoint - * @param $uploadSessionId * @return boolean * * @throws FacebookSDKException */ - public function finish($endpoint, $uploadSessionId) + public function finish($endpoint, $uploadSessionId, $metadata = []) { - $finishReqParams = [ + $params = array_merge($metadata, [ 'upload_phase' => 'finish', 'upload_session_id' => $uploadSessionId, - ]; - - $request = new FacebookRequest( - $this->app, - $this->accessToken, - 'POST', - $endpoint, - $finishReqParams, - null, - $this->graphVersion - ); + ]); + $request = $this->makeUploadRequest($endpoint, $params); $response = $this->client->sendRequest($request)->getDecodedBody(); return $response['success']; } + + /** + * Helper to make FacebookRequest entities. + * + * @param string $endpoint The endpoint to POST to. + * @param array $params The params to send with the request. + * + * @return FacebookRequest + */ + private function makeUploadRequest($endpoint, $params = []) + { + return new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion); + } } diff --git a/src/Facebook/FileUpload/FacebookResumeContext.php b/src/Facebook/FileUpload/FacebookResumeContext.php deleted file mode 100644 index 490739535..000000000 --- a/src/Facebook/FileUpload/FacebookResumeContext.php +++ /dev/null @@ -1,98 +0,0 @@ -accessToken = $accessToken; - $this->chunk = $chunk; - $this->endpoint = $endpoint; - $this->maxTransferTries = $maxTransferTries; - } - - /** - * @return string - */ - public function getEndpoint() - { - return $this->endpoint; - } - - /** - * @return FacebookTransferChunk - */ - public function getChunk() - { - return $this->chunk; - } - - /** - * @return string - */ - public function getAccessToken() - { - return $this->accessToken; - } - - /** - * @return int - */ - public function getMaxTransferTries() - { - return $this->maxTransferTries; - } -} diff --git a/src/Facebook/FileUpload/FacebookTransferChunk.php b/src/Facebook/FileUpload/FacebookTransferChunk.php index fa0158bac..356c14ef1 100644 --- a/src/Facebook/FileUpload/FacebookTransferChunk.php +++ b/src/Facebook/FileUpload/FacebookTransferChunk.php @@ -28,52 +28,69 @@ * * @package Facebook */ -class FacebookTransferChunk extends FacebookVideo +class FacebookTransferChunk { /** - * @var int ID of the upload session + * @var FacebookFile The file to chunk during upload. + */ + private $file; + + /** + * @var int The ID of the upload session. */ private $uploadSessionId; /** - * @var int Start byte position of the next file chunk + * @var int Start byte position of the next file chunk. */ private $startOffset; /** - * @var int The maximum bytes to read + * @var int End byte position of the next file chunk. */ - private $maxLen = -1; + private $endOffset; /** - * @var int ID of the video + * @var int The ID of the video. */ private $videoId; /** - * @param string $filePath + * @param FacebookFile $file * @param int $uploadSessionId * @param int $videoId * @param int $startOffset - * @param int $maxLen + * @param int $endOffset */ - public function __construct($filePath, $uploadSessionId, $videoId, $startOffset, $maxLen) + public function __construct(FacebookFile $file, $uploadSessionId, $videoId, $startOffset, $endOffset) { - parent::__construct($filePath); + $this->file = $file; $this->uploadSessionId = $uploadSessionId; - $this->startOffset = $startOffset; - $this->maxLen = $maxLen; $this->videoId = $videoId; + $this->startOffset = $startOffset; + $this->endOffset = $endOffset; + } + + /** + * Return the file entity. + * + * @return FacebookFile + */ + public function getFile() + { + return $this->file; } /** - * Return the contents of the file. + * Return a FacebookFile entity with partial content. * - * @return string + * @return FacebookFile */ - public function getContents() + public function getPartialFile() { - return stream_get_contents($this->stream, $this->maxLen, $this->startOffset); + $maxLength = $this->endOffset - $this->startOffset; + + return new FacebookFile($this->file->getFilePath(), $maxLength, $this->startOffset); } /** @@ -93,7 +110,7 @@ public function getUploadSessionId() */ public function isLastChunk() { - return $this->maxLen === 0; + return $this->startOffset === $this->endOffset; } /** diff --git a/tests/FileUpload/FacebookFileTest.php b/tests/FileUpload/FacebookFileTest.php index 1eb5c0bc9..686ee4ec6 100644 --- a/tests/FileUpload/FacebookFileTest.php +++ b/tests/FileUpload/FacebookFileTest.php @@ -27,7 +27,6 @@ class FacebookFileTest extends \PHPUnit_Framework_TestCase { - protected $testFile = ''; public function setUp() @@ -43,6 +42,14 @@ public function testCanOpenAndReadAndCloseAFile() $this->assertEquals('This is a text file used for testing. Let\'s dance.', $fileContents); } + public function testPartialFilesCanBeCreated() + { + $file = new FacebookFile($this->testFile, 14, 5); + $fileContents = $file->getContents(); + + $this->assertEquals('is a text file', $fileContents); + } + /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index aaa0992cd..eae7f0bcb 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -24,199 +24,144 @@ namespace Facebook\Tests; -use Facebook\Exceptions\FacebookResponseException; -use Facebook\Exceptions\FacebookResumableUploadException; -use Facebook\Exceptions\FacebookSDKException; +use Facebook\FileUpload\FacebookFile; use Facebook\FacebookApp; use Facebook\FacebookClient; use Facebook\FileUpload\FacebookResumableUploader; -use Facebook\Http\GraphRawResponse; -use Facebook\HttpClients\FacebookHttpClientInterface; +use Facebook\FileUpload\FacebookTransferChunk; +use Facebook\FacebookRequest; +use Facebook\FacebookResponse; -class VideoUploadClientHandlerSuccess implements FacebookHttpClientInterface +class FooFacebookClientForResumableUpload extends FacebookClient { - public function send($url, $method, $body, array $headers, $timeOut) - { - if (preg_split("/=/", explode('&', $body)[0])[1] == 'start') { - return $this->mockStart(); - } - - if (preg_split("/=/", explode('&', $body)[0])[1] == 'finish') { - return $this->mockFinish(); - } - - return $this->mockTransfer(); - } - - public function mockStart() - { - $header = [ - "Content-Type" => "application/json; charset=UTF-8", - "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", - "facebook-api-version" => "v2.3", - ]; - - $body = '{"video_id":"162719974059555","start_offset":"0","end_offset":"2087",' . - '"upload_session_id":"162719977392888"}'; - - return new GraphRawResponse($header, $body, 200); - } + protected $response = ''; - public function mockTransfer() + // Successful responses + public function setSuccessfulStartResponse() { - $header = [ - "Content-Type" => "application/json; charset=UTF-8", - "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", - "facebook-api-version" => "v2.3", - ]; - - $body = '{"start_offset":"2087","end_offset":"2087"}'; - - return new GraphRawResponse($header, $body, 200); + $this->response = '{"video_id":"1337","start_offset":"0","end_offset":"123","upload_session_id":"42"}'; } - public function mockFinish() + public function setSuccessfulTransferResponse() { - $header = [ - "Content-Type" => "application/json; charset=UTF-8", - "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", - "facebook-api-version" => "v2.3", - ]; - - $body = '{"success":true}'; - - return new GraphRawResponse($header, $body, 200); + $this->response = '{"start_offset":"124","end_offset":"223"}'; } -} -class VideoUploadClientHandlerFail implements FacebookHttpClientInterface -{ - public function send($url, $method, $body, array $headers, $timeOut) + public function setSuccessfulFinishResponse() { - if (preg_split("/=/", explode('&', $body)[0])[1] == 'start') { - return $this->mockStart(); - } - - if (preg_split("/=/", explode('&', $body)[0])[1] == 'finish') { - return $this->mockFinish(); - } - - return $this->mockTransfer(); + $this->response = '{"success":true}'; } - public function mockStart() + // Error responses + public function setFailedStartResponse() { - $header = [ - "Content-Type" => "application/json; charset=UTF-8", - "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", - "facebook-api-version" => "v2.3", - "WWW-Authenticate" => 'OAuth "Facebook Platform" "invalid_token" "Error validating access token', - ]; - - $body = '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . - '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . - '"type":"OAuthException","code":190,"error_subcode":463}}'; - - return new GraphRawResponse($header, $body, 400); + $this->response = '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . + '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . + '"type":"OAuthException","code":190,"error_subcode":463}}'; } - public function mockTransfer() + public function setFailedTransferResponse() { - $header = [ - "Content-Type" => "application/json; charset=UTF-8", - "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", - "facebook-api-version" => "v2.3", - "WWW-Authenticate" => 'OAuth "Facebook Platform" "invalid_token" "Error validating access token', - ]; - - $body = '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . - '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . - '"type":"OAuthException","code":190,"error_subcode":1363033}}'; - - return new GraphRawResponse($header, $body, 400); + $this->response = '{"error":{"message":"There was a problem uploading your video. Please try uploading it again.",' . + '"type":"FacebookApiException","code":6000,"error_subcode":1363019}}'; } - public function mockFinish() + public function sendRequest(FacebookRequest $request) { - $header = [ - "Content-Type" => "application/json; charset=UTF-8", - "Date" => "Mon, 10 Aug 2015 07:14:04 GMT", - "facebook-api-version" => "v2.3", - ]; + $returnResponse = new FacebookResponse($request, $this->response, 0, []); - $body = '{"success":true}'; + if ($returnResponse->isError()) { + throw $returnResponse->getThrownException(); + } - return new GraphRawResponse($header, $body, 200); + return $returnResponse; } } - class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase { /** * @var FacebookApp */ private $fbApp; + /** - * @var FacebookClient + * @var FooFacebookClientForResumableUpload */ - private $fbSuccessClient; + private $client; + /** - * @var FacebookClient + * @var FacebookFile */ - private $fbFailClient; + private $file; public function setUp() { $this->fbApp = new FacebookApp('app_id', 'app_secret'); - $this->fbSuccessClient = new FacebookClient(new VideoUploadClientHandlerSuccess()); - $this->fbFailClient = new FacebookClient(new VideoUploadClientHandlerFail()); + $this->client = new FooFacebookClientForResumableUpload(); + $this->file = new FacebookFile(__DIR__.'/../foo.txt'); } - public function testSuccess() + public function testResumableUploadCanStartTransferAndFinish() { - $fileUploader = new FacebookResumableUploader($this->fbApp, $this->fbSuccessClient, 'access_token'); - $endpoint = '/113582528973300/videos'; - $filePath = __DIR__ . '/../foo.mp4'; - $chunk = $fileUploader->start($endpoint, $filePath); + $this->client->setSuccessfulStartResponse(); + $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->assertEquals('162719977392888', $chunk->getUploadSessionId()); - $this->assertEquals('162719974059555', $chunk->getVideoId()); + $this->assertEquals('42', $chunk->getUploadSessionId()); + $this->assertEquals('1337', $chunk->getVideoId()); - $chunk = $fileUploader->transfer($endpoint, $chunk); - $this->assertEquals(2087, $chunk->getStartOffset()); + $this->client->setSuccessfulTransferResponse(); + $newChunk = $uploader->transfer($endpoint, $chunk); + $this->assertEquals('124', $newChunk->getStartOffset()); + $this->assertNotSame($newChunk, $chunk); - $this->assertTrue($fileUploader->finish($endpoint, $chunk->getUploadSessionId())); + $this->client->setSuccessfulFinishResponse(); + $finalResponse = $uploader->finish($endpoint, $chunk->getUploadSessionId(), []); + $this->assertTrue($finalResponse); } - public function testFail() + /** + * @expectedException \Facebook\Exceptions\FacebookResponseException + */ + public function testStartWillLetErrorResponsesThrow() { - $fileUploader = new FacebookResumableUploader($this->fbApp, $this->fbFailClient, 'access_token'); - $endpoint = '/113582528973300/videos'; - $filePath = __DIR__ . '/../foo.mp4'; - - $catchResException = false; - try { - $chunk = $fileUploader->start($endpoint, $filePath); - } catch (FacebookSDKException $e) { - $catchResException = true; - } - $this->assertTrue($catchResException); - - // get file chunk - $catchResumableException = false; - $successUploader = new FacebookResumableUploader($this->fbApp, $this->fbSuccessClient, 'access_token'); - $chunk = $successUploader->start($endpoint, $filePath); - try { - $chunk = $fileUploader->transfer($endpoint, $chunk); - } catch (FacebookSDKException $e) { - if ($e->getPrevious() instanceof FacebookResumableUploadException) { - $catchResumableException = true; - $this->assertInstanceOf('Facebook\FileUpload\FacebookResumeContext', - $e->getPrevious()->getResumeContext()); - } - } - $this->assertTrue($catchResumableException); + $this->client->setFailedStartResponse(); + $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); + + $chunk = $uploader->start('/me/videos', $this->file); + } + + public function testFailedResumableTransferWillNotThrowAndReturnSameChunk() + { + $this->client->setFailedTransferResponse(); + $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); + + $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); + $newChunk = $uploader->transfer('/me/videos', $chunk); + $this->assertSame($newChunk, $chunk); + } + + public function testCanGetSuccessfulTransferWithMaxTries() + { + $this->client->setSuccessfulTransferResponse(); + $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); + + $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); + $newChunk = $uploader->maxTriesTransfer('/me/videos', $chunk, 3); + $this->assertNotSame($newChunk, $chunk); } -} \ No newline at end of file + /** + * @expectedException \Facebook\Exceptions\FacebookResponseException + */ + public function testMaxingOutRetriesWillThrow() + { + $this->client->setFailedTransferResponse(); + $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); + + $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); + $newChunk = $uploader->maxTriesTransfer('/me/videos', $chunk, 3); + } +} From 09234df04bfc6257f391686270310444c5bb4b37 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 23 Sep 2015 21:52:45 -0500 Subject: [PATCH 180/407] Add resumable upload error subcode --- src/Facebook/Exceptions/FacebookResponseException.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 4aea23908..9ec7060b1 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -90,6 +90,7 @@ public static function create(FacebookResponse $response) case 467: return new static($response, new FacebookAuthenticationException($message, $code)); // Video upload resumable error + case 1363030: case 1363019: case 1363037: case 1363033: From e923eff7e2c6663d7db4bab57315d8ba084af966 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 23 Sep 2015 21:54:53 -0500 Subject: [PATCH 181/407] Remove test video file --- tests/foo.mp4 | Bin 2087 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/foo.mp4 diff --git a/tests/foo.mp4 b/tests/foo.mp4 deleted file mode 100644 index b5df99c881ccaabca1481c3fd301ea29c24b3ca4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2087 zcmb7EeQXp(6rbxC2NGy#gEbV`Qi>(^?sl)oL8}{D8$zQ;gpWiDLKVf*_08Ug1^maC%)HDN~5uvh?zR%(m=p$@sTrHU1HEOMzsUzIt*`V&z@>HGwtXl>_g;wBnEEqbVTrBB^ z#aNxj^IExV1F|4;V54N=>EHee&{=5N2`kbO6eKO41BFEaCos`fa8@e0kRV~=W7{T+ zp#XsFuxuqA+4giHX3G^cOnitC``CI-qGH(gwr=<(z*}`gPh1G`Sw}7nG?9@xV@w(R z>`H)S5qZ`l#{awLm?j)tkhQ}0YIKa*kDjjq-J90@i7gWz27+x=%Wu*F4#-e%i9UiK@ssd~R=D|>*sEra17?hi)iydy7A%Q`|P)l8|hK2?w zd5em~g`A33<05&TK|_|nM^Oz?3F)O2&-po?r73uCY%wKZzohWBEK^FC(i9isq(&XH zbOg>3hG8ffvq2o8^m;#_*_5g`vJBaMn!qwn8iHV>WHEvTAIV4}d>R+3!7SsY_@Ji9 zoDV`7%FwVRi8`P;kvRfyKnr}G47-3ip-Bm0*3A?_#Q>)pK2@(3Rd9_bs8fAPAfRJ| zb+{=bs6hlIa#NC`)N(;M`I021OCk@=BnX-cX;u+llsSVmB8CjCNgOx<@0aQ|uF=OU zvdUR4!HnQrB!(abIBFd6322;*bwCYRtO*(_pjzArX0|wieDEKKaq2t{VZPpAJv6DK zabzeO)`JkD@xElgBv9j7UJFpNA0|Wkf&+}eNmF&C8}EdfF|u*!NU zQH3$XmBKAREv^o3klY7qf#=cmSE_coj3TGy0cT|Y6c@X^4x$F8?l zo@zQ~4&JLk8MnHZc+|NadopuYE#fzHKi-6vRn5lv&mFkp70w(?yKLWYH%=TbEor?l z;hQ~ak(1_EJp*?-YW%kRpE~Gsm6IZl%?o}#-u!3I!VrDCVaDV8DPMoKw;^GHyhR&yQWx zd9dox%GxF6dS7R8@$km8Kkw`{w_Gheyt$*RWQ*sE9a~Lv{Jot+;}=S=b*)=$-d%}O zvX^t8&NhFUI`olUISwC!jPmw5FMkM^L(tN3*Qx=fm$z3pOp1XP3xI7`-pMFXfTBs% smq6Q55>W+lzwKp7RGmaEGZWTbNfdP?xV{8xM@*b+r)DKk8GADN51|1xg8%>k From ef58fb6ede92bf36d28707f57b723a59b06f06a2 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 23 Sep 2015 21:59:39 -0500 Subject: [PATCH 182/407] Fix PSR-2 error --- src/Facebook/GraphNodes/GraphGroup.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphGroup.php b/src/Facebook/GraphNodes/GraphGroup.php index 07a4dbd75..728b241fe 100644 --- a/src/Facebook/GraphNodes/GraphGroup.php +++ b/src/Facebook/GraphNodes/GraphGroup.php @@ -167,5 +167,4 @@ public function getVenue() { return $this->getField('venue'); } - } From 7a3a1092b3cf81bab78ed52bc7529ead4da5ccf7 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 24 Sep 2015 07:58:42 -0500 Subject: [PATCH 183/407] Add option to ignore warnings in code sniffer --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3c16c4a6..f03bd7904 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ $ composer global require squizlabs/php_codesniffer Then you can `cd` into the Facebook PHP SDK folder and run Code Sniffer against the `src/` directory. ``` bash -$ ~/.composer/vendor/bin/phpcs src --standard=psr2 -sp +$ ~/.composer/vendor/bin/phpcs src --standard=psr2 -spn ``` **Happy coding**! From d61ac6c6e220c4c577ce4a15b85863f77f59b4e9 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 24 Sep 2015 08:21:02 -0500 Subject: [PATCH 184/407] Few tweaks --- .../FileUpload/FacebookResumableUploader.php | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index caa7c4c0a..1a2c35969 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -87,9 +87,7 @@ public function start($endpoint, FacebookFile $file) 'upload_phase' => 'start', 'file_size' => $file->getSize(), ]; - $request = $this->makeUploadRequest($endpoint, $params); - - $response = $this->client->sendRequest($request)->getDecodedBody(); + $response = $this->sendUploadRequest($endpoint, $params); return new FacebookTransferChunk($file, $response['upload_session_id'], $response['video_id'], $response['start_offset'], $response['end_offset']); } @@ -113,10 +111,9 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow 'start_offset' => $chunk->getStartOffset(), 'video_file_chunk' => $chunk->getPartialFile(), ]; - $request = $this->makeUploadRequest($endpoint, $params); try { - $response = $this->client->sendRequest($request)->getDecodedBody(); + $response = $this->sendUploadRequest($endpoint, $params); } catch (FacebookResponseException $e) { $preException = $e->getPrevious(); if ($allowToThrow || !$preException instanceof FacebookResumableUploadException) { @@ -174,23 +171,23 @@ public function finish($endpoint, $uploadSessionId, $metadata = []) 'upload_phase' => 'finish', 'upload_session_id' => $uploadSessionId, ]); - $request = $this->makeUploadRequest($endpoint, $params); - - $response = $this->client->sendRequest($request)->getDecodedBody(); + $response = $this->sendUploadRequest($endpoint, $params); return $response['success']; } /** - * Helper to make FacebookRequest entities. + * Helper to make a FacebookRequest and send it. * * @param string $endpoint The endpoint to POST to. * @param array $params The params to send with the request. * - * @return FacebookRequest + * @return array */ - private function makeUploadRequest($endpoint, $params = []) + private function sendUploadRequest($endpoint, $params = []) { - return new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion); + $request = new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion); + + return $this->client->sendRequest($request)->getDecodedBody(); } } From 44489b8e8200ca9d2b9db9d473dcaa0714acf068 Mon Sep 17 00:00:00 2001 From: SammyK Date: Wed, 30 Sep 2015 10:22:43 -0500 Subject: [PATCH 185/407] Move maxTriesTransfer() from uploader to main Facebook service class --- src/Facebook/Facebook.php | 49 +++++++++++++++---- .../FileUpload/FacebookResumableUploader.php | 27 ---------- tests/FacebookTest.php | 36 ++++++++++++++ .../FacebookResumableUploaderTest.php | 22 --------- 4 files changed, 75 insertions(+), 59 deletions(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 253fcf319..e7b3a42d5 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -27,6 +27,7 @@ use Facebook\Authentication\OAuth2Client; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookResumableUploader; +use Facebook\FileUpload\FacebookTransferChunk; use Facebook\FileUpload\FacebookVideo; use Facebook\GraphNodes\GraphEdge; use Facebook\Url\UrlDetectionInterface; @@ -591,12 +592,12 @@ public function videoToUpload($pathToFile) /** * Upload a video in chunks. * - * @param int $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. + * @param int $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 * @@ -604,16 +605,16 @@ public function videoToUpload($pathToFile) */ public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = null, $maxTransferTries = 5, $graphVersion = null) { - $accessToken = $accessToken ?: $this->defaultAccessToken; + $accessToken = $accessToken ?: $this->defaultAccessToken; $graphVersion = $graphVersion ?: $this->defaultGraphVersion; $uploader = new FacebookResumableUploader($this->app, $this->client, $accessToken, $graphVersion); $endpoint = '/'.$target.'/videos'; - $file = $this->videoToUpload($pathToFile); - $chunk = $uploader->start($endpoint, $file); + $file = $this->videoToUpload($pathToFile); + $chunk = $uploader->start($endpoint, $file); do { - $chunk = $uploader->maxTriesTransfer($endpoint, $chunk, $maxTransferTries); + $chunk = $this->maxTriesTransfer($uploader, $endpoint, $chunk, $maxTransferTries); } while (!$chunk->isLastChunk()); return [ @@ -621,4 +622,32 @@ public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId(), $metadata), ]; } + + /** + * Attempts to upload a chunk of a file in $retryCountdown tries. + * + * @param FacebookResumableUploader $uploader + * @param string $endpoint + * @param FacebookTransferChunk $chunk + * @param int $retryCountdown + * + * @return FacebookTransferChunk + * + * @throws FacebookSDKException + */ + public function maxTriesTransfer(FacebookResumableUploader $uploader, $endpoint, FacebookTransferChunk $chunk, $retryCountdown) + { + $allowToThrow = $retryCountdown < 1; + + $newChunk = $uploader->transfer($endpoint, $chunk, $allowToThrow); + + if ($newChunk !== $chunk) { + return $newChunk; + } + + $retryCountdown--; + + // If transfer() returned the same chunk entity, the transfer failed but is resumable. + return $this->maxTriesTransfer($uploader, $endpoint, $chunk, $retryCountdown); + } } diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 1a2c35969..36c14c885 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -127,33 +127,6 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow return new FacebookTransferChunk($chunk->getFile(), $chunk->getUploadSessionId(), $chunk->getVideoId(), $response['start_offset'], $response['end_offset']); } - /** - * Attempts to upload a chunk of a file in $retryCountdown tries. - * - * @param string $endpoint - * @param FacebookTransferChunk $chunk - * @param int $retryCountdown - * - * @return FacebookTransferChunk - * - * @throws FacebookResponseException - */ - public function maxTriesTransfer($endpoint, FacebookTransferChunk $chunk, $retryCountdown) - { - $allowToThrow = $retryCountdown < 1; - - $newChunk = $this->transfer($endpoint, $chunk, $allowToThrow); - - if ($newChunk !== $chunk) { - return $newChunk; - } - - $retryCountdown--; - - // If transfer() returned the same chunk entity, the transfer failed but is resumable. - return $this->maxTriesTransfer($endpoint, $chunk, $retryCountdown); - } - /** * Upload by chunks - finish phase * diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 36486655b..3c70672fb 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -23,6 +23,7 @@ */ namespace Facebook\Tests; +use Mockery as m; use Facebook\Facebook; use Facebook\FacebookClient; use Facebook\Http\GraphRawResponse; @@ -33,6 +34,8 @@ use Facebook\FacebookRequest; use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphEdge; +use Facebook\FileUpload\FacebookFile; +use Facebook\FileUpload\FacebookTransferChunk; class FooClientInterface implements FacebookHttpClientInterface { @@ -378,4 +381,37 @@ public function testPaginationReturnsProperResponse() $this->assertInstanceOf('Facebook\FacebookResponse', $lastResponse); $this->assertEquals(1337, $lastResponse->getHttpStatusCode()); } + + public function testCanGetSuccessfulTransferWithMaxTries() + { + $chunk = new FacebookTransferChunk(new FacebookFile(__DIR__.'/foo.txt'), '1', '2', '3', '4'); + $newChunk = new FacebookTransferChunk(new FacebookFile(__DIR__.'/foo.txt'), '11', '12', '13', '14'); + + $uploader = m::mock('Facebook\FileUpload\FacebookResumableUploader'); + $uploader->shouldReceive('transfer') + ->once() + ->andReturn($newChunk); + + $fb = new Facebook($this->config); + $newChunk = $fb->maxTriesTransfer($uploader, '/me/videos', $chunk, 3); + $this->assertNotSame($newChunk, $chunk); + } + + public function testMaxingOutRetriesWillFail() + { + $chunk = new FacebookTransferChunk(new FacebookFile(__DIR__.'/foo.txt'), '1', '2', '3', '4'); + + $uploader = m::mock('Facebook\FileUpload\FacebookResumableUploader'); + $uploader->shouldReceive('transfer') + ->twice() + ->andReturn($chunk); + $uploader->shouldReceive('transfer') + ->once() + ->andReturn('Final fail'); + + $fb = new Facebook($this->config); + $newChunk = $fb->maxTriesTransfer($uploader, '/me/videos', $chunk, 3); + + $this->assertEquals('Final fail', $newChunk); + } } diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index eae7f0bcb..e67220eef 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -142,26 +142,4 @@ public function testFailedResumableTransferWillNotThrowAndReturnSameChunk() $newChunk = $uploader->transfer('/me/videos', $chunk); $this->assertSame($newChunk, $chunk); } - - public function testCanGetSuccessfulTransferWithMaxTries() - { - $this->client->setSuccessfulTransferResponse(); - $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); - - $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); - $newChunk = $uploader->maxTriesTransfer('/me/videos', $chunk, 3); - $this->assertNotSame($newChunk, $chunk); - } - - /** - * @expectedException \Facebook\Exceptions\FacebookResponseException - */ - public function testMaxingOutRetriesWillThrow() - { - $this->client->setFailedTransferResponse(); - $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); - - $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); - $newChunk = $uploader->maxTriesTransfer('/me/videos', $chunk, 3); - } } From b968dcaa4cb9fca8e7e34b0d3ccd8d1b211fab75 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 2 Oct 2015 00:05:49 -0500 Subject: [PATCH 186/407] Refactor maxTriesTransfer() to be private and refactor tests --- src/Facebook/Facebook.php | 6 +- tests/FacebookTest.php | 49 ++++---- .../FakeGraphApiForResumableUpload.php | 111 ++++++++++++++++++ .../FacebookResumableUploaderTest.php | 70 ++--------- 4 files changed, 147 insertions(+), 89 deletions(-) create mode 100644 tests/FakeGraphApi/FakeGraphApiForResumableUpload.php diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index e7b3a42d5..d4788aba0 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -635,11 +635,9 @@ public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = * * @throws FacebookSDKException */ - public function maxTriesTransfer(FacebookResumableUploader $uploader, $endpoint, FacebookTransferChunk $chunk, $retryCountdown) + private function maxTriesTransfer(FacebookResumableUploader $uploader, $endpoint, FacebookTransferChunk $chunk, $retryCountdown) { - $allowToThrow = $retryCountdown < 1; - - $newChunk = $uploader->transfer($endpoint, $chunk, $allowToThrow); + $newChunk = $uploader->transfer($endpoint, $chunk, $retryCountdown < 1); if ($newChunk !== $chunk) { return $newChunk; diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 3c70672fb..b17aaa3d8 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -23,7 +23,6 @@ */ namespace Facebook\Tests; -use Mockery as m; use Facebook\Facebook; use Facebook\FacebookClient; use Facebook\Http\GraphRawResponse; @@ -34,8 +33,7 @@ use Facebook\FacebookRequest; use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphEdge; -use Facebook\FileUpload\FacebookFile; -use Facebook\FileUpload\FacebookTransferChunk; +use Facebook\Tests\FakeGraphApi\FakeGraphApiForResumableUpload; class FooClientInterface implements FacebookHttpClientInterface { @@ -384,34 +382,29 @@ public function testPaginationReturnsProperResponse() public function testCanGetSuccessfulTransferWithMaxTries() { - $chunk = new FacebookTransferChunk(new FacebookFile(__DIR__.'/foo.txt'), '1', '2', '3', '4'); - $newChunk = new FacebookTransferChunk(new FacebookFile(__DIR__.'/foo.txt'), '11', '12', '13', '14'); - - $uploader = m::mock('Facebook\FileUpload\FacebookResumableUploader'); - $uploader->shouldReceive('transfer') - ->once() - ->andReturn($newChunk); - - $fb = new Facebook($this->config); - $newChunk = $fb->maxTriesTransfer($uploader, '/me/videos', $chunk, 3); - $this->assertNotSame($newChunk, $chunk); + $config = array_merge($this->config, [ + 'http_client_handler' => new FakeGraphApiForResumableUpload(), + ]); + $fb = new Facebook($config); + $response = $fb->uploadVideo('me', __DIR__.'/foo.txt', [], 'foo-token', 3); + $this->assertEquals([ + 'video_id' => '1337', + 'success' => true, + ], $response); } - public function testMaxingOutRetriesWillFail() + /** + * @expectedException \Facebook\Exceptions\FacebookResponseException + */ + public function testMaxingOutRetriesWillThrow() { - $chunk = new FacebookTransferChunk(new FacebookFile(__DIR__.'/foo.txt'), '1', '2', '3', '4'); - - $uploader = m::mock('Facebook\FileUpload\FacebookResumableUploader'); - $uploader->shouldReceive('transfer') - ->twice() - ->andReturn($chunk); - $uploader->shouldReceive('transfer') - ->once() - ->andReturn('Final fail'); - - $fb = new Facebook($this->config); - $newChunk = $fb->maxTriesTransfer($uploader, '/me/videos', $chunk, 3); + $client = new FakeGraphApiForResumableUpload(); + $client->failOnTransfer(); - $this->assertEquals('Final fail', $newChunk); + $config = array_merge($this->config, [ + 'http_client_handler' => $client, + ]); + $fb = new Facebook($config); + $response = $fb->uploadVideo('4', __DIR__.'/foo.txt', [], 'foo-token', 3); } } diff --git a/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php b/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php new file mode 100644 index 000000000..76fb20d7c --- /dev/null +++ b/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php @@ -0,0 +1,111 @@ +respondWith = 'FAIL_ON_START'; + } + + public function failOnTransfer() + { + $this->respondWith = 'FAIL_ON_TRANSFER'; + } + + public function send($url, $method, $body, array $headers, $timeOut) + { + // Could be start, transfer or finish + if (strpos($body, 'transfer') !== false) { + return $this->respondTransfer(); + } elseif (strpos($body, 'finish') !== false) { + return $this->respondFinish(); + } + + return $this->respondStart(); + } + + private function respondStart() + { + if ($this->respondWith == 'FAIL_ON_START') { + return new GraphRawResponse( + "HTTP/1.1 500 OK\r\nFoo: Bar", + '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . + '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . + '"type":"OAuthException","code":190,"error_subcode":463}}' + ); + } + + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nFoo: Bar", + '{"video_id":"1337","start_offset":"0","end_offset":"20","upload_session_id":"42"}' + ); + } + + private function respondTransfer() + { + if ($this->respondWith == 'FAIL_ON_TRANSFER') { + return new GraphRawResponse( + "HTTP/1.1 500 OK\r\nFoo: Bar", + '{"error":{"message":"There was a problem uploading your video. Please try uploading it again.",' . + '"type":"FacebookApiException","code":6000,"error_subcode":1363019}}' + ); + } + + switch ($this->transferCount) { + case 0: + $data = ['start_offset' => 20, 'end_offset' => 40]; + break; + case 1: + $data = ['start_offset' => 40, 'end_offset' => 50]; + break; + default: + $data = ['start_offset' => 50, 'end_offset' => 50]; + break; + } + + $this->transferCount++; + + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nFoo: Bar", + json_encode($data) + ); + } + + private function respondFinish() + { + return new GraphRawResponse( + "HTTP/1.1 200 OK\r\nFoo: Bar", + '{"success":true}' + ); + } +} diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index e67220eef..f021c7fa2 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -22,61 +22,14 @@ * */ -namespace Facebook\Tests; +namespace Facebook\Tests\FileUpload; use Facebook\FileUpload\FacebookFile; use Facebook\FacebookApp; use Facebook\FacebookClient; use Facebook\FileUpload\FacebookResumableUploader; use Facebook\FileUpload\FacebookTransferChunk; -use Facebook\FacebookRequest; -use Facebook\FacebookResponse; - -class FooFacebookClientForResumableUpload extends FacebookClient -{ - protected $response = ''; - - // Successful responses - public function setSuccessfulStartResponse() - { - $this->response = '{"video_id":"1337","start_offset":"0","end_offset":"123","upload_session_id":"42"}'; - } - - public function setSuccessfulTransferResponse() - { - $this->response = '{"start_offset":"124","end_offset":"223"}'; - } - - public function setSuccessfulFinishResponse() - { - $this->response = '{"success":true}'; - } - - // Error responses - public function setFailedStartResponse() - { - $this->response = '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . - '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . - '"type":"OAuthException","code":190,"error_subcode":463}}'; - } - - public function setFailedTransferResponse() - { - $this->response = '{"error":{"message":"There was a problem uploading your video. Please try uploading it again.",' . - '"type":"FacebookApiException","code":6000,"error_subcode":1363019}}'; - } - - public function sendRequest(FacebookRequest $request) - { - $returnResponse = new FacebookResponse($request, $this->response, 0, []); - - if ($returnResponse->isError()) { - throw $returnResponse->getThrownException(); - } - - return $returnResponse; - } -} +use Facebook\Tests\FakeGraphApi\FakeGraphApiForResumableUpload; class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase { @@ -86,10 +39,15 @@ class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase private $fbApp; /** - * @var FooFacebookClientForResumableUpload + * @var FacebookClient */ private $client; + /** + * @var FakeGraphApiForResumableUpload + */ + private $graphApi; + /** * @var FacebookFile */ @@ -98,13 +56,13 @@ class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase public function setUp() { $this->fbApp = new FacebookApp('app_id', 'app_secret'); - $this->client = new FooFacebookClientForResumableUpload(); + $this->graphApi = new FakeGraphApiForResumableUpload(); + $this->client = new FacebookClient($this->graphApi); $this->file = new FacebookFile(__DIR__.'/../foo.txt'); } public function testResumableUploadCanStartTransferAndFinish() { - $this->client->setSuccessfulStartResponse(); $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); $endpoint = '/me/videos'; $chunk = $uploader->start($endpoint, $this->file); @@ -112,12 +70,10 @@ public function testResumableUploadCanStartTransferAndFinish() $this->assertEquals('42', $chunk->getUploadSessionId()); $this->assertEquals('1337', $chunk->getVideoId()); - $this->client->setSuccessfulTransferResponse(); $newChunk = $uploader->transfer($endpoint, $chunk); - $this->assertEquals('124', $newChunk->getStartOffset()); + $this->assertEquals(20, $newChunk->getStartOffset()); $this->assertNotSame($newChunk, $chunk); - $this->client->setSuccessfulFinishResponse(); $finalResponse = $uploader->finish($endpoint, $chunk->getUploadSessionId(), []); $this->assertTrue($finalResponse); } @@ -127,7 +83,7 @@ public function testResumableUploadCanStartTransferAndFinish() */ public function testStartWillLetErrorResponsesThrow() { - $this->client->setFailedStartResponse(); + $this->graphApi->failOnStart(); $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); $chunk = $uploader->start('/me/videos', $this->file); @@ -135,7 +91,7 @@ public function testStartWillLetErrorResponsesThrow() public function testFailedResumableTransferWillNotThrowAndReturnSameChunk() { - $this->client->setFailedTransferResponse(); + $this->graphApi->failOnTransfer(); $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); From d2f095764323f6338d6b06cbbf7a39712898bb94 Mon Sep 17 00:00:00 2001 From: SammyK Date: Fri, 2 Oct 2015 10:48:46 -0500 Subject: [PATCH 187/407] Update docs to include resumable upload feature --- docs/Facebook.fbmd | 57 ++++++++++++++++++++++++++++++++++ docs/FacebookFile.fbmd | 5 +-- docs/FacebookVideo.fbmd | 25 +++++++++++++-- docs/example_upload_video.fbmd | 32 +++++++++++++++++-- 4 files changed, 113 insertions(+), 6 deletions(-) diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 7286a3f10..90f52260a 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -495,4 +495,61 @@ $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; ~~~~ + +## uploadVideo() {#upload-video} +~~~~ +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](/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](/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](/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 + +~~~~ +// 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/FacebookFile.fbmd b/docs/FacebookFile.fbmd index 3242b8a7a..4f90859b7 100644 --- a/docs/FacebookFile.fbmd +++ b/docs/FacebookFile.fbmd @@ -5,7 +5,7 @@ Uploading files to the Graph API is made a breeze with the Facebook SDK for PHP.
-## Facebook\FileUpload\FacebookFile(string $pathToFile) {#overview} +## Facebook\FileUpload\FacebookFile(string $pathToFile, int $maxLength = -1, int $offset = -1) {#overview} The `FacebookFile` entity represents a local or remote file to be uploaded with a request to Graph. @@ -17,7 +17,6 @@ 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. ~~~~ @@ -25,6 +24,8 @@ $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). diff --git a/docs/FacebookVideo.fbmd b/docs/FacebookVideo.fbmd index f24242b77..2227a684a 100644 --- a/docs/FacebookVideo.fbmd +++ b/docs/FacebookVideo.fbmd @@ -5,7 +5,7 @@ Uploading video files to the Graph API is made a breeze with the SDK for PHP. -## Facebook\FileUpload\FacebookVideo(string $pathToVideoFile) {#overview} +## Facebook\FileUpload\FacebookVideo(string $pathToVideoFile, int $maxLength = -1, int $offset = -1) {#overview} The `FacebookVideo` entity represents a local or remote video file to be uploaded with a request to Graph. @@ -24,12 +24,33 @@ $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 {#usage} -The following example uploads a video for a user. +In Graph v2.3, functionality was added to [upload video files in chunks](/docs/graph-api/video-uploads#resumable). The PHP SDK provides a handy API to easily upload video files in chunks via the [`uploadVideo()` method](/docs/php/Facebook#upload-video). + +~~~~ +// 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. ~~~~ // Upload a video for a user diff --git a/docs/example_upload_video.fbmd b/docs/example_upload_video.fbmd index 375cac1a7..bfa340f88 100644 --- a/docs/example_upload_video.fbmd +++ b/docs/example_upload_video.fbmd @@ -12,13 +12,42 @@ This example covers uploading & posting a video to a user's timeline with the Fa type: 'warning', }) +The following example will upload a video in chunks using the [resumable upload](/docs/graph-api/video-uploads#resumable) feature added in Graph v2.3. + ~~~~ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.4', ]); +$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](/docs/php/Facebook#upload-video). + +For versions of Graph before v2.3, videos had to be uploaded in one request. + +~~~~ +$fb = new Facebook\Facebook([/* . . . */]); + $data = [ 'title' => 'My Foo Video', 'description' => 'This video is full of foo and bar action.', @@ -38,7 +67,6 @@ try { } $graphNode = $response->getGraphNode(); -var_dump($graphNode); echo 'Video ID: ' . $graphNode['id']; ~~~~ From f2efd38cffd562aa7fdfaf3bf389f5e95ac3103e Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Mon, 5 Oct 2015 14:27:30 -0700 Subject: [PATCH 188/407] Don't convert 0 timestamp to Date, to support non-expiring tokens. --- src/Facebook/Authentication/AccessTokenMetadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Authentication/AccessTokenMetadata.php b/src/Facebook/Authentication/AccessTokenMetadata.php index f302a6d2f..daa2e1073 100644 --- a/src/Facebook/Authentication/AccessTokenMetadata.php +++ b/src/Facebook/Authentication/AccessTokenMetadata.php @@ -382,7 +382,7 @@ private function convertTimestampToDateTime($timestamp) private function castTimestampsToDateTime() { foreach (static::$dateProperties as $key) { - if (isset($this->metadata[$key])) { + if (isset($this->metadata[$key]) && $this->metadata[$key] !== 0) { $this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]); } } From 540015d33ec5d27485cf466ccb69ed67dcc6ae93 Mon Sep 17 00:00:00 2001 From: SammyK Date: Thu, 8 Oct 2015 21:12:25 -0500 Subject: [PATCH 189/407] Update Graph version to v2.5 --- README.md | 2 +- docs/Facebook.fbmd | 8 ++++---- docs/FacebookRequest.fbmd | 2 +- docs/example_access_token_from_canvas.fbmd | 2 +- docs/example_access_token_from_javascript.fbmd | 4 ++-- docs/example_access_token_from_page_tab.fbmd | 2 +- docs/example_batch_request.fbmd | 4 ++-- docs/example_batch_upload.fbmd | 2 +- docs/example_facebook_login.fbmd | 4 ++-- docs/example_pagination_basic.fbmd | 4 ++-- docs/example_post_links.fbmd | 2 +- docs/example_retrieve_user_profile.fbmd | 2 +- docs/example_upload_photo.fbmd | 2 +- docs/example_upload_video.fbmd | 2 +- docs/sdk_getting_started.fbmd | 2 +- src/Facebook/Facebook.php | 2 +- src/Facebook/GraphNodes/GraphAchievement.php | 2 +- 17 files changed, 24 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7d60e6e87..8d5158c2d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Simple GET example of a user's profile. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.4', + 'default_graph_version' => 'v2.5', //'default_access_token' => '{access-token}', // optional ]); diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index 90f52260a..b081f0ed3 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -13,7 +13,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.4', + 'default_graph_version' => 'v2.5', // . . . ]); ~~~~ @@ -53,7 +53,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.4', + 'default_graph_version' => 'v2.5', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), @@ -74,7 +74,7 @@ The default fallback access token to use if one is not explicitly provided. The Enable [beta mode](/docs/support/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` {#defaultversion} -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.0`. Defaults to the latest version of Graph. +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.5`. Defaults to the [latest version of Graph](/docs/apps/changelog). ### `http_client_handler` {#httpclient} Allows you to overwrite the default HTTP client. @@ -326,7 +326,7 @@ public Facebook\FacebookResponse sendRequest( Sends a request to the Graph API. ~~~~ -$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.2'); +$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.5'); ~~~~ ## sendBatchRequest() {#send-batch-request} diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index da487b357..8f9948331 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -211,6 +211,6 @@ $fb = new Facebook\Facebook(/* . . . */); $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); -// /v2.2/me?fields=id,name&access_token=token&appsecret_proof=proof +// /v2.5/me?fields=id,name&access_token=token&appsecret_proof=proof ~~~~ diff --git a/docs/example_access_token_from_canvas.fbmd b/docs/example_access_token_from_canvas.fbmd index a4571e2ac..9cfd361f3 100644 --- a/docs/example_access_token_from_canvas.fbmd +++ b/docs/example_access_token_from_canvas.fbmd @@ -13,7 +13,7 @@ A signed request will be sent to your app via the HTTP POST method within the co $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $helper = $fb->getCanvasHelper(); diff --git a/docs/example_access_token_from_javascript.fbmd b/docs/example_access_token_from_javascript.fbmd index 9fa2b8aca..e2b049eb2 100644 --- a/docs/example_access_token_from_javascript.fbmd +++ b/docs/example_access_token_from_javascript.fbmd @@ -32,7 +32,7 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh FB.init({ appId: 'your-app-id', cookie: true, // This is important, it's not enabled by default - version: 'v2.2' + version: 'v2.5' }); }; @@ -55,7 +55,7 @@ After the user successfully logs in, redirect the user (or make an AJAX request) $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $helper = $fb->getJavaScriptHelper(); diff --git a/docs/example_access_token_from_page_tab.fbmd b/docs/example_access_token_from_page_tab.fbmd index 447463335..b093ba6e7 100644 --- a/docs/example_access_token_from_page_tab.fbmd +++ b/docs/example_access_token_from_page_tab.fbmd @@ -13,7 +13,7 @@ Page tabs behave much like the app canvas. The PHP SDK provides a helper for pag $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $helper = $fb->getPageTabHelper(); diff --git a/docs/example_batch_request.fbmd b/docs/example_batch_request.fbmd index 1d31684c5..eb364d635 100644 --- a/docs/example_batch_request.fbmd +++ b/docs/example_batch_request.fbmd @@ -13,7 +13,7 @@ The following example assumes we have the following permissions granted from the $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); // Since all the requests will be sent on behalf of the same user, @@ -114,7 +114,7 @@ Since the requests sent in a batch are unrelated by default, we can make request $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $batch = [ diff --git a/docs/example_batch_upload.fbmd b/docs/example_batch_upload.fbmd index 14ac292fa..5d58f7629 100644 --- a/docs/example_batch_upload.fbmd +++ b/docs/example_batch_upload.fbmd @@ -15,7 +15,7 @@ The following example will upload two photos and one video. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); // Since all the requests will be sent on behalf of the same user, diff --git a/docs/example_facebook_login.fbmd b/docs/example_facebook_login.fbmd index 58473596c..26f019db9 100644 --- a/docs/example_facebook_login.fbmd +++ b/docs/example_facebook_login.fbmd @@ -19,7 +19,7 @@ In this example, the PHP script that generates the login link is called `/login. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $helper = $fb->getRedirectLoginHelper(); @@ -38,7 +38,7 @@ echo 'Log in with Facebook!'; $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $helper = $fb->getRedirectLoginHelper(); diff --git a/docs/example_pagination_basic.fbmd b/docs/example_pagination_basic.fbmd index 41894b698..28521a476 100644 --- a/docs/example_pagination_basic.fbmd +++ b/docs/example_pagination_basic.fbmd @@ -7,7 +7,7 @@ This example covers basic cursor pagination with the Facebook SDK for PHP. ## Example {#example} -The Graph API supports [several methods to paginate over response data](https://developers.facebook.com/docs/graph-api/using-graph-api/v2.2#paging). The PHP SDK supports cursor-based pagination out of the box. It does all the heavy lifting of managing page cursors for you. +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. @@ -15,7 +15,7 @@ In this example we'll pull five entries from a user's feed (assuming the user ap $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); try { diff --git a/docs/example_post_links.fbmd b/docs/example_post_links.fbmd index 164d5196a..492e3bdff 100644 --- a/docs/example_post_links.fbmd +++ b/docs/example_post_links.fbmd @@ -15,7 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $linkData = [ diff --git a/docs/example_retrieve_user_profile.fbmd b/docs/example_retrieve_user_profile.fbmd index a11f3126c..899e50322 100644 --- a/docs/example_retrieve_user_profile.fbmd +++ b/docs/example_retrieve_user_profile.fbmd @@ -15,7 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); try { diff --git a/docs/example_upload_photo.fbmd b/docs/example_upload_photo.fbmd index a88945afb..e7b90d180 100644 --- a/docs/example_upload_photo.fbmd +++ b/docs/example_upload_photo.fbmd @@ -15,7 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); $data = [ diff --git a/docs/example_upload_video.fbmd b/docs/example_upload_video.fbmd index bfa340f88..3d7356939 100644 --- a/docs/example_upload_video.fbmd +++ b/docs/example_upload_video.fbmd @@ -18,7 +18,7 @@ The following example will upload a video in chunks using the [resumable upload] $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.4', + 'default_graph_version' => 'v2.5', ]); $data = [ diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 71dba1e6f..0536b216e 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -117,7 +117,7 @@ Before we can send requests to the Graph API, we need to load our app configurat $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.2', + 'default_graph_version' => 'v2.5', ]); ~~~ diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index d4788aba0..b97e3bcc4 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -64,7 +64,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.4'; + const DEFAULT_GRAPH_VERSION = 'v2.5'; /** * @const string The name of the environment variable that contains the app ID. diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php index 3fba815c9..4a546f86d 100644 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -92,7 +92,7 @@ public function getData() /** * Returns the type of achievement. * - * @see https://developers.facebook.com/docs/graph-api/reference/v2.2/achievement + * @see https://developers.facebook.com/docs/graph-api/reference/achievement * * @return string */ From b192bb30905bc25a634a7864d6f0fd8f31a24ce3 Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Tue, 13 Oct 2015 23:39:32 +0200 Subject: [PATCH 190/407] added .gitattributes --- .gitattributes | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..898df38eb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +.gitattributes export-ignore +.gitignore export-ignore +.scrutinizer.yml export-ignore +.travis.yml export-ignore +CHANGELOG.md export-ignore +CONTRIBUTING.md export-ignore +docs export-ignore +phpunit.xml.dist export-ignore +README.md export-ignore +tests export-ignore From cc551f793492fa92ca107d596a6f1e3a62fb894c Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 13 Oct 2015 15:11:58 -0700 Subject: [PATCH 191/407] Updating to 5.1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8d5158c2d..f91c4067b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.0.0-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.0-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. @@ -15,7 +15,7 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). ```json { "require": { - "facebook/php-sdk-v4": "~5.0" + "facebook/php-sdk-v4": "~5.1" } } ``` From 67faf5fa188a81c67fd99302a914fb1788f9d53d Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Wed, 14 Oct 2015 12:49:52 +0200 Subject: [PATCH 192/407] added psr2 check to travis-ci --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index c3082dfd5..5d5684650 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,11 @@ before_install: - travis_retry composer self-update install: + - travis_retry composer require --dev --no-update squizlabs/php_codesniffer:~2.3 - travis_retry composer install --prefer-source --no-interaction script: + - vendor/bin/phpcs --standard=psr2 src/ - vendor/bin/phpunit --coverage-text --exclude-group integration matrix: From 4a59da92823e6e3d2f47e87de0dd84d39978d18a Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Wed, 14 Oct 2015 14:23:56 +0200 Subject: [PATCH 193/407] applied scripts from CONTRIBUTING.md --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5d5684650..9813280e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,11 +13,11 @@ before_install: - travis_retry composer self-update install: - - travis_retry composer require --dev --no-update squizlabs/php_codesniffer:~2.3 + - travis_retry composer require --dev --no-update squizlabs/php_codesniffer - travis_retry composer install --prefer-source --no-interaction script: - - vendor/bin/phpcs --standard=psr2 src/ + - vendor/bin/phpcs src --standard=psr2 -spn - vendor/bin/phpunit --coverage-text --exclude-group integration matrix: From 1928f6332526a9f163c5e22fb60baf591e936cdf Mon Sep 17 00:00:00 2001 From: Luke Shaheen Date: Wed, 14 Oct 2015 10:04:19 -0400 Subject: [PATCH 194/407] Include link to upgrade guide in readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f91c4067b..9ee00793b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). } ``` +## Upgrading to v5.x + +Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [read the upgrade guide](https://www.sammyk.me/upgrading-the-facebook-php-sdk-from-v4-to-v5) before upgrading. + ## Usage From b09067b7373fd7ba8ccf40b1c01663c4d78741e4 Mon Sep 17 00:00:00 2001 From: Luke Shaheen Date: Wed, 14 Oct 2015 13:48:10 -0400 Subject: [PATCH 195/407] Typo fix in FacebookApp doc --- docs/FacebookApp.fbmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index e17b09a24..4ee6bb07e 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -39,13 +39,13 @@ Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessTo ~~~~ public string getId() ~~~~ -Returns an the app id. +Returns the app id. ## getSecret() {#get-secret} ~~~~ public string getSecret() ~~~~ -Returns an the app secret. +Returns the app secret. ## Serialization {#serialization} From e3986fab5ba2c24bb15002a0bb0644816b5752b8 Mon Sep 17 00:00:00 2001 From: Luke Shaheen Date: Wed, 14 Oct 2015 13:50:19 -0400 Subject: [PATCH 196/407] Revert "Typo fix in FacebookApp doc" This reverts commit b09067b7373fd7ba8ccf40b1c01663c4d78741e4. --- docs/FacebookApp.fbmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index 4ee6bb07e..e17b09a24 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -39,13 +39,13 @@ Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessTo ~~~~ public string getId() ~~~~ -Returns the app id. +Returns an the app id. ## getSecret() {#get-secret} ~~~~ public string getSecret() ~~~~ -Returns the app secret. +Returns an the app secret. ## Serialization {#serialization} From bd55939d2ed0c35b85086ebe53cb9fd6991b6726 Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Thu, 15 Oct 2015 02:06:21 +0200 Subject: [PATCH 197/407] moved runtime exception to native TypeError --- src/Facebook/Facebook.php | 23 +++++++++++------------ tests/FacebookTest.php | 9 ++++++--- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 227a16667..be3f4fe54 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -158,14 +158,6 @@ public function __construct(array $config = []) $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; $this->client = new FacebookClient($httpClientHandler, $enableBeta); - if (isset($config['url_detection_handler'])) { - if ($config['url_detection_handler'] instanceof UrlDetectionInterface) { - $this->urlDetectionHandler = $config['url_detection_handler']; - } else { - throw new \InvalidArgumentException('The url_detection_handler must be an instance of Facebook\Url\UrlDetectionInterface'); - } - } - if (isset($config['pseudo_random_string_generator'])) { if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) { $this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator']; @@ -191,6 +183,7 @@ public function __construct(array $config = []) throw new \InvalidArgumentException('The persistent_data_handler must be set to "session", "memory", or be an instance of Facebook\PersistentData\PersistentDataInterface'); } } + $this->setUrlDetectionHandler($config['url_detection_handler'] ?: new FacebookUrlDetectionHandler()); if (isset($config['default_access_token'])) { $this->setDefaultAccessToken($config['default_access_token']); @@ -257,13 +250,19 @@ public function getLastResponse() */ public function getUrlDetectionHandler() { - if (!$this->urlDetectionHandler instanceof UrlDetectionInterface) { - $this->urlDetectionHandler = new FacebookUrlDetectionHandler(); - } - return $this->urlDetectionHandler; } + /** + * Changes the URL detection handler. + * + * @param UrlDetectionInterface $urlDetectionHandler + */ + private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler) + { + $this->urlDetectionHandler = $urlDetectionHandler; + } + /** * Returns the default AccessToken entity. * diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 36486655b..98f81a8ab 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -176,11 +176,14 @@ public function testPersistentDataHandlerCanBeForced() ); } - /** - * @expectedException \InvalidArgumentException - */ public function testSettingAnInvalidUrlHandlerThrows() { + $expectedException = (PHP_MAJOR_VERSION > 5 && class_exists('TypeError')) + ? 'TypeError' + : 'PHPUnit_Framework_Error'; + + $this->setExpectedException($expectedException); + $config = array_merge($this->config, [ 'url_detection_handler' => 'foo_handler', ]); From a0dcde25ccc33b7537b98d7f160f65730ddf091b Mon Sep 17 00:00:00 2001 From: Luke Shaheen Date: Thu, 15 Oct 2015 08:02:23 -0400 Subject: [PATCH 198/407] Typo fix in FacebookApp doc --- docs/FacebookApp.fbmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/FacebookApp.fbmd b/docs/FacebookApp.fbmd index e17b09a24..4ee6bb07e 100644 --- a/docs/FacebookApp.fbmd +++ b/docs/FacebookApp.fbmd @@ -39,13 +39,13 @@ Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessTo ~~~~ public string getId() ~~~~ -Returns an the app id. +Returns the app id. ## getSecret() {#get-secret} ~~~~ public string getSecret() ~~~~ -Returns an the app secret. +Returns the app secret. ## Serialization {#serialization} From 979de7f8e5781ef0e2716b1049aebb022f1a4c46 Mon Sep 17 00:00:00 2001 From: Luke Shaheen Date: Thu, 15 Oct 2015 12:06:18 -0400 Subject: [PATCH 199/407] Change SDK version to 5.1.0 --- src/Facebook/Facebook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index b97e3bcc4..b2e8260b0 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -59,7 +59,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.0.0'; + const VERSION = '5.1.0'; /** * @const string Default Graph API version for requests. From fb4de4f35c6995babd672ee3e4b3cf00ce14c9b2 Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Thu, 15 Oct 2015 02:06:49 +0200 Subject: [PATCH 200/407] splitted complex constructor into different factories --- src/Facebook/Facebook.php | 96 ++++++------------ .../HttpClients/HttpClientsFactory.php | 98 +++++++++++++++++++ .../PersistentData/PersistentDataFactory.php | 65 ++++++++++++ .../PseudoRandomStringGeneratorFactory.php | 93 ++++++++++++++++++ 4 files changed, 286 insertions(+), 66 deletions(-) create mode 100644 src/Facebook/HttpClients/HttpClientsFactory.php create mode 100644 src/Facebook/PersistentData/PersistentDataFactory.php create mode 100644 src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index be3f4fe54..e91648dba 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -30,17 +30,11 @@ use Facebook\GraphNodes\GraphEdge; use Facebook\Url\UrlDetectionInterface; use Facebook\Url\FacebookUrlDetectionHandler; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; -use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; -use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; -use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; -use Facebook\HttpClients\FacebookHttpClientInterface; -use Facebook\HttpClients\FacebookCurlHttpClient; -use Facebook\HttpClients\FacebookStreamHttpClient; -use Facebook\HttpClients\FacebookGuzzleHttpClient; +use Facebook\HttpClients\HttpClientsFactory; +use Facebook\PersistentData\PersistentDataFactory; use Facebook\PersistentData\PersistentDataInterface; -use Facebook\PersistentData\FacebookSessionPersistentDataHandler; -use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; use Facebook\Helpers\FacebookCanvasHelper; use Facebook\Helpers\FacebookJavaScriptHelper; use Facebook\Helpers\FacebookPageTabHelper; @@ -128,73 +122,43 @@ class Facebook */ public function __construct(array $config = []) { - $appId = isset($config['app_id']) ? $config['app_id'] : getenv(static::APP_ID_ENV_NAME); - if (!$appId) { + $config = array_merge([ + 'app_id' => getenv(static::APP_ID_ENV_NAME), + 'app_secret' => getenv(static::APP_SECRET_ENV_NAME), + 'default_graph_version' => static::DEFAULT_GRAPH_VERSION, + 'enable_beta_mode' => false, + 'http_client_handler' => null, + 'persistent_data_handler' => null, + 'pseudo_random_string_generator' => null, + 'url_detection_handler' => null, + ], $config); + + if (!$config['app_id']) { throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"'); } - - $appSecret = isset($config['app_secret']) ? $config['app_secret'] : getenv(static::APP_SECRET_ENV_NAME); - if (!$appSecret) { + if (!$config['app_secret']) { throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"'); } - $this->app = new FacebookApp($appId, $appSecret); - - $httpClientHandler = null; - if (isset($config['http_client_handler'])) { - if ($config['http_client_handler'] instanceof FacebookHttpClientInterface) { - $httpClientHandler = $config['http_client_handler']; - } elseif ($config['http_client_handler'] === 'curl') { - $httpClientHandler = new FacebookCurlHttpClient(); - } elseif ($config['http_client_handler'] === 'stream') { - $httpClientHandler = new FacebookStreamHttpClient(); - } elseif ($config['http_client_handler'] === 'guzzle') { - $httpClientHandler = new FacebookGuzzleHttpClient(); - } else { - throw new \InvalidArgumentException('The http_client_handler must be set to "curl", "stream", "guzzle", or be an instance of Facebook\HttpClients\FacebookHttpClientInterface'); - } - } - - $enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; - $this->client = new FacebookClient($httpClientHandler, $enableBeta); - - if (isset($config['pseudo_random_string_generator'])) { - if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) { - $this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator']; - } elseif ($config['pseudo_random_string_generator'] === 'mcrypt') { - $this->pseudoRandomStringGenerator = new McryptPseudoRandomStringGenerator(); - } elseif ($config['pseudo_random_string_generator'] === 'openssl') { - $this->pseudoRandomStringGenerator = new OpenSslPseudoRandomStringGenerator(); - } elseif ($config['pseudo_random_string_generator'] === 'urandom') { - $this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator(); - } else { - throw new \InvalidArgumentException('The pseudo_random_string_generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface'); - } - } - - if (isset($config['persistent_data_handler'])) { - if ($config['persistent_data_handler'] instanceof PersistentDataInterface) { - $this->persistentDataHandler = $config['persistent_data_handler']; - } elseif ($config['persistent_data_handler'] === 'session') { - $this->persistentDataHandler = new FacebookSessionPersistentDataHandler(); - } elseif ($config['persistent_data_handler'] === 'memory') { - $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); - } else { - throw new \InvalidArgumentException('The persistent_data_handler must be set to "session", "memory", or be an instance of Facebook\PersistentData\PersistentDataInterface'); - } - } + $this->app = new FacebookApp($config['app_id'], $config['app_secret']); + $this->client = new FacebookClient( + HttpClientsFactory::createHttpClient($config['http_client_handler']), + $config['enable_beta_mode'] + ); + $this->pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator( + $config['pseudo_random_string_generator'] + ); $this->setUrlDetectionHandler($config['url_detection_handler'] ?: new FacebookUrlDetectionHandler()); + $this->persistentDataHandler = PersistentDataFactory::createPersistentDataHandler( + $config['persistent_data_handler'] + ); if (isset($config['default_access_token'])) { $this->setDefaultAccessToken($config['default_access_token']); } - if (isset($config['default_graph_version'])) { - $this->defaultGraphVersion = $config['default_graph_version']; - } else { - // @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set - $this->defaultGraphVersion = static::DEFAULT_GRAPH_VERSION; - } + // @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set + $this->defaultGraphVersion = $config['default_graph_version']; } /** @@ -255,7 +219,7 @@ public function getUrlDetectionHandler() /** * Changes the URL detection handler. - * + * * @param UrlDetectionInterface $urlDetectionHandler */ private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler) diff --git a/src/Facebook/HttpClients/HttpClientsFactory.php b/src/Facebook/HttpClients/HttpClientsFactory.php new file mode 100644 index 000000000..977a5cbbc --- /dev/null +++ b/src/Facebook/HttpClients/HttpClientsFactory.php @@ -0,0 +1,98 @@ + Date: Thu, 15 Oct 2015 23:07:55 +0200 Subject: [PATCH 201/407] added changelog and tests --- CHANGELOG.md | 1 + tests/HttpClients/HttpClientsFactoryTest.php | 68 +++++++++++++++++++ .../PersistentDataFactoryTest.php | 68 +++++++++++++++++++ .../PseudoRandomStringFactoryTest.php | 63 +++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 tests/HttpClients/HttpClientsFactoryTest.php create mode 100644 tests/PersistentData/PersistentDataFactoryTest.php create mode 100644 tests/PseudoRandomString/PseudoRandomStringFactoryTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index aeb629e10..55dc0ef68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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 diff --git a/tests/HttpClients/HttpClientsFactoryTest.php b/tests/HttpClients/HttpClientsFactoryTest.php new file mode 100644 index 000000000..78876b13d --- /dev/null +++ b/tests/HttpClients/HttpClientsFactoryTest.php @@ -0,0 +1,68 @@ +assertInstanceOf(self::COMMON_INTERFACE, $httpClient); + $this->assertInstanceOf($expected, $httpClient); + } + + /** + * @return array + */ + public function httpClientsProvider() + { + return [ + ['curl', self::COMMON_NAMESPACE . 'FacebookCurlHttpClient'], + ['guzzle', self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], + ['stream', self::COMMON_NAMESPACE . 'FacebookStreamHttpClient'], + [new Client(), self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], + [new FacebookCurlHttpClient(), self::COMMON_NAMESPACE . 'FacebookCurlHttpClient'], + [new FacebookGuzzleHttpClient(), self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], + [new FacebookStreamHttpClient(), self::COMMON_NAMESPACE . 'FacebookStreamHttpClient'], + [null, self::COMMON_INTERFACE], + ]; + } +} diff --git a/tests/PersistentData/PersistentDataFactoryTest.php b/tests/PersistentData/PersistentDataFactoryTest.php new file mode 100644 index 000000000..dfb871ce4 --- /dev/null +++ b/tests/PersistentData/PersistentDataFactoryTest.php @@ -0,0 +1,68 @@ +assertInstanceOf(self::COMMON_INTERFACE, $persistentDataHandler); + $this->assertInstanceOf($expected, $persistentDataHandler); + } + + /** + * @return array + */ + public function persistentDataHandlerProviders() + { + $handlers = [ + ['memory', self::COMMON_NAMESPACE . 'FacebookMemoryPersistentDataHandler'], + [new FacebookMemoryPersistentDataHandler(), self::COMMON_NAMESPACE . 'FacebookMemoryPersistentDataHandler'], + [new FacebookSessionPersistentDataHandler(false), self::COMMON_NAMESPACE . 'FacebookSessionPersistentDataHandler'], + [null, self::COMMON_INTERFACE], + ]; + + if (session_status() === PHP_SESSION_ACTIVE) { + $handlers[] = ['session', self::COMMON_NAMESPACE . 'FacebookSessionPersistentDataHandler']; + } + + return $handlers; + } +} diff --git a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php new file mode 100644 index 000000000..e6f2094f3 --- /dev/null +++ b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php @@ -0,0 +1,63 @@ +assertInstanceOf(self::COMMON_INTERFACE, $pseudoRandomStringGenerator); + $this->assertInstanceOf($expected, $pseudoRandomStringGenerator); + } + + /** + * @return array + */ + public function httpClientsProvider() + { + return [ + ['mcrypt', self::COMMON_NAMESPACE . 'McryptPseudoRandomStringGenerator'], + ['openssl', self::COMMON_NAMESPACE . 'OpenSslPseudoRandomStringGenerator'], + ['urandom', self::COMMON_NAMESPACE . 'UrandomPseudoRandomStringGenerator'], + [null, self::COMMON_INTERFACE], + ]; + } +} From 9ba45783bfa3d904383da239b8cbe8adc5674770 Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Fri, 16 Oct 2015 11:26:15 +0200 Subject: [PATCH 202/407] check curl extension --- src/Facebook/FacebookClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index b10762f1b..70a463e72 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -124,7 +124,7 @@ public function getHttpClientHandler() */ public function detectHttpClientHandler() { - return function_exists('curl_init') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient(); + return extension_loaded('curl') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient(); } /** From 94015dc715982708e5414ec607f469778fb114ae Mon Sep 17 00:00:00 2001 From: Rafael Dohms Date: Fri, 16 Oct 2015 12:02:35 +0200 Subject: [PATCH 203/407] Updating Composer install instructions The `require` command is the best way to add new dependencies to a project and runs with as little side effects as possible. Since last year it also binds properly to the latest version of the package. Its the recommended way to add new dependencies. --- README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9ee00793b..5219df685 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,10 @@ This repository contains the open source PHP SDK that allows you to access the F ## Installation -The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). Add the Facebook PHP SDK package to your `composer.json` file. +The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). Run this command: -```json -{ - "require": { - "facebook/php-sdk-v4": "~5.1" - } -} +```sh +composer require facebook/php-sdk-v4 ``` ## Upgrading to v5.x From d3f771d34f828938c6979efdc175729f20094602 Mon Sep 17 00:00:00 2001 From: Rafael Dohms Date: Fri, 16 Oct 2015 15:33:17 +0200 Subject: [PATCH 204/407] Updating Composer install instructions In line with my edit in the repo, this ensures the use of the best option to install new dependencies, by running with as little side effects as possible and requiring only a single action. --- docs/sdk_getting_started.fbmd | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 0536b216e..4081443ae 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -29,14 +29,10 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta ## Installing with Composer (recommended) {#install-composer} -[Composer](https://getcomposer.org/) is the recommended way to install the Facebook SDK for PHP. Simply add the following "require" entry to the `composer.json` file in the root of your project. +[Composer](https://getcomposer.org/) is the recommended way to install the Facebook SDK for PHP. Simply run the following following in the root of your project. ~~~ -{ - "require" : { - "facebook/php-sdk-v4" : "~5.0" - } -} +composer require facebook/php-sdk-v4 ~~~ %FB(devsite:markdown-wiki:info-card { @@ -44,7 +40,7 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta type: 'info', }) -Then run `composer install` from the command line, and composer will download the latest version of the SDK and put it in the `/vendor/` directory. +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. From 5e619d95b0b1553a2dd11f85bc9b5080db16a3bc Mon Sep 17 00:00:00 2001 From: Rafael Dohms Date: Fri, 16 Oct 2015 15:36:41 +0200 Subject: [PATCH 205/407] Update sdk_getting_started.fbmd Typo fix. --- docs/sdk_getting_started.fbmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 4081443ae..66db16475 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -29,7 +29,7 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta ## Installing with Composer (recommended) {#install-composer} -[Composer](https://getcomposer.org/) is the recommended way to install the Facebook SDK for PHP. Simply run the following following in the root of your project. +[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/php-sdk-v4 From 7b1c435dccc09fef7ee2e71c5b313c492a1270fa Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 20 Oct 2015 09:08:45 -0500 Subject: [PATCH 206/407] Fix parsing of batch headers --- src/Facebook/FacebookBatchResponse.php | 20 +++++++++++++++++++- tests/FacebookBatchResponseTest.php | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Facebook/FacebookBatchResponse.php b/src/Facebook/FacebookBatchResponse.php index 5ea765e30..9262646b7 100644 --- a/src/Facebook/FacebookBatchResponse.php +++ b/src/Facebook/FacebookBatchResponse.php @@ -102,7 +102,7 @@ public function addResponse($key, $response) $httpResponseBody = isset($response['body']) ? $response['body'] : null; $httpResponseCode = isset($response['code']) ? $response['code'] : null; - $httpResponseHeaders = isset($response['headers']) ? $response['headers'] : []; + $httpResponseHeaders = isset($response['headers']) ? $this->normalizeBatchHeaders($response['headers']) : []; $this->responses[$originalRequestName] = new FacebookResponse( $originalRequest, @@ -151,4 +151,22 @@ public function offsetGet($offset) { return isset($this->responses[$offset]) ? $this->responses[$offset] : null; } + + /** + * Converts the batch header array into a standard format. + * + * @param array $batchHeaders + * + * @return array + */ + private function normalizeBatchHeaders(array $batchHeaders) + { + $headers = []; + + foreach ($batchHeaders as $header) { + $headers[$header['name']] = $header['value']; + } + + return $headers; + } } diff --git a/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index dec92a190..edbed3784 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -135,4 +135,30 @@ public function testTheOriginalRequestCanBeObtainedForEachRequest() $this->assertEquals('foo_token_two', $batchResponse[1]->getAccessToken()); $this->assertEquals('foo_token_three', $batchResponse[2]->getAccessToken()); } + + public function testHeadersFromBatchRequestCanBeAccessed() + { + $graphResponseJson = '['; + $graphResponseJson .= '{"code":200,"headers":[{"name":"Facebook-API-Version","value":"v2.0"},{"name":"ETag","value":"\"fooTag\""}],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ',{"code":200,"headers":[{"name":"Facebook-API-Version","value":"v2.5"},{"name":"ETag","value":"\"barTag\""}],"body":"{\"foo\":\"bar\"}"}'; + $graphResponseJson .= ']'; + $response = new FacebookResponse($this->request, $graphResponseJson, 200); + + $requests = [ + new FacebookRequest($this->app, 'foo_token_one', 'GET', '/me'), + new FacebookRequest($this->app, 'foo_token_two', 'GET', '/you'), + ]; + + $batchRequest = new FacebookBatchRequest($this->app, $requests); + $batchResponse = new FacebookBatchResponse($batchRequest, $response); + + $this->assertEquals('v2.0', $batchResponse[0]->getGraphVersion()); + $this->assertEquals('"fooTag"', $batchResponse[0]->getETag()); + $this->assertEquals('v2.5', $batchResponse[1]->getGraphVersion()); + $this->assertEquals('"barTag"', $batchResponse[1]->getETag()); + $this->assertEquals([ + 'Facebook-API-Version' => 'v2.5', + 'ETag' => '"barTag"', + ], $batchResponse[1]->getHeaders()); + } } From 9fb0069b69983ede766c3f6c001fa59aa1115fb6 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 20 Oct 2015 09:31:43 -0500 Subject: [PATCH 207/407] Add TODO note for PHP 5.5 support --- src/Facebook/FacebookBatchResponse.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Facebook/FacebookBatchResponse.php b/src/Facebook/FacebookBatchResponse.php index 9262646b7..820157d16 100644 --- a/src/Facebook/FacebookBatchResponse.php +++ b/src/Facebook/FacebookBatchResponse.php @@ -102,6 +102,7 @@ public function addResponse($key, $response) $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']) : []; $this->responses[$originalRequestName] = new FacebookResponse( @@ -154,6 +155,7 @@ public function offsetGet($offset) /** * Converts the batch header array into a standard format. + * @TODO replace with array_column() when PHP 5.5 is supported. * * @param array $batchHeaders * From f29580b5ab77ff415495a75ec5118de052a1a85a Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Thu, 22 Oct 2015 22:02:11 +0100 Subject: [PATCH 208/407] removed duplicated logic (`createPseudoRandomStringGenerator`) --- .../Helpers/FacebookRedirectLoginHelper.php | 42 ++++--------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 144a5b454..10fc7fab0 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -25,16 +25,14 @@ use Facebook\Authentication\AccessToken; use Facebook\Authentication\OAuth2Client; -use Facebook\Url\UrlDetectionInterface; -use Facebook\Url\FacebookUrlDetectionHandler; -use Facebook\Url\FacebookUrlManipulator; -use Facebook\PersistentData\PersistentDataInterface; +use Facebook\Exceptions\FacebookSDKException; use Facebook\PersistentData\FacebookSessionPersistentDataHandler; +use Facebook\PersistentData\PersistentDataInterface; +use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; -use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; -use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; -use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; -use Facebook\Exceptions\FacebookSDKException; +use Facebook\Url\FacebookUrlDetectionHandler; +use Facebook\Url\FacebookUrlManipulator; +use Facebook\Url\UrlDetectionInterface; /** * Class FacebookRedirectLoginHelper @@ -79,7 +77,7 @@ public function __construct(OAuth2Client $oAuth2Client, PersistentDataInterface $this->oAuth2Client = $oAuth2Client; $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); - $this->pseudoRandomStringGenerator = $prsg ?: $this->detectPseudoRandomStringGenerator(); + $this->pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator($prsg); } /** @@ -112,32 +110,6 @@ public function getPseudoRandomStringGenerator() return $this->pseudoRandomStringGenerator; } - /** - * Detects which pseudo-random string generator to use. - * - * @return PseudoRandomStringGeneratorInterface - * - * @throws FacebookSDKException - */ - public function detectPseudoRandomStringGenerator() - { - // Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically - // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() first. - if (function_exists('mcrypt_create_iv')) { - return new McryptPseudoRandomStringGenerator(); - } - - if (function_exists('openssl_random_pseudo_bytes')) { - return new OpenSslPseudoRandomStringGenerator(); - } - - if (!ini_get('open_basedir') && is_readable('/dev/urandom')) { - return new UrandomPseudoRandomStringGenerator(); - } - - throw new FacebookSDKException('Unable to detect a cryptographically secure pseudo-random string generator.'); - } - /** * Stores CSRF state and returns a URL to which the user should be sent to in order to continue the login process with Facebook. * From f1c62b6dcea7490e9e9fa9523ab59943373b549e Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Tue, 27 Oct 2015 18:43:16 +0100 Subject: [PATCH 209/407] remove unused `$previousException` --- src/Facebook/Exceptions/FacebookResponseException.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 9ec7060b1..6379edbb4 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -77,8 +77,6 @@ public static function create(FacebookResponse $response) $code = isset($data['error']['code']) ? $data['error']['code'] : null; $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; - $previousException = null; - if (isset($data['error']['error_subcode'])) { switch ($data['error']['error_subcode']) { // Other authentication issues From 3a08836e027595f99c008dc9b1576d64f51ac0ea Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Tue, 27 Oct 2015 22:17:41 +0100 Subject: [PATCH 210/407] single internal type for response headers --- src/Facebook/HttpClients/FacebookStream.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Facebook/HttpClients/FacebookStream.php b/src/Facebook/HttpClients/FacebookStream.php index 95aa22e7a..1ec7177dc 100644 --- a/src/Facebook/HttpClients/FacebookStream.php +++ b/src/Facebook/HttpClients/FacebookStream.php @@ -41,7 +41,7 @@ class FacebookStream /** * @var array Response headers from the stream wrapper */ - protected $responseHeaders; + protected $responseHeaders = []; /** * Make a new context stream reference instance @@ -56,7 +56,7 @@ public function streamContextCreate(array $options) /** * The response headers from the stream wrapper * - * @return array|null + * @return array */ public function getResponseHeaders() { @@ -73,7 +73,7 @@ public function getResponseHeaders() public function fileGetContents($url) { $rawResponse = file_get_contents($url, false, $this->stream); - $this->responseHeaders = $http_response_header; + $this->responseHeaders = $http_response_header ?: []; return $rawResponse; } From d4ae9ff4f6a50f91910821edbea1fc055f0a33cb Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Tue, 27 Oct 2015 22:18:13 +0100 Subject: [PATCH 211/407] use the empty function instead of implicit casting --- src/Facebook/HttpClients/FacebookStreamHttpClient.php | 2 +- src/Facebook/Url/FacebookUrlManipulator.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/HttpClients/FacebookStreamHttpClient.php b/src/Facebook/HttpClients/FacebookStreamHttpClient.php index b15751431..b88a6625a 100644 --- a/src/Facebook/HttpClients/FacebookStreamHttpClient.php +++ b/src/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -66,7 +66,7 @@ public function send($url, $method, $body, array $headers, $timeOut) $rawBody = $this->facebookStream->fileGetContents($url); $rawHeaders = $this->facebookStream->getResponseHeaders(); - if ($rawBody === false || !$rawHeaders) { + if ($rawBody === false || empty($rawHeaders)) { throw new FacebookSDKException('Stream returned an empty response', 660); } diff --git a/src/Facebook/Url/FacebookUrlManipulator.php b/src/Facebook/Url/FacebookUrlManipulator.php index 20a0299e0..2e540956e 100644 --- a/src/Facebook/Url/FacebookUrlManipulator.php +++ b/src/Facebook/Url/FacebookUrlManipulator.php @@ -76,7 +76,7 @@ public static function removeParamsFromUrl($url, array $paramsToFilter) */ public static function appendParamsToUrl($url, array $newParams = []) { - if (!$newParams) { + if (empty($newParams)) { return $url; } From 1727ff566430a7022019c79e7d0c1cd4faf60282 Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Wed, 28 Oct 2015 11:33:32 +0100 Subject: [PATCH 212/407] replaced deprecated method --- src/Facebook/GraphNodes/GraphObjectFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphObjectFactory.php b/src/Facebook/GraphNodes/GraphObjectFactory.php index 8615990dc..28bd8afe5 100644 --- a/src/Facebook/GraphNodes/GraphObjectFactory.php +++ b/src/Facebook/GraphNodes/GraphObjectFactory.php @@ -68,7 +68,7 @@ public function makeGraphObject($subclassName = null) */ public function makeGraphEvent() { - return $this->makeGraphObject(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); } /** From cad8914a0e4093c243913f1598a7717c2b244094 Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Fri, 30 Oct 2015 16:57:33 +0100 Subject: [PATCH 213/407] documentation fixes --- src/Facebook/Authentication/OAuth2Client.php | 6 +++--- src/Facebook/FileUpload/FacebookResumableUploader.php | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Facebook/Authentication/OAuth2Client.php b/src/Facebook/Authentication/OAuth2Client.php index 8e364ec83..bd35b9a60 100644 --- a/src/Facebook/Authentication/OAuth2Client.php +++ b/src/Facebook/Authentication/OAuth2Client.php @@ -250,9 +250,9 @@ protected function requestAnAccessToken(array $params) /** * Send a request to Graph with an app access token. * - * @param string $endpoint - * @param array $params - * @param string|null $accessToken + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken * * @return FacebookResponse * diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 36c14c885..948746ca5 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -23,8 +23,9 @@ */ namespace Facebook\FileUpload; -use Facebook\Exceptions\FacebookResumableUploadException; +use Facebook\Authentication\AccessToken; use Facebook\Exceptions\FacebookResponseException; +use Facebook\Exceptions\FacebookResumableUploadException; use Facebook\Exceptions\FacebookSDKException; use Facebook\FacebookApp; use Facebook\FacebookClient; @@ -58,10 +59,10 @@ class FacebookResumableUploader protected $graphVersion; /** - * @param FacebookApp $app - * @param FacebookClient $client - * @param string $accessToken - * @param string $graphVersion + * @param FacebookApp $app + * @param FacebookClient $client + * @param AccessToken|string|null $accessToken + * @param string $graphVersion */ public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $graphVersion) { From 5e7d44c09bfa3c11c5ef982f9c7872e80e97f52d Mon Sep 17 00:00:00 2001 From: Aleksey Kozakov Date: Tue, 10 Nov 2015 12:01:29 +0200 Subject: [PATCH 214/407] [Bugfix] Facebook AccessToken is being validated correctly in FacebookClient --- src/Facebook/FacebookClient.php | 2 +- tests/FacebookClientTest.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Facebook/FacebookClient.php b/src/Facebook/FacebookClient.php index 70a463e72..d9bbec5b5 100644 --- a/src/Facebook/FacebookClient.php +++ b/src/Facebook/FacebookClient.php @@ -197,7 +197,7 @@ public function prepareRequestMessage(FacebookRequest $request) */ public function sendRequest(FacebookRequest $request) { - if (get_class($request) === 'FacebookRequest') { + if (get_class($request) === 'Facebook\FacebookRequest') { $request->validateAccessToken(); } diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 6e9bb6cf5..1f09e2120 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -218,6 +218,14 @@ public function testARequestWithFilesWillBeMultipart() $this->assertContains('multipart/form-data; boundary=', $headersSent['Content-Type']); } + public function testAFacebookRequestValidateAccessTokenIsNotProvided(){ + + $this->setExpectedException('Facebook\Exceptions\FacebookSDKException'); + + $fbRequest = new FacebookRequest($this->fbApp, null, 'GET', '/foo'); + $this->fbClient->sendRequest($fbRequest); + } + /** * @group integration */ From 1535d1be7f750750e8387bfabfb95286147372dd Mon Sep 17 00:00:00 2001 From: Aleksey Kozakov Date: Tue, 10 Nov 2015 15:59:45 +0200 Subject: [PATCH 215/407] Rename test method - testAFacebookRequestValidatesTheAccessTokenWhenOneIsNotProvided --- tests/FacebookClientTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 1f09e2120..68b685d97 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -218,8 +218,8 @@ public function testARequestWithFilesWillBeMultipart() $this->assertContains('multipart/form-data; boundary=', $headersSent['Content-Type']); } - public function testAFacebookRequestValidateAccessTokenIsNotProvided(){ - + public function testAFacebookRequestValidatesTheAccessTokenWhenOneIsNotProvided() + { $this->setExpectedException('Facebook\Exceptions\FacebookSDKException'); $fbRequest = new FacebookRequest($this->fbApp, null, 'GET', '/foo'); From 8d74588f2f88980c3504333111523ca231796a72 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Thu, 12 Nov 2015 11:21:46 -0800 Subject: [PATCH 216/407] Updating to 5.1.1 --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5219df685..e3098f167 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.0-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.1-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index c82ad5ae6..10bdfeedb 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.1.0'; + const VERSION = '5.1.1'; /** * @const string Default Graph API version for requests. From f2dfdc158368b1bb414c5ada73b988c17e85fdef Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 19 Nov 2015 16:12:07 +0100 Subject: [PATCH 217/407] Fix #529 --- src/Facebook/PersistentData/PersistentDataFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/PersistentData/PersistentDataFactory.php b/src/Facebook/PersistentData/PersistentDataFactory.php index 76aa1f9f0..3ac14c3d8 100644 --- a/src/Facebook/PersistentData/PersistentDataFactory.php +++ b/src/Facebook/PersistentData/PersistentDataFactory.php @@ -54,7 +54,7 @@ public static function createPersistentDataHandler($handler) } if ('session' === $handler) { - new FacebookSessionPersistentDataHandler(); + return new FacebookSessionPersistentDataHandler(); } if ('memory' === $handler) { return new FacebookMemoryPersistentDataHandler(); From 2c42fb3002953355f12d3c6e8003a9fd5af563d9 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Thu, 19 Nov 2015 13:07:36 -0800 Subject: [PATCH 218/407] 5.1.2 with fix for session handling. --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3098f167..4c44c2f7d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.1-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.2-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 10bdfeedb..4204a4332 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.1.1'; + const VERSION = '5.1.2'; /** * @const string Default Graph API version for requests. From d2e181469074544a2c832dffb6bf25ad597f51cf Mon Sep 17 00:00:00 2001 From: Koen Punt Date: Fri, 4 Dec 2015 22:48:38 +0100 Subject: [PATCH 219/407] fix use of exception class there is no Facebook\HttpClients\Exception class --- src/Facebook/HttpClients/HttpClientsFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/HttpClients/HttpClientsFactory.php b/src/Facebook/HttpClients/HttpClientsFactory.php index 977a5cbbc..0402fbc42 100644 --- a/src/Facebook/HttpClients/HttpClientsFactory.php +++ b/src/Facebook/HttpClients/HttpClientsFactory.php @@ -25,6 +25,7 @@ use GuzzleHttp\Client; use InvalidArgumentException; +use Exception; class HttpClientsFactory { From 10538dcfe4792d056a2278e6344dd1c7568d4998 Mon Sep 17 00:00:00 2001 From: Stephan Alber Date: Fri, 8 Jan 2016 10:39:22 -0800 Subject: [PATCH 220/407] Added version number (v5) to headline We received a report that people are confused by the repo name. `facebook-php-sdk-v4` indicates that the repo is for v4, not v5 or other versions. To make clear that people can find v5 in this repo the latest version number should be part of the headline. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c44c2f7d..219a028ed 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Facebook SDK for PHP +# Facebook SDK for PHP (v5) [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) From d1e8a73d5353a674aad4ccb1851328f232277087 Mon Sep 17 00:00:00 2001 From: Michelangelo Date: Fri, 15 Jan 2016 16:57:37 +0100 Subject: [PATCH 221/407] GitHub Issue #546: Received a fatal because mb_substr was not found. Added logic to wrap the extension missing fatal error and ensured the mb_filter function is taken from PHP base namespace and not from the FB SDK namespace. Test running and succeeded: PHPUnit 4.8.21 by Sebastian Bergmann and contributors. ............................................................... 63 / 267 ( 23%) ............................................................... 126 / 267 ( 47%) ............................................................... 189 / 267 ( 70%) ............................................................... 252 / 267 ( 94%) ............... Time: 6.36 seconds, Memory: 12.00Mb OK (267 tests, 614 assertions) --- .../PseudoRandomString/PseudoRandomStringGeneratorTrait.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index a41ce5985..665ee24ea 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -48,11 +48,15 @@ public function validateLength($length) * * @param string $binaryData The binary data to convert to hex. * @param int $length The length of the string to return. + * @throws \RuntimeException Throws an exception when multibyte support is not enabled * * @return string */ public function binToHex($binaryData, $length) { - return mb_substr(bin2hex($binaryData), 0, $length); + if(true !== extension_loaded('mbstring')) { + throw new \RuntimeException('Multibyte support required'); + } + return \mb_substr(\bin2hex($binaryData), 0, $length); } } From 822833ac7204584f18882bcf253494a5ca647a3c Mon Sep 17 00:00:00 2001 From: Michelangelo Date: Sat, 16 Jan 2016 13:48:15 +0100 Subject: [PATCH 222/407] GitHub Issue #546: Received a fatal because mb_substr was not found. Updating PSR-2 validation, misconfigured my PHP Sniffs. Error fixed ``` ~/.composer/vendor/bin/phpcs src --standard=psr2 -spn ............................................................ 60 / 73 (82%) ............. Time: 1.95 secs; Memory: 14Mb ``` --- .../PseudoRandomString/PseudoRandomStringGeneratorTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index 665ee24ea..04390af46 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -54,8 +54,8 @@ public function validateLength($length) */ public function binToHex($binaryData, $length) { - if(true !== extension_loaded('mbstring')) { - throw new \RuntimeException('Multibyte support required'); + if (true !== extension_loaded('mbstring')) { + throw new \RuntimeException('Multibyte support required'); } return \mb_substr(\bin2hex($binaryData), 0, $length); } From bed3bb59600eaadb7cbfd6d4113220c720de7e9d Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Feb 2016 15:31:44 -0600 Subject: [PATCH 223/407] Fix failing tests when mcrypt or openssl not installed --- .../PseudoRandomStringFactoryTest.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php index e6f2094f3..2ffdb723b 100644 --- a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php +++ b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php @@ -53,11 +53,19 @@ public function testCreateHttpClient($handler, $expected) */ public function httpClientsProvider() { - return [ - ['mcrypt', self::COMMON_NAMESPACE . 'McryptPseudoRandomStringGenerator'], - ['openssl', self::COMMON_NAMESPACE . 'OpenSslPseudoRandomStringGenerator'], - ['urandom', self::COMMON_NAMESPACE . 'UrandomPseudoRandomStringGenerator'], - [null, self::COMMON_INTERFACE], + $providers = [ + [null, self::COMMON_INTERFACE], ]; + if (function_exists('mcrypt_create_iv')) { + $providers[] = ['mcrypt', self::COMMON_NAMESPACE . 'McryptPseudoRandomStringGenerator']; + } + if (function_exists('openssl_random_pseudo_bytes')) { + $providers[] = ['openssl', self::COMMON_NAMESPACE . 'OpenSslPseudoRandomStringGenerator']; + } + if (!ini_get('open_basedir') && is_readable('/dev/urandom')) { + $providers[] = ['urandom', self::COMMON_NAMESPACE . 'UrandomPseudoRandomStringGenerator']; + } + + return $providers; } } From 8e70f35cacfc83eab5d530b99a9e7aca581e7f02 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Feb 2016 15:56:17 -0600 Subject: [PATCH 224/407] Remove mb-string dependency --- composer.json | 6 +-- .../HttpClients/FacebookCurlHttpClient.php | 53 ++---------------- .../PseudoRandomStringGeneratorTrait.php | 5 +- src/Facebook/SignedRequest.php | 10 +--- src/Facebook/polyfills.php | 43 +++++++++++++++ .../FacebookCurlHttpClientTest.php | 54 ------------------- 6 files changed, 52 insertions(+), 119 deletions(-) create mode 100644 src/Facebook/polyfills.php diff --git a/composer.json b/composer.json index 31e70cd4e..93af8bf50 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,7 @@ } ], "require": { - "php": ">=5.4.0", - "ext-mbstring": "*" + "php": ">=5.4.0" }, "require-dev": { "phpunit/phpunit": "~4.0", @@ -26,7 +25,8 @@ "autoload": { "psr-4": { "Facebook\\": "src/Facebook/" - } + }, + "files": ["src/Facebook/polyfills.php"] }, "autoload-dev": { "psr-4": { diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 955ac0622..06c847af5 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -53,16 +53,6 @@ class FacebookCurlHttpClient implements FacebookHttpClientInterface */ protected $facebookCurl; - /** - * @const Curl Version which is unaffected by the proxy header length error. - */ - const CURL_PROXY_QUIRK_VER = 0x071E00; - - /** - * @const "Connection Established" header text - */ - const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n"; - /** * @param FacebookCurl|null Procedural curl as object */ @@ -164,47 +154,10 @@ public function compileRequestHeaders(array $headers) */ public function extractResponseHeadersAndBody() { - $headerSize = $this->getHeaderSize(); - - $rawHeaders = mb_substr($this->rawResponse, 0, $headerSize); - $rawBody = mb_substr($this->rawResponse, $headerSize); + $parts = explode("\r\n\r\n", $this->rawResponse); + $rawBody = array_pop($parts); + $rawHeaders = implode("\r\n\r\n", $parts); return [trim($rawHeaders), trim($rawBody)]; } - - /** - * Return proper header size - * - * @return integer - */ - private function getHeaderSize() - { - $headerSize = $this->facebookCurl->getinfo(CURLINFO_HEADER_SIZE); - // This corrects a Curl bug where header size does not account - // for additional Proxy headers. - if ($this->needsCurlProxyFix()) { - // Additional way to calculate the request body size. - if (preg_match('/Content-Length: (\d+)/', $this->rawResponse, $m)) { - $headerSize = mb_strlen($this->rawResponse) - $m[1]; - } elseif (stripos($this->rawResponse, self::CONNECTION_ESTABLISHED) !== false) { - $headerSize += mb_strlen(self::CONNECTION_ESTABLISHED); - } - } - - return $headerSize; - } - - /** - * Detect versions of Curl which report incorrect header lengths when - * using Proxies. - * - * @return boolean - */ - private function needsCurlProxyFix() - { - $ver = $this->facebookCurl->version(); - $version = $ver['version_number']; - - return $version < self::CURL_PROXY_QUIRK_VER; - } } diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index 04390af46..4c284a4a2 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -54,9 +54,6 @@ public function validateLength($length) */ public function binToHex($binaryData, $length) { - if (true !== extension_loaded('mbstring')) { - throw new \RuntimeException('Multibyte support required'); - } - return \mb_substr(\bin2hex($binaryData), 0, $length); + return \substr(\bin2hex($binaryData), 0, $length); } } diff --git a/src/Facebook/SignedRequest.php b/src/Facebook/SignedRequest.php index 77099a346..6d233ce8d 100644 --- a/src/Facebook/SignedRequest.php +++ b/src/Facebook/SignedRequest.php @@ -268,14 +268,8 @@ protected function hashSignature($encodedData) */ protected function validateSignature($hashedSig, $sig) { - if (mb_strlen($hashedSig) === mb_strlen($sig)) { - $validate = 0; - for ($i = 0; $i < mb_strlen($sig); $i++) { - $validate |= ord($hashedSig[$i]) ^ ord($sig[$i]); - } - if ($validate === 0) { - return; - } + if (\hash_equals($hashedSig, $sig)) { + return; } throw new FacebookSDKException('Signed request has an invalid signature.', 602); diff --git a/src/Facebook/polyfills.php b/src/Facebook/polyfills.php new file mode 100644 index 000000000..9922d142f --- /dev/null +++ b/src/Facebook/polyfills.php @@ -0,0 +1,43 @@ += 0; $i--) { + $ret |= ord($res[$i]); + } + + return !$ret; + } +} diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 4cf31d339..042aa1ae3 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -146,15 +146,6 @@ public function testCanCloseConnection() public function testIsolatesTheHeaderAndBody() { - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(strlen($this->fakeRawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('exec') ->once() @@ -170,15 +161,6 @@ public function testIsolatesTheHeaderAndBody() public function testProperlyHandlesProxyHeaders() { $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($rawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('exec') ->once() @@ -194,15 +176,6 @@ public function testProperlyHandlesProxyHeaders() public function testProperlyHandlesProxyHeadersWithCurlBug() { $rawHeader = $this->fakeRawProxyHeader . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); $this->curlMock ->shouldReceive('exec') ->once() @@ -218,15 +191,6 @@ public function testProperlyHandlesProxyHeadersWithCurlBug() public function testProperlyHandlesProxyHeadersWithCurlBug2() { $rawHeader = $this->fakeRawProxyHeader2 . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); // Mimic bug that doesn't count proxy header - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_BUGGY]); $this->curlMock ->shouldReceive('exec') ->once() @@ -242,15 +206,6 @@ public function testProperlyHandlesProxyHeadersWithCurlBug2() public function testProperlyHandlesRedirectHeaders() { $rawHeader = $this->fakeRawRedirectHeader . $this->fakeRawHeader; - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($rawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('exec') ->once() @@ -281,15 +236,6 @@ public function testCanSendNormalRequest() ->shouldReceive('errno') ->once() ->andReturn(null); - $this->curlMock - ->shouldReceive('getinfo') - ->with(CURLINFO_HEADER_SIZE) - ->once() - ->andReturn(mb_strlen($this->fakeRawHeader)); - $this->curlMock - ->shouldReceive('version') - ->once() - ->andReturn(['version_number' => self::CURL_VERSION_STABLE]); $this->curlMock ->shouldReceive('close') ->once() From 24c10c96d0f2c16647a4d42c4716aa9f8cb51438 Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Feb 2016 16:01:25 -0600 Subject: [PATCH 225/407] Fix tests that fail with cURL is not installed --- tests/FacebookTest.php | 3 +++ .../FacebookCurlHttpClientTest.php | 3 +++ tests/HttpClients/HttpClientsFactoryTest.php | 22 +++++++++++-------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 75f90c1f9..246d24db4 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -120,6 +120,9 @@ public function testSettingAnInvalidHttpClientHandlerThrows() public function testCurlHttpClientHandlerCanBeForced() { + if (!extension_loaded('curl')) { + $this->markTestSkipped('cURL must be installed to test cURL client handler.'); + } $config = array_merge($this->config, [ 'http_client_handler' => 'curl' ]); diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 042aa1ae3..11a7f630f 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -43,6 +43,9 @@ class FacebookCurlHttpClientTest extends AbstractTestHttpClient public function setUp() { + if (!extension_loaded('curl')) { + $this->markTestSkipped('cURL must be installed to test cURL client handler.'); + } $this->curlMock = m::mock('Facebook\HttpClients\FacebookCurl'); $this->curlClient = new FacebookCurlHttpClient($this->curlMock); } diff --git a/tests/HttpClients/HttpClientsFactoryTest.php b/tests/HttpClients/HttpClientsFactoryTest.php index 78876b13d..b3d9b8f3f 100644 --- a/tests/HttpClients/HttpClientsFactoryTest.php +++ b/tests/HttpClients/HttpClientsFactoryTest.php @@ -54,15 +54,19 @@ public function testCreateHttpClient($handler, $expected) */ public function httpClientsProvider() { - return [ - ['curl', self::COMMON_NAMESPACE . 'FacebookCurlHttpClient'], - ['guzzle', self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], - ['stream', self::COMMON_NAMESPACE . 'FacebookStreamHttpClient'], - [new Client(), self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], - [new FacebookCurlHttpClient(), self::COMMON_NAMESPACE . 'FacebookCurlHttpClient'], - [new FacebookGuzzleHttpClient(), self::COMMON_NAMESPACE . 'FacebookGuzzleHttpClient'], - [new FacebookStreamHttpClient(), self::COMMON_NAMESPACE . 'FacebookStreamHttpClient'], - [null, self::COMMON_INTERFACE], + $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], ]; + if (extension_loaded('curl')) { + $clients[] = ['curl', self::COMMON_NAMESPACE . 'FacebookCurlHttpClient']; + $clients[] = [new FacebookCurlHttpClient(), self::COMMON_NAMESPACE . 'FacebookCurlHttpClient']; + } + + return $clients; } } From 5202853ea882caef9028350a0cd21d9c042d845e Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Feb 2016 16:13:35 -0600 Subject: [PATCH 226/407] Update hash_equals polyfill to include xor in for loop --- src/Facebook/polyfills.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Facebook/polyfills.php b/src/Facebook/polyfills.php index 9922d142f..1472e39e8 100644 --- a/src/Facebook/polyfills.php +++ b/src/Facebook/polyfills.php @@ -23,21 +23,22 @@ */ /** - * @see http://php.net/manual/en/function.hash-equals.php#115635 + * @see https://github.com/sarciszewski/php-future/blob/master/src/Security.php#L37-L51 */ if(!function_exists('hash_equals')) { - function hash_equals($str1, $str2) + function hash_equals($knownString, $userString) { - if(strlen($str1) != strlen($str2)) { + $kLen = strlen($knownString); + $uLen = strlen($userString); + if ($kLen !== $uLen) { return false; } - - $res = $str1 ^ $str2; - $ret = 0; - for($i = strlen($res) - 1; $i >= 0; $i--) { - $ret |= ord($res[$i]); + $result = 0; + for ($i = 0; $i < $kLen; $i++) { + $result |= (ord($knownString[$i]) ^ ord($userString[$i])); } - return !$ret; + // They are only identical strings if $result is exactly 0... + return 0 === $result; } } From 3858c7e21b5b35187a221d8091fae0240ad1873b Mon Sep 17 00:00:00 2001 From: SammyK Date: Tue, 9 Feb 2016 16:20:15 -0600 Subject: [PATCH 227/407] Update CSRF comparison to use hash_equals() --- .../Helpers/FacebookRedirectLoginHelper.php | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 10fc7fab0..5cb5d90f5 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -235,27 +235,19 @@ public function getAccessToken($redirectUrl = null) protected function validateCsrf() { $state = $this->getState(); - $savedState = $this->persistentDataHandler->get('state'); - - if (!$state || !$savedState) { - throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.'); + if (!$state) { + throw new FacebookSDKException('Cross-site request forgery validation failed. Required GET param "state" missing.'); } - - $savedLen = strlen($savedState); - $givenLen = strlen($state); - - if ($savedLen !== $givenLen) { - throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); + $savedState = $this->persistentDataHandler->get('state'); + if (!$savedState) { + throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing from persistent data.'); } - $result = 0; - for ($i = 0; $i < $savedLen; $i++) { - $result |= ord($state[$i]) ^ ord($savedState[$i]); + if (\hash_equals($savedState, $state)) { + return; } - if ($result !== 0) { - throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); - } + throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } /** From cd5e91308b833cc145ef524584c0ab80df10aae4 Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 9 Feb 2016 18:16:38 -0500 Subject: [PATCH 228/407] Update polyfills.php https://github.com/facebook/facebook-php-sdk-v4/pull/552#issuecomment-182123879 --- src/Facebook/polyfills.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Facebook/polyfills.php b/src/Facebook/polyfills.php index 1472e39e8..cb88083ec 100644 --- a/src/Facebook/polyfills.php +++ b/src/Facebook/polyfills.php @@ -28,8 +28,13 @@ if(!function_exists('hash_equals')) { function hash_equals($knownString, $userString) { - $kLen = strlen($knownString); - $uLen = strlen($userString); + if (function_exists('mb_strlen')) { + $kLen = mb_strlen($knownString, '8bit'); + $uLen = mb_strlen($userString, '8bit'); + } else { + $kLen = strlen($knownString); + $uLen = strlen($userString); + } if ($kLen !== $uLen) { return false; } From 78bb4c997635ec8999e6bb63324fb89f304af4c8 Mon Sep 17 00:00:00 2001 From: jfreed Date: Tue, 9 Feb 2016 18:23:34 -0500 Subject: [PATCH 229/407] Updated copyright year from 2014 to 2016. --- src/Facebook/Authentication/AccessToken.php | 2 +- src/Facebook/Authentication/AccessTokenMetadata.php | 2 +- src/Facebook/Authentication/OAuth2Client.php | 2 +- src/Facebook/Exceptions/FacebookAuthenticationException.php | 2 +- src/Facebook/Exceptions/FacebookAuthorizationException.php | 2 +- src/Facebook/Exceptions/FacebookClientException.php | 2 +- src/Facebook/Exceptions/FacebookOtherException.php | 2 +- src/Facebook/Exceptions/FacebookResponseException.php | 2 +- src/Facebook/Exceptions/FacebookResumableUploadException.php | 2 +- src/Facebook/Exceptions/FacebookSDKException.php | 2 +- src/Facebook/Exceptions/FacebookServerException.php | 2 +- src/Facebook/Exceptions/FacebookThrottleException.php | 2 +- src/Facebook/Facebook.php | 2 +- src/Facebook/FacebookApp.php | 2 +- src/Facebook/FacebookBatchRequest.php | 2 +- src/Facebook/FacebookBatchResponse.php | 2 +- src/Facebook/FacebookClient.php | 2 +- src/Facebook/FacebookRequest.php | 2 +- src/Facebook/FacebookResponse.php | 2 +- src/Facebook/FileUpload/FacebookFile.php | 2 +- src/Facebook/FileUpload/FacebookResumableUploader.php | 2 +- src/Facebook/FileUpload/FacebookTransferChunk.php | 2 +- src/Facebook/FileUpload/FacebookVideo.php | 2 +- src/Facebook/FileUpload/Mimetypes.php | 2 +- src/Facebook/GraphNodes/Collection.php | 2 +- src/Facebook/GraphNodes/GraphAchievement.php | 2 +- src/Facebook/GraphNodes/GraphAlbum.php | 2 +- src/Facebook/GraphNodes/GraphApplication.php | 2 +- src/Facebook/GraphNodes/GraphCoverPhoto.php | 2 +- src/Facebook/GraphNodes/GraphEdge.php | 2 +- src/Facebook/GraphNodes/GraphEvent.php | 2 +- src/Facebook/GraphNodes/GraphGroup.php | 2 +- src/Facebook/GraphNodes/GraphList.php | 2 +- src/Facebook/GraphNodes/GraphLocation.php | 2 +- src/Facebook/GraphNodes/GraphNode.php | 2 +- src/Facebook/GraphNodes/GraphNodeFactory.php | 2 +- src/Facebook/GraphNodes/GraphObject.php | 2 +- src/Facebook/GraphNodes/GraphObjectFactory.php | 2 +- src/Facebook/GraphNodes/GraphPage.php | 2 +- src/Facebook/GraphNodes/GraphPicture.php | 2 +- src/Facebook/GraphNodes/GraphSessionInfo.php | 2 +- src/Facebook/GraphNodes/GraphUser.php | 2 +- src/Facebook/Helpers/FacebookCanvasHelper.php | 2 +- src/Facebook/Helpers/FacebookJavaScriptHelper.php | 2 +- src/Facebook/Helpers/FacebookPageTabHelper.php | 2 +- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 +- src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php | 2 +- src/Facebook/Http/GraphRawResponse.php | 2 +- src/Facebook/Http/RequestBodyInterface.php | 2 +- src/Facebook/Http/RequestBodyMultipart.php | 2 +- src/Facebook/Http/RequestBodyUrlEncoded.php | 2 +- src/Facebook/HttpClients/FacebookCurl.php | 2 +- src/Facebook/HttpClients/FacebookCurlHttpClient.php | 2 +- src/Facebook/HttpClients/FacebookGuzzleHttpClient.php | 2 +- src/Facebook/HttpClients/FacebookHttpClientInterface.php | 2 +- src/Facebook/HttpClients/FacebookStream.php | 2 +- src/Facebook/HttpClients/FacebookStreamHttpClient.php | 2 +- src/Facebook/HttpClients/HttpClientsFactory.php | 2 +- .../PersistentData/FacebookMemoryPersistentDataHandler.php | 2 +- .../PersistentData/FacebookSessionPersistentDataHandler.php | 2 +- src/Facebook/PersistentData/PersistentDataFactory.php | 2 +- src/Facebook/PersistentData/PersistentDataInterface.php | 2 +- .../PseudoRandomString/McryptPseudoRandomStringGenerator.php | 2 +- .../PseudoRandomString/OpenSslPseudoRandomStringGenerator.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorFactory.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorInterface.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorTrait.php | 2 +- .../PseudoRandomString/UrandomPseudoRandomStringGenerator.php | 2 +- src/Facebook/SignedRequest.php | 2 +- src/Facebook/Url/FacebookUrlDetectionHandler.php | 2 +- src/Facebook/Url/FacebookUrlManipulator.php | 2 +- src/Facebook/Url/UrlDetectionInterface.php | 2 +- src/Facebook/autoload.php | 2 +- tests/Authentication/AccessTokenMetadata.php | 2 +- tests/Authentication/AccessTokenTest.php | 2 +- tests/Authentication/FooFacebookClientForOAuth2Test.php | 2 +- tests/Authentication/OAuth2ClientTest.php | 2 +- tests/Exceptions/FacebookResponseExceptionTest.php | 2 +- tests/FacebookAppTest.php | 2 +- tests/FacebookBatchRequestTest.php | 2 +- tests/FacebookBatchResponseTest.php | 2 +- tests/FacebookClientTest.php | 2 +- tests/FacebookRequestTest.php | 2 +- tests/FacebookResponseTest.php | 2 +- tests/FacebookTest.php | 2 +- tests/FakeGraphApi/FakeGraphApiForResumableUpload.php | 2 +- tests/FileUpload/FacebookFileTest.php | 2 +- tests/FileUpload/FacebookResumableUploaderTest.php | 2 +- tests/FileUpload/MimetypesTest.php | 2 +- tests/GraphNodes/AbstractGraphNode.php | 2 +- tests/GraphNodes/CollectionTest.php | 2 +- tests/GraphNodes/GraphAchievementTest.php | 2 +- tests/GraphNodes/GraphAlbumTest.php | 2 +- tests/GraphNodes/GraphEdgeTest.php | 2 +- tests/GraphNodes/GraphEventTest.php | 2 +- tests/GraphNodes/GraphGroupTest.php | 2 +- tests/GraphNodes/GraphNodeFactoryTest.php | 2 +- tests/GraphNodes/GraphNodeTest.php | 2 +- tests/GraphNodes/GraphObjectFactoryTest.php | 2 +- tests/GraphNodes/GraphPageTest.php | 2 +- tests/GraphNodes/GraphSessionInfoTest.php | 2 +- tests/GraphNodes/GraphUserTest.php | 2 +- tests/Helpers/FacebookCanvasHelperTest.php | 2 +- tests/Helpers/FacebookJavaScriptHelperTest.php | 2 +- tests/Helpers/FacebookPageTabHelperTest.php | 2 +- tests/Helpers/FacebookRedirectLoginHelperTest.php | 2 +- tests/Helpers/FacebookSignedRequestFromInputHelperTest.php | 2 +- tests/Http/GraphRawResponseTest.php | 2 +- tests/Http/RequestBodyMultipartTest.php | 2 +- tests/Http/RequestUrlEncodedTest.php | 2 +- tests/HttpClients/AbstractTestHttpClient.php | 2 +- tests/HttpClients/FacebookCurlHttpClientTest.php | 2 +- tests/HttpClients/FacebookGuzzleHttpClientTest.php | 2 +- tests/HttpClients/FacebookStreamHttpClientTest.php | 2 +- tests/HttpClients/HttpClientsFactoryTest.php | 2 +- .../PersistentData/FacebookMemoryPersistentDataHandlerTest.php | 2 +- .../PersistentData/FacebookSessionPersistentDataHandlerTest.php | 2 +- tests/PersistentData/PersistentDataFactoryTest.php | 2 +- .../McryptPseudoRandomStringGeneratorTest.php | 2 +- .../OpenSslPseudoRandomStringGeneratorTest.php | 2 +- tests/PseudoRandomString/PseudoRandomStringFactoryTest.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php | 2 +- .../UrandomPseudoRandomStringGeneratorTest.php | 2 +- tests/SignedRequestTest.php | 2 +- tests/Url/FacebookUrlDetectionHandlerTest.php | 2 +- tests/Url/FacebookUrlManipulatorTest.php | 2 +- tests/bootstrap.php | 2 +- 127 files changed, 127 insertions(+), 127 deletions(-) diff --git a/src/Facebook/Authentication/AccessToken.php b/src/Facebook/Authentication/AccessToken.php index 582ea6136..867f752eb 100644 --- a/src/Facebook/Authentication/AccessToken.php +++ b/src/Facebook/Authentication/AccessToken.php @@ -1,6 +1,6 @@ Date: Wed, 10 Feb 2016 05:05:05 -0600 Subject: [PATCH 230/407] Fix formatting issue --- src/Facebook/polyfills.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/polyfills.php b/src/Facebook/polyfills.php index cb88083ec..f6eaeb62e 100644 --- a/src/Facebook/polyfills.php +++ b/src/Facebook/polyfills.php @@ -25,7 +25,7 @@ /** * @see https://github.com/sarciszewski/php-future/blob/master/src/Security.php#L37-L51 */ -if(!function_exists('hash_equals')) { +if (!function_exists('hash_equals')) { function hash_equals($knownString, $userString) { if (function_exists('mb_strlen')) { From 80d7c60705dedf41b958d9e39e49dfb933bb1ec4 Mon Sep 17 00:00:00 2001 From: jfreed Date: Wed, 10 Feb 2016 07:25:09 -0500 Subject: [PATCH 231/407] Missed LICENSE and tests/FacebookTestCredentials.php.dist. Update from 2014 to 2016. --- LICENSE | 2 +- tests/FacebookTestCredentials.php.dist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index be3927bf1..458f22e92 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2014 Facebook, Inc. +Copyright 2016 Facebook, Inc. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary diff --git a/tests/FacebookTestCredentials.php.dist b/tests/FacebookTestCredentials.php.dist index e5b66f7cc..5ef6a5b54 100644 --- a/tests/FacebookTestCredentials.php.dist +++ b/tests/FacebookTestCredentials.php.dist @@ -1,6 +1,6 @@ Date: Wed, 10 Feb 2016 18:26:06 -0600 Subject: [PATCH 232/407] Add better error checking for app IDs as int when greater than PHP_INT_MAX --- src/Facebook/FacebookApp.php | 11 ++++++++++- tests/FacebookAppTest.php | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Facebook/FacebookApp.php b/src/Facebook/FacebookApp.php index 84956ce98..2f4da1be8 100644 --- a/src/Facebook/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -24,6 +24,7 @@ namespace Facebook; use Facebook\Authentication\AccessToken; +use Facebook\Exceptions\FacebookSDKException; class FacebookApp implements \Serializable { @@ -40,10 +41,18 @@ class FacebookApp implements \Serializable /** * @param string $id * @param string $secret + * + * @throws FacebookSDKException */ public function __construct($id, $secret) { - $this->id = $id; + 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.'); + } + // 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; } diff --git a/tests/FacebookAppTest.php b/tests/FacebookAppTest.php index d1b453dbc..257047a81 100644 --- a/tests/FacebookAppTest.php +++ b/tests/FacebookAppTest.php @@ -63,4 +63,19 @@ public function testSerialization() $this->assertEquals('id', $newApp->getId()); $this->assertEquals('secret', $newApp->getSecret()); } + + /** + * @expectedException \Facebook\Exceptions\FacebookSDKException + */ + public function testOverflowIntegersWillThrow() + { + new FacebookApp(PHP_INT_MAX + 1, "foo"); + } + + public function testUnserializedIdsWillBeString() + { + $newApp = unserialize(serialize(new FacebookApp(1, "foo"))); + + $this->assertSame('1', $newApp->getId()); + } } From fdd5d4a60cbf326345cd3ab8cda42656c64b5008 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 12 Apr 2016 17:20:57 -0500 Subject: [PATCH 233/407] Bump Graph version to v2.6 --- README.md | 2 +- docs/Facebook.fbmd | 8 ++++---- docs/FacebookRequest.fbmd | 2 +- docs/example_access_token_from_canvas.fbmd | 2 +- docs/example_access_token_from_javascript.fbmd | 4 ++-- docs/example_access_token_from_page_tab.fbmd | 2 +- docs/example_batch_request.fbmd | 4 ++-- docs/example_batch_upload.fbmd | 2 +- docs/example_facebook_login.fbmd | 4 ++-- docs/example_pagination_basic.fbmd | 2 +- docs/example_post_links.fbmd | 2 +- docs/example_retrieve_user_profile.fbmd | 2 +- docs/example_upload_photo.fbmd | 2 +- docs/example_upload_video.fbmd | 2 +- docs/sdk_getting_started.fbmd | 2 +- src/Facebook/Facebook.php | 2 +- 16 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 219a028ed..697d9e747 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Simple GET example of a user's profile. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', //'default_access_token' => '{access-token}', // optional ]); diff --git a/docs/Facebook.fbmd b/docs/Facebook.fbmd index b081f0ed3..5a86e64f4 100644 --- a/docs/Facebook.fbmd +++ b/docs/Facebook.fbmd @@ -13,7 +13,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', // . . . ]); ~~~~ @@ -53,7 +53,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), @@ -74,7 +74,7 @@ The default fallback access token to use if one is not explicitly provided. The Enable [beta mode](/docs/support/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` {#defaultversion} -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.5`. Defaults to the [latest version of Graph](/docs/apps/changelog). +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.6`. Defaults to the [latest version of Graph](/docs/apps/changelog). ### `http_client_handler` {#httpclient} Allows you to overwrite the default HTTP client. @@ -326,7 +326,7 @@ public Facebook\FacebookResponse sendRequest( Sends a request to the Graph API. ~~~~ -$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.5'); +$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.6'); ~~~~ ## sendBatchRequest() {#send-batch-request} diff --git a/docs/FacebookRequest.fbmd b/docs/FacebookRequest.fbmd index 8f9948331..8e41c7318 100644 --- a/docs/FacebookRequest.fbmd +++ b/docs/FacebookRequest.fbmd @@ -211,6 +211,6 @@ $fb = new Facebook\Facebook(/* . . . */); $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); -// /v2.5/me?fields=id,name&access_token=token&appsecret_proof=proof +// /v2.6/me?fields=id,name&access_token=token&appsecret_proof=proof ~~~~ diff --git a/docs/example_access_token_from_canvas.fbmd b/docs/example_access_token_from_canvas.fbmd index 9cfd361f3..b7e1b8076 100644 --- a/docs/example_access_token_from_canvas.fbmd +++ b/docs/example_access_token_from_canvas.fbmd @@ -13,7 +13,7 @@ A signed request will be sent to your app via the HTTP POST method within the co $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $helper = $fb->getCanvasHelper(); diff --git a/docs/example_access_token_from_javascript.fbmd b/docs/example_access_token_from_javascript.fbmd index e2b049eb2..b13645425 100644 --- a/docs/example_access_token_from_javascript.fbmd +++ b/docs/example_access_token_from_javascript.fbmd @@ -32,7 +32,7 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh FB.init({ appId: 'your-app-id', cookie: true, // This is important, it's not enabled by default - version: 'v2.5' + version: 'v2.6' }); }; @@ -55,7 +55,7 @@ After the user successfully logs in, redirect the user (or make an AJAX request) $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $helper = $fb->getJavaScriptHelper(); diff --git a/docs/example_access_token_from_page_tab.fbmd b/docs/example_access_token_from_page_tab.fbmd index b093ba6e7..bdcbe8160 100644 --- a/docs/example_access_token_from_page_tab.fbmd +++ b/docs/example_access_token_from_page_tab.fbmd @@ -13,7 +13,7 @@ Page tabs behave much like the app canvas. The PHP SDK provides a helper for pag $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $helper = $fb->getPageTabHelper(); diff --git a/docs/example_batch_request.fbmd b/docs/example_batch_request.fbmd index eb364d635..ddd52bdf1 100644 --- a/docs/example_batch_request.fbmd +++ b/docs/example_batch_request.fbmd @@ -13,7 +13,7 @@ The following example assumes we have the following permissions granted from the $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); // Since all the requests will be sent on behalf of the same user, @@ -114,7 +114,7 @@ Since the requests sent in a batch are unrelated by default, we can make request $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $batch = [ diff --git a/docs/example_batch_upload.fbmd b/docs/example_batch_upload.fbmd index 5d58f7629..f18f32b6c 100644 --- a/docs/example_batch_upload.fbmd +++ b/docs/example_batch_upload.fbmd @@ -15,7 +15,7 @@ The following example will upload two photos and one video. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); // Since all the requests will be sent on behalf of the same user, diff --git a/docs/example_facebook_login.fbmd b/docs/example_facebook_login.fbmd index 26f019db9..9a4e9b75b 100644 --- a/docs/example_facebook_login.fbmd +++ b/docs/example_facebook_login.fbmd @@ -19,7 +19,7 @@ In this example, the PHP script that generates the login link is called `/login. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $helper = $fb->getRedirectLoginHelper(); @@ -38,7 +38,7 @@ echo 'Log in with Facebook!'; $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $helper = $fb->getRedirectLoginHelper(); diff --git a/docs/example_pagination_basic.fbmd b/docs/example_pagination_basic.fbmd index 28521a476..629de2a29 100644 --- a/docs/example_pagination_basic.fbmd +++ b/docs/example_pagination_basic.fbmd @@ -15,7 +15,7 @@ In this example we'll pull five entries from a user's feed (assuming the user ap $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); try { diff --git a/docs/example_post_links.fbmd b/docs/example_post_links.fbmd index 492e3bdff..5f052c2a1 100644 --- a/docs/example_post_links.fbmd +++ b/docs/example_post_links.fbmd @@ -15,7 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $linkData = [ diff --git a/docs/example_retrieve_user_profile.fbmd b/docs/example_retrieve_user_profile.fbmd index 899e50322..67cdb7e7b 100644 --- a/docs/example_retrieve_user_profile.fbmd +++ b/docs/example_retrieve_user_profile.fbmd @@ -15,7 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); try { diff --git a/docs/example_upload_photo.fbmd b/docs/example_upload_photo.fbmd index e7b90d180..d10c87b33 100644 --- a/docs/example_upload_photo.fbmd +++ b/docs/example_upload_photo.fbmd @@ -15,7 +15,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $data = [ diff --git a/docs/example_upload_video.fbmd b/docs/example_upload_video.fbmd index 3d7356939..11789e66e 100644 --- a/docs/example_upload_video.fbmd +++ b/docs/example_upload_video.fbmd @@ -18,7 +18,7 @@ The following example will upload a video in chunks using the [resumable upload] $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); $data = [ diff --git a/docs/sdk_getting_started.fbmd b/docs/sdk_getting_started.fbmd index 66db16475..bbb8330ec 100644 --- a/docs/sdk_getting_started.fbmd +++ b/docs/sdk_getting_started.fbmd @@ -113,7 +113,7 @@ Before we can send requests to the Graph API, we need to load our app configurat $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.5', + 'default_graph_version' => 'v2.6', ]); ~~~ diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 4204a4332..dd273e835 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -58,7 +58,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.5'; + const DEFAULT_GRAPH_VERSION = 'v2.6'; /** * @const string The name of the environment variable that contains the app ID. From 6547b91ca3fc20e20089fd16465352ff7ae5af2d Mon Sep 17 00:00:00 2001 From: Nick Matthews Date: Sun, 17 Apr 2016 17:17:57 +0000 Subject: [PATCH 234/407] Implementing new Birthday class to handle Graph API response variations --- docs/Birthday.fbmd | 63 ++++++++++++++++++ docs/GraphNode.fbmd | 4 +- docs/sdk_reference.fbmd | 4 ++ src/Facebook/GraphNodes/Birthday.php | 92 +++++++++++++++++++++++++++ src/Facebook/GraphNodes/GraphNode.php | 16 ++++- tests/GraphNodes/GraphUserTest.php | 66 ++++++++++++++++++- 6 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 docs/Birthday.fbmd create mode 100644 src/Facebook/GraphNodes/Birthday.php diff --git a/docs/Birthday.fbmd b/docs/Birthday.fbmd new file mode 100644 index 000000000..3be5fcf0f --- /dev/null +++ b/docs/Birthday.fbmd @@ -0,0 +1,63 @@ + +# 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 {#overview} + +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: + +~~~~ +$fb = new Facebook\Facebook(\* *\); +// Returns a `Facebook\FacebookResponse` object +$response = $fb->get('/something'); + +// 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 {#instance-methods} + +### hasDate() {#has-date} +~~~~ +public boolean hasDate() +~~~~ +Returns whether or not the birthday object contains the day and month of birth. + + + +### hasYear() {#has-year} +~~~~ +public boolean hasYear() +~~~~ +Returns whether or not the birthday object contains the year of birth. + diff --git a/docs/GraphNode.fbmd b/docs/GraphNode.fbmd index 66ca76aae..c7cc30ea9 100644 --- a/docs/GraphNode.fbmd +++ b/docs/GraphNode.fbmd @@ -166,9 +166,9 @@ Returns the `link` property for the user as a string if present. ### getBirthday() {#user-getbirthday} ~~~~ -public \DateTime|null getBirthday() +public \Facebook\GraphNodes\Birthday|null getBirthday() ~~~~ -Returns the `birthday` property for the user as a `\DateTime` if present. +Returns the `birthday` property for the user as a `\Facebook\GraphNodes\Birthday` if present. ### getLocation() {#user-getlocation} ~~~~ diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 2ab60bb16..8832d0844 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -172,6 +172,10 @@ Graph nodes are collections that represent nodes returned by the Graph API. And '[`Facebook\\GraphNodes\\GraphUser`](/docs/php/GraphNode#user-instance-methods)', 'A collection that represents a User node.', ], + [ + '[`Facebook\\GraphNodes\\Birthday`](/docs/php/Birthday#instance-methods)', + 'A class that represents a GraphUser\'s birthday.', + ], ], }) diff --git a/src/Facebook/GraphNodes/Birthday.php b/src/Facebook/GraphNodes/Birthday.php new file mode 100644 index 000000000..05c78a9ae --- /dev/null +++ b/src/Facebook/GraphNodes/Birthday.php @@ -0,0 +1,92 @@ +hasYear = true; + } + + if (count($parts) === 3 || count($parts) === 2) { + $this->hasDate = true; + } + + parent::__construct($date, $timezone); + } + + /** + * Returns whether date object contains birth day and month + * + * @return bool + */ + public function hasDate() + { + return $this->hasDate; + } + + /** + * Returns whether date object contains birth year + * + * @return bool + */ + public function hasYear() + { + return $this->hasYear; + } +} diff --git a/src/Facebook/GraphNodes/GraphNode.php b/src/Facebook/GraphNodes/GraphNode.php index c9f58c348..f838b3062 100644 --- a/src/Facebook/GraphNodes/GraphNode.php +++ b/src/Facebook/GraphNodes/GraphNode.php @@ -62,10 +62,11 @@ public function castItems(array $data) foreach ($data as $k => $v) { if ($this->shouldCastAsDateTime($k) && (is_numeric($v) - || $k === 'birthday' || $this->isIso8601DateString($v)) ) { $items[$k] = $this->castToDateTime($v); + } else if ($k === 'birthday') { + $items[$k] = $this->castToBirthday($v); } else { $items[$k] = $v; } @@ -149,7 +150,6 @@ public function shouldCastAsDateTime($key) 'backdated_time', 'issued_at', 'expires_at', - 'birthday', 'publish_time' ], true); } @@ -173,6 +173,18 @@ public function castToDateTime($value) return $dt; } + /** + * Casts a birthday value from Graph to Birthday + * + * @param string $value + * + * @return \Facebook\GraphNodes\Birthday + */ + public function castToBirthday($value) + { + return new Birthday($value); + } + /** * Getter for $graphObjectMap. * diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index 25a7cc5a4..e545065d5 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -42,7 +42,25 @@ public function setUp() public function testDatesGetCastToDateTime() { $dataFromGraph = [ - 'birthday' => '1984-01-01', + 'updated_time' => '2016-04-26 13:22:05' + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $updatedTime = $graphNode->getField('updated_time'); + + $this->assertInstanceOf('DateTime', $updatedTime); + } + + public function testBirthdaysGetCastToBirthday() + { + $dataFromGraph = [ + 'birthday' => '1984/01/01', ]; $this->responseMock @@ -54,7 +72,53 @@ public function testDatesGetCastToDateTime() $birthday = $graphNode->getBirthday(); + // Test to ensure BC $this->assertInstanceOf('DateTime', $birthday); + + $this->assertInstanceOf('\\Facebook\\GraphNodes\\Birthday', $birthday); + $this->assertTrue($birthday->hasDate()); + $this->assertTrue($birthday->hasYear()); + $this->assertEquals('1984/01/01', $birthday->format('Y/m/d')); + } + + public function testBirthdayCastHandlesDateWithoutYear() + { + $dataFromGraph = [ + 'birthday' => '03/21', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $birthday = $graphNode->getBirthday(); + + $this->assertTrue($birthday->hasDate()); + $this->assertFalse($birthday->hasYear()); + $this->assertEquals('03/21', $birthday->format('m/d')); + } + + public function testBirthdayCastHandlesYearWithoutDate() + { + $dataFromGraph = [ + 'birthday' => '1984', + ]; + + $this->responseMock + ->shouldReceive('getDecodedBody') + ->once() + ->andReturn($dataFromGraph); + $factory = new GraphNodeFactory($this->responseMock); + $graphNode = $factory->makeGraphUser(); + + $birthday = $graphNode->getBirthday(); + + $this->assertTrue($birthday->hasYear()); + $this->assertFalse($birthday->hasDate()); + $this->assertEquals('1984', $birthday->format('Y')); } public function testPagePropertiesWillGetCastAsGraphPageObjects() From 3ee3ac068544b1c268becc4a18cc3075f1393e3c Mon Sep 17 00:00:00 2001 From: Nick Matthews Date: Sun, 17 Apr 2016 17:55:06 +0000 Subject: [PATCH 235/407] Correcting typos in Birthday docs --- docs/Birthday.fbmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Birthday.fbmd b/docs/Birthday.fbmd index 3be5fcf0f..303a29da3 100644 --- a/docs/Birthday.fbmd +++ b/docs/Birthday.fbmd @@ -22,12 +22,12 @@ Usage: ~~~~ $fb = new Facebook\Facebook(\* *\); // Returns a `Facebook\FacebookResponse` object -$response = $fb->get('/something'); +$response = $fb->get('/me'); // Get the response typed as a GraphUser $user = $response->getGraphUser(); -// Gets birthday value, assume graph return was format MM/DD +// Gets birthday value, assume Graph return was format MM/DD $birthday = $user->getBirthday(); var_dump($birthday); From 6b596986000108bc928faf5bb2386e301c505e74 Mon Sep 17 00:00:00 2001 From: Nick Matthews Date: Sun, 17 Apr 2016 19:01:58 +0000 Subject: [PATCH 236/407] Coding style violations, removing timezone --- src/Facebook/GraphNodes/Birthday.php | 17 +++++------------ src/Facebook/GraphNodes/GraphNode.php | 4 ++-- tests/GraphNodes/GraphUserTest.php | 2 +- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/Facebook/GraphNodes/Birthday.php b/src/Facebook/GraphNodes/Birthday.php index 05c78a9ae..35ca57d23 100644 --- a/src/Facebook/GraphNodes/Birthday.php +++ b/src/Facebook/GraphNodes/Birthday.php @@ -24,7 +24,6 @@ namespace Facebook\GraphNodes; use DateTime; -use DateTimeZone; /** * Birthday object to handle various Graph return formats @@ -52,22 +51,16 @@ class Birthday extends DateTime * * @link https://developers.facebook.com/docs/graph-api/reference/user * - * @param string $date - * @param DateTimeZone $timezone + * @param string $date */ - public function __construct($date, DateTimeZone $timezone = null) + public function __construct($date) { $parts = explode('/', $date); - if (count($parts) === 3 || count($parts) === 1) { - $this->hasYear = true; - } + $this->hasYear = count($parts) === 3 || count($parts) === 1; + $this->hasDate = count($parts) === 3 || count($parts) === 2; - if (count($parts) === 3 || count($parts) === 2) { - $this->hasDate = true; - } - - parent::__construct($date, $timezone); + parent::__construct($date); } /** diff --git a/src/Facebook/GraphNodes/GraphNode.php b/src/Facebook/GraphNodes/GraphNode.php index f838b3062..bd79bf0ea 100644 --- a/src/Facebook/GraphNodes/GraphNode.php +++ b/src/Facebook/GraphNodes/GraphNode.php @@ -65,7 +65,7 @@ public function castItems(array $data) || $this->isIso8601DateString($v)) ) { $items[$k] = $this->castToDateTime($v); - } else if ($k === 'birthday') { + } elseif ($k === 'birthday') { $items[$k] = $this->castToBirthday($v); } else { $items[$k] = $v; @@ -178,7 +178,7 @@ public function castToDateTime($value) * * @param string $value * - * @return \Facebook\GraphNodes\Birthday + * @return Birthday */ public function castToBirthday($value) { diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index e545065d5..415116a4e 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -42,7 +42,7 @@ public function setUp() public function testDatesGetCastToDateTime() { $dataFromGraph = [ - 'updated_time' => '2016-04-26 13:22:05' + 'updated_time' => '2016-04-26 13:22:05', ]; $this->responseMock From e4e6df7a0f131bf8e8eb7240ccb1b02cf173ed21 Mon Sep 17 00:00:00 2001 From: Nick Matthews Date: Tue, 19 Apr 2016 21:01:40 +0000 Subject: [PATCH 237/407] Setting Birthday variables to private, moving Birthday docs link to more appropriate location --- docs/GraphNode.fbmd | 2 +- docs/sdk_reference.fbmd | 4 ---- src/Facebook/GraphNodes/Birthday.php | 4 ++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/GraphNode.fbmd b/docs/GraphNode.fbmd index c7cc30ea9..0263fa4f2 100644 --- a/docs/GraphNode.fbmd +++ b/docs/GraphNode.fbmd @@ -168,7 +168,7 @@ Returns the `link` property for the user as a string if present. ~~~~ public \Facebook\GraphNodes\Birthday|null getBirthday() ~~~~ -Returns the `birthday` property for the user as a `\Facebook\GraphNodes\Birthday` if present. +Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](/docs/php/Birthday) if present. ### getLocation() {#user-getlocation} ~~~~ diff --git a/docs/sdk_reference.fbmd b/docs/sdk_reference.fbmd index 8832d0844..2ab60bb16 100644 --- a/docs/sdk_reference.fbmd +++ b/docs/sdk_reference.fbmd @@ -172,10 +172,6 @@ Graph nodes are collections that represent nodes returned by the Graph API. And '[`Facebook\\GraphNodes\\GraphUser`](/docs/php/GraphNode#user-instance-methods)', 'A collection that represents a User node.', ], - [ - '[`Facebook\\GraphNodes\\Birthday`](/docs/php/Birthday#instance-methods)', - 'A class that represents a GraphUser\'s birthday.', - ], ], }) diff --git a/src/Facebook/GraphNodes/Birthday.php b/src/Facebook/GraphNodes/Birthday.php index 35ca57d23..e45dcf4b1 100644 --- a/src/Facebook/GraphNodes/Birthday.php +++ b/src/Facebook/GraphNodes/Birthday.php @@ -35,12 +35,12 @@ class Birthday extends DateTime /** * @var bool */ - protected $hasDate = false; + private $hasDate = false; /** * @var bool */ - protected $hasYear = false; + private $hasYear = false; /** * Parses Graph birthday format to set indication flags, possible values: From 2cfda4066e9d4f2fc7524a0071f9628384bf910d Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 19 Apr 2016 15:26:20 -0700 Subject: [PATCH 238/407] Updating logic for x_forwarded_host --- .../Url/FacebookUrlDetectionHandler.php | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index aa691f108..ae4662293 100644 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -95,7 +95,7 @@ protected function protocolWithActiveSsl($protocol) protected function getHostName() { // Check for proxy first - if ($host = $this->getHeader('X_FORWARDED_HOST')) { + if ($this->isValidForwardedHost() && $host = $this->getHeader('X_FORWARDED_HOST')) { $elements = explode(',', $host); $host = $elements[count($elements) - 1]; } elseif (!$host = $this->getHeader('HOST')) { @@ -160,4 +160,24 @@ protected function getHeader($key) { return $this->getServerVar('HTTP_' . $key); } + + /** + * Checks if the value in X_FORWARDED_HOST is a valid hostname + * Could prevent unintended redirections + */ + protected function isValidForwardedHost() + { + $host = $this->getHeader('X_FORWARDED_HOST'); + if (!$host) { + return false; + } + + $elements = explode(',', $host); + $host = $elements[count($elements) - 1]; + + return return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) //valid chars check + && preg_match("/^.{1,253}$/", $domain_name) //overall length check + && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name) ); //length of each label + } + } From 6239abdf6299b829fb061041789a669e36e8f8f6 Mon Sep 17 00:00:00 2001 From: Daniel Rodrigo Fleck Date: Sat, 30 Apr 2016 08:53:27 -0300 Subject: [PATCH 239/407] Typo fix in FacebookRequest DocBlock --- src/Facebook/FacebookRequest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index 1fd9af87f..2edd103a9 100644 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -154,7 +154,7 @@ public function getAccessToken() } /** - * Return the access token for this request an an AccessToken entity. + * Return the access token for this request as an AccessToken entity. * * @return AccessToken|null */ @@ -214,8 +214,6 @@ public function validateAccessToken() * Set the HTTP method for this request. * * @param string - * - * @return FacebookRequest */ public function setMethod($method) { @@ -273,7 +271,7 @@ public function setEndpoint($endpoint) } /** - * Return the HTTP method for this request. + * Return the endpoint for this request. * * @return string */ From 7ee89e3ea40ce42ce2641d0283965d28ed8abb1b Mon Sep 17 00:00:00 2001 From: paddyohanlon Date: Mon, 9 May 2016 20:45:12 +0200 Subject: [PATCH 240/407] Update README.md, correctly reference Facebook Change `new Facebook\Facebook` to `new Facebook` to fix error 'Fatal error: Class 'Facebook\Facebook\Facebook' not found...'. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 219a028ed..f5d8737de 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ Simple GET example of a user's profile. ```php -$fb = new Facebook\Facebook([ +$fb = new Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', 'default_graph_version' => 'v2.5', From 44252462e1861e95f7497f5edb260f80b14a38e4 Mon Sep 17 00:00:00 2001 From: diegoquinteiro Date: Mon, 9 May 2016 18:07:55 -0300 Subject: [PATCH 241/407] Avoids using unserialize to prevent Object Injection security issue. --- src/Facebook/FacebookApp.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/FacebookApp.php b/src/Facebook/FacebookApp.php index 7edad61cb..7a8dd6e40 100644 --- a/src/Facebook/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -84,7 +84,7 @@ public function getAccessToken() */ public function serialize() { - return serialize([$this->id, $this->secret]); + return json_encode([$this->id, $this->secret]); } /** @@ -94,7 +94,7 @@ public function serialize() */ public function unserialize($serialized) { - list($id, $secret) = unserialize($serialized); + list($id, $secret) = json_decode($serialized); $this->__construct($id, $secret); } From 44cd4c2d8fda3e94917f25e829db3aa8cb1df161 Mon Sep 17 00:00:00 2001 From: diegoquinteiro Date: Mon, 9 May 2016 19:09:50 -0300 Subject: [PATCH 242/407] Uses implode/explode instead of json decode as it is vulnerable to hashtable colision DoS attacks --- src/Facebook/FacebookApp.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facebook/FacebookApp.php b/src/Facebook/FacebookApp.php index 7a8dd6e40..794e1e748 100644 --- a/src/Facebook/FacebookApp.php +++ b/src/Facebook/FacebookApp.php @@ -84,7 +84,7 @@ public function getAccessToken() */ public function serialize() { - return json_encode([$this->id, $this->secret]); + return implode('|', [$this->id, $this->secret]); } /** @@ -94,7 +94,7 @@ public function serialize() */ public function unserialize($serialized) { - list($id, $secret) = json_decode($serialized); + list($id, $secret) = explode('|', $serialized); $this->__construct($id, $secret); } From 40c74a2c3313de49e6033efc4c24d385843c433b Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 19 Apr 2016 16:34:31 -0700 Subject: [PATCH 243/407] Updating per feedback. --- .gitignore | 1 - .../Url/FacebookUrlDetectionHandler.php | 24 +++++++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 0c2e885a4..56b4feb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ vendor/ composer.lock tests/FacebookTestCredentials.php - diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index ae4662293..60baf48ee 100644 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -95,8 +95,8 @@ protected function protocolWithActiveSsl($protocol) protected function getHostName() { // Check for proxy first - if ($this->isValidForwardedHost() && $host = $this->getHeader('X_FORWARDED_HOST')) { - $elements = explode(',', $host); + if ($header = $this->getHeader('X_FORWARDED_HOST') && $this->isValidForwardedHost($header)) { + $elements = explode(',', $header); $host = $elements[count($elements) - 1]; } elseif (!$host = $this->getHeader('HOST')) { if (!$host = $this->getServerVar('SERVER_NAME')) { @@ -164,20 +164,18 @@ 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() + protected function isValidForwardedHost($header) { - $host = $this->getHeader('X_FORWARDED_HOST'); - if (!$host) { - return false; - } - - $elements = explode(',', $host); + $elements = explode(',', $header); $host = $elements[count($elements) - 1]; - return return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) //valid chars check - && preg_match("/^.{1,253}$/", $domain_name) //overall length check - && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name) ); //length of each label + 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 } - } From c51f90d1c119b82c6eb952c073a1f12fd76b528b Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 10 May 2016 08:47:53 -0700 Subject: [PATCH 244/407] updating to 5.1.3 --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 219a028ed..12d7fd579 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.2-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.3-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index da5119c3e..21a0f14b9 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.1.2'; + const VERSION = '5.1.3'; /** * @const string Default Graph API version for requests. From 3279e1b50f1d3f22f3523374418ee26c7b52a088 Mon Sep 17 00:00:00 2001 From: diegoquinteiro Date: Wed, 11 May 2016 16:42:30 -0300 Subject: [PATCH 245/407] Add breaking change warning to changelog --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55dc0ef68..96a4c4263 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,10 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org ## 5.0.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. - +- 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 - 5.0 (2015-??-??) - New features - Added the `Facebook\Facebook` super service for an easier API @@ -22,8 +25,8 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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 + - 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 From 38fd7187a6704d3ab14ded2f3a534ac4ee6f3481 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Fri, 13 May 2016 10:28:30 -0700 Subject: [PATCH 246/407] Updated to 5.1.4 --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 12d7fd579..a3c39c23f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.3-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.4-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 21a0f14b9..648c870ca 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.1.3'; + const VERSION = '5.1.4'; /** * @const string Default Graph API version for requests. From 6727ffa49e4d8a47cee576d4a452c922849431ec Mon Sep 17 00:00:00 2001 From: Emanuele Minotto Date: Wed, 10 Feb 2016 01:38:03 +0100 Subject: [PATCH 247/407] Use Composer safe versions --- .travis.yml | 5 ----- composer.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9813280e1..c3949a800 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,8 +19,3 @@ install: script: - vendor/bin/phpcs src --standard=psr2 -spn - vendor/bin/phpunit --coverage-text --exclude-group integration - -matrix: - allow_failures: - - php: 7.0 - fast_finish: true diff --git a/composer.json b/composer.json index 93af8bf50..20f9934be 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": ">=5.4.0" + "php": "^5.4|^7.0" }, "require-dev": { "phpunit/phpunit": "~4.0", From 69b363dc6a834f725590a6f8a988cec06ad3cd32 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Wed, 18 May 2016 16:57:32 -0500 Subject: [PATCH 248/407] Update CHANGELOG and bump version --- CHANGELOG.md | 5 ++++- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96a4c4263..82526f183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,12 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org/). -## 5.0.x +## 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. +- 5.1.5 + - Removed mbstring extension dependency + - Updated required PHP version syntax in composer.json - 5.1.4 - Breaking changes - Changes the serialization method of FacebookApp diff --git a/README.md b/README.md index a3c39c23f..4dbf6635a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.4-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.5-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 648c870ca..ed74fe854 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.1.4'; + const VERSION = '5.1.5'; /** * @const string Default Graph API version for requests. From c60fba1fe1de62db1e0776d32fc2fb778189459c Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Wed, 18 May 2016 17:04:36 -0500 Subject: [PATCH 249/407] Update CHANGELOG and bump version --- CHANGELOG.md | 4 ++++ README.md | 2 +- src/Facebook/Facebook.php | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82526f183..b30852a25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org ## 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. +- 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 - 5.1.5 - Removed mbstring extension dependency - Updated required PHP version syntax in composer.json diff --git a/README.md b/README.md index c5670b999..24308d1c5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.1.5-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.2.0-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 5ebcda92a..8e2952140 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.1.5'; + const VERSION = '5.2.0'; /** * @const string Default Graph API version for requests. From 0ed1163467c0df7923b630dca212b2850e63f173 Mon Sep 17 00:00:00 2001 From: Jean Baptiste Noblot Date: Fri, 20 May 2016 15:55:06 +0200 Subject: [PATCH 250/407] Change return type of getThrownException --- src/Facebook/FacebookResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/FacebookResponse.php b/src/Facebook/FacebookResponse.php index 5a1cc4d5b..1966484d9 100644 --- a/src/Facebook/FacebookResponse.php +++ b/src/Facebook/FacebookResponse.php @@ -213,7 +213,7 @@ public function makeException() /** * Returns the exception that was thrown for this request. * - * @return FacebookSDKException|null + * @return FacebookResponseException|null */ public function getThrownException() { From a883d83d2060051561458755dcd163f79bdf1d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 20:39:42 +0200 Subject: [PATCH 251/407] Fix: Reduce visibility of setUp() --- tests/Authentication/OAuth2ClientTest.php | 2 +- tests/Exceptions/FacebookResponseExceptionTest.php | 2 +- tests/FacebookAppTest.php | 2 +- tests/FacebookBatchRequestTest.php | 2 +- tests/FacebookBatchResponseTest.php | 2 +- tests/FacebookClientTest.php | 2 +- tests/FacebookResponseTest.php | 2 +- tests/FileUpload/FacebookFileTest.php | 2 +- tests/FileUpload/FacebookResumableUploaderTest.php | 2 +- tests/GraphNodes/AbstractGraphNode.php | 2 +- tests/GraphNodes/GraphAlbumTest.php | 2 +- tests/GraphNodes/GraphEdgeTest.php | 2 +- tests/GraphNodes/GraphEventTest.php | 2 +- tests/GraphNodes/GraphGroupTest.php | 2 +- tests/GraphNodes/GraphNodeFactoryTest.php | 2 +- tests/GraphNodes/GraphObjectFactoryTest.php | 2 +- tests/GraphNodes/GraphPageTest.php | 2 +- tests/GraphNodes/GraphSessionInfoTest.php | 2 +- tests/GraphNodes/GraphUserTest.php | 2 +- tests/Helpers/FacebookCanvasHelperTest.php | 2 +- tests/Helpers/FacebookRedirectLoginHelperTest.php | 2 +- tests/Helpers/FacebookSignedRequestFromInputHelperTest.php | 2 +- tests/HttpClients/FacebookCurlHttpClientTest.php | 2 +- tests/HttpClients/FacebookGuzzleHttpClientTest.php | 2 +- tests/HttpClients/FacebookStreamHttpClientTest.php | 2 +- tests/SignedRequestTest.php | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/Authentication/OAuth2ClientTest.php b/tests/Authentication/OAuth2ClientTest.php index 4ad8548bf..e8a07fbe8 100644 --- a/tests/Authentication/OAuth2ClientTest.php +++ b/tests/Authentication/OAuth2ClientTest.php @@ -46,7 +46,7 @@ class OAuth2ClientTest extends \PHPUnit_Framework_TestCase */ protected $oauth; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_secret'); $this->client = new FooFacebookClientForOAuth2Test(); diff --git a/tests/Exceptions/FacebookResponseExceptionTest.php b/tests/Exceptions/FacebookResponseExceptionTest.php index 6a085aaf7..59ae0c2ed 100644 --- a/tests/Exceptions/FacebookResponseExceptionTest.php +++ b/tests/Exceptions/FacebookResponseExceptionTest.php @@ -36,7 +36,7 @@ class FacebookResponseExceptionTest extends \PHPUnit_Framework_TestCase */ protected $request; - public function setUp() + protected function setUp() { $this->request = new FacebookRequest(new FacebookApp('123', 'foo')); } diff --git a/tests/FacebookAppTest.php b/tests/FacebookAppTest.php index b919b1ee6..4c72fa2f7 100644 --- a/tests/FacebookAppTest.php +++ b/tests/FacebookAppTest.php @@ -32,7 +32,7 @@ class FacebookAppTest extends \PHPUnit_Framework_TestCase */ private $app; - public function setUp() + protected function setUp() { $this->app = new FacebookApp('id', 'secret'); } diff --git a/tests/FacebookBatchRequestTest.php b/tests/FacebookBatchRequestTest.php index 48b8cf40b..4d41a6f4d 100755 --- a/tests/FacebookBatchRequestTest.php +++ b/tests/FacebookBatchRequestTest.php @@ -36,7 +36,7 @@ class FacebookBatchRequestTest extends \PHPUnit_Framework_TestCase */ private $app; - public function setUp() + protected function setUp() { $this->app = new FacebookApp('123', 'foo_secret'); } diff --git a/tests/FacebookBatchResponseTest.php b/tests/FacebookBatchResponseTest.php index 38c174550..8109519c1 100755 --- a/tests/FacebookBatchResponseTest.php +++ b/tests/FacebookBatchResponseTest.php @@ -41,7 +41,7 @@ class FacebookBatchResponseTest extends \PHPUnit_Framework_TestCase */ protected $request; - public function setUp() + protected function setUp() { $this->app = new FacebookApp('123', 'foo_secret'); $this->request = new FacebookRequest( diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 5eb331dd0..18e134674 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -82,7 +82,7 @@ class FacebookClientTest extends \PHPUnit_Framework_TestCase */ public static $testFacebookClient; - public function setUp() + protected function setUp() { $this->fbApp = new FacebookApp('id', 'shhhh!'); $this->fbClient = new FacebookClient(new MyFooClientHandler()); diff --git a/tests/FacebookResponseTest.php b/tests/FacebookResponseTest.php index 779ae00b7..faa8a2ecc 100755 --- a/tests/FacebookResponseTest.php +++ b/tests/FacebookResponseTest.php @@ -34,7 +34,7 @@ class FacebookResponseTest extends \PHPUnit_Framework_TestCase */ protected $request; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_secret'); $this->request = new FacebookRequest( diff --git a/tests/FileUpload/FacebookFileTest.php b/tests/FileUpload/FacebookFileTest.php index 20849b32a..6034a4f50 100644 --- a/tests/FileUpload/FacebookFileTest.php +++ b/tests/FileUpload/FacebookFileTest.php @@ -29,7 +29,7 @@ class FacebookFileTest extends \PHPUnit_Framework_TestCase { protected $testFile = ''; - public function setUp() + protected function setUp() { $this->testFile = __DIR__ . '/../foo.txt'; } diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index a27e97192..72c88062e 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -53,7 +53,7 @@ class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase */ private $file; - public function setUp() + protected function setUp() { $this->fbApp = new FacebookApp('app_id', 'app_secret'); $this->graphApi = new FakeGraphApiForResumableUpload(); diff --git a/tests/GraphNodes/AbstractGraphNode.php b/tests/GraphNodes/AbstractGraphNode.php index 109a723f4..2db5aad2d 100644 --- a/tests/GraphNodes/AbstractGraphNode.php +++ b/tests/GraphNodes/AbstractGraphNode.php @@ -33,7 +33,7 @@ abstract class AbstractGraphNode extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { parent::setUp(); $this->responseMock = m::mock('\Facebook\FacebookResponse'); diff --git a/tests/GraphNodes/GraphAlbumTest.php b/tests/GraphNodes/GraphAlbumTest.php index 326ccccd3..de20d2b02 100644 --- a/tests/GraphNodes/GraphAlbumTest.php +++ b/tests/GraphNodes/GraphAlbumTest.php @@ -34,7 +34,7 @@ class GraphAlbumTest extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } diff --git a/tests/GraphNodes/GraphEdgeTest.php b/tests/GraphNodes/GraphEdgeTest.php index 5113bc2ea..93c91a3fa 100644 --- a/tests/GraphNodes/GraphEdgeTest.php +++ b/tests/GraphNodes/GraphEdgeTest.php @@ -40,7 +40,7 @@ class GraphEdgeTest extends \PHPUnit_Framework_TestCase 'previous' => 'https://graph.facebook.com/v7.12/998899/photos?pretty=0&limit=25&before=foo_before_cursor', ]; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); $this->request = new FacebookRequest( diff --git a/tests/GraphNodes/GraphEventTest.php b/tests/GraphNodes/GraphEventTest.php index 8de45a549..97b049493 100644 --- a/tests/GraphNodes/GraphEventTest.php +++ b/tests/GraphNodes/GraphEventTest.php @@ -34,7 +34,7 @@ class GraphEventTest extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { $this->responseMock = m::mock('\Facebook\FacebookResponse'); } diff --git a/tests/GraphNodes/GraphGroupTest.php b/tests/GraphNodes/GraphGroupTest.php index 9704a8143..f32c88fb6 100644 --- a/tests/GraphNodes/GraphGroupTest.php +++ b/tests/GraphNodes/GraphGroupTest.php @@ -34,7 +34,7 @@ class GraphGroupTest extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { $this->responseMock = m::mock('\Facebook\FacebookResponse'); } diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 93d15b266..a8d0bc2e4 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -47,7 +47,7 @@ class GraphNodeFactoryTest extends \PHPUnit_Framework_TestCase */ protected $request; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); $this->request = new FacebookRequest( diff --git a/tests/GraphNodes/GraphObjectFactoryTest.php b/tests/GraphNodes/GraphObjectFactoryTest.php index 5df6aabcd..885f3eb71 100644 --- a/tests/GraphNodes/GraphObjectFactoryTest.php +++ b/tests/GraphNodes/GraphObjectFactoryTest.php @@ -38,7 +38,7 @@ class GraphObjectFactoryTest extends \PHPUnit_Framework_TestCase */ protected $request; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); $this->request = new FacebookRequest( diff --git a/tests/GraphNodes/GraphPageTest.php b/tests/GraphNodes/GraphPageTest.php index 99df8a20f..72efbaf2e 100644 --- a/tests/GraphNodes/GraphPageTest.php +++ b/tests/GraphNodes/GraphPageTest.php @@ -33,7 +33,7 @@ class GraphPageTest extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } diff --git a/tests/GraphNodes/GraphSessionInfoTest.php b/tests/GraphNodes/GraphSessionInfoTest.php index 1cded4fee..3720ee92f 100644 --- a/tests/GraphNodes/GraphSessionInfoTest.php +++ b/tests/GraphNodes/GraphSessionInfoTest.php @@ -33,7 +33,7 @@ class GraphSessionInfoTest extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } diff --git a/tests/GraphNodes/GraphUserTest.php b/tests/GraphNodes/GraphUserTest.php index 415116a4e..7a1919c17 100644 --- a/tests/GraphNodes/GraphUserTest.php +++ b/tests/GraphNodes/GraphUserTest.php @@ -34,7 +34,7 @@ class GraphUserTest extends \PHPUnit_Framework_TestCase */ protected $responseMock; - public function setUp() + protected function setUp() { $this->responseMock = m::mock('\\Facebook\\FacebookResponse'); } diff --git a/tests/Helpers/FacebookCanvasHelperTest.php b/tests/Helpers/FacebookCanvasHelperTest.php index 29d9431b8..a7506dd57 100644 --- a/tests/Helpers/FacebookCanvasHelperTest.php +++ b/tests/Helpers/FacebookCanvasHelperTest.php @@ -36,7 +36,7 @@ class FacebookCanvasHelperTest extends \PHPUnit_Framework_TestCase */ protected $helper; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); $this->helper = new FacebookCanvasHelper($app, new FacebookClient()); diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 1c8bd112a..1891e1792 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -61,7 +61,7 @@ class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase const REDIRECT_URL = 'http://invalid.zzz'; - public function setUp() + protected function setUp() { $this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index 2d5fa0927..c22f4f0f9 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -61,7 +61,7 @@ class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCa public $rawSignedRequestAuthorizedWithCode = 'oBtmZlsFguNQvGRETDYQQu1-PhwcArgbBBEK4urbpRA=.eyJjb2RlIjoiZm9vX2NvZGUiLCJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwNjMxMDc1MiwidXNlcl9pZCI6IjEyMyJ9'; public $rawSignedRequestUnauthorized = 'KPlyhz-whtYAhHWr15N5TkbS_avz-2rUJFpFkfXKC88=.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImlzc3VlZF9hdCI6MTQwMjU1MTA4Nn0='; - public function setUp() + protected function setUp() { $app = new FacebookApp('123', 'foo_app_secret'); $this->helper = new FooSignedRequestHelper($app, new FooSignedRequestHelperFacebookClient()); diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index bbb8d2bc5..67bed5252 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -41,7 +41,7 @@ class FacebookCurlHttpClientTest extends AbstractTestHttpClient const CURL_VERSION_STABLE = 0x072400; const CURL_VERSION_BUGGY = 0x071400; - public function setUp() + protected function setUp() { if (!extension_loaded('curl')) { $this->markTestSkipped('cURL must be installed to test cURL client handler.'); diff --git a/tests/HttpClients/FacebookGuzzleHttpClientTest.php b/tests/HttpClients/FacebookGuzzleHttpClientTest.php index 2c6a973ba..5c39807bd 100644 --- a/tests/HttpClients/FacebookGuzzleHttpClientTest.php +++ b/tests/HttpClients/FacebookGuzzleHttpClientTest.php @@ -42,7 +42,7 @@ class FacebookGuzzleHttpClientTest extends AbstractTestHttpClient */ protected $guzzleClient; - public function setUp() + protected function setUp() { $this->guzzleMock = m::mock('GuzzleHttp\Client'); $this->guzzleClient = new FacebookGuzzleHttpClient($this->guzzleMock); diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index fc1d4d8f8..f63c0ebba 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -38,7 +38,7 @@ class FacebookStreamHttpClientTest extends AbstractTestHttpClient */ protected $streamClient; - public function setUp() + protected function setUp() { $this->streamMock = m::mock('Facebook\HttpClients\FacebookStream'); $this->streamClient = new FacebookStreamHttpClient($this->streamMock); diff --git a/tests/SignedRequestTest.php b/tests/SignedRequestTest.php index 5bf579c7f..7d58072f5 100644 --- a/tests/SignedRequestTest.php +++ b/tests/SignedRequestTest.php @@ -46,7 +46,7 @@ class SignedRequestTest extends \PHPUnit_Framework_TestCase 'foo' => 'bar', ]; - public function setUp() + protected function setUp() { $this->app = new FacebookApp('123', 'foo_app_secret'); } From ca5f4bac0c589c2cb8f7d8d455c97cfb840574ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 20:52:10 +0200 Subject: [PATCH 252/407] Fix: Actually append Test to name of file containing test --- .../{AccessTokenMetadata.php => AccessTokenMetadataTest.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/Authentication/{AccessTokenMetadata.php => AccessTokenMetadataTest.php} (100%) diff --git a/tests/Authentication/AccessTokenMetadata.php b/tests/Authentication/AccessTokenMetadataTest.php similarity index 100% rename from tests/Authentication/AccessTokenMetadata.php rename to tests/Authentication/AccessTokenMetadataTest.php From ea60444ff4e8a2885d420147f60ab3ebee558931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 21:03:27 +0200 Subject: [PATCH 253/407] Fix: Remove unused imports --- tests/Authentication/OAuth2ClientTest.php | 1 - tests/PseudoRandomString/PseudoRandomStringFactoryTest.php | 3 --- tests/bootstrap.php | 2 -- 3 files changed, 6 deletions(-) diff --git a/tests/Authentication/OAuth2ClientTest.php b/tests/Authentication/OAuth2ClientTest.php index 4ad8548bf..c2c460e5c 100644 --- a/tests/Authentication/OAuth2ClientTest.php +++ b/tests/Authentication/OAuth2ClientTest.php @@ -23,7 +23,6 @@ */ namespace Facebook\Tests\Authentication; -use Mockery as m; use Facebook\Facebook; use Facebook\FacebookApp; use Facebook\Authentication\OAuth2Client; diff --git a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php index 381fe3608..996e6fcaf 100644 --- a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php +++ b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php @@ -23,10 +23,7 @@ */ namespace Facebook\Tests\PseudoRandomString; -use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; -use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory; -use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; use PHPUnit_Framework_TestCase; class PseudoRandomStringFactoryTest extends PHPUnit_Framework_TestCase diff --git a/tests/bootstrap.php b/tests/bootstrap.php index aaa79539b..b2744a194 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -25,8 +25,6 @@ require_once __DIR__ . '/../vendor/autoload.php'; -use Facebook\FacebookClient; - // Delete the temp test user after all tests have fired register_shutdown_function(function () { //echo "\nTotal requests made to Graph: " . FacebookClient::$requestCount . "\n\n"; From eac40c47010ba8feab254eb4b9beafaad9fb51ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 21:05:16 +0200 Subject: [PATCH 254/407] Fix: Remove unused local variables --- tests/FacebookTest.php | 14 +++++++------- tests/FileUpload/FacebookResumableUploaderTest.php | 2 +- .../FacebookSessionPersistentDataHandlerTest.php | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 05e2bbdda..ed41d432c 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -91,7 +91,7 @@ public function testInstantiatingWithoutAppIdThrows() $config = [ 'app_secret' => 'foo_secret', ]; - $fb = new Facebook($config); + new Facebook($config); } /** @@ -104,7 +104,7 @@ public function testInstantiatingWithoutAppSecretThrows() $config = [ 'app_id' => 'foo_id', ]; - $fb = new Facebook($config); + new Facebook($config); } /** @@ -115,7 +115,7 @@ public function testSettingAnInvalidHttpClientHandlerThrows() $config = array_merge($this->config, [ 'http_client_handler' => 'foo_handler', ]); - $fb = new Facebook($config); + new Facebook($config); } public function testCurlHttpClientHandlerCanBeForced() @@ -165,7 +165,7 @@ public function testSettingAnInvalidPersistentDataHandlerThrows() $config = array_merge($this->config, [ 'persistent_data_handler' => 'foo_handler', ]); - $fb = new Facebook($config); + new Facebook($config); } public function testPersistentDataHandlerCanBeForced() @@ -191,7 +191,7 @@ public function testSettingAnInvalidUrlHandlerThrows() $config = array_merge($this->config, [ 'url_detection_handler' => 'foo_handler', ]); - $fb = new Facebook($config); + new Facebook($config); } public function testTheUrlHandlerWillDefaultToTheFacebookImplementation() @@ -302,7 +302,7 @@ public function testSettingAnAccessThatIsNotStringOrAccessTokenThrows() $config = array_merge($this->config, [ 'default_access_token' => 123, ]); - $fb = new Facebook($config); + new Facebook($config); } public function testCreatingANewRequestWillDefaultToTheProperConfig() @@ -413,6 +413,6 @@ public function testMaxingOutRetriesWillThrow() 'http_client_handler' => $client, ]); $fb = new Facebook($config); - $response = $fb->uploadVideo('4', __DIR__.'/foo.txt', [], 'foo-token', 3); + $fb->uploadVideo('4', __DIR__.'/foo.txt', [], 'foo-token', 3); } } diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index a27e97192..62e0dcb75 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -86,7 +86,7 @@ public function testStartWillLetErrorResponsesThrow() $this->graphApi->failOnStart(); $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); - $chunk = $uploader->start('/me/videos', $this->file); + $uploader->start('/me/videos', $this->file); } public function testFailedResumableTransferWillNotThrowAndReturnSameChunk() diff --git a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php index 9b212f055..9e208531f 100644 --- a/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php +++ b/tests/PersistentData/FacebookSessionPersistentDataHandlerTest.php @@ -32,7 +32,7 @@ class FacebookSessionPersistentDataHandlerTest extends \PHPUnit_Framework_TestCa */ public function testInactiveSessionsWillThrow() { - $handler = new FacebookSessionPersistentDataHandler(); + new FacebookSessionPersistentDataHandler(); } public function testCanSetAValue() From 5ff7c3d1fc0ca8cb46ee4b19cbfed898f194dc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 21:08:56 +0200 Subject: [PATCH 255/407] Fix: Attempt to cache dependencies between builds --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c3949a800..19f9c1b35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,12 +9,16 @@ php: sudo: false +cache: + directories: + - $HOME/.composer/cache + before_install: - travis_retry composer self-update install: - travis_retry composer require --dev --no-update squizlabs/php_codesniffer - - travis_retry composer install --prefer-source --no-interaction + - travis_retry composer install --prefer-dist --no-interaction script: - vendor/bin/phpcs src --standard=psr2 -spn From 5d1a9f128bfbe44b1a6521d8740bc3f3649c6d79 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Mon, 23 May 2016 15:10:37 -0700 Subject: [PATCH 256/407] Added a note to changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b30852a25..b1f5c526d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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-??-??) - New features - Added the `Facebook\Facebook` super service for an easier API From d8dd22e4f260e2db89409cd19f86d5e3546b522b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 21:28:44 +0200 Subject: [PATCH 257/407] Enhancement: Extract configuration file for phpcs --- .travis.yml | 2 +- CONTRIBUTING.md | 2 +- phpcs.xml.dist | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 phpcs.xml.dist diff --git a/.travis.yml b/.travis.yml index 19f9c1b35..ee6153074 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,5 +21,5 @@ install: - travis_retry composer install --prefer-dist --no-interaction script: - - vendor/bin/phpcs src --standard=psr2 -spn + - vendor/bin/phpcs - vendor/bin/phpunit --coverage-text --exclude-group integration diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f03bd7904..1d922863e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ $ composer global require squizlabs/php_codesniffer Then you can `cd` into the Facebook PHP SDK folder and run Code Sniffer against the `src/` directory. ``` bash -$ ~/.composer/vendor/bin/phpcs src --standard=psr2 -spn +$ ~/.composer/vendor/bin/phpcs ``` **Happy coding**! diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 000000000..886a4c7aa --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,6 @@ + + + src/ + + + From 7379ae6899519592465dfb07870760f62c07807a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 21:33:05 +0200 Subject: [PATCH 258/407] Enhancement: Require code in tests/ to be PSR-2-compliant --- .scrutinizer.yml | 1 + phpcs.xml.dist | 1 + 2 files changed, 2 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 663201362..05bdf778c 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,6 +1,7 @@ filter: paths: - 'src/*' + - 'tests/*' tools: php_code_sniffer: diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 886a4c7aa..96c56f886 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -1,6 +1,7 @@ src/ + tests/ From 44998450d8f272bc3d6ac9041a0a1a5c2b57f482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sat, 21 May 2016 21:34:23 +0200 Subject: [PATCH 259/407] Fix: Extract class definitions, indentation --- tests/FacebookClientTest.php | 24 ---------- tests/FacebookTest.php | 44 ------------------- .../FakeGraphApiForResumableUpload.php | 26 +++++------ tests/FooBarPseudoRandomStringGenerator.php | 34 ++++++++++++++ tests/FooClientInterface.php | 38 ++++++++++++++++ tests/FooPersistentDataInterface.php | 38 ++++++++++++++++ tests/FooUrlDetectionInterface.php | 34 ++++++++++++++ tests/GraphNodes/GraphNodeFactoryTest.php | 12 ----- tests/GraphNodes/MyFooGraphNode.php | 33 ++++++++++++++ tests/GraphNodes/MyFooSubClassGraphNode.php | 30 +++++++++++++ .../FacebookRedirectLoginHelperTest.php | 18 -------- ...cebookSignedRequestFromInputHelperTest.php | 25 ----------- .../FooPseudoRandomStringGenerator.php | 34 ++++++++++++++ .../Helpers/FooRedirectLoginOAuth2Client.php | 34 ++++++++++++++ tests/Helpers/FooSignedRequestHelper.php | 34 ++++++++++++++ .../FooSignedRequestHelperFacebookClient.php | 41 +++++++++++++++++ tests/MyFooBatchClientHandler.php | 38 ++++++++++++++++ tests/MyFooClientHandler.php | 38 ++++++++++++++++ .../MyFooBarPseudoRandomStringGenerator.php | 31 +++++++++++++ .../PseudoRandomStringGeneratorTraitTest.php | 7 --- 20 files changed, 470 insertions(+), 143 deletions(-) create mode 100644 tests/FooBarPseudoRandomStringGenerator.php create mode 100644 tests/FooClientInterface.php create mode 100644 tests/FooPersistentDataInterface.php create mode 100644 tests/FooUrlDetectionInterface.php create mode 100644 tests/GraphNodes/MyFooGraphNode.php create mode 100644 tests/GraphNodes/MyFooSubClassGraphNode.php create mode 100644 tests/Helpers/FooPseudoRandomStringGenerator.php create mode 100644 tests/Helpers/FooRedirectLoginOAuth2Client.php create mode 100644 tests/Helpers/FooSignedRequestHelper.php create mode 100644 tests/Helpers/FooSignedRequestHelperFacebookClient.php create mode 100644 tests/MyFooBatchClientHandler.php create mode 100644 tests/MyFooClientHandler.php create mode 100644 tests/PseudoRandomString/MyFooBarPseudoRandomStringGenerator.php diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index 18e134674..bcd03f2f3 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -29,8 +29,6 @@ use Facebook\FacebookRequest; use Facebook\FacebookBatchRequest; use Facebook\FacebookClient; -use Facebook\Http\GraphRawResponse; -use Facebook\HttpClients\FacebookHttpClientInterface; use Facebook\FileUpload\FacebookFile; use Facebook\FileUpload\FacebookVideo; // These are needed when you uncomment the HTTP clients below. @@ -38,28 +36,6 @@ use Facebook\HttpClients\FacebookGuzzleHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; -class MyFooClientHandler implements FacebookHttpClientInterface -{ - public function send($url, $method, $body, array $headers, $timeOut) - { - return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", - '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' - ); - } -} - -class MyFooBatchClientHandler implements FacebookHttpClientInterface -{ - public function send($url, $method, $body, array $headers, $timeOut) - { - return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", - '[{"code":"123","body":"Foo"},{"code":"1337","body":"Bar"}]' - ); - } -} - class FacebookClientTest extends \PHPUnit_Framework_TestCase { /** diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index ed41d432c..d2172f263 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -25,55 +25,11 @@ use Facebook\Facebook; use Facebook\FacebookClient; -use Facebook\Http\GraphRawResponse; -use Facebook\HttpClients\FacebookHttpClientInterface; -use Facebook\PersistentData\PersistentDataInterface; -use Facebook\Url\UrlDetectionInterface; -use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; use Facebook\FacebookRequest; use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphEdge; use Facebook\Tests\FakeGraphApi\FakeGraphApiForResumableUpload; -class FooClientInterface implements FacebookHttpClientInterface -{ - public function send($url, $method, $body, array $headers, $timeOut) - { - return new GraphRawResponse( - "HTTP/1.1 1337 OK\r\nDate: Mon, 19 May 2014 18:37:17 GMT", - '{"data":[{"id":"123","name":"Foo"},{"id":"1337","name":"Bar"}]}' - ); - } -} - -class FooPersistentDataInterface implements PersistentDataInterface -{ - public function get($key) - { - return 'foo'; - } - - public function set($key, $value) - { - } -} - -class FooUrlDetectionInterface implements UrlDetectionInterface -{ - public function getCurrentUrl() - { - return 'https://foo.bar'; - } -} - -class FooBarPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface -{ - public function getPseudoRandomString($length) - { - return 'csprs123'; - } -} - class FacebookTest extends \PHPUnit_Framework_TestCase { protected $config = [ diff --git a/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php b/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php index d7e54bfb2..64c94d640 100644 --- a/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php +++ b/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php @@ -58,16 +58,16 @@ private function respondStart() { if ($this->respondWith == 'FAIL_ON_START') { return new GraphRawResponse( - "HTTP/1.1 500 OK\r\nFoo: Bar", - '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . - '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . - '"type":"OAuthException","code":190,"error_subcode":463}}' + "HTTP/1.1 500 OK\r\nFoo: Bar", + '{"error":{"message":"Error validating access token: Session has expired on Monday, ' . + '10-Aug-15 01:00:00 PDT. The current time is Monday, 10-Aug-15 01:14:23 PDT.",' . + '"type":"OAuthException","code":190,"error_subcode":463}}' ); } return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nFoo: Bar", - '{"video_id":"1337","start_offset":"0","end_offset":"20","upload_session_id":"42"}' + "HTTP/1.1 200 OK\r\nFoo: Bar", + '{"video_id":"1337","start_offset":"0","end_offset":"20","upload_session_id":"42"}' ); } @@ -75,9 +75,9 @@ private function respondTransfer() { if ($this->respondWith == 'FAIL_ON_TRANSFER') { return new GraphRawResponse( - "HTTP/1.1 500 OK\r\nFoo: Bar", - '{"error":{"message":"There was a problem uploading your video. Please try uploading it again.",' . - '"type":"FacebookApiException","code":6000,"error_subcode":1363019}}' + "HTTP/1.1 500 OK\r\nFoo: Bar", + '{"error":{"message":"There was a problem uploading your video. Please try uploading it again.",' . + '"type":"FacebookApiException","code":6000,"error_subcode":1363019}}' ); } @@ -96,16 +96,16 @@ private function respondTransfer() $this->transferCount++; return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nFoo: Bar", - json_encode($data) + "HTTP/1.1 200 OK\r\nFoo: Bar", + json_encode($data) ); } private function respondFinish() { return new GraphRawResponse( - "HTTP/1.1 200 OK\r\nFoo: Bar", - '{"success":true}' + "HTTP/1.1 200 OK\r\nFoo: Bar", + '{"success":true}' ); } } diff --git a/tests/FooBarPseudoRandomStringGenerator.php b/tests/FooBarPseudoRandomStringGenerator.php new file mode 100644 index 000000000..d29bd2020 --- /dev/null +++ b/tests/FooBarPseudoRandomStringGenerator.php @@ -0,0 +1,34 @@ + '\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', - ]; -} class GraphNodeFactoryTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/GraphNodes/MyFooGraphNode.php b/tests/GraphNodes/MyFooGraphNode.php new file mode 100644 index 000000000..179f726e2 --- /dev/null +++ b/tests/GraphNodes/MyFooGraphNode.php @@ -0,0 +1,33 @@ + '\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', + ]; +} diff --git a/tests/GraphNodes/MyFooSubClassGraphNode.php b/tests/GraphNodes/MyFooSubClassGraphNode.php new file mode 100644 index 000000000..ea96008ec --- /dev/null +++ b/tests/GraphNodes/MyFooSubClassGraphNode.php @@ -0,0 +1,30 @@ +getParams(); - $rawResponse = json_encode([ - 'access_token' => 'foo_access_token_from:' . $params['code'], - ]); - - return new FacebookResponse($request, $rawResponse, 200); - } -} class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Helpers/FooPseudoRandomStringGenerator.php b/tests/Helpers/FooPseudoRandomStringGenerator.php new file mode 100644 index 000000000..eeb85a9ff --- /dev/null +++ b/tests/Helpers/FooPseudoRandomStringGenerator.php @@ -0,0 +1,34 @@ +getParams(); + $rawResponse = json_encode([ + 'access_token' => 'foo_access_token_from:' . $params['code'], + ]); + + return new FacebookResponse($request, $rawResponse, 200); + } +} diff --git a/tests/MyFooBatchClientHandler.php b/tests/MyFooBatchClientHandler.php new file mode 100644 index 000000000..af7ba569c --- /dev/null +++ b/tests/MyFooBatchClientHandler.php @@ -0,0 +1,38 @@ + Date: Thu, 26 May 2016 03:42:43 +0700 Subject: [PATCH 260/407] Corrected phpDoc comment for binToHex The method doesn't actually throw \InvalidArgumentException --- .../PseudoRandomString/PseudoRandomStringGeneratorTrait.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php index 838054f17..c579e64bd 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorTrait.php @@ -48,7 +48,6 @@ public function validateLength($length) * * @param string $binaryData The binary data to convert to hex. * @param int $length The length of the string to return. - * @throws \RuntimeException Throws an exception when multibyte support is not enabled * * @return string */ From 1f54c6011c3952d6fbb63d6afc4646b7103c6db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Wed, 25 May 2016 18:53:28 +0200 Subject: [PATCH 261/407] Fix: Move test assets to Fixtures namespace --- tests/FacebookClientTest.php | 4 +++- tests/FacebookTest.php | 14 +++++++++----- .../FacebookResumableUploaderTest.php | 2 +- .../FakeGraphApiForResumableUpload.php | 2 +- .../FooBarPseudoRandomStringGenerator.php | 2 +- tests/{ => Fixtures}/FooClientInterface.php | 2 +- .../FooPersistentDataInterface.php | 2 +- .../FooPseudoRandomStringGenerator.php | 2 +- .../FooRedirectLoginOAuth2Client.php | 2 +- .../FooSignedRequestHelper.php | 2 +- .../FooSignedRequestHelperFacebookClient.php | 2 +- .../FooUrlDetectionInterface.php | 2 +- .../MyFooBarPseudoRandomStringGenerator.php | 2 +- .../{ => Fixtures}/MyFooBatchClientHandler.php | 2 +- tests/{ => Fixtures}/MyFooClientHandler.php | 2 +- .../MyFooGraphNode.php | 4 ++-- .../MyFooSubClassGraphNode.php | 2 +- tests/GraphNodes/GraphNodeFactoryTest.php | 18 +++++++++--------- .../FacebookRedirectLoginHelperTest.php | 2 ++ ...acebookSignedRequestFromInputHelperTest.php | 2 ++ .../PseudoRandomStringGeneratorTraitTest.php | 2 ++ 21 files changed, 43 insertions(+), 31 deletions(-) rename tests/{FakeGraphApi => Fixtures}/FakeGraphApiForResumableUpload.php (98%) rename tests/{ => Fixtures}/FooBarPseudoRandomStringGenerator.php (97%) rename tests/{ => Fixtures}/FooClientInterface.php (97%) rename tests/{ => Fixtures}/FooPersistentDataInterface.php (97%) rename tests/{Helpers => Fixtures}/FooPseudoRandomStringGenerator.php (97%) rename tests/{Helpers => Fixtures}/FooRedirectLoginOAuth2Client.php (97%) rename tests/{Helpers => Fixtures}/FooSignedRequestHelper.php (97%) rename tests/{Helpers => Fixtures}/FooSignedRequestHelperFacebookClient.php (97%) rename tests/{ => Fixtures}/FooUrlDetectionInterface.php (97%) rename tests/{PseudoRandomString => Fixtures}/MyFooBarPseudoRandomStringGenerator.php (96%) rename tests/{ => Fixtures}/MyFooBatchClientHandler.php (97%) rename tests/{ => Fixtures}/MyFooClientHandler.php (97%) rename tests/{GraphNodes => Fixtures}/MyFooGraphNode.php (91%) rename tests/{GraphNodes => Fixtures}/MyFooSubClassGraphNode.php (96%) diff --git a/tests/FacebookClientTest.php b/tests/FacebookClientTest.php index bcd03f2f3..b9903184c 100644 --- a/tests/FacebookClientTest.php +++ b/tests/FacebookClientTest.php @@ -35,6 +35,8 @@ use Facebook\HttpClients\FacebookCurlHttpClient; use Facebook\HttpClients\FacebookGuzzleHttpClient; use Facebook\HttpClients\FacebookStreamHttpClient; +use Facebook\Tests\Fixtures\MyFooBatchClientHandler; +use Facebook\Tests\Fixtures\MyFooClientHandler; class FacebookClientTest extends \PHPUnit_Framework_TestCase { @@ -70,7 +72,7 @@ public function testACustomHttpClientCanBeInjected() $client = new FacebookClient($handler); $httpHandler = $client->getHttpClientHandler(); - $this->assertInstanceOf('Facebook\Tests\MyFooClientHandler', $httpHandler); + $this->assertInstanceOf('Facebook\Tests\Fixtures\MyFooClientHandler', $httpHandler); } public function testTheHttpClientWillFallbackToDefault() diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index d2172f263..23eeb65a2 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -28,7 +28,11 @@ use Facebook\FacebookRequest; use Facebook\Authentication\AccessToken; use Facebook\GraphNodes\GraphEdge; -use Facebook\Tests\FakeGraphApi\FakeGraphApiForResumableUpload; +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; class FacebookTest extends \PHPUnit_Framework_TestCase { @@ -292,19 +296,19 @@ public function testCanInjectCustomHandlers() $fb = new Facebook($config); $this->assertInstanceOf( - 'Facebook\Tests\FooClientInterface', + 'Facebook\Tests\Fixtures\FooClientInterface', $fb->getClient()->getHttpClientHandler() ); $this->assertInstanceOf( - 'Facebook\Tests\FooPersistentDataInterface', + 'Facebook\Tests\Fixtures\FooPersistentDataInterface', $fb->getRedirectLoginHelper()->getPersistentDataHandler() ); $this->assertInstanceOf( - 'Facebook\Tests\FooUrlDetectionInterface', + 'Facebook\Tests\Fixtures\FooUrlDetectionInterface', $fb->getRedirectLoginHelper()->getUrlDetectionHandler() ); $this->assertInstanceOf( - 'Facebook\Tests\FooBarPseudoRandomStringGenerator', + 'Facebook\Tests\Fixtures\FooBarPseudoRandomStringGenerator', $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() ); } diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index e689d476f..4100e3863 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -29,7 +29,7 @@ use Facebook\FacebookClient; use Facebook\FileUpload\FacebookResumableUploader; use Facebook\FileUpload\FacebookTransferChunk; -use Facebook\Tests\FakeGraphApi\FakeGraphApiForResumableUpload; +use Facebook\Tests\Fixtures\FakeGraphApiForResumableUpload; class FacebookResumableUploaderTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php b/tests/Fixtures/FakeGraphApiForResumableUpload.php similarity index 98% rename from tests/FakeGraphApi/FakeGraphApiForResumableUpload.php rename to tests/Fixtures/FakeGraphApiForResumableUpload.php index 64c94d640..7d01fb983 100644 --- a/tests/FakeGraphApi/FakeGraphApiForResumableUpload.php +++ b/tests/Fixtures/FakeGraphApiForResumableUpload.php @@ -22,7 +22,7 @@ * */ -namespace Facebook\Tests\FakeGraphApi; +namespace Facebook\Tests\Fixtures; use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; diff --git a/tests/FooBarPseudoRandomStringGenerator.php b/tests/Fixtures/FooBarPseudoRandomStringGenerator.php similarity index 97% rename from tests/FooBarPseudoRandomStringGenerator.php rename to tests/Fixtures/FooBarPseudoRandomStringGenerator.php index d29bd2020..e389155c0 100644 --- a/tests/FooBarPseudoRandomStringGenerator.php +++ b/tests/Fixtures/FooBarPseudoRandomStringGenerator.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests; +namespace Facebook\Tests\Fixtures; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; diff --git a/tests/FooClientInterface.php b/tests/Fixtures/FooClientInterface.php similarity index 97% rename from tests/FooClientInterface.php rename to tests/Fixtures/FooClientInterface.php index e1c7da693..132c6ab38 100644 --- a/tests/FooClientInterface.php +++ b/tests/Fixtures/FooClientInterface.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests; +namespace Facebook\Tests\Fixtures; use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; diff --git a/tests/FooPersistentDataInterface.php b/tests/Fixtures/FooPersistentDataInterface.php similarity index 97% rename from tests/FooPersistentDataInterface.php rename to tests/Fixtures/FooPersistentDataInterface.php index 71702b434..2a0825e0f 100644 --- a/tests/FooPersistentDataInterface.php +++ b/tests/Fixtures/FooPersistentDataInterface.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests; +namespace Facebook\Tests\Fixtures; use Facebook\PersistentData\PersistentDataInterface; diff --git a/tests/Helpers/FooPseudoRandomStringGenerator.php b/tests/Fixtures/FooPseudoRandomStringGenerator.php similarity index 97% rename from tests/Helpers/FooPseudoRandomStringGenerator.php rename to tests/Fixtures/FooPseudoRandomStringGenerator.php index eeb85a9ff..9e64c9f9a 100644 --- a/tests/Helpers/FooPseudoRandomStringGenerator.php +++ b/tests/Fixtures/FooPseudoRandomStringGenerator.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Helpers; +namespace Facebook\Tests\Fixtures; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; diff --git a/tests/Helpers/FooRedirectLoginOAuth2Client.php b/tests/Fixtures/FooRedirectLoginOAuth2Client.php similarity index 97% rename from tests/Helpers/FooRedirectLoginOAuth2Client.php rename to tests/Fixtures/FooRedirectLoginOAuth2Client.php index 0a2ca5973..7c2fef78a 100644 --- a/tests/Helpers/FooRedirectLoginOAuth2Client.php +++ b/tests/Fixtures/FooRedirectLoginOAuth2Client.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Helpers; +namespace Facebook\Tests\Fixtures; use Facebook\Authentication\OAuth2Client; diff --git a/tests/Helpers/FooSignedRequestHelper.php b/tests/Fixtures/FooSignedRequestHelper.php similarity index 97% rename from tests/Helpers/FooSignedRequestHelper.php rename to tests/Fixtures/FooSignedRequestHelper.php index e44121c88..7df853976 100644 --- a/tests/Helpers/FooSignedRequestHelper.php +++ b/tests/Fixtures/FooSignedRequestHelper.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Helpers; +namespace Facebook\Tests\Fixtures; use Facebook\Helpers\FacebookSignedRequestFromInputHelper; diff --git a/tests/Helpers/FooSignedRequestHelperFacebookClient.php b/tests/Fixtures/FooSignedRequestHelperFacebookClient.php similarity index 97% rename from tests/Helpers/FooSignedRequestHelperFacebookClient.php rename to tests/Fixtures/FooSignedRequestHelperFacebookClient.php index 37167c3e3..043c7ef20 100644 --- a/tests/Helpers/FooSignedRequestHelperFacebookClient.php +++ b/tests/Fixtures/FooSignedRequestHelperFacebookClient.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\Helpers; +namespace Facebook\Tests\Fixtures; use Facebook\FacebookClient; use Facebook\FacebookRequest; diff --git a/tests/FooUrlDetectionInterface.php b/tests/Fixtures/FooUrlDetectionInterface.php similarity index 97% rename from tests/FooUrlDetectionInterface.php rename to tests/Fixtures/FooUrlDetectionInterface.php index d797a55db..87122f103 100644 --- a/tests/FooUrlDetectionInterface.php +++ b/tests/Fixtures/FooUrlDetectionInterface.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests; +namespace Facebook\Tests\Fixtures; use Facebook\Url\UrlDetectionInterface; diff --git a/tests/PseudoRandomString/MyFooBarPseudoRandomStringGenerator.php b/tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php similarity index 96% rename from tests/PseudoRandomString/MyFooBarPseudoRandomStringGenerator.php rename to tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php index ae788f85c..dfdc1540a 100644 --- a/tests/PseudoRandomString/MyFooBarPseudoRandomStringGenerator.php +++ b/tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\PseudoRandomString; +namespace Facebook\Tests\Fixtures; use Facebook\PseudoRandomString\PseudoRandomStringGeneratorTrait; diff --git a/tests/MyFooBatchClientHandler.php b/tests/Fixtures/MyFooBatchClientHandler.php similarity index 97% rename from tests/MyFooBatchClientHandler.php rename to tests/Fixtures/MyFooBatchClientHandler.php index af7ba569c..46a12cd74 100644 --- a/tests/MyFooBatchClientHandler.php +++ b/tests/Fixtures/MyFooBatchClientHandler.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests; +namespace Facebook\Tests\Fixtures; use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; diff --git a/tests/MyFooClientHandler.php b/tests/Fixtures/MyFooClientHandler.php similarity index 97% rename from tests/MyFooClientHandler.php rename to tests/Fixtures/MyFooClientHandler.php index 9a5fc96e6..750f46d6a 100644 --- a/tests/MyFooClientHandler.php +++ b/tests/Fixtures/MyFooClientHandler.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests; +namespace Facebook\Tests\Fixtures; use Facebook\Http\GraphRawResponse; use Facebook\HttpClients\FacebookHttpClientInterface; diff --git a/tests/GraphNodes/MyFooGraphNode.php b/tests/Fixtures/MyFooGraphNode.php similarity index 91% rename from tests/GraphNodes/MyFooGraphNode.php rename to tests/Fixtures/MyFooGraphNode.php index 179f726e2..ecdecad62 100644 --- a/tests/GraphNodes/MyFooGraphNode.php +++ b/tests/Fixtures/MyFooGraphNode.php @@ -21,13 +21,13 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\GraphNodes; +namespace Facebook\Tests\Fixtures; use Facebook\GraphNodes\GraphNode; class MyFooGraphNode extends GraphNode { protected static $graphObjectMap = [ - 'foo_object' => '\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', + 'foo_object' => '\Facebook\Tests\Fixtures\MyFooSubClassGraphNode', ]; } diff --git a/tests/GraphNodes/MyFooSubClassGraphNode.php b/tests/Fixtures/MyFooSubClassGraphNode.php similarity index 96% rename from tests/GraphNodes/MyFooSubClassGraphNode.php rename to tests/Fixtures/MyFooSubClassGraphNode.php index ea96008ec..9ce95a6a3 100644 --- a/tests/GraphNodes/MyFooSubClassGraphNode.php +++ b/tests/Fixtures/MyFooSubClassGraphNode.php @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. * */ -namespace Facebook\Tests\GraphNodes; +namespace Facebook\Tests\Fixtures; use Facebook\GraphNodes\GraphNode; diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 586607f8b..4f769718a 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -114,7 +114,7 @@ public function testValidSubClassesWillNotThrow() { GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphNode'); GraphNodeFactory::validateSubclass('\Facebook\GraphNodes\GraphAlbum'); - GraphNodeFactory::validateSubclass('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + GraphNodeFactory::validateSubclass('\Facebook\Tests\Fixtures\MyFooGraphNode'); } public function testCastingAsASubClassObjectWillInstantiateTheSubClass() @@ -123,9 +123,9 @@ public function testCastingAsASubClassObjectWillInstantiateTheSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\Fixtures\MyFooGraphNode'); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $mySubClassObject); } public function testASubClassMappingWillAutomaticallyInstantiateSubClass() @@ -134,11 +134,11 @@ public function testASubClassMappingWillAutomaticallyInstantiateSubClass() $res = new FacebookResponse($this->request, $data); $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\Fixtures\MyFooGraphNode'); $fooObject = $mySubClassObject->getField('foo_object'); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooSubClassGraphNode', $fooObject); + $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooSubClassGraphNode', $fooObject); } public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() @@ -155,12 +155,12 @@ public function testAnUnknownGraphNodeWillBeCastAsAGenericGraphNode() $factory = new GraphNodeFactory($res); - $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\GraphNodes\MyFooGraphNode'); + $mySubClassObject = $factory->makeGraphNode('\Facebook\Tests\Fixtures\MyFooGraphNode'); $unknownObject = $mySubClassObject->getField('unknown_object'); - $this->assertInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $mySubClassObject); + $this->assertInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $mySubClassObject); $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $unknownObject); - $this->assertNotInstanceOf('\Facebook\Tests\GraphNodes\MyFooGraphNode', $unknownObject); + $this->assertNotInstanceOf('\Facebook\Tests\Fixtures\MyFooGraphNode', $unknownObject); } public function testAListFromGraphWillBeCastAsAGraphEdge() diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index d9a2fbb29..9bdaff439 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -28,6 +28,8 @@ use Facebook\FacebookClient; use Facebook\Helpers\FacebookRedirectLoginHelper; use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; +use Facebook\Tests\Fixtures\FooPseudoRandomStringGenerator; +use Facebook\Tests\Fixtures\FooRedirectLoginOAuth2Client; class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php index cd7699416..bfb3e0cf7 100644 --- a/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php +++ b/tests/Helpers/FacebookSignedRequestFromInputHelperTest.php @@ -24,6 +24,8 @@ namespace Facebook\Tests\Helpers; use Facebook\FacebookApp; +use Facebook\Tests\Fixtures\FooSignedRequestHelper; +use Facebook\Tests\Fixtures\FooSignedRequestHelperFacebookClient; class FacebookSignedRequestFromInputHelperTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php index 135507f86..d1fd4327c 100644 --- a/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php +++ b/tests/PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php @@ -23,6 +23,8 @@ */ namespace Facebook\Tests\PseudoRandomString; +use Facebook\Tests\Fixtures\MyFooBarPseudoRandomStringGenerator; + class PseudoRandomStringGeneratorTraitTest extends \PHPUnit_Framework_TestCase { /** From 40252bf7b74869e5d177b18e3546416d8d0ca6a7 Mon Sep 17 00:00:00 2001 From: Lars Moelleken Date: Sun, 29 May 2016 21:29:55 +0200 Subject: [PATCH 262/407] fixed issue#598 -> if composer isn't used, we need to include the polyfills manually --- src/Facebook/autoload.php | 4 ++++ src/Facebook/polyfills.php | 2 ++ tests/FacebookTest.php | 6 ++++++ tests/HttpClients/FacebookStreamHttpClientTest.php | 2 +- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 7334a918d..8cbc13eda 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -32,6 +32,10 @@ throw new Exception('The Facebook SDK requires PHP version 5.4 or higher.'); } +if (defined('FACEBOOK_SDK_POLYFILLS_LOADED') === false) { + require_once __DIR__ . 'polyfills.php'; +} + /** * Register the autoloader for the Facebook SDK classes. * diff --git a/src/Facebook/polyfills.php b/src/Facebook/polyfills.php index f6eaeb62e..b484fe1c7 100644 --- a/src/Facebook/polyfills.php +++ b/src/Facebook/polyfills.php @@ -22,6 +22,8 @@ * */ +define('FACEBOOK_SDK_POLYFILLS_LOADED', 1); + /** * @see https://github.com/sarciszewski/php-future/blob/master/src/Security.php#L37-L51 */ diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 23eeb65a2..2b5b8e89a 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -41,6 +41,12 @@ class FacebookTest extends \PHPUnit_Framework_TestCase 'app_secret' => 'foo_secret', ]; + public function testLoadPolyfills() + { + $this->assertEquals(true, defined('FACEBOOK_SDK_POLYFILLS_LOADED')); + $this->assertEquals(1, FACEBOOK_SDK_POLYFILLS_LOADED); + } + /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index f63c0ebba..ea27e9ad1 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -95,7 +95,7 @@ public function testCanSendNormalRequest() $this->streamMock ->shouldReceive('getResponseHeaders') ->once() - ->andReturn(explode("\n", trim($this->fakeRawHeader))); + ->andReturn(explode(PHP_EOL, trim($this->fakeRawHeader))); $this->streamMock ->shouldReceive('fileGetContents') ->once() From 88a4a595093e17b09d03a837aa3cb8630dccef9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ku=C4=8Dera?= Date: Tue, 14 Jun 2016 20:35:03 +0200 Subject: [PATCH 263/407] FacebookRedirectLoginHelper::makeUrl() - not generating new state if one already exists --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 190bbe3ca..4d452e279 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -122,7 +122,7 @@ public function getPseudoRandomStringGenerator() */ private function makeUrl($redirectUrl, array $scope, array $params = [], $separator = '&') { - $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); + $state = $this->persistentDataHandler->get('state') ?: $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state); return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $state, $scope, $params, $separator); From b5bd073e67daeb10a7c95940813b71ac6137f8e3 Mon Sep 17 00:00:00 2001 From: Sergey Lutskanu Date: Fri, 5 Aug 2016 12:02:15 +0300 Subject: [PATCH 264/407] Fixed issue when Notice "Undefined variable: header" occured on PHP 7.0 --- src/Facebook/Url/FacebookUrlDetectionHandler.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Url/FacebookUrlDetectionHandler.php b/src/Facebook/Url/FacebookUrlDetectionHandler.php index 60baf48ee..da7ac0e35 100644 --- a/src/Facebook/Url/FacebookUrlDetectionHandler.php +++ b/src/Facebook/Url/FacebookUrlDetectionHandler.php @@ -95,7 +95,8 @@ protected function protocolWithActiveSsl($protocol) protected function getHostName() { // Check for proxy first - if ($header = $this->getHeader('X_FORWARDED_HOST') && $this->isValidForwardedHost($header)) { + $header = $this->getHeader('X_FORWARDED_HOST'); + if ($header && $this->isValidForwardedHost($header)) { $elements = explode(',', $header); $host = $elements[count($elements) - 1]; } elseif (!$host = $this->getHeader('HOST')) { From 499d0e46bc4b689bdb02c7025422b894680b6046 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 6 Aug 2016 15:35:10 -0500 Subject: [PATCH 265/407] Reset the CSRF so that it does not get reused --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 4d452e279..cc207ce3f 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -219,6 +219,7 @@ public function getAccessToken($redirectUrl = null) } $this->validateCsrf(); + $this->resetCsrf(); $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); // At minimum we need to remove the state param @@ -250,6 +251,14 @@ protected function validateCsrf() throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } + /** + * Resets the CSRF so that it doesn't get reused. + */ + private function resetCsrf() + { + $this->persistentDataHandler->set('state', null); + } + /** * Return the code. * From 5fc7fb0b9f212aecfc81b3ca233d68b766114787 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 6 Aug 2016 15:45:58 -0500 Subject: [PATCH 266/407] Finish off #599 --- src/Facebook/autoload.php | 4 +--- src/Facebook/polyfills.php | 2 -- tests/FacebookTest.php | 6 ------ tests/HttpClients/FacebookStreamHttpClientTest.php | 2 +- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index 8cbc13eda..f4b2652fa 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -32,9 +32,7 @@ throw new Exception('The Facebook SDK requires PHP version 5.4 or higher.'); } -if (defined('FACEBOOK_SDK_POLYFILLS_LOADED') === false) { - require_once __DIR__ . 'polyfills.php'; -} +require_once __DIR__ . 'polyfills.php'; /** * Register the autoloader for the Facebook SDK classes. diff --git a/src/Facebook/polyfills.php b/src/Facebook/polyfills.php index b484fe1c7..f6eaeb62e 100644 --- a/src/Facebook/polyfills.php +++ b/src/Facebook/polyfills.php @@ -22,8 +22,6 @@ * */ -define('FACEBOOK_SDK_POLYFILLS_LOADED', 1); - /** * @see https://github.com/sarciszewski/php-future/blob/master/src/Security.php#L37-L51 */ diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 2b5b8e89a..23eeb65a2 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -41,12 +41,6 @@ class FacebookTest extends \PHPUnit_Framework_TestCase 'app_secret' => 'foo_secret', ]; - public function testLoadPolyfills() - { - $this->assertEquals(true, defined('FACEBOOK_SDK_POLYFILLS_LOADED')); - $this->assertEquals(1, FACEBOOK_SDK_POLYFILLS_LOADED); - } - /** * @expectedException \Facebook\Exceptions\FacebookSDKException */ diff --git a/tests/HttpClients/FacebookStreamHttpClientTest.php b/tests/HttpClients/FacebookStreamHttpClientTest.php index ea27e9ad1..f63c0ebba 100644 --- a/tests/HttpClients/FacebookStreamHttpClientTest.php +++ b/tests/HttpClients/FacebookStreamHttpClientTest.php @@ -95,7 +95,7 @@ public function testCanSendNormalRequest() $this->streamMock ->shouldReceive('getResponseHeaders') ->once() - ->andReturn(explode(PHP_EOL, trim($this->fakeRawHeader))); + ->andReturn(explode("\n", trim($this->fakeRawHeader))); $this->streamMock ->shouldReceive('fileGetContents') ->once() From 440e577e1b8cb84801e958eba8f4ef4bf8953112 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 6 Aug 2016 15:54:17 -0500 Subject: [PATCH 267/407] Finish off #581 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c33cb5641..7b711a941 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ Simple GET example of a user's profile. ```php -$fb = new Facebook([ +$fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', 'default_graph_version' => 'v2.6', @@ -42,14 +42,14 @@ $fb = new Facebook([ // $helper = $fb->getPageTabHelper(); try { - // Get the Facebook\GraphNodes\GraphUser object for the current user. + // 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) { +} catch(\Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); exit; -} catch(Facebook\Exceptions\FacebookSDKException $e) { +} catch(\Facebook\Exceptions\FacebookSDKException $e) { // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e->getMessage(); exit; From c16003fbfb7186fdcdb7e4782aa2592eff22fc08 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 6 Aug 2016 16:23:04 -0500 Subject: [PATCH 268/407] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1f5c526d..aafc53c8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org ## 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. +- 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) - 5.2.0 - Added new Birthday class to handle Graph API response variations - Bumped Graph version to v2.6 From 8e5d9ae444b01f07bad6dff4da7c9606d379bd74 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 6 Aug 2016 16:29:17 -0500 Subject: [PATCH 269/407] Bump Graph API version to v2.7 --- CHANGELOG.md | 2 ++ src/Facebook/Facebook.php | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aafc53c8a..b37bea77c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org ## 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. +- 5.3.0 + - 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) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 8e2952140..b262a4aef 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,12 +53,12 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.2.0'; + const VERSION = '5.3.0'; /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.6'; + const DEFAULT_GRAPH_VERSION = 'v2.7'; /** * @const string The name of the environment variable that contains the app ID. From 8b036b4b5b8c2149c8b773705aeeb46b323f7a43 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 9 Aug 2016 06:25:17 -0500 Subject: [PATCH 270/407] Fix bug with including polyfills.php --- src/Facebook/autoload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/autoload.php b/src/Facebook/autoload.php index f4b2652fa..00c319913 100644 --- a/src/Facebook/autoload.php +++ b/src/Facebook/autoload.php @@ -32,7 +32,7 @@ throw new Exception('The Facebook SDK requires PHP version 5.4 or higher.'); } -require_once __DIR__ . 'polyfills.php'; +require_once __DIR__ . '/polyfills.php'; /** * Register the autoloader for the Facebook SDK classes. From 7ed1ecdae6a5b2f8b8f60e132d06594b39b16fb1 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 9 Aug 2016 06:32:26 -0500 Subject: [PATCH 271/407] Bump patch version and update CHANGELOG --- CHANGELOG.md | 2 ++ src/Facebook/Facebook.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b37bea77c..6bd2450fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org ## 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. +- 5.3.1 + - 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. - 5.2.1 diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index b262a4aef..73778dd48 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.3.0'; + const VERSION = '5.3.1'; /** * @const string Default Graph API version for requests. From f017fe1e16cec1322a863ec86321d11b3c7ac0b0 Mon Sep 17 00:00:00 2001 From: Vivek Hamirwasia Date: Mon, 22 Aug 2016 16:22:12 -0700 Subject: [PATCH 272/407] Updating composer.json Changing the repo name to php-graph-sdk as discussed in https://github.com/facebook/php-graph-sdk/issues/638 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 20f9934be..b96dc67c3 100644 --- a/composer.json +++ b/composer.json @@ -1,14 +1,14 @@ { - "name": "facebook/php-sdk-v4", + "name": "facebook/php-graph-sdk", "description": "Facebook SDK for PHP", "keywords": ["facebook", "sdk"], "type": "library", - "homepage": "https://github.com/facebook/facebook-php-sdk-v4", + "homepage": "https://github.com/facebook/php-graph-sdk", "license": "Facebook Platform", "authors": [ { "name": "Facebook", - "homepage": "https://github.com/facebook/facebook-php-sdk-v4/contributors" + "homepage": "https://github.com/facebook/php-graph-sdk/contributors" } ], "require": { From 1bb4d6cb14da97c96f2ae90e861b0fa6f0a2482f Mon Sep 17 00:00:00 2001 From: Vivek Hamirwasia Date: Mon, 22 Aug 2016 16:25:54 -0700 Subject: [PATCH 273/407] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b96dc67c3..86eec0323 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "facebook/php-graph-sdk", + "name": "facebook/graph-sdk", "description": "Facebook SDK for PHP", "keywords": ["facebook", "sdk"], "type": "library", From ab068ef4097878e2a2a03a5c5b4bcbfc1f44f7cb Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 22 Aug 2016 18:57:48 -0500 Subject: [PATCH 274/407] Update README to feflect new package name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b711a941..7592a9b11 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This repository contains the open source PHP SDK that allows you to access the F The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). Run this command: ```sh -composer require facebook/php-sdk-v4 +composer require facebook/graph-sdk ``` ## Upgrading to v5.x From a5e46b276e7b441713d4e95dfae0f80288525d9c Mon Sep 17 00:00:00 2001 From: Dawid Nowak Date: Tue, 23 Aug 2016 20:04:00 +0200 Subject: [PATCH 275/407] FacebookRequest:setAccessToken(): accepts null as an argument It's called from the constructor which clearly allows null (in its phpdoc) --- src/Facebook/FacebookRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/FacebookRequest.php b/src/Facebook/FacebookRequest.php index 2edd103a9..e5c847017 100644 --- a/src/Facebook/FacebookRequest.php +++ b/src/Facebook/FacebookRequest.php @@ -108,7 +108,7 @@ public function __construct(FacebookApp $app = null, $accessToken = null, $metho /** * Set the access token for this request. * - * @param AccessToken|string + * @param AccessToken|string|null * * @return FacebookRequest */ From 9e5b721cd10b0c1cfd35b5898c2d448dcd20388b Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 29 Aug 2016 09:01:38 -0500 Subject: [PATCH 276/407] Update badges, links and Graph version --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7592a9b11..116f74147 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Facebook SDK for PHP (v5) -[![Build Status](https://img.shields.io/travis/facebook/facebook-php-sdk-v4/master.svg)](https://travis-ci.org/facebook/facebook-php-sdk-v4) +[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/master.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.2.0-blue.svg)](https://packagist.org/packages/facebook/php-sdk-v4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.3.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. @@ -31,7 +31,7 @@ Simple GET example of a user's profile. $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.7', //'default_access_token' => '{access-token}', // optional ]); @@ -81,9 +81,9 @@ $ ./vendor/bin/phpunit --exclude-group integration ## Contributing -For us to accept contributions you will have to first have signed the [Contributor License Agreement](https://developers.facebook.com/opensource/cla). Please see [CONTRIBUTING](https://github.com/facebook/facebook-php-sdk-v4/blob/master/CONTRIBUTING.md) for details. +For us to accept contributions you will have to first have signed the [Contributor License Agreement](https://developers.facebook.com/opensource/cla). Please see [CONTRIBUTING](https://github.com/facebook/php-graph-sdk/blob/master/CONTRIBUTING.md) for details. ## License -Please see the [license file](https://github.com/facebook/facebook-php-sdk-v4/blob/master/LICENSE) for more information. +Please see the [license file](https://github.com/facebook/php-graph-sdk/blob/master/LICENSE) for more information. From 43edeafb013af66700c7984fd28d08e3ca8c4d6d Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 29 Aug 2016 09:06:11 -0500 Subject: [PATCH 277/407] Update branch in badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 116f74147..53cc82e52 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Facebook SDK for PHP (v5) -[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/master.svg)](https://travis-ci.org/facebook/php-graph-sdk) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=master) +[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.3.svg)](https://travis-ci.org/facebook/php-graph-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.3)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.3) [![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.3.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) From c6358958d1cfe208ea414ee0e5f2912bb6dc24d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ty=C3=A1s=20Somfai?= Date: Wed, 12 Oct 2016 19:56:12 +0200 Subject: [PATCH 278/407] Fixed AccessToken::isLongLived documentation. --- docs/AccessToken.fbmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AccessToken.fbmd b/docs/AccessToken.fbmd index ff7f1abfc..6f1a097bc 100644 --- a/docs/AccessToken.fbmd +++ b/docs/AccessToken.fbmd @@ -33,7 +33,7 @@ originally provided, the method will return `null`. 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 `null`. [See more about long-lived and short-lived access tokens](https://developers.facebook.com/docs/facebook-login/access-tokens#extending). +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() {#is-app-access-token} ~~~~ From adb299f1bc7ded372279e73fb722da2fbc9173a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Wed, 7 Sep 2016 12:24:43 +0200 Subject: [PATCH 279/407] Fix: Method does not return anything --- src/Facebook/FacebookBatchRequest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Facebook/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php index fc6561173..d61d35779 100644 --- a/src/Facebook/FacebookBatchRequest.php +++ b/src/Facebook/FacebookBatchRequest.php @@ -168,8 +168,6 @@ public function getRequests() /** * Prepares the requests to be sent as a batch request. - * - * @return string */ public function prepareRequestsForBatch() { From 9c5a1c7f89b0028d0738105bd73c55917e03b233 Mon Sep 17 00:00:00 2001 From: Phelipe Alves de Souza Date: Fri, 16 Sep 2016 19:53:24 -0300 Subject: [PATCH 280/407] Removed unnecessary space --- src/Facebook/GraphNodes/GraphAchievement.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphAchievement.php b/src/Facebook/GraphNodes/GraphAchievement.php index b6586dc19..ddd2a02fe 100644 --- a/src/Facebook/GraphNodes/GraphAchievement.php +++ b/src/Facebook/GraphNodes/GraphAchievement.php @@ -28,7 +28,6 @@ * * @package Facebook */ - class GraphAchievement extends GraphNode { /** From 3cd1b92603b9e95cb7aee72e3bad8a31d1fca628 Mon Sep 17 00:00:00 2001 From: flod1 Date: Thu, 15 Sep 2016 10:46:06 +0200 Subject: [PATCH 281/407] add cover and picture type and methode add cover and picture type, graphobjectMap and methode --- src/Facebook/GraphNodes/GraphPage.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index f9c81cf67..08f72fe88 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -37,6 +37,8 @@ class GraphPage extends GraphNode 'best_page' => '\Facebook\GraphNodes\GraphPage', 'global_brand_parent_page' => '\Facebook\GraphNodes\GraphPage', 'location' => '\Facebook\GraphNodes\GraphLocation', + 'cover' => '\Facebook\GraphNodes\GraphCoverPhoto', + 'picture' => '\Facebook\GraphNodes\GraphPicture', ]; /** @@ -99,6 +101,26 @@ public function getLocation() return $this->getField('location'); } + /** + * Returns CoverPhoto of the Page. + * + * @return GraphCoverPhoto|null + */ + public function getCover() + { + return $this->getField('cover'); + } + + /** + * Returns Picture of the Page. + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getField('picture'); + } + /** * Returns the page access token for the admin user. * From dfbd470c43627927947ae0caae40ae4503f6e66f Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Wed, 12 Oct 2016 13:45:25 -0500 Subject: [PATCH 282/407] Bump Graph version to v2.8 --- src/Facebook/Facebook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 73778dd48..52628aee6 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -58,7 +58,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.7'; + const DEFAULT_GRAPH_VERSION = 'v2.8'; /** * @const string The name of the environment variable that contains the app ID. From c69c3c0bb304ec1fe9400b4bc47ab641c9002eee Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Wed, 12 Oct 2016 13:53:27 -0500 Subject: [PATCH 283/407] Bump version and update README and CHANGELOG --- CHANGELOG.md | 7 ++++++- README.md | 8 ++++---- src/Facebook/Facebook.php | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bd2450fe..d7c1ef294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org ## 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. + +- 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) - 5.3.1 - Fixed a bug where the `polyfills.php` file wasn't being included properly when using the built-in auto loader (#633) - 5.3.0 @@ -26,7 +31,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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-??-??) +- 5.0 (2015-07-09) - New features - Added the `Facebook\Facebook` super service for an easier API - Improved "reauthentication" and "rerequest" support diff --git a/README.md b/README.md index 53cc82e52..f636bcf0e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Facebook SDK for PHP (v5) -[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.3.svg)](https://travis-ci.org/facebook/php-graph-sdk) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.3)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.3) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.3.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.4.svg)](https://travis-ci.org/facebook/php-graph-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.4)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.4) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. @@ -31,7 +31,7 @@ Simple GET example of a user's profile. $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.7', + 'default_graph_version' => 'v2.8', //'default_access_token' => '{access-token}', // optional ]); diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 52628aee6..04a67cc79 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.3.1'; + const VERSION = '5.4.0'; /** * @const string Default Graph API version for requests. From 68a32a1ed6ec8ef8f172cd84b9a5226e945aa1ff Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 14 Oct 2016 10:40:21 -0500 Subject: [PATCH 284/407] Refactor landing documenation page --- docs/README.md | 34 ++++++++++++++++++++++++++++++++++ docs/sdk_landing_page.fbmd | 38 -------------------------------------- 2 files changed, 34 insertions(+), 38 deletions(-) create mode 100644 docs/README.md delete mode 100644 docs/sdk_landing_page.fbmd diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..38cb7b99a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,34 @@ +# Facebook SDK v5 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](docs/sdk_getting_started.fbmd) guide, and then check out some of the examples below. + +--- + +## Examples {#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)](docs/example_facebook_login.fbmd) + - [Obtaining an access token from the SDK for JavaScript](docs/example_access_token_from_javascript.fbmd) + - [Obtaining an access token within a Facebook Canvas context](docs/example_access_token_from_canvas.fbmd) + - [Obtaining an access token within a Facebook Page tab context](docs/example_access_token_from_page_tab.fbmd) +- **User profile** + - [Retrieve a user's profile](docs/example_retrieve_user_profile.fbmd) + - [Post a link to a user's feed](docs/example_post_links.fbmd) +- **File Uploads** + - [Upload a photo to a user's profile](docs/example_upload_photo.fbmd) + - [Upload a video to a user's profile](docs/example_upload_video.fbmd) +- **Batch Requests** + - [Sending requests in a batch](docs/example_batch_request.fbmd) + - [Uploading files in a batch](docs/example_batch_upload.fbmd) +- **Pagination** + - [Basic pagination](docs/example_pagination_basic.fbmd) + +## API Reference {#reference} + +For a full list of classes, see the API [reference page](docs/sdk_reference.fbmd). diff --git a/docs/sdk_landing_page.fbmd b/docs/sdk_landing_page.fbmd deleted file mode 100644 index d59701e43..000000000 --- a/docs/sdk_landing_page.fbmd +++ /dev/null @@ -1,38 +0,0 @@ - -# Facebook SDK v5 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](/docs/reference/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](/docs/php/gettingstarted) guide, and then check out some of the examples below. - - - -## Examples {#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)](/docs/php/howto/example_facebook_login) - - [Obtaining an access token from the SDK for JavaScript](/docs/php/howto/example_access_token_from_javascript) - - [Obtaining an access token within a Facebook Canvas context](/docs/php/howto/example_access_token_from_canvas) - - [Obtaining an access token within a Facebook Page tab context](/docs/php/howto/example_access_token_from_page_tab) -- **User profile** - - [Retrieve a user's profile](/docs/php/howto/example_retrieve_user_profile) - - [Post a link to a user's feed](/docs/php/howto/example_post_links) -- **File Uploads** - - [Upload a photo to a user's profile](/docs/php/howto/example_upload_photo) - - [Upload a video to a user's profile](/docs/php/howto/example_upload_video) -- **Batch Requests** - - [Sending requests in a batch](/docs/php/howto/example_batch_request) - - [Uploading files in a batch](/docs/php/howto/example_batch_upload) -- **Pagination** - - [Basic pagination](/docs/php/howto/example_pagination_basic) - - - -## API Reference {#reference} - -For a full list of classes, see the API [reference page](/docs/php/reference). - From 0e30a5a8cf4fa0835a0b7656bb5490b78e5628e5 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 14 Oct 2016 10:41:13 -0500 Subject: [PATCH 285/407] Remove Facebook link anchors --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 38cb7b99a..e04da58bd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,7 @@ For installation & implementation instructions, look through the [Getting Starte --- -## Examples {#examples} +## Examples The following examples demonstrate how you would accomplish common tasks with the Facebook SDK for PHP. @@ -29,6 +29,6 @@ The following examples demonstrate how you would accomplish common tasks with th - **Pagination** - [Basic pagination](docs/example_pagination_basic.fbmd) -## API Reference {#reference} +## API Reference For a full list of classes, see the API [reference page](docs/sdk_reference.fbmd). From 5885f26966aa8b7054ad68841dc44694f7a6434a Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 14 Oct 2016 10:42:21 -0500 Subject: [PATCH 286/407] Update relative paths --- docs/README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/README.md b/docs/README.md index e04da58bd..e7db5c07e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,7 @@ The Facebook SDK for PHP is a library with powerful features that enable PHP dev 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](docs/sdk_getting_started.fbmd) guide, and then check out some of the examples below. +For installation & implementation instructions, look through the [Getting Started with the Facebook SDK for PHP](./sdk_getting_started.fbmd) guide, and then check out some of the examples below. --- @@ -13,22 +13,22 @@ For installation & implementation instructions, look through the [Getting Starte The following examples demonstrate how you would accomplish common tasks with the Facebook SDK for PHP. - **Authentication & Signed Requests** - - [Facebook Login (OAuth 2.0)](docs/example_facebook_login.fbmd) - - [Obtaining an access token from the SDK for JavaScript](docs/example_access_token_from_javascript.fbmd) - - [Obtaining an access token within a Facebook Canvas context](docs/example_access_token_from_canvas.fbmd) - - [Obtaining an access token within a Facebook Page tab context](docs/example_access_token_from_page_tab.fbmd) + - [Facebook Login (OAuth 2.0)](./example_facebook_login.fbmd) + - [Obtaining an access token from the SDK for JavaScript](./example_access_token_from_javascript.fbmd) + - [Obtaining an access token within a Facebook Canvas context](./example_access_token_from_canvas.fbmd) + - [Obtaining an access token within a Facebook Page tab context](./example_access_token_from_page_tab.fbmd) - **User profile** - - [Retrieve a user's profile](docs/example_retrieve_user_profile.fbmd) - - [Post a link to a user's feed](docs/example_post_links.fbmd) + - [Retrieve a user's profile](./example_retrieve_user_profile.fbmd) + - [Post a link to a user's feed](./example_post_links.fbmd) - **File Uploads** - - [Upload a photo to a user's profile](docs/example_upload_photo.fbmd) - - [Upload a video to a user's profile](docs/example_upload_video.fbmd) + - [Upload a photo to a user's profile](./example_upload_photo.fbmd) + - [Upload a video to a user's profile](./example_upload_video.fbmd) - **Batch Requests** - - [Sending requests in a batch](docs/example_batch_request.fbmd) - - [Uploading files in a batch](docs/example_batch_upload.fbmd) + - [Sending requests in a batch](./example_batch_request.fbmd) + - [Uploading files in a batch](./example_batch_upload.fbmd) - **Pagination** - - [Basic pagination](docs/example_pagination_basic.fbmd) + - [Basic pagination](./example_pagination_basic.fbmd) ## API Reference -For a full list of classes, see the API [reference page](docs/sdk_reference.fbmd). +For a full list of classes, see the API [reference page](./sdk_reference.fbmd). From 558a5e86fa6385dd5ab45e2ad907254869f246d4 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 15 Oct 2016 06:08:54 -0400 Subject: [PATCH 287/407] Remove version number from title in docs landing --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e7db5c07e..55d26bafd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -# Facebook SDK v5 for PHP +# 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. From f360ba3205ee471836ed07f03bd3b786e3ba2d64 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sat, 15 Oct 2016 06:23:28 -0400 Subject: [PATCH 288/407] Move and rename docs for better organization --- docs/README.md | 26 ++-- .../access_token_from_canvas.md} | 0 .../access_token_from_javascript.md} | 0 .../access_token_from_page_tab.md} | 0 .../batch_request.md} | 0 .../batch_upload.md} | 0 .../facebook_login.md} | 0 .../pagination_basic.md} | 0 .../post_links.md} | 0 .../retrieve_user_profile.md} | 0 .../upload_photo.md} | 0 .../upload_video.md} | 0 ...etting_started.fbmd => getting_started.md} | 0 docs/{sdk_reference.fbmd => reference.md} | 0 .../AccessToken.md} | 0 docs/{Birthday.fbmd => reference/Birthday.md} | 0 docs/{Facebook.fbmd => reference/Facebook.md} | 0 .../FacebookApp.md} | 0 .../FacebookBatchRequest.md} | 0 .../FacebookBatchResponse.md} | 0 .../FacebookCanvasHelper.md} | 0 .../FacebookClient.md} | 0 .../FacebookFile.md} | 0 .../FacebookJavaScriptHelper.md} | 0 .../FacebookPageTabHelper.md} | 0 .../FacebookRedirectLoginHelper.md} | 0 .../FacebookRequest.md} | 0 .../FacebookResponse.md} | 0 .../FacebookResponseException.md} | 0 .../FacebookSDKException.md} | 0 .../FacebookVideo.md} | 0 .../GraphEdge.md} | 0 .../GraphNode.md} | 0 .../PersistentDataInterface.md} | 0 .../PseudoRandomStringGeneratorInterface.md} | 0 .../SignedRequest.md} | 0 .../UrlDetectionInterface.md} | 0 docs/sdk_downloads.fbmd | 137 ------------------ 38 files changed, 13 insertions(+), 150 deletions(-) rename docs/{example_access_token_from_canvas.fbmd => examples/access_token_from_canvas.md} (100%) rename docs/{example_access_token_from_javascript.fbmd => examples/access_token_from_javascript.md} (100%) rename docs/{example_access_token_from_page_tab.fbmd => examples/access_token_from_page_tab.md} (100%) rename docs/{example_batch_request.fbmd => examples/batch_request.md} (100%) rename docs/{example_batch_upload.fbmd => examples/batch_upload.md} (100%) rename docs/{example_facebook_login.fbmd => examples/facebook_login.md} (100%) rename docs/{example_pagination_basic.fbmd => examples/pagination_basic.md} (100%) rename docs/{example_post_links.fbmd => examples/post_links.md} (100%) rename docs/{example_retrieve_user_profile.fbmd => examples/retrieve_user_profile.md} (100%) rename docs/{example_upload_photo.fbmd => examples/upload_photo.md} (100%) rename docs/{example_upload_video.fbmd => examples/upload_video.md} (100%) rename docs/{sdk_getting_started.fbmd => getting_started.md} (100%) rename docs/{sdk_reference.fbmd => reference.md} (100%) rename docs/{AccessToken.fbmd => reference/AccessToken.md} (100%) rename docs/{Birthday.fbmd => reference/Birthday.md} (100%) rename docs/{Facebook.fbmd => reference/Facebook.md} (100%) rename docs/{FacebookApp.fbmd => reference/FacebookApp.md} (100%) rename docs/{FacebookBatchRequest.fbmd => reference/FacebookBatchRequest.md} (100%) rename docs/{FacebookBatchResponse.fbmd => reference/FacebookBatchResponse.md} (100%) rename docs/{FacebookCanvasHelper.fbmd => reference/FacebookCanvasHelper.md} (100%) rename docs/{FacebookClient.fbmd => reference/FacebookClient.md} (100%) rename docs/{FacebookFile.fbmd => reference/FacebookFile.md} (100%) rename docs/{FacebookJavaScriptHelper.fbmd => reference/FacebookJavaScriptHelper.md} (100%) rename docs/{FacebookPageTabHelper.fbmd => reference/FacebookPageTabHelper.md} (100%) rename docs/{FacebookRedirectLoginHelper.fbmd => reference/FacebookRedirectLoginHelper.md} (100%) rename docs/{FacebookRequest.fbmd => reference/FacebookRequest.md} (100%) rename docs/{FacebookResponse.fbmd => reference/FacebookResponse.md} (100%) rename docs/{FacebookResponseException.fbmd => reference/FacebookResponseException.md} (100%) rename docs/{FacebookSDKException.fbmd => reference/FacebookSDKException.md} (100%) rename docs/{FacebookVideo.fbmd => reference/FacebookVideo.md} (100%) rename docs/{GraphEdge.fbmd => reference/GraphEdge.md} (100%) rename docs/{GraphNode.fbmd => reference/GraphNode.md} (100%) rename docs/{PersistentDataInterface.fbmd => reference/PersistentDataInterface.md} (100%) rename docs/{PseudoRandomStringGeneratorInterface.fbmd => reference/PseudoRandomStringGeneratorInterface.md} (100%) rename docs/{SignedRequest.fbmd => reference/SignedRequest.md} (100%) rename docs/{UrlDetectionInterface.fbmd => reference/UrlDetectionInterface.md} (100%) delete mode 100644 docs/sdk_downloads.fbmd diff --git a/docs/README.md b/docs/README.md index 55d26bafd..e61b0d995 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,7 @@ The Facebook SDK for PHP is a library with powerful features that enable PHP dev 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](./sdk_getting_started.fbmd) guide, and then check out some of the examples below. +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. --- @@ -13,22 +13,22 @@ For installation & implementation instructions, look through the [Getting Starte The following examples demonstrate how you would accomplish common tasks with the Facebook SDK for PHP. - **Authentication & Signed Requests** - - [Facebook Login (OAuth 2.0)](./example_facebook_login.fbmd) - - [Obtaining an access token from the SDK for JavaScript](./example_access_token_from_javascript.fbmd) - - [Obtaining an access token within a Facebook Canvas context](./example_access_token_from_canvas.fbmd) - - [Obtaining an access token within a Facebook Page tab context](./example_access_token_from_page_tab.fbmd) + - [Facebook Login (OAuth 2.0)](./example/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](./example_retrieve_user_profile.fbmd) - - [Post a link to a user's feed](./example_post_links.fbmd) + - [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](./example_upload_photo.fbmd) - - [Upload a video to a user's profile](./example_upload_video.fbmd) + - [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](./example_batch_request.fbmd) - - [Uploading files in a batch](./example_batch_upload.fbmd) + - [Sending requests in a batch](./examples/batch_request.md) + - [Uploading files in a batch](./examples/batch_upload.md) - **Pagination** - - [Basic pagination](./example_pagination_basic.fbmd) + - [Basic pagination](./examples/pagination_basic.md) ## API Reference -For a full list of classes, see the API [reference page](./sdk_reference.fbmd). +For a full list of classes, see the API [reference page](./sdk_reference.md). diff --git a/docs/example_access_token_from_canvas.fbmd b/docs/examples/access_token_from_canvas.md similarity index 100% rename from docs/example_access_token_from_canvas.fbmd rename to docs/examples/access_token_from_canvas.md diff --git a/docs/example_access_token_from_javascript.fbmd b/docs/examples/access_token_from_javascript.md similarity index 100% rename from docs/example_access_token_from_javascript.fbmd rename to docs/examples/access_token_from_javascript.md diff --git a/docs/example_access_token_from_page_tab.fbmd b/docs/examples/access_token_from_page_tab.md similarity index 100% rename from docs/example_access_token_from_page_tab.fbmd rename to docs/examples/access_token_from_page_tab.md diff --git a/docs/example_batch_request.fbmd b/docs/examples/batch_request.md similarity index 100% rename from docs/example_batch_request.fbmd rename to docs/examples/batch_request.md diff --git a/docs/example_batch_upload.fbmd b/docs/examples/batch_upload.md similarity index 100% rename from docs/example_batch_upload.fbmd rename to docs/examples/batch_upload.md diff --git a/docs/example_facebook_login.fbmd b/docs/examples/facebook_login.md similarity index 100% rename from docs/example_facebook_login.fbmd rename to docs/examples/facebook_login.md diff --git a/docs/example_pagination_basic.fbmd b/docs/examples/pagination_basic.md similarity index 100% rename from docs/example_pagination_basic.fbmd rename to docs/examples/pagination_basic.md diff --git a/docs/example_post_links.fbmd b/docs/examples/post_links.md similarity index 100% rename from docs/example_post_links.fbmd rename to docs/examples/post_links.md diff --git a/docs/example_retrieve_user_profile.fbmd b/docs/examples/retrieve_user_profile.md similarity index 100% rename from docs/example_retrieve_user_profile.fbmd rename to docs/examples/retrieve_user_profile.md diff --git a/docs/example_upload_photo.fbmd b/docs/examples/upload_photo.md similarity index 100% rename from docs/example_upload_photo.fbmd rename to docs/examples/upload_photo.md diff --git a/docs/example_upload_video.fbmd b/docs/examples/upload_video.md similarity index 100% rename from docs/example_upload_video.fbmd rename to docs/examples/upload_video.md diff --git a/docs/sdk_getting_started.fbmd b/docs/getting_started.md similarity index 100% rename from docs/sdk_getting_started.fbmd rename to docs/getting_started.md diff --git a/docs/sdk_reference.fbmd b/docs/reference.md similarity index 100% rename from docs/sdk_reference.fbmd rename to docs/reference.md diff --git a/docs/AccessToken.fbmd b/docs/reference/AccessToken.md similarity index 100% rename from docs/AccessToken.fbmd rename to docs/reference/AccessToken.md diff --git a/docs/Birthday.fbmd b/docs/reference/Birthday.md similarity index 100% rename from docs/Birthday.fbmd rename to docs/reference/Birthday.md diff --git a/docs/Facebook.fbmd b/docs/reference/Facebook.md similarity index 100% rename from docs/Facebook.fbmd rename to docs/reference/Facebook.md diff --git a/docs/FacebookApp.fbmd b/docs/reference/FacebookApp.md similarity index 100% rename from docs/FacebookApp.fbmd rename to docs/reference/FacebookApp.md diff --git a/docs/FacebookBatchRequest.fbmd b/docs/reference/FacebookBatchRequest.md similarity index 100% rename from docs/FacebookBatchRequest.fbmd rename to docs/reference/FacebookBatchRequest.md diff --git a/docs/FacebookBatchResponse.fbmd b/docs/reference/FacebookBatchResponse.md similarity index 100% rename from docs/FacebookBatchResponse.fbmd rename to docs/reference/FacebookBatchResponse.md diff --git a/docs/FacebookCanvasHelper.fbmd b/docs/reference/FacebookCanvasHelper.md similarity index 100% rename from docs/FacebookCanvasHelper.fbmd rename to docs/reference/FacebookCanvasHelper.md diff --git a/docs/FacebookClient.fbmd b/docs/reference/FacebookClient.md similarity index 100% rename from docs/FacebookClient.fbmd rename to docs/reference/FacebookClient.md diff --git a/docs/FacebookFile.fbmd b/docs/reference/FacebookFile.md similarity index 100% rename from docs/FacebookFile.fbmd rename to docs/reference/FacebookFile.md diff --git a/docs/FacebookJavaScriptHelper.fbmd b/docs/reference/FacebookJavaScriptHelper.md similarity index 100% rename from docs/FacebookJavaScriptHelper.fbmd rename to docs/reference/FacebookJavaScriptHelper.md diff --git a/docs/FacebookPageTabHelper.fbmd b/docs/reference/FacebookPageTabHelper.md similarity index 100% rename from docs/FacebookPageTabHelper.fbmd rename to docs/reference/FacebookPageTabHelper.md diff --git a/docs/FacebookRedirectLoginHelper.fbmd b/docs/reference/FacebookRedirectLoginHelper.md similarity index 100% rename from docs/FacebookRedirectLoginHelper.fbmd rename to docs/reference/FacebookRedirectLoginHelper.md diff --git a/docs/FacebookRequest.fbmd b/docs/reference/FacebookRequest.md similarity index 100% rename from docs/FacebookRequest.fbmd rename to docs/reference/FacebookRequest.md diff --git a/docs/FacebookResponse.fbmd b/docs/reference/FacebookResponse.md similarity index 100% rename from docs/FacebookResponse.fbmd rename to docs/reference/FacebookResponse.md diff --git a/docs/FacebookResponseException.fbmd b/docs/reference/FacebookResponseException.md similarity index 100% rename from docs/FacebookResponseException.fbmd rename to docs/reference/FacebookResponseException.md diff --git a/docs/FacebookSDKException.fbmd b/docs/reference/FacebookSDKException.md similarity index 100% rename from docs/FacebookSDKException.fbmd rename to docs/reference/FacebookSDKException.md diff --git a/docs/FacebookVideo.fbmd b/docs/reference/FacebookVideo.md similarity index 100% rename from docs/FacebookVideo.fbmd rename to docs/reference/FacebookVideo.md diff --git a/docs/GraphEdge.fbmd b/docs/reference/GraphEdge.md similarity index 100% rename from docs/GraphEdge.fbmd rename to docs/reference/GraphEdge.md diff --git a/docs/GraphNode.fbmd b/docs/reference/GraphNode.md similarity index 100% rename from docs/GraphNode.fbmd rename to docs/reference/GraphNode.md diff --git a/docs/PersistentDataInterface.fbmd b/docs/reference/PersistentDataInterface.md similarity index 100% rename from docs/PersistentDataInterface.fbmd rename to docs/reference/PersistentDataInterface.md diff --git a/docs/PseudoRandomStringGeneratorInterface.fbmd b/docs/reference/PseudoRandomStringGeneratorInterface.md similarity index 100% rename from docs/PseudoRandomStringGeneratorInterface.fbmd rename to docs/reference/PseudoRandomStringGeneratorInterface.md diff --git a/docs/SignedRequest.fbmd b/docs/reference/SignedRequest.md similarity index 100% rename from docs/SignedRequest.fbmd rename to docs/reference/SignedRequest.md diff --git a/docs/UrlDetectionInterface.fbmd b/docs/reference/UrlDetectionInterface.md similarity index 100% rename from docs/UrlDetectionInterface.fbmd rename to docs/reference/UrlDetectionInterface.md diff --git a/docs/sdk_downloads.fbmd b/docs/sdk_downloads.fbmd deleted file mode 100644 index 93b3f91e8..000000000 --- a/docs/sdk_downloads.fbmd +++ /dev/null @@ -1,137 +0,0 @@ - -# Downloads for the Facebook PHP SDK - -For full details on what changed between each version release, see the [CHANGELOG](https://github.com/facebook/facebook-php-sdk-v4/blob/master/CHANGELOG.md). - -%FB(devsite:markdown-wiki:table { - columns: ['Package','Date','Change Summary',], - rows: [ - [ - '[Facebook SDK 5.0.0](https://github.com/facebook/facebook-php-sdk-v4/archive/5.0.0.zip)', - 'July 1, 2015', - 'New API, a major refactoring driven by the community, removed statics', - ], - [ - '[Facebook SDK 4.0.23](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.23.zip)', - 'April 3, 2015', - 'Redirect login helper response handling updates', - ], - [ - '[Facebook SDK 4.0.22](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.22.zip)', - 'April 2, 2015', - 'Graph v2.3 support, array handling updates', - ], - [ - '[Facebook SDK 4.0.21](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.21.zip)', - 'March 31, 2015', - 'Added FacebookPermissions enum', - ], - [ - '[Facebook SDK 4.0.20](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.20.zip)', - 'March 2, 2015', - 'Bug fixes', - ], - [ - '[Facebook SDK 4.0.19](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.19.zip)', - 'March 2, 2015', - 'Updated CSRF validation to use constant-time evaluation', - ], - [ - '[Facebook SDK 4.0.18](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.18.zip)', - 'February 24, 2015', - 'Revert unintended breaking change in 4.0.17', - ], - [ - '[Facebook SDK 4.0.17](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.17.zip)', - 'February 19, 2015', - 'Graph video support, bug fixes', - ], - [ - '[Facebook SDK 4.0.16](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.16.zip)', - 'February 3, 2015', - 'Reauthentication and curl updates', - ], - [ - '[Facebook SDK 4.0.15](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.15.zip)', - 'January 6, 2015', - 'Prevent generating a logout URL for app access tokens', - ], - [ - '[Facebook SDK 4.0.14](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.14.zip)', - 'December 29, 2014', - 'Updates to GraphUser/GraphAlbum, expanded CSRF protection', - ], - [ - '[Facebook SDK 4.0.13](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.13.zip)', - 'December 12, 2014', - 'Updated certificate handling, composer details, bug fixes', - ], - [ - '[Facebook SDK 4.0.12](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.12.zip)', - 'October 30, 2014', - 'Graph v2.2 support', - ], - [ - '[Facebook SDK 4.0.11](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.11.zip)', - 'August 25, 2014', - 'Re-request support', - ], - [ - '[Facebook SDK 4.0.10](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.10.zip)', - 'August 12, 2014', - 'Bug fixes', - ], - [ - '[Facebook SDK 4.0.9](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.9.zip)', - 'June 27, 2014', - 'Improved security, added autoloader', - ], - [ - '[Facebook SDK 4.0.8](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.8.zip)', - 'June 10, 2014', - 'Added stream wrapper and Guzzle HTTP clients', - ], - [ - '[Facebook SDK 4.0.7](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.7.zip)', - 'May 31, 2014', - 'Added FacebookPageTabHelper', - ], - [ - '[Facebook SDK 4.0.6](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.6.zip)', - 'May 24, 2014', - 'Custom HTTP clients', - ], - [ - '[Facebook SDK 4.0.5](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.5.zip)', - 'May 19, 2014', - 'Added stream wrapper fallback', - ], - [ - '[Facebook SDK 4.0.4](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.4.zip)', - 'May 15, 2014', - 'Added more error codes', - ], - [ - '[Facebook SDK 4.0.3](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.3.zip)', - 'May 14, 2014', - 'Bug fixes', - ], - [ - '[Facebook SDK 4.0.2](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.2.zip)', - 'May 7, 2014', - 'Added PSR-4, eTags', - ], - [ - '[Facebook SDK 4.0.1](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.1.zip)', - 'May 5, 2014', - 'Improved signed request parsing', - ], - [ - '[Facebook SDK 4.0.0](https://github.com/facebook/facebook-php-sdk-v4/archive/4.0.0.zip)', - 'April 30, 2014', - 'Initial release. Yay!', - ], - ], -}) - - From f37841c0beca19fd20c59d1c3760d91fbd92b9fb Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 18 Oct 2016 07:13:07 -0500 Subject: [PATCH 289/407] Update README link to repo docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f636bcf0e..0d0862660 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ $me = $response->getGraphUser(); echo 'Logged in as ' . $me->getName(); ``` -Complete documentation, installation instructions, and examples are available at: [https://developers.facebook.com/docs/php](https://developers.facebook.com/docs/php) +Complete documentation, installation instructions, and examples are available at: [https://developers.facebook.com/docs/php](docs/) ## Tests From 0e2a1eaaf227af2f3971abcaffa098dfaedfaaf4 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 18 Oct 2016 07:13:56 -0500 Subject: [PATCH 290/407] Update README link to repo docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0d0862660..9b643831c 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ $me = $response->getGraphUser(); echo 'Logged in as ' . $me->getName(); ``` -Complete documentation, installation instructions, and examples are available at: [https://developers.facebook.com/docs/php](docs/) +Complete documentation, installation instructions, and examples are available [here](docs/). ## Tests From 01b41da8b480a4959dff76f5ed2af4fe5c75e3e2 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 18 Oct 2016 07:14:02 -0500 Subject: [PATCH 291/407] Fix link in docs --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index e61b0d995..0223a7a39 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,7 @@ For installation & implementation instructions, look through the [Getting Starte The following examples demonstrate how you would accomplish common tasks with the Facebook SDK for PHP. - **Authentication & Signed Requests** - - [Facebook Login (OAuth 2.0)](./example/facebook_login.md) + - [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) From 1f75b862d65a4afc297d6c2b22b867fff818eec9 Mon Sep 17 00:00:00 2001 From: Titus Keuler Date: Tue, 18 Oct 2016 13:09:42 +0000 Subject: [PATCH 292/407] fixed invalid format handling of headers[x-fb-ads-insights-throttle] --- src/Facebook/Http/GraphRawResponse.php | 2 +- tests/Http/GraphRawResponseTest.php | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php index 324a94472..c51994b09 100644 --- a/src/Facebook/Http/GraphRawResponse.php +++ b/src/Facebook/Http/GraphRawResponse.php @@ -129,7 +129,7 @@ protected function setHeadersFromString($rawHeaders) if (strpos($line, ': ') === false) { $this->setHttpResponseCodeFromHeader($line); } else { - list($key, $value) = explode(': ', $line); + list($key, $value) = explode(': ', $line, 2); $this->headers[$key] = $value; } } diff --git a/tests/Http/GraphRawResponseTest.php b/tests/Http/GraphRawResponseTest.php index aca6ba8de..ec6422986 100644 --- a/tests/Http/GraphRawResponseTest.php +++ b/tests/Http/GraphRawResponseTest.php @@ -48,6 +48,9 @@ class GraphRawResponseTest extends \PHPUnit_Framework_TestCase '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}']; + public function testCanSetTheHeadersFromAnArray() { $myHeaders = [ @@ -79,4 +82,12 @@ public function testWillIgnoreProxyHeaders() $this->assertEquals($this->fakeHeadersAsArray, $headers); $this->assertEquals(200, $httpResponseCode); } + + public function testCanTransformJsonHeaderValues() + { + $response = new GraphRawResponse($this->jsonFakeHeader, ''); + $headers = $response->getHeaders(); + + $this->assertEquals($this->jsonFakeHeaderAsArray['x-fb-ads-insights-throttle'], $headers['x-fb-ads-insights-throttle']); + } } From a5a6b6cc493d8dc417f588c7c0bdfc6396198350 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 18 Oct 2016 12:19:03 -0700 Subject: [PATCH 293/407] Version bump and update CHANGELOG --- CHANGELOG.md | 2 ++ README.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7c1ef294..7dfd41830 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.4.1 (2016-10-18) + - 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) diff --git a/README.md b/README.md index 9b643831c..5a61e16d0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.4.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.4)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.4) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. From 59d8bc472a0cbbea8361c25011afefda68abdfc5 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 31 Oct 2016 08:48:12 -0500 Subject: [PATCH 294/407] Add support for PHP 7 CSPRNG and use as first check to keep deprecated errors from showing up in PHP 7.1 --- .../PseudoRandomStringGeneratorFactory.php | 14 ++++- ...RandomBytesPseudoRandomStringGenerator.php | 59 +++++++++++++++++++ tests/FacebookTest.php | 19 ++++++ .../PseudoRandomStringFactoryTest.php | 9 ++- ...omBytesPseudoRandomStringGeneratorTest.php | 44 ++++++++++++++ 5 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php create mode 100644 tests/PseudoRandomString/RandomBytesPseudoRandomStringGeneratorTest.php diff --git a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php index 210f255f4..8aa7459f1 100644 --- a/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php +++ b/src/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php @@ -38,7 +38,7 @@ private function __construct() * * @param PseudoRandomStringGeneratorInterface|string|null $generator * - * @throws InvalidArgumentException If the pseudo random string generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface. + * @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 */ @@ -52,6 +52,9 @@ public static function createPseudoRandomStringGenerator($generator) return $generator; } + if ('random_bytes' === $generator) { + return new RandomBytesPseudoRandomStringGenerator(); + } if ('mcrypt' === $generator) { return new McryptPseudoRandomStringGenerator(); } @@ -62,7 +65,7 @@ public static function createPseudoRandomStringGenerator($generator) return new UrandomPseudoRandomStringGenerator(); } - throw new InvalidArgumentException('The pseudo random string generator must be set to "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", "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface'); } /** @@ -74,8 +77,13 @@ public static function createPseudoRandomStringGenerator($generator) */ private static function detectDefaultPseudoRandomStringGenerator() { + // 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() first. + // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() next. if (function_exists('mcrypt_create_iv')) { return new McryptPseudoRandomStringGenerator(); } diff --git a/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php b/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php new file mode 100644 index 000000000..0a32ae6a2 --- /dev/null +++ b/src/Facebook/PseudoRandomString/RandomBytesPseudoRandomStringGenerator.php @@ -0,0 +1,59 @@ +validateLength($length); + + return $this->binToHex(random_bytes($length), $length); + } +} diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 23eeb65a2..1e6a4ab1c 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -191,6 +191,25 @@ public function testSettingAnInvalidPseudoRandomStringGeneratorThrows() new Facebook($config); } + public function testRandomBytesCsprgCanBeForced() + { + if (!function_exists('random_bytes')) { + $this->markTestSkipped( + 'Must have PHP 7 or paragonie/random_compat installed to test random_bytes().' + ); + } + + $config = array_merge($this->config, [ + 'persistent_data_handler' => 'memory', // To keep session errors from happening + 'pseudo_random_string_generator' => 'random_bytes' + ]); + $fb = new Facebook($config); + $this->assertInstanceOf( + 'Facebook\PseudoRandomString\RandomBytesPseudoRandomStringGenerator', + $fb->getRedirectLoginHelper()->getPseudoRandomStringGenerator() + ); + } + public function testMcryptCsprgCanBeForced() { if (!function_exists('mcrypt_create_iv')) { diff --git a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php index 996e6fcaf..9beb616d3 100644 --- a/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php +++ b/tests/PseudoRandomString/PseudoRandomStringFactoryTest.php @@ -35,9 +35,9 @@ class PseudoRandomStringFactoryTest extends PHPUnit_Framework_TestCase * @param mixed $handler * @param string $expected * - * @dataProvider httpClientsProvider + * @dataProvider csprngProvider */ - public function testCreateHttpClient($handler, $expected) + public function testCsprng($handler, $expected) { $pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator($handler); @@ -48,11 +48,14 @@ public function testCreateHttpClient($handler, $expected) /** * @return array */ - public function httpClientsProvider() + public function csprngProvider() { $providers = [ [null, self::COMMON_INTERFACE], ]; + if (function_exists('random_bytes')) { + $providers[] = ['random_bytes', self::COMMON_NAMESPACE . 'RandomBytesPseudoRandomStringGenerator']; + } if (function_exists('mcrypt_create_iv')) { $providers[] = ['mcrypt', self::COMMON_NAMESPACE . 'McryptPseudoRandomStringGenerator']; } diff --git a/tests/PseudoRandomString/RandomBytesPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/RandomBytesPseudoRandomStringGeneratorTest.php new file mode 100644 index 000000000..cdff9ed4d --- /dev/null +++ b/tests/PseudoRandomString/RandomBytesPseudoRandomStringGeneratorTest.php @@ -0,0 +1,44 @@ +markTestSkipped( + 'Must have PHP 7 or paragonie/random_compat installed to test random_bytes().' + ); + } + + $csprng = new RandomBytesPseudoRandomStringGenerator; + $randomString = $csprng->getPseudoRandomString(10); + + $this->assertEquals(1, preg_match('/^([0-9a-f]+)$/', $randomString)); + $this->assertEquals(10, strlen($randomString)); + } +} From f4c7c11f5d7fad1124c6fe4a9f4096afee2cb88c Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 31 Oct 2016 08:49:50 -0500 Subject: [PATCH 295/407] Suggest installing paragonie/random_compat --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 86eec0323..9d54abc37 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "guzzlehttp/guzzle": "~5.0" }, "suggest": { + "paragonie/random_compat": "Provides a better CSPRNG option in PHP 5", "guzzlehttp/guzzle": "Allows for implementation of the Guzzle HTTP client" }, "autoload": { From 2839246e971aef150650196acbb46d47e5207370 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Tue, 15 Nov 2016 08:34:16 -0600 Subject: [PATCH 296/407] Update CHANGELOG and bump version number --- CHANGELOG.md | 2 ++ README.md | 2 +- src/Facebook/Facebook.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dfd41830..5645f21f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.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) - 5.4.1 (2016-10-18) - Fixed a bug that was not properly parsing response headers when they contained the colon `:` character. (#679) - 5.4.0 (2016-10-12) diff --git a/README.md b/README.md index 5a61e16d0..b02ecc1dd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.4.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.4)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.4) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.2-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 04a67cc79..76ed77984 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.4.0'; + const VERSION = '5.4.2'; /** * @const string Default Graph API version for requests. From 856161449c44c0d4e2b5093a44e8655d87215d13 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 10:44:16 -0700 Subject: [PATCH 297/407] remove card tags --- docs/examples/access_token_from_canvas.md | 4 -- docs/examples/access_token_from_javascript.md | 4 -- docs/examples/access_token_from_page_tab.md | 4 -- docs/examples/batch_request.md | 6 --- docs/examples/batch_upload.md | 4 -- docs/examples/facebook_login.md | 8 ---- docs/examples/pagination_basic.md | 4 -- docs/examples/post_links.md | 4 -- docs/examples/retrieve_user_profile.md | 4 -- docs/examples/upload_photo.md | 4 -- docs/examples/upload_video.md | 4 -- docs/getting_started.md | 20 --------- docs/reference.md | 18 -------- docs/reference/AccessToken.md | 6 --- docs/reference/Birthday.md | 8 ---- docs/reference/Facebook.md | 10 ----- docs/reference/FacebookApp.md | 4 -- docs/reference/FacebookBatchRequest.md | 10 ----- docs/reference/FacebookBatchResponse.md | 8 ---- docs/reference/FacebookCanvasHelper.md | 16 ------- docs/reference/FacebookClient.md | 14 ------- docs/reference/FacebookFile.md | 6 --- docs/reference/FacebookJavaScriptHelper.md | 14 ------- docs/reference/FacebookPageTabHelper.md | 10 ----- docs/reference/FacebookRedirectLoginHelper.md | 16 ------- docs/reference/FacebookRequest.md | 37 ---------------- docs/reference/FacebookResponse.md | 42 ------------------- docs/reference/FacebookResponseException.md | 6 --- docs/reference/FacebookSDKException.md | 6 --- docs/reference/FacebookVideo.md | 6 --- docs/reference/GraphEdge.md | 10 ----- docs/reference/GraphNode.md | 26 ------------ docs/reference/PersistentDataInterface.md | 8 ---- .../PseudoRandomStringGeneratorInterface.md | 6 --- docs/reference/SignedRequest.md | 16 ------- docs/reference/UrlDetectionInterface.md | 6 --- 36 files changed, 379 deletions(-) diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index b7e1b8076..49956bb56 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -1,10 +1,7 @@ - # 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 {#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. @@ -42,4 +39,3 @@ 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 index b13645425..22ae79077 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -1,10 +1,7 @@ - # 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 {#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. @@ -87,4 +84,3 @@ $_SESSION['fb_access_token'] = (string) $accessToken; // 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 index bdcbe8160..fca98c0f1 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -1,10 +1,7 @@ - # 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 {#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. @@ -48,4 +45,3 @@ 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 index ddd52bdf1..22b2f23b1 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -1,10 +1,7 @@ - # Batch Request Example This example covers sending a batch request with the Facebook SDK for PHP. - - ## Example {#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). @@ -103,9 +100,7 @@ It should also contain a response containing two photos from the user. content: "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).", type: 'warning', }) - - ## Multiple User 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. @@ -149,4 +144,3 @@ foreach ($responses as $key => $response) { } } ~~~~ - diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index f18f32b6c..c0cc3b32f 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -1,10 +1,7 @@ - # Batch File Upload Example This example covers uploading files in a batch request with the Facebook SDK for PHP. - - ## Example {#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. @@ -63,4 +60,3 @@ foreach ($responses as $key => $response) { } } ~~~~ - diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index 9a4e9b75b..b1a07deaf 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -1,18 +1,13 @@ - # Facebook Login Example This example covers Facebook Login with the Facebook SDK for PHP. - - ## Example {#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 {#login} ~~~~ @@ -29,9 +24,7 @@ $loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permiss echo 'Log in with Facebook!'; ~~~~ - - ## /fb-callback.php {#fbcallback} ~~~~ @@ -106,4 +99,3 @@ $_SESSION['fb_access_token'] = (string) $accessToken; // 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 index 629de2a29..8c58102f0 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -1,10 +1,7 @@ - # Pagination Example This example covers basic cursor pagination with the Facebook SDK for PHP. - - ## Example {#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. @@ -45,4 +42,3 @@ foreach ($nextFeed as $status) { var_dump($status->asArray()); } ~~~~ - diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index 5f052c2a1..6e67fac1f 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -1,4 +1,3 @@ - # 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. @@ -6,9 +5,7 @@ This example covers posting a link to the current user's timeline using the Grap It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). - - ## Example {#example} ~~~~ @@ -40,4 +37,3 @@ 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 index 67cdb7e7b..3a1be7627 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -1,4 +1,3 @@ - # 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. @@ -6,9 +5,7 @@ This example covers getting profile information for the current user and printin It assumes that you've already obtained an access token from one of the helpers found [here](/docs/php/sdk_reference#helpers). For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). - - ## Example {#example} ~~~~ @@ -35,4 +32,3 @@ echo 'Name: ' . $user['name']; // OR // echo 'Name: ' . $user->getName(); ~~~~ - diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index d10c87b33..d3212bccb 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -1,4 +1,3 @@ - # 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. @@ -6,9 +5,7 @@ This example covers uploading a photo to the current User's profile using the Gr It assumes that you've already acquired an access token using one of the helper classes found [here](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). - - ## Example {#example} ~~~~ @@ -40,4 +37,3 @@ 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 index 11789e66e..e04837498 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -1,10 +1,7 @@ - # Video Upload Example This example covers uploading & posting a video to a user's timeline with the Facebook SDK for PHP. - - ## Example {#example} %FB(devsite:markdown-wiki:info-card { @@ -70,4 +67,3 @@ $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; ~~~~ - diff --git a/docs/getting_started.md b/docs/getting_started.md index bbb8330ec..b30ddc5f9 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,32 +1,23 @@ - # 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 {#psr-4} 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 {#requirements} - PHP 5.4 or greater - The [mbstring](http://php.net/manual/en/book.mbstring.php) extension - [Composer](https://getcomposer.org/) *(optional)* - - ## Installing the Facebook SDK for PHP {#installation} There are two methods to install the Facebook SDK for PHP. The recommended installation method is by using [Composer](#install-composer). If are unable to use Composer for your project, you can still [install the SDK manually](#install-manually) by downloading the source files and including the autoloader. - - ## Installing with Composer (recommended) {#install-composer} [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. @@ -47,9 +38,7 @@ Make sure to include the Composer autoloader at the top of your script. ~~~ require_once __DIR__ . '/vendor/autoload.php'; ~~~ - - ## Manually installing (if you really have to) {#install-manually} First, download the source code and unzip it wherever you like in your project. @@ -97,9 +86,7 @@ If the autoloader is having trouble detecting the path to the source files, we c define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v5/'); require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; ~~~ - - ## Configuration and setup {#setup} %FB(devsite:markdown-wiki:info-card { @@ -125,9 +112,7 @@ You'll need to replace the `{app-id}` and `{app-secret}` with your Facebook app' }) The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). - - ## Authentication and authorization {#authentication} The SDK can be used to support logging a Facebook user into your site using Facebook Login which is based on OAuth 2.0. @@ -254,9 +239,7 @@ if (isset($accessToken)) { content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](/docs/javascript/reference/FB.init). 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.", type: 'warning', }) - - ## Extending the access token {#extending-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. @@ -272,9 +255,7 @@ $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken('{access-token}') ~~~ [See more about long-lived and short-lived access tokens](/docs/facebook-login/access-tokens#extending). - - ## Making Requests to the Graph API {#making-requests} Once you have an instance of the `Facebook\Facebook` service and obtained an access token, you can begin making calls to the Graph API. @@ -321,4 +302,3 @@ $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](/docs/php/reference). - diff --git a/docs/reference.md b/docs/reference.md index 2ab60bb16..4ad829157 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -1,10 +1,7 @@ - # Facebook SDK for PHP Reference (v5) Below is the API reference for the Facebook SDK for PHP. - - # Core API {#core-api} These classes are at the core of the Facebook SDK for PHP. @@ -22,9 +19,7 @@ These classes are at the core of the Facebook SDK for PHP. ], ], }) - - # Authentication {#authentication} These classes facilitate authenticating a Facebook user with OAuth 2.0. @@ -50,9 +45,7 @@ These classes facilitate authenticating a Facebook user with OAuth 2.0. ], ], }) - - # Requests and Responses {#requests-and-responses} These classes are used in a Graph API request/response cycle. @@ -82,9 +75,7 @@ These classes are used in a Graph API request/response cycle. ], ], }) - - # Signed Requests {#signed-requests} Classes to help obtain and manage signed requests. @@ -110,9 +101,7 @@ Classes to help obtain and manage signed requests. ], ], }) - - # Core Exceptions {#core-exceptions} These are the core exceptions that the SDK will throw when an error occurs. @@ -130,9 +119,7 @@ These are the core exceptions that the SDK will throw when an error occurs. ], ], }) - - # Graph Nodes and Edges {#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. @@ -174,9 +161,7 @@ Graph nodes are collections that represent nodes returned by the Graph API. And ], ], }) - - # File Uploads {#file-uploads} These are entities that represent files to be uploaded with a Graph request. @@ -194,9 +179,7 @@ These are entities that represent files to be uploaded with a Graph request. ], ], }) - - # Extensibility {#extensibility} You can overwrite certain functionality of the SDK by coding to an interface and injecting an instance of your custom functionality. @@ -226,4 +209,3 @@ You can overwrite certain functionality of the SDK by coding to an interface and ], ], }) - diff --git a/docs/reference/AccessToken.md b/docs/reference/AccessToken.md index 6f1a097bc..8124286df 100644 --- a/docs/reference/AccessToken.md +++ b/docs/reference/AccessToken.md @@ -1,10 +1,7 @@ - # 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 {#overview} 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. @@ -46,9 +43,7 @@ Since app access tokens contain the app secret in plain-text, it's very importan 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 {#from-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. @@ -59,4 +54,3 @@ You can optionally pass an expiration date in the form of timestamp as the secon $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 index 303a29da3..74b181e5a 100644 --- a/docs/reference/Birthday.md +++ b/docs/reference/Birthday.md @@ -1,4 +1,3 @@ - # 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. @@ -8,9 +7,7 @@ Users may opt not to share birth day or month, or may not share birth year. Poss * MM/DD/YYYY * MM/DD * YYYY - - ## Facebook\GraphNodes\Birthday {#overview} 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. @@ -42,9 +39,7 @@ var_dump($birthday->hasYear()); var_dump($birthday->format('m/d')); // 03/21 ~~~~ - - ## Instance Methods {#instance-methods} ### hasDate() {#has-date} @@ -52,12 +47,9 @@ var_dump($birthday->format('m/d')); public boolean hasDate() ~~~~ Returns whether or not the birthday object contains the day and month of birth. - - ### hasYear() {#has-year} ~~~~ 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 index 5a86e64f4..375491066 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -1,10 +1,7 @@ - # 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 {#overview} To instantiate a new `Facebook\Facebook` service, pass an array of configuration options to the constructor. @@ -38,9 +35,7 @@ $res = $fb->get('/me', '{access-token}'); $res = $fb->post('/me/feed', ['foo' => 'bar'], '{access-token}'); $res = $fb->delete('/{node-id}', '{access-token}'); ~~~~ - - ## Configuration options {#config} 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. @@ -143,9 +138,7 @@ $fb = new Facebook([ ~~~~ If any other value is provided an `InvalidArgumentException` will be thrown. - - ## Environment variables fallback {#env-vars} 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. @@ -155,9 +148,7 @@ To take advantage of this feature, simply set an environment variable named `FAC ~~~~ $fb = new Facebook\Facebook(); ~~~~ - - # Instance Methods {#instance-methods} ## getApp() {#get-app} @@ -552,4 +543,3 @@ try { echo 'Video ID: ' . $response['video_id']; ~~~~ - diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index 4ee6bb07e..e2c2d4b88 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -1,4 +1,3 @@ - # FacebookApp for the Facebook SDK for PHP In order to make requests to the Graph API, you need to [create a Facebook app](/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. @@ -7,9 +6,7 @@ In order to make requests to the Graph API, you need to [create a Facebook app]( content: "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.", type: 'warning', }) - - ## Facebook\FacebookApp {#overview} To instantiate a new `Facebook\FacebookApp` entity, pass the app ID and app secret to the constructor. @@ -61,4 +58,3 @@ $unserializedFacebookApp = unserialize($serializedFacebookApp); echo $unserializedFacebookApp->getAccessToken(); // foo-app-id|foo-app-secret ~~~~ - diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index b20020d82..7855cb33e 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -1,10 +1,7 @@ - # FacebookBatchRequest for the Facebook SDK for PHP Represents a batch request that will be sent to the Graph API. - - ## Facebook\FacebookBatchRequest {#overview} You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor. @@ -56,9 +53,7 @@ foreach ($batchResponse as $key => $response) { } } ~~~~ - - ## Instance Methods {#instance-methods} Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. @@ -73,17 +68,13 @@ public add( Adds a request to be sent in the batch request. The `$request` can be a single [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) or an array of `Facebook\FacebookRequest`'s. The `$name` argument is optional and is used to identify the request in the batch. - - ### getRequests() {#get-requests} ~~~~ public array getRequests() ~~~~ Returns the array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent in the batch request. - - ## Array Access {#array-access} Since `Facebook\FacebookBatchRequest` implements `\IteratorAggregate` and `\ArrayAccess`, the requests can be accessed via array syntax and can also be iterated over. @@ -104,4 +95,3 @@ array(2) { . . . */ ~~~~ - diff --git a/docs/reference/FacebookBatchResponse.md b/docs/reference/FacebookBatchResponse.md index 569bbda6c..ede1e6083 100644 --- a/docs/reference/FacebookBatchResponse.md +++ b/docs/reference/FacebookBatchResponse.md @@ -1,10 +1,7 @@ - # FacebookBatchResponse for the Facebook SDK for PHP Represents a batch response returned from the Graph API. - - ## Facebook\FacebookBatchResponse {#overview} After sending a batch request to the Graph API, the response will be returned in the form of a `Facebook\FacebookBatchResponse` entity. @@ -43,9 +40,7 @@ foreach ($batchResponse as $key => $response) { var_dump($batchResponse); // class Facebook\FacebookBatchResponse . . . ~~~~ - - ## Instance Methods {#instance-methods} Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. @@ -55,9 +50,7 @@ Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\Faceb public array getResponses() ~~~~ Returns the array of [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entities that were returned from Graph. - - ## Array Access {#array-access} Since `Facebook\FacebookBatchResponse` implements `\IteratorAggregate` and `\ArrayAccess`, the responses can be accessed via array syntax and can also be iterated over. @@ -81,4 +74,3 @@ foreach ($batchResponse as $key => $response) { var_dump($batchResponse['foo']); // class Facebook\FacebookResponse . . . ~~~~ - diff --git a/docs/reference/FacebookCanvasHelper.md b/docs/reference/FacebookCanvasHelper.md index 969a9a696..4fb31cf49 100644 --- a/docs/reference/FacebookCanvasHelper.md +++ b/docs/reference/FacebookCanvasHelper.md @@ -1,4 +1,3 @@ - # 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). @@ -6,9 +5,7 @@ The `FacebookCanvasHelper` is used to obtain an access token or signed request w ~~~ Facebook\Helpers\FacebookCanvasHelper( Facebook\FacebookApp $facebookApp ) ~~~ - - ## Usage {#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. @@ -46,9 +43,7 @@ if (isset($accessToken)) { ~~~ The `$accessToken` will be `null` if the signed request did not contain any OAuth 2.0 data to obtain the access token. - - ## Instance Methods {#instance-methods} ### __construct() {#construct} @@ -56,17 +51,13 @@ The `$accessToken` will be `null` if the signed request did not contain any OAut 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() {#get-access-token} ~~~ public Facebook\AccessToken|null getAccessToken() ~~~ Checks the signed request for authentication data and tries to obtain an access token access token. - - ### getUserId() {#get-user-id} ~~~ public string|null getUserId() @@ -92,28 +83,21 @@ if ($signedRequest) { $userId = $signedRequest->get('user_id'); } ~~~ - - ### getAppData() {#get-app-data} ~~~ public string|null getAppData() ~~~ Gets the value that is set in the `app_data` property if present. - - ### getSignedRequest() {#get-signed-request} ~~~ public Facebook\SignedRequest|null getSignedRequest() ~~~ Returns the signed request as an instance of [`Facebook\SignedRequest`](/docs/php/SignedRequest) if present. - - ### getRawSignedRequest() {#get-raw-signed-request} ~~~ 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 index 9e9304cd4..0b5e84472 100644 --- a/docs/reference/FacebookClient.md +++ b/docs/reference/FacebookClient.md @@ -1,10 +1,7 @@ - # 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 {#overview} 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`. @@ -25,9 +22,7 @@ $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 {#instance-methods} ### getHttpClientHandler() {#get-http-client-handler} @@ -35,25 +30,19 @@ The `Facebook\FacebookClient` service takes the guess-work out of managing those public Facebook\HttpClients\FacebookHttpClientInterface getHttpClientHandler() ~~~~ Returns the instance of [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface) that the service is using. - - ### setHttpClientHandler() {#set-http-client-handler} ~~~~ public setHttpClientHandler(Facebook\HttpClients\FacebookHttpClientInterface $client) ~~~~ If you've coded your own HTTP client to the [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface), you can inject it into the service using this method. - - ### enableBetaMode() {#enable-beta-mode} ~~~~ 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() {#send-request} ~~~~ public Facebook\FacebookResponse sendRequest(Facebook\FacebookRequest $request) @@ -67,9 +56,7 @@ Returns the response from Graph in the form of a [`Facebook\FacebookResponse`](/ If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) will be thrown. If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) will be thrown. - - ### sendBatchRequest() {#send-batch-request} ~~~~ public Facebook\FacebookBatchResponse sendBatchRequest(Facebook\FacebookBatchRequest $batchRequest) @@ -83,4 +70,3 @@ Returns the response from Graph in the form of a [`Facebook\FacebookBatchRespons If there was an error processing the request before sending, a [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) will be thrown. If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) will be thrown. - diff --git a/docs/reference/FacebookFile.md b/docs/reference/FacebookFile.md index 4f90859b7..a785443a6 100644 --- a/docs/reference/FacebookFile.md +++ b/docs/reference/FacebookFile.md @@ -1,10 +1,7 @@ - # 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) {#overview} The `FacebookFile` entity represents a local or remote file to be uploaded with a request to Graph. @@ -26,9 +23,7 @@ $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 {#usage} The following example uploads a photo for a user. @@ -64,4 +59,3 @@ $data = [ $response = $fb->post('/me/photos', $data); ~~~~ - diff --git a/docs/reference/FacebookJavaScriptHelper.md b/docs/reference/FacebookJavaScriptHelper.md index d6f02ccb4..00fbe1fdf 100644 --- a/docs/reference/FacebookJavaScriptHelper.md +++ b/docs/reference/FacebookJavaScriptHelper.md @@ -1,10 +1,7 @@ - # 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 {#usage} This helper will handle validating and decode the signed request from the cookie set by the JavaScript SDK. @@ -42,9 +39,7 @@ if (isset($accessToken)) { ~~~ 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 {#instance-methods} ### __construct() {#construct} @@ -52,17 +47,13 @@ You will likely want to make an Ajax request when the login state changes in the 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() {#get-access-token} ~~~ 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() {#get-user-id} ~~~ public string|null getUserId() @@ -88,20 +79,15 @@ if ($signedRequest) { $userId = $signedRequest->get('user_id'); } ~~~ - - ### getSignedRequest() {#get-signed-request} ~~~ public Facebook\SignedRequest|null getSignedRequest() ~~~ Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedRequest) entity if present. - - ### getRawSignedRequest() {#get-raw-signed-request} ~~~ 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 index 6ae23e900..eb62cc870 100644 --- a/docs/reference/FacebookPageTabHelper.md +++ b/docs/reference/FacebookPageTabHelper.md @@ -1,10 +1,7 @@ - # 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 {#usage} The usage of the `FacebookPageTabHelper` is exactly the same as [`FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) with additional methods to obtain the `page` data from the signed request. @@ -40,9 +37,7 @@ if (isset($accessToken)) { // Logged in. } ~~~ - - ## Instance Methods {#instance-methods} ### getPageData() {#get-page-data} @@ -50,20 +45,15 @@ if (isset($accessToken)) { public string|null getPageData($key, $default = null) ~~~ Gets a value from the `page` property if present. - - ### isAdmin() {#is-admin} ~~~ public boolean isAdmin() ~~~ Returns `true` is the user has authenticated your app and is an admin of the parent page. - - ### getPageId() {#get-page-id} ~~~ 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 index 97bd57d8d..8e19f299a 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -1,10 +1,7 @@ - # 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 {#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. @@ -75,9 +72,7 @@ if (isset($accessToken)) { exit; } ~~~ - - ## Instance Methods {#instance-methods} ### getLoginUrl() {#get-login-url} @@ -90,33 +85,25 @@ Generates an authorization URL to ask a user for access to their profile on beha - `$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() {#get-re-request-url} ~~~~ 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() {#get-re-authentication-url} ~~~~ 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() {#get-logout-url} ~~~~ 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() {#get-access-token} ~~~~ public Facebook\Authentication\AccessToken|null getAccessToken(string $redirectUrl = null) @@ -127,9 +114,7 @@ If no authorization code could be found from the `code` param in the URL, this m #### 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 {#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. @@ -150,4 +135,3 @@ The CSRF value that the `getLoginUrl()`, `getReRequestUrl()`, and `getReAuthenti ### 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`](/docs/php/UrlDetectionInterface). - \ No newline at end of file diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 8e41c7318..80aa3c6e8 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -1,10 +1,7 @@ - # FacebookRequest for the Facebook SDK for PHP Represents a request that will be sent to the Graph API. - - ## Facebook\FacebookRequest {#overview} You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. @@ -55,67 +52,50 @@ $graphNode = $response->getGraphNode(); echo 'User name: ' . $graphNode['name']; ~~~~ - - ## Instance Methods {#instance-methods} ### setAccessToken() {#set-access-token} ~~~~ public setAccessToken(string|Facebook\AccessToken $accessToken) ~~~~ -Sets the access token to be used for the request. - - ### getAccessToken() {#get-access-token} ~~~~ public string getAccessToken() ~~~~ Returns the access token to be used for the request in the form of a string. - - ### setApp() {#set-app} ~~~~ public setApp(Facebook\FacebookApp $app) ~~~~ Sets the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. - - ### getApp() {#get-app} ~~~~ public Facebook\FacebookApp getApp() ~~~~ Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. - - ### getAppSecretProof() {#get-app-secret-proof} ~~~~ public string getAppSecretProof() ~~~~ Returns the [app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests/#appsecret_proof) to sign the request. - - ### setMethod() {#set-method} ~~~~ public setMethod(string $method) ~~~~ Sets the HTTP verb to use for the request. - - ### getMethod() {#get-method} ~~~~ public string setMethod() ~~~~ Returns the HTTP verb to use for the request. - - ### setEndpoint() {#set-endpoint} ~~~~ public setEndpoint(string $endpoint) @@ -125,17 +105,13 @@ Sets the Graph URL endpoint to be used with the request. The endpoint must be ex ~~~~ $request->setEndpoint('/me'); ~~~~ - - ### getEndpoint() {#get-endpoint} ~~~~ public string getEndpoint() ~~~~ Returns the Graph URL endpoint to be used with the request. - - ### setHeaders() {#set-headers} ~~~~ public setHeaders(array $headers) @@ -147,25 +123,19 @@ $request->setHeaders([ 'X-foo-header' => 'Something', ]); ~~~~ - - ### getHeaders() {#get-headers} ~~~~ public array getHeaders() ~~~~ Returns the request headers that will be sent with the request. The eTag headers `If-None-Match` are appended automatically. - - ### setETag() {#set-etag} ~~~~ public setETag(string $eTag) ~~~~ Sets the eTag that will be using for matching the `If-None-Match` header. - - ### setParams() {#set-params} ~~~~ public setParams(array $params) @@ -181,25 +151,19 @@ $request->setParams([ ~~~~ 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() {#get-params} ~~~~ 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() {#get-graph-version} ~~~~ public string getGraphVersion() ~~~~ Returns the Graph version prefix to be used with the request. - - ### getUrl() {#get-url} ~~~~ public string getUrl() @@ -213,4 +177,3 @@ $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); // /v2.6/me?fields=id,name&access_token=token&appsecret_proof=proof ~~~~ - diff --git a/docs/reference/FacebookResponse.md b/docs/reference/FacebookResponse.md index 30b694194..339e22760 100644 --- a/docs/reference/FacebookResponse.md +++ b/docs/reference/FacebookResponse.md @@ -1,10 +1,7 @@ - # FacebookResponse for the Facebook SDK for PHP Represents a response from the Graph API. - - ## Facebook\FacebookResponse {#overview} After sending a request to the Graph API, the response will be returned in the form of a `Facebook\FacebookResponse` entity. @@ -30,9 +27,7 @@ try { var_dump($response); // class Facebook\FacebookResponse . . . ~~~~ - - ## Instance Methods {#instance-methods} ### getRequest() {#get-request} @@ -40,145 +35,109 @@ var_dump($response); public Facebook\FacebookRequest getRequest() ~~~~ Returns the original [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. - - ### getAccessToken() {#get-access-token} ~~~~ public string getAccessToken() ~~~~ Returns the access token that was used for the original request in the form of a string. - - ### getApp() {#get-app} ~~~~ public Facebook\FacebookApp getApp() ~~~~ Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. - - ### getHttpStatusCode() {#get-http-status-code} ~~~~ public int getHttpStatusCode() ~~~~ Returns the HTTP response code for this response. - - ### getHeaders() {#get-headers} ~~~~ public array getHeaders() ~~~~ Returns the response headers that were returned. - - ### getBody() {#get-body} ~~~~ public string getBody() ~~~~ Returns the raw, unparsed body of the response as a string. - - ### getDecodedBody() {#get-decoded-body} ~~~~ public array getDecodedBody() ~~~~ Returns the parsed body of the response as an array. - - ### getAppSecretProof() {#get-app-secret-proof} ~~~~ 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() {#get-etag} ~~~~ 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() {#get-graph-version} ~~~~ 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() {#is-error} ~~~~ 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() {#throw-exception} ~~~~ public throwException() ~~~~ Throws the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. - - ### getThrownException() {#get-thrown-exception} ~~~~ public Facebook\Exceptions\FacebookResponseException getThrownException() ~~~~ Returns the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. This is mainly useful for dealing with [responses to batch requests](/docs/php/FacebookBatchResponse). - - ### getGraphNode() {#get-graph-node} ~~~~ public Facebook\GraphNodes\GraphNode getGraphNode() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode) collection. - - ### getGraphAlbum() {#get-graph-album} ~~~~ public Facebook\GraphNodes\GraphAlbum getGraphAlbum() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) collection. - - ### getGraphPage() {#get-graph-page} ~~~~ public Facebook\GraphNodes\GraphPage getGraphPage() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods) collection. - - ### getGraphSessionInfo() {#get-graph-session-info} ~~~~ public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphNode#sessioninfo-instance-methods) collection. - - ### getGraphUser() {#get-graph-user} ~~~~ public Facebook\GraphNodes\GraphUser getGraphUser() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods) collection. - - ### getGraphEdge() {#get-graph-edge} ~~~~ public Facebook\GraphNodes\GraphEdge getGraphEdge( @@ -200,4 +159,3 @@ foreach ($events as $event) { // . . . } ~~~~ - diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md index a0eda9217..fa529512e 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -1,10 +1,7 @@ - # FacebookResponseException for the Facebook SDK for PHP Represents an error response from the Graph API. - - ## Facebook\Exceptions\FacebookResponseException {#overview} 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. @@ -51,9 +48,7 @@ try { }) These exceptions are derived from the [error responses from the Graph API](/docs/graph-api/using-graph-api/#errors). - - ## Instance Methods {#instance-methods} `FacebookResponseException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. @@ -81,4 +76,3 @@ Returns the raw response body used to create the exception as a string. ### getResponse {#getresponse} `getResponse()` Returns the `FacebookResponse` entity which represents the HTTP response. - \ No newline at end of file diff --git a/docs/reference/FacebookSDKException.md b/docs/reference/FacebookSDKException.md index 07c0cb967..f75a00cc4 100644 --- a/docs/reference/FacebookSDKException.md +++ b/docs/reference/FacebookSDKException.md @@ -1,19 +1,13 @@ - # FacebookSDKException for the Facebook SDK for PHP Represents an exception thrown by the SDK. - - ## Facebook\Exceptions\FacebookSDKException {#overview} 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](/docs/php/FacebookResponseException). - - ## Instance Methods {#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 index 2227a684a..479527515 100644 --- a/docs/reference/FacebookVideo.md +++ b/docs/reference/FacebookVideo.md @@ -1,10 +1,7 @@ - # 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) {#overview} The `FacebookVideo` entity represents a local or remote video file to be uploaded with a request to Graph. @@ -26,9 +23,7 @@ $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 {#usage} In Graph v2.3, functionality was added to [upload video files in chunks](/docs/graph-api/video-uploads#resumable). The PHP SDK provides a handy API to easily upload video files in chunks via the [`uploadVideo()` method](/docs/php/Facebook#upload-video). @@ -71,4 +66,3 @@ $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; ~~~~ - diff --git a/docs/reference/GraphEdge.md b/docs/reference/GraphEdge.md index 4f451d18d..5aaf373e5 100644 --- a/docs/reference/GraphEdge.md +++ b/docs/reference/GraphEdge.md @@ -1,10 +1,7 @@ - # 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 {#overview} You can grab a `GraphEdge` from a response from Graph. @@ -21,9 +18,7 @@ foreach ($graphEdge as $graphNode) { // . . . } ~~~~ - - ## Pagination {#pagination} With the help of the `Facebook\Facebook` super service class, the `GraphEdge` collection can grab the next and previous sets of data. @@ -38,9 +33,7 @@ $previousPageOfAlbums = $fb->previous($previousOfAlbums); ~~~~ When the next or previous page returns no results, `$fb->next()` will return `null`. - - ## Deep Pagination {#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`. @@ -68,9 +61,7 @@ do { $pageCount++; } while ($pageCount < $maxPages && $pagesEdge = $fb->next($pagesEdge)); ~~~~ - - ## Method Reference {#method-reference} ### getMetaData() {#get-meta-data} @@ -121,4 +112,3 @@ $likesEdge = $response->getGraphEdge(); $totalCount = $likesEdge->getTotalCount(); // Returns: 10 ~~~~ - diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 0263fa4f2..07670a445 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -1,10 +1,7 @@ - # 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 {#overview} This base class has several subclasses: @@ -42,9 +39,7 @@ echo $user->getName(); // From GraphUser echo $graphNode->getField('country'); // From GraphNode echo $location->getCountry(); // From GraphLocation ~~~~ - - ## SPL Libraries {#spl} 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`. @@ -66,9 +61,6 @@ foreach ($graphNode as $key => $value) { $total = count($graphNode); ~~~~ - - - ## GraphNode Instance Methods {#instance-methods} @@ -97,9 +89,7 @@ Returns an array with the names of all fields present on the graph node. ### map {#map} `map(Closure $callback)` Provides a way to map over the data within the collection just like `array_map()`. - - ## GraphUser Instance Methods {#user-instance-methods} The `GraphUser` collection represents a [User](https://developers.facebook.com/docs/graph-api/reference/user) Graph node. @@ -187,9 +177,7 @@ Returns the `hometown` property for the user as a `Facebook\GraphNodes\GraphPage public Facebook\GraphNodes\GraphUser|null getHometown() ~~~~ Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. - - ## GraphPage Instance Methods {#page-instance-methods} The `GraphPage` collection represents a [Page](https://developers.facebook.com/docs/graph-api/reference/page) Graph node. @@ -265,9 +253,7 @@ Returns the `access_token` property for the page if present. (Only available in 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 {#album-instance-methods} The `GraphAlbum` collection represents an [Album](https://developers.facebook.com/docs/graph-api/reference/album) Graph node. @@ -375,9 +361,7 @@ Returns the `privacy` property for the album as a string if present. 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 {#location-instance-methods} All getter methods return `null` if the property does not exist on the node. @@ -417,9 +401,7 @@ Returns the `latitude` property for the location as a float if present. public float|null getLongitude() ~~~~ Returns the `longitude` property for the location as a float if present. - - ## GraphPicture Instance Methods {#picture-instance-methods} All getter methods return `null` if the property does not exist on the node. @@ -429,9 +411,7 @@ All getter methods return `null` if the property does not exist on the node. public string|null getUrl() ~~~~ Returns the `url` property for the picture as a string if present. - - ## GraphAchievement Instance Methods {#achievement-instance-methods} All getter methods return `null` if the property does not exist on the node. @@ -441,9 +421,7 @@ All getter methods return `null` if the property does not exist on the node. public string|null getId() ~~~~ Returns the `id` property for the achievement as a string if present. - - ## GraphEvent Instance Methods {#event-instance-methods} All getter methods return `null` if the property does not exist on the node. @@ -568,10 +546,7 @@ Returns the `noreply_count` property (Number of people who did not reply to the 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 {#group-instance-methods} All getter methods return `null` if the field does not exist on the node. @@ -641,4 +616,3 @@ Returns the `updated_time` field (The last time the Group was updated (this incl 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 index f6fb4c083..d12712fc6 100644 --- a/docs/reference/PersistentDataInterface.md +++ b/docs/reference/PersistentDataInterface.md @@ -1,10 +1,7 @@ - # 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 {#overview} 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. @@ -57,9 +54,7 @@ use Facebook\Helpers\FacebookRedirectLoginHelper; $myPersistentDataHandler = new MyLaravelPersistentDataHandler(); $helper = new FacebookRedirectLoginHelper($fbApp, $myPersistentDataHandler); ~~~~ - - ## Method Reference {#method-reference} ### get() {#get} @@ -67,12 +62,9 @@ $helper = new FacebookRedirectLoginHelper($fbApp, $myPersistentDataHandler); public mixed get(string $key) ~~~~ Returns a value from the persistent data store or `null` if the value does not exist. - - ### set() {#set} ~~~~ 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 index e0aa5d819..b8a986680 100644 --- a/docs/reference/PseudoRandomStringGeneratorInterface.md +++ b/docs/reference/PseudoRandomStringGeneratorInterface.md @@ -1,10 +1,7 @@ - # 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 {#overview} 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. @@ -52,9 +49,7 @@ use Facebook\Helpers\FacebookRedirectLoginHelper; $myPseudoRandomStringGenerator = new MyCustomPseudoRandomStringGenerator(); $helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStringGenerator); ~~~~ - - ## Method Reference {#method-reference} ### getPseudoRandomString() {#get-pseudo-random-string} @@ -62,4 +57,3 @@ $helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStr 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 index 06e593dad..d37e152b3 100644 --- a/docs/reference/SignedRequest.md +++ b/docs/reference/SignedRequest.md @@ -1,10 +1,7 @@ - # SignedRequest entity for the Facebook SDK for PHP The `Facebook\SignedRequest` entity represents a signed request. - - ## Facebook\SignedRequest {#overview} [Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) 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. @@ -33,9 +30,7 @@ $signedRequest = $helper->getSignedRequest(); $helper = $fb->getPageTabHelper(); $signedRequest = $helper->getSignedRequest(); ~~~~ - - ## Instance Methods {#instance-methods} ### getRawSignedRequest() {#get-raw-signed-request} @@ -43,41 +38,31 @@ $signedRequest = $helper->getSignedRequest(); public string|null getRawSignedRequest() ~~~~ Returns the original raw encoded signed request in the form of a string. - - ### getPayload() {#get-payload} ~~~~ 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() {#get} ~~~~ 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() {#get-user-id} ~~~~ 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() {#has-oauth-data} ~~~~ public boolean hasOAuthData() ~~~~ Returns `true` if the payload data contains either an `oauth_token` or `code` field. Returns `false` if neither value exists. - - ### make() {#make} ~~~~ public string make(array $payload) @@ -98,4 +83,3 @@ $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 index 2f93d3907..6a2fe65e2 100644 --- a/docs/reference/UrlDetectionInterface.md +++ b/docs/reference/UrlDetectionInterface.md @@ -1,10 +1,7 @@ - # 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 {#overview} 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. @@ -44,9 +41,7 @@ use Facebook\Helpers\FacebookRedirectLoginHelper; $myUrlDetectionHandler = new MyLaravelUrlDetectionHandler(); $helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); ~~~~ - - ## Method Reference {#method-reference} ### getCurrentUrl() {#get-current-url} @@ -54,4 +49,3 @@ $helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); public string getCurrentUrl() ~~~~ Returns the full and currently active URL. - From f96a5c08eb8a3a5a3bfee19eccb8254b8e720b58 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 11:53:40 -0700 Subject: [PATCH 298/407] remove FB header anchors --- docs/examples/access_token_from_canvas.md | 2 +- docs/examples/access_token_from_javascript.md | 2 +- docs/examples/access_token_from_page_tab.md | 2 +- docs/examples/batch_request.md | 4 +- docs/examples/batch_upload.md | 2 +- docs/examples/facebook_login.md | 6 +- docs/examples/pagination_basic.md | 2 +- docs/examples/post_links.md | 2 +- docs/examples/retrieve_user_profile.md | 2 +- docs/examples/upload_photo.md | 2 +- docs/examples/upload_video.md | 2 +- docs/getting_started.md | 26 +-- docs/reference.md | 16 +- docs/reference/AccessToken.md | 16 +- docs/reference/Birthday.md | 8 +- docs/reference/Facebook.md | 72 +++---- docs/reference/FacebookApp.md | 12 +- docs/reference/FacebookBatchRequest.md | 10 +- docs/reference/FacebookBatchResponse.md | 8 +- docs/reference/FacebookCanvasHelper.md | 4 +- docs/reference/FacebookClient.md | 14 +- docs/reference/FacebookFile.md | 4 +- docs/reference/FacebookJavaScriptHelper.md | 4 +- docs/reference/FacebookPageTabHelper.md | 10 +- docs/reference/FacebookRedirectLoginHelper.md | 16 +- docs/reference/FacebookRequest.md | 36 ++-- docs/reference/FacebookResponse.md | 42 ++-- docs/reference/FacebookResponseException.md | 16 +- docs/reference/FacebookSDKException.md | 4 +- docs/reference/FacebookVideo.md | 4 +- docs/reference/GraphEdge.md | 16 +- docs/reference/GraphNode.md | 196 ++++++++++-------- docs/reference/PersistentDataInterface.md | 8 +- .../PseudoRandomStringGeneratorInterface.md | 6 +- docs/reference/SignedRequest.md | 16 +- docs/reference/UrlDetectionInterface.md | 6 +- 36 files changed, 305 insertions(+), 293 deletions(-) diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index 49956bb56..42c4098d7 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -2,7 +2,7 @@ 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 {#example} +## 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. diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index 22ae79077..0dcfa3bfc 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -2,7 +2,7 @@ This example covers obtaining an access token and signed request from the Facebook JavaScript SDK with the Facebook SDK for PHP. -## Example {#example} +## 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. diff --git a/docs/examples/access_token_from_page_tab.md b/docs/examples/access_token_from_page_tab.md index fca98c0f1..97e094ac7 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -2,7 +2,7 @@ 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 {#example} +## 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. diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index 22b2f23b1..5d75f41a0 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -2,7 +2,7 @@ This example covers sending a batch request with the Facebook SDK for PHP. -## Example {#example} +## 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). @@ -101,7 +101,7 @@ It should also contain a response containing two photos from the user. type: 'warning', }) -## Multiple User Example {#multiple-user-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. diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index c0cc3b32f..25f1b984e 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -2,7 +2,7 @@ This example covers uploading files in a batch request with the Facebook SDK for PHP. -## Example {#example} +## 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. diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index b1a07deaf..df05994c3 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -2,13 +2,13 @@ This example covers Facebook Login with the Facebook SDK for PHP. -## Example {#example} +## 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 {#login} +## /login.php ~~~~ $fb = new Facebook\Facebook([ @@ -25,7 +25,7 @@ $loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permiss echo 'Log in with Facebook!'; ~~~~ -## /fb-callback.php {#fbcallback} +## /fb-callback.php ~~~~ $fb = new Facebook\Facebook([ diff --git a/docs/examples/pagination_basic.md b/docs/examples/pagination_basic.md index 8c58102f0..9a8f91ee4 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -2,7 +2,7 @@ This example covers basic cursor pagination with the Facebook SDK for PHP. -## Example {#example} +## 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. diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index 6e67fac1f..00315f260 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -6,7 +6,7 @@ It assumes that you've already obtained an access token from one of the helpers For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). -## Example {#example} +## Example ~~~~ $fb = new Facebook\Facebook([ diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md index 3a1be7627..e03e6bec3 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -6,7 +6,7 @@ It assumes that you've already obtained an access token from one of the helpers For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). -## Example {#example} +## Example ~~~~ $fb = new Facebook\Facebook([ diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index d3212bccb..a34882cde 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -6,7 +6,7 @@ It assumes that you've already acquired an access token using one of the helper For more information, see the documentation for [`Facebook\Facebook`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). -## Example {#example} +## Example ~~~~ $fb = new Facebook\Facebook([ diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index e04837498..dbe91cf85 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -2,7 +2,7 @@ This example covers uploading & posting a video to a user's timeline with the Facebook SDK for PHP. -## Example {#example} +## Example %FB(devsite:markdown-wiki:info-card { content: "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.", diff --git a/docs/getting_started.md b/docs/getting_started.md index b30ddc5f9..223c992fb 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -2,23 +2,23 @@ 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 {#psr-4} +## 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 {#requirements} +## System requirements - PHP 5.4 or greater - The [mbstring](http://php.net/manual/en/book.mbstring.php) extension - [Composer](https://getcomposer.org/) *(optional)* -## Installing the Facebook SDK for PHP {#installation} +## 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](#install-composer). If are unable to use Composer for your project, you can still [install the SDK manually](#install-manually) by downloading the source files and including the autoloader. -## Installing with Composer (recommended) {#install-composer} +## 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. @@ -39,7 +39,7 @@ Make sure to include the Composer autoloader at the top of your script. require_once __DIR__ . '/vendor/autoload.php'; ~~~ -## Manually installing (if you really have to) {#install-manually} +## Manually installing (if you really have to) First, download the source code and unzip it wherever you like in your project. @@ -59,7 +59,7 @@ require_once __DIR__ . '/path/to/facebook-php-sdk-v4/src/Facebook/autoload.php'; The autoloader should be able to auto-detect the proper location of the source code. -### Keeping things tidy {#tidy-up} +### 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. @@ -87,7 +87,7 @@ define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v5/'); require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; ~~~ -## Configuration and setup {#setup} +## Configuration and setup %FB(devsite:markdown-wiki:info-card { content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](/apps).", @@ -113,14 +113,14 @@ You'll need to replace the `{app-id}` and `{app-secret}` with your Facebook app' The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). -## Authentication and authorization {#authentication} +## 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](/docs/php/reference#helpers). -### Obtaining an access token from redirect {#authentication-redirect} +### Obtaining an access token from redirect For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) 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`](/docs/php/AccessToken) entity. @@ -172,7 +172,7 @@ if (isset($accessToken)) { ~~~ -### Obtaining an access token from a Facebook Canvas context {#authentication-canvas} +### Obtaining an access token from a Facebook Canvas context If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) to get an [`AccessToken`](/docs/php/AccessToken) entity for the user. @@ -209,7 +209,7 @@ if (isset($accessToken)) { }) -### Obtaining an access token from the SDK for JavaScript {#authentication-javascript} +### 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](/docs/php/FacebookJavaScriptHelper). The `getAccessToken()` method will return an [`AccessToken`](/docs/php/AccessToken) entity. @@ -240,7 +240,7 @@ if (isset($accessToken)) { type: 'warning', }) -## Extending the access token {#extending-access-token} +## 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. @@ -256,7 +256,7 @@ $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken('{access-token}') [See more about long-lived and short-lived access tokens](/docs/facebook-login/access-tokens#extending). -## Making Requests to the Graph API {#making-requests} +## 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. diff --git a/docs/reference.md b/docs/reference.md index 4ad829157..dff139ab2 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -2,7 +2,7 @@ Below is the API reference for the Facebook SDK for PHP. -# Core API {#core-api} +# Core API These classes are at the core of the Facebook SDK for PHP. @@ -20,7 +20,7 @@ These classes are at the core of the Facebook SDK for PHP. ], }) -# Authentication {#authentication} +# Authentication These classes facilitate authenticating a Facebook user with OAuth 2.0. @@ -46,7 +46,7 @@ These classes facilitate authenticating a Facebook user with OAuth 2.0. ], }) -# Requests and Responses {#requests-and-responses} +# Requests and Responses These classes are used in a Graph API request/response cycle. @@ -76,7 +76,7 @@ These classes are used in a Graph API request/response cycle. ], }) -# Signed Requests {#signed-requests} +# Signed Requests Classes to help obtain and manage signed requests. @@ -102,7 +102,7 @@ Classes to help obtain and manage signed requests. ], }) -# Core Exceptions {#core-exceptions} +# Core Exceptions These are the core exceptions that the SDK will throw when an error occurs. @@ -120,7 +120,7 @@ These are the core exceptions that the SDK will throw when an error occurs. ], }) -# Graph Nodes and Edges {#graph-nodes-and-edges} +# 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. @@ -162,7 +162,7 @@ Graph nodes are collections that represent nodes returned by the Graph API. And ], }) -# File Uploads {#file-uploads} +# File Uploads These are entities that represent files to be uploaded with a Graph request. @@ -180,7 +180,7 @@ These are entities that represent files to be uploaded with a Graph request. ], }) -# Extensibility {#extensibility} +# Extensibility You can overwrite certain functionality of the SDK by coding to an interface and injecting an instance of your custom functionality. diff --git a/docs/reference/AccessToken.md b/docs/reference/AccessToken.md index 8124286df..396750886 100644 --- a/docs/reference/AccessToken.md +++ b/docs/reference/AccessToken.md @@ -2,49 +2,49 @@ 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 {#overview} +## 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() {#get-value} +### getValue() ~~~~ 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() {#get-expires-at} +### getExpiresAt() ~~~~ 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() {#is-expired} +### isExpired() ~~~~ 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() {#is-long-lived} +### isLongLived() ~~~~ 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() {#is-app-access-token} +### isAppAccessToken() ~~~~ 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() {#is-app-secret-proof} +### getAppSecretProof() ~~~~ 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 {#from-string} +## 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. diff --git a/docs/reference/Birthday.md b/docs/reference/Birthday.md index 74b181e5a..090c572d9 100644 --- a/docs/reference/Birthday.md +++ b/docs/reference/Birthday.md @@ -8,7 +8,7 @@ Users may opt not to share birth day or month, or may not share birth year. Poss * MM/DD * YYYY -## Facebook\GraphNodes\Birthday {#overview} +## 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. @@ -40,15 +40,15 @@ var_dump($birthday->format('m/d')); // 03/21 ~~~~ -## Instance Methods {#instance-methods} +## Instance Methods -### hasDate() {#has-date} +### hasDate() ~~~~ public boolean hasDate() ~~~~ Returns whether or not the birthday object contains the day and month of birth. -### hasYear() {#has-year} +### hasYear() ~~~~ public boolean hasYear() ~~~~ diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md index 375491066..129d422b4 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -2,7 +2,7 @@ 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 {#overview} +## Facebook\Facebook To instantiate a new `Facebook\Facebook` service, pass an array of configuration options to the constructor. @@ -36,7 +36,7 @@ $res = $fb->post('/me/feed', ['foo' => 'bar'], '{access-token}'); $res = $fb->delete('/{node-id}', '{access-token}'); ~~~~ -## Configuration options {#config} +## 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. @@ -56,22 +56,22 @@ $fb = new Facebook\Facebook([ ]); ~~~~ -### `app_id` {#appid} +### `app_id` The ID of your Facebook app (required). -### `app_secret` {#appsecret} +### `app_secret` The secret of your Facebook app (required). -### `default_access_token` {#defaulttoken} +### `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` {#enablebeta} +### `enable_beta_mode` Enable [beta mode](/docs/support/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` {#defaultversion} +### `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.6`. Defaults to the [latest version of Graph](/docs/apps/changelog). -### `http_client_handler` {#httpclient} +### `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`. @@ -88,7 +88,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -### `persistent_data_handler` {#datahandler} +### `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`. @@ -103,7 +103,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -### `url_detection_handler` {#urlhandler} +### `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](/docs/php/UrlDetectionInterface)` and set the value of `url_detection_handler` to an instance of your custom URL detector. @@ -116,7 +116,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -### `pseudo_random_string_generator` {#prsg} +### `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. @@ -139,7 +139,7 @@ $fb = new Facebook([ If any other value is provided an `InvalidArgumentException` will be thrown. -## Environment variables fallback {#env-vars} +## 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. @@ -149,45 +149,45 @@ To take advantage of this feature, simply set an environment variable named `FAC $fb = new Facebook\Facebook(); ~~~~ -# Instance Methods {#instance-methods} +# Instance Methods -## getApp() {#get-app} +## getApp() ~~~~ public FacebookApp getApp() ~~~~ Returns the instance of `Facebook\FacebookApp` for the instantiated service. -## getClient() {#get-client} +## getClient() ~~~~ public Facebook\FacebookClient getClient() ~~~~ Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) for the instantiated service. -## getOAuth2Client() {#get-oauth2-client} +## getOAuth2Client() ~~~~ public Facebook\Authentication\OAuth2Client getOAuth2Client() ~~~~ Returns an instance of [`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client). -## getLastResponse() {#get-last-response} +## getLastResponse() ~~~~ 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() {#get-url-detection-handler} +## getUrlDetectionHandler() ~~~~ public Facebook\Url\UrlDetectionInterface getUrlDetectionHandler() ~~~~ Returns an instance of [`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface). -## getDefaultAccessToken() {#get-default-access-token} +## getDefaultAccessToken() ~~~~ public Facebook\Authentication\AccessToken|null getDefaultAccessToken() ~~~~ Returns the default fallback [`AccessToken`](/docs/php/AccessToken) 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() {#set-default-access-token} +## setDefaultAccessToken() ~~~~ public setDefaultAccessToken(string|Facebook\AccessToken $accessToken) ~~~~ @@ -204,13 +204,13 @@ $fb->setDefaultAccessToken($accessToken); This setting will overwrite the value from `default_access_token` option if it was passed to the `Facebook\Facebook` constructor. -## getDefaultGraphVersion() {#get-default-graph-version} +## getDefaultGraphVersion() ~~~~ 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() {#get} +## get() ~~~~ public Facebook\FacebookResponse get( string $endpoint, @@ -238,7 +238,7 @@ The access token (as a string or `AccessToken` entity) to use for the request. I `$graphVersion` This will overwrite the Graph version that was set in the `default_graph_version` configuration option. -## post() {#post} +## post() ~~~~ public Facebook\FacebookResponse post( string $endpoint, @@ -260,7 +260,7 @@ The associative array of params you want to send in the body of the POST request $response = $fb->post('/me/feed', ['message' => 'Foo message']); ~~~~ -## delete() {#delete} +## delete() ~~~~ public Facebook\FacebookResponse delete( string $endpoint, @@ -279,7 +279,7 @@ The arguments are the same as `post()` above. $response = $fb->delete('/{node-id}', ['object' => '1234']); ~~~~ -## request() {#request} +## request() ~~~~ public Facebook\FacebookRequest request( string $method, @@ -302,7 +302,7 @@ The HTTP request verb to use for this request. This can be set to any verb that $request = $fb->request('GET', '/{node-id}'); ~~~~ -## sendRequest() {#send-request} +## sendRequest() ~~~~ public Facebook\FacebookResponse sendRequest( string $method, @@ -320,7 +320,7 @@ Sends a request to the Graph API. $response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.6'); ~~~~ -## sendBatchRequest() {#send-batch-request} +## sendBatchRequest() ~~~~ public Facebook\FacebookBatchResponse sendBatchRequest( array $requests, @@ -349,7 +349,7 @@ $batchResponse = $fb->sendBatchRequest($requests); [See a full batch example](/docs/php/howto/example_batch_request). -## getRedirectLoginHelper() {#get-redirect-login-helper} +## getRedirectLoginHelper() ~~~~ public Facebook\Helpers\FacebookRedirectLoginHelper getRedirectLoginHelper() ~~~~ @@ -360,7 +360,7 @@ Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRed $helper = $fb->getRedirectLoginHelper(); ~~~~ -## getJavaScriptHelper() {#get-javascript-helper} +## getJavaScriptHelper() ~~~~ public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() ~~~~ @@ -371,7 +371,7 @@ Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaSc $helper = $fb->getJavaScriptHelper(); ~~~~ -## getCanvasHelper() {#get-canvas-helper} +## getCanvasHelper() ~~~~ public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() ~~~~ @@ -382,7 +382,7 @@ Returns a [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelp $helper = $fb->getCanvasHelper(); ~~~~ -## getPageTabHelper() {#get-page-tab-helper} +## getPageTabHelper() ~~~~ public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() ~~~~ @@ -393,7 +393,7 @@ Returns a [`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHe $helper = $fb->getPageTabHelper(); ~~~~ -## next() {#next} +## next() ~~~~ public Facebook\GraphNodes\GraphEdge|null next(Facebook\GraphNodes\GraphEdge $graphEdge) ~~~~ @@ -427,14 +427,14 @@ if (count($photosEdge) > 0) { } ~~~~ -## previous() {#previous} +## previous() ~~~~ 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() {#file-to-upload} +## fileToUpload() ~~~~ public Facebook\FileUpload\FacebookFile fileToUpload(string $pathToFile) ~~~~ @@ -460,7 +460,7 @@ $graphNode = $response->getGraphNode(); echo 'Photo ID: ' . $graphNode['id']; ~~~~ -## videoToUpload() {#video-to-upload} +## videoToUpload() ~~~~ public Facebook\FileUpload\FacebookVideo videoToUpload(string $pathToVideoFile) ~~~~ @@ -487,7 +487,7 @@ $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; ~~~~ -## uploadVideo() {#upload-video} +## uploadVideo() ~~~~ public array videoToUpload( string $target, diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index e2c2d4b88..97b6c983f 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -7,7 +7,7 @@ In order to make requests to the Graph API, you need to [create a Facebook app]( type: 'warning', }) -## Facebook\FacebookApp {#overview} +## Facebook\FacebookApp To instantiate a new `Facebook\FacebookApp` entity, pass the app ID and app secret to the constructor. @@ -24,27 +24,27 @@ $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 {#instance-methods} +## Instance Methods -## getAccessToken() {#get-access-token} +## getAccessToken() ~~~~ public Facebook\Authentication\AccessToken getAccessToken() ~~~~ Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessToken) entity. -## getId() {#get-id} +## getId() ~~~~ public string getId() ~~~~ Returns the app id. -## getSecret() {#get-secret} +## getSecret() ~~~~ public string getSecret() ~~~~ Returns the app secret. -## Serialization {#serialization} +## Serialization The `Facebook\FacebookApp` entity can be serialized and unserialized. diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index 7855cb33e..72328c188 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -2,7 +2,7 @@ Represents a batch request that will be sent to the Graph API. -## Facebook\FacebookBatchRequest {#overview} +## Facebook\FacebookBatchRequest You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor. @@ -54,11 +54,11 @@ foreach ($batchResponse as $key => $response) { } ~~~~ -## Instance Methods {#instance-methods} +## Instance Methods Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. -### add() {#add} +### add() ~~~~ public add( array|Facebook\FacebookBatchRequest $request, @@ -69,13 +69,13 @@ Adds a request to be sent in the batch request. The `$request` can be a single [ The `$name` argument is optional and is used to identify the request in the batch. -### getRequests() {#get-requests} +### getRequests() ~~~~ public array getRequests() ~~~~ Returns the array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent in the batch request. -## Array Access {#array-access} +## Array Access Since `Facebook\FacebookBatchRequest` implements `\IteratorAggregate` and `\ArrayAccess`, the requests can be accessed via array syntax and can also be iterated over. diff --git a/docs/reference/FacebookBatchResponse.md b/docs/reference/FacebookBatchResponse.md index ede1e6083..f91d1bbf6 100644 --- a/docs/reference/FacebookBatchResponse.md +++ b/docs/reference/FacebookBatchResponse.md @@ -2,7 +2,7 @@ Represents a batch response returned from the Graph API. -## Facebook\FacebookBatchResponse {#overview} +## Facebook\FacebookBatchResponse After sending a batch request to the Graph API, the response will be returned in the form of a `Facebook\FacebookBatchResponse` entity. @@ -41,17 +41,17 @@ var_dump($batchResponse); // class Facebook\FacebookBatchResponse . . . ~~~~ -## Instance Methods {#instance-methods} +## Instance Methods Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. -### getResponses() {#get-responses} +### getResponses() ~~~~ public array getResponses() ~~~~ Returns the array of [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entities that were returned from Graph. -## Array Access {#array-access} +## Array Access Since `Facebook\FacebookBatchResponse` implements `\IteratorAggregate` and `\ArrayAccess`, the responses can be accessed via array syntax and can also be iterated over. diff --git a/docs/reference/FacebookCanvasHelper.md b/docs/reference/FacebookCanvasHelper.md index 4fb31cf49..50c0fc66d 100644 --- a/docs/reference/FacebookCanvasHelper.md +++ b/docs/reference/FacebookCanvasHelper.md @@ -6,7 +6,7 @@ The `FacebookCanvasHelper` is used to obtain an access token or signed request w Facebook\Helpers\FacebookCanvasHelper( Facebook\FacebookApp $facebookApp ) ~~~ -## Usage {#usage} +## 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. @@ -44,7 +44,7 @@ if (isset($accessToken)) { The `$accessToken` will be `null` if the signed request did not contain any OAuth 2.0 data to obtain the access token. -## Instance Methods {#instance-methods} +## Instance Methods ### __construct() {#construct} ~~~~ diff --git a/docs/reference/FacebookClient.md b/docs/reference/FacebookClient.md index 0b5e84472..342d49c86 100644 --- a/docs/reference/FacebookClient.md +++ b/docs/reference/FacebookClient.md @@ -2,7 +2,7 @@ The `Facebook\FacebookClient` service class juggles the dependencies needed to make requests to the Graph API. -## Facebook\FacebookClient {#overview} +## 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`. @@ -23,27 +23,27 @@ The Graph API has a number of different base URL's based on what request you wan 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 {#instance-methods} +## Instance Methods -### getHttpClientHandler() {#get-http-client-handler} +### getHttpClientHandler() ~~~~ public Facebook\HttpClients\FacebookHttpClientInterface getHttpClientHandler() ~~~~ Returns the instance of [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface) that the service is using. -### setHttpClientHandler() {#set-http-client-handler} +### setHttpClientHandler() ~~~~ public setHttpClientHandler(Facebook\HttpClients\FacebookHttpClientInterface $client) ~~~~ If you've coded your own HTTP client to the [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface), you can inject it into the service using this method. -### enableBetaMode() {#enable-beta-mode} +### enableBetaMode() ~~~~ 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() {#send-request} +### sendRequest() ~~~~ public Facebook\FacebookResponse sendRequest(Facebook\FacebookRequest $request) ~~~~ @@ -57,7 +57,7 @@ If there was an error processing the request before sending, a [`Facebook\Except If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) will be thrown. -### sendBatchRequest() {#send-batch-request} +### sendBatchRequest() ~~~~ public Facebook\FacebookBatchResponse sendBatchRequest(Facebook\FacebookBatchRequest $batchRequest) ~~~~ diff --git a/docs/reference/FacebookFile.md b/docs/reference/FacebookFile.md index a785443a6..761849414 100644 --- a/docs/reference/FacebookFile.md +++ b/docs/reference/FacebookFile.md @@ -2,7 +2,7 @@ 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) {#overview} +## 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. @@ -24,7 +24,7 @@ $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 {#usage} +## Usage The following example uploads a photo for a user. diff --git a/docs/reference/FacebookJavaScriptHelper.md b/docs/reference/FacebookJavaScriptHelper.md index 00fbe1fdf..799a4dad2 100644 --- a/docs/reference/FacebookJavaScriptHelper.md +++ b/docs/reference/FacebookJavaScriptHelper.md @@ -2,7 +2,7 @@ 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 {#usage} +## Usage This helper will handle validating and decode the signed request from the cookie set by the JavaScript SDK. @@ -40,7 +40,7 @@ if (isset($accessToken)) { 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 {#instance-methods} +## Instance Methods ### __construct() {#construct} ~~~~ diff --git a/docs/reference/FacebookPageTabHelper.md b/docs/reference/FacebookPageTabHelper.md index eb62cc870..2908a7e42 100644 --- a/docs/reference/FacebookPageTabHelper.md +++ b/docs/reference/FacebookPageTabHelper.md @@ -2,7 +2,7 @@ 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 {#usage} +## Usage The usage of the `FacebookPageTabHelper` is exactly the same as [`FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) with additional methods to obtain the `page` data from the signed request. @@ -38,21 +38,21 @@ if (isset($accessToken)) { } ~~~ -## Instance Methods {#instance-methods} +## Instance Methods -### getPageData() {#get-page-data} +### getPageData() ~~~ public string|null getPageData($key, $default = null) ~~~ Gets a value from the `page` property if present. -### isAdmin() {#is-admin} +### isAdmin() ~~~ public boolean isAdmin() ~~~ Returns `true` is the user has authenticated your app and is an admin of the parent page. -### getPageId() {#get-page-id} +### getPageId() ~~~ public string|null getPageId() ~~~ diff --git a/docs/reference/FacebookRedirectLoginHelper.md b/docs/reference/FacebookRedirectLoginHelper.md index 8e19f299a..3fbd4446f 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -2,7 +2,7 @@ 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 {#usage} +## 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. @@ -73,9 +73,9 @@ if (isset($accessToken)) { } ~~~ -## Instance Methods {#instance-methods} +## Instance Methods -### getLoginUrl() {#get-login-url} +### getLoginUrl() ~~~~ public string getLoginUrl(string $redirectUrl, array $scope = [], string $separator = '&') ~~~~ @@ -86,25 +86,25 @@ Generates an authorization URL to ask a user for access to their profile on beha - `$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() {#get-re-request-url} +### getReRequestUrl() ~~~~ 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() {#get-re-authentication-url} +### getReAuthenticationUrl() ~~~~ 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() {#get-logout-url} +### getLogoutUrl() ~~~~ 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() {#get-access-token} +### getAccessToken() ~~~~ public Facebook\Authentication\AccessToken|null getAccessToken(string $redirectUrl = null) ~~~~ @@ -115,7 +115,7 @@ If no authorization code could be found from the `code` param in the URL, this m #### 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 {#extensibility-points} +## 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. diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 80aa3c6e8..148791abf 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -2,7 +2,7 @@ Represents a request that will be sent to the Graph API. -## Facebook\FacebookRequest {#overview} +## Facebook\FacebookRequest You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. @@ -53,50 +53,50 @@ $graphNode = $response->getGraphNode(); echo 'User name: ' . $graphNode['name']; ~~~~ -## Instance Methods {#instance-methods} +## Instance Methods -### setAccessToken() {#set-access-token} +### setAccessToken() ~~~~ public setAccessToken(string|Facebook\AccessToken $accessToken) ~~~~ -### getAccessToken() {#get-access-token} +### getAccessToken() ~~~~ public string getAccessToken() ~~~~ Returns the access token to be used for the request in the form of a string. -### setApp() {#set-app} +### setApp() ~~~~ public setApp(Facebook\FacebookApp $app) ~~~~ Sets the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. -### getApp() {#get-app} +### getApp() ~~~~ public Facebook\FacebookApp getApp() ~~~~ Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. -### getAppSecretProof() {#get-app-secret-proof} +### getAppSecretProof() ~~~~ public string getAppSecretProof() ~~~~ Returns the [app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests/#appsecret_proof) to sign the request. -### setMethod() {#set-method} +### setMethod() ~~~~ public setMethod(string $method) ~~~~ Sets the HTTP verb to use for the request. -### getMethod() {#get-method} +### getMethod() ~~~~ public string setMethod() ~~~~ Returns the HTTP verb to use for the request. -### setEndpoint() {#set-endpoint} +### setEndpoint() ~~~~ public setEndpoint(string $endpoint) ~~~~ @@ -106,13 +106,13 @@ Sets the Graph URL endpoint to be used with the request. The endpoint must be ex $request->setEndpoint('/me'); ~~~~ -### getEndpoint() {#get-endpoint} +### getEndpoint() ~~~~ public string getEndpoint() ~~~~ Returns the Graph URL endpoint to be used with the request. -### setHeaders() {#set-headers} +### setHeaders() ~~~~ public setHeaders(array $headers) ~~~~ @@ -124,19 +124,19 @@ $request->setHeaders([ ]); ~~~~ -### getHeaders() {#get-headers} +### getHeaders() ~~~~ public array getHeaders() ~~~~ Returns the request headers that will be sent with the request. The eTag headers `If-None-Match` are appended automatically. -### setETag() {#set-etag} +### setETag() ~~~~ public setETag(string $eTag) ~~~~ Sets the eTag that will be using for matching the `If-None-Match` header. -### setParams() {#set-params} +### setParams() ~~~~ public setParams(array $params) ~~~~ @@ -152,19 +152,19 @@ $request->setParams([ 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() {#get-params} +### getParams() ~~~~ 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() {#get-graph-version} +### getGraphVersion() ~~~~ public string getGraphVersion() ~~~~ Returns the Graph version prefix to be used with the request. -### getUrl() {#get-url} +### getUrl() ~~~~ public string getUrl() ~~~~ diff --git a/docs/reference/FacebookResponse.md b/docs/reference/FacebookResponse.md index 339e22760..c52577675 100644 --- a/docs/reference/FacebookResponse.md +++ b/docs/reference/FacebookResponse.md @@ -2,7 +2,7 @@ Represents a response from the Graph API. -## Facebook\FacebookResponse {#overview} +## Facebook\FacebookResponse After sending a request to the Graph API, the response will be returned in the form of a `Facebook\FacebookResponse` entity. @@ -28,117 +28,117 @@ var_dump($response); // class Facebook\FacebookResponse . . . ~~~~ -## Instance Methods {#instance-methods} +## Instance Methods -### getRequest() {#get-request} +### getRequest() ~~~~ public Facebook\FacebookRequest getRequest() ~~~~ Returns the original [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. -### getAccessToken() {#get-access-token} +### getAccessToken() ~~~~ public string getAccessToken() ~~~~ Returns the access token that was used for the original request in the form of a string. -### getApp() {#get-app} +### getApp() ~~~~ public Facebook\FacebookApp getApp() ~~~~ Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. -### getHttpStatusCode() {#get-http-status-code} +### getHttpStatusCode() ~~~~ public int getHttpStatusCode() ~~~~ Returns the HTTP response code for this response. -### getHeaders() {#get-headers} +### getHeaders() ~~~~ public array getHeaders() ~~~~ Returns the response headers that were returned. -### getBody() {#get-body} +### getBody() ~~~~ public string getBody() ~~~~ Returns the raw, unparsed body of the response as a string. -### getDecodedBody() {#get-decoded-body} +### getDecodedBody() ~~~~ public array getDecodedBody() ~~~~ Returns the parsed body of the response as an array. -### getAppSecretProof() {#get-app-secret-proof} +### getAppSecretProof() ~~~~ 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() {#get-etag} +### getETag() ~~~~ 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() {#get-graph-version} +### getGraphVersion() ~~~~ 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() {#is-error} +### isError() ~~~~ 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() {#throw-exception} +### throwException() ~~~~ public throwException() ~~~~ Throws the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. -### getThrownException() {#get-thrown-exception} +### getThrownException() ~~~~ public Facebook\Exceptions\FacebookResponseException getThrownException() ~~~~ Returns the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. This is mainly useful for dealing with [responses to batch requests](/docs/php/FacebookBatchResponse). -### getGraphNode() {#get-graph-node} +### getGraphNode() ~~~~ public Facebook\GraphNodes\GraphNode getGraphNode() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode) collection. -### getGraphAlbum() {#get-graph-album} +### getGraphAlbum() ~~~~ public Facebook\GraphNodes\GraphAlbum getGraphAlbum() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) collection. -### getGraphPage() {#get-graph-page} +### getGraphPage() ~~~~ public Facebook\GraphNodes\GraphPage getGraphPage() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods) collection. -### getGraphSessionInfo() {#get-graph-session-info} +### getGraphSessionInfo() ~~~~ public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphNode#sessioninfo-instance-methods) collection. -### getGraphUser() {#get-graph-user} +### getGraphUser() ~~~~ public Facebook\GraphNodes\GraphUser getGraphUser() ~~~~ Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods) collection. -### getGraphEdge() {#get-graph-edge} +### getGraphEdge() ~~~~ public Facebook\GraphNodes\GraphEdge getGraphEdge( string|null $subclassName, diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md index fa529512e..d09369081 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -2,7 +2,7 @@ Represents an error response from the Graph API. -## Facebook\Exceptions\FacebookResponseException {#overview} +## 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. @@ -49,30 +49,30 @@ try { These exceptions are derived from the [error responses from the Graph API](/docs/graph-api/using-graph-api/#errors). -## Instance Methods {#instance-methods} +## Instance Methods `FacebookResponseException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. -### getHttpStatusCode {#gethttpstatus} +### getHttpStatusCode `getHttpStatusCode()` Returns the HTTP status code returned with this exception. -### getSubErrorCode {#getsuberrorcode} +### getSubErrorCode `getSubErrorCode()` Returns the numeric sub-error code returned from the Graph API. -### getErrorType {#geterrortype} +### getErrorType `getErrorType()` Returns the type of error as a string. -### getResponseData {#getresponsedata} +### getResponseData `getResponseData()` Returns the decoded response body used to create the exception as an array. -### getRawResponse {#getrawresponse} +### getRawResponse `getRawResponse()` Returns the raw response body used to create the exception as a string. -### getResponse {#getresponse} +### getResponse `getResponse()` Returns the `FacebookResponse` entity which represents the HTTP response. diff --git a/docs/reference/FacebookSDKException.md b/docs/reference/FacebookSDKException.md index f75a00cc4..683b3779c 100644 --- a/docs/reference/FacebookSDKException.md +++ b/docs/reference/FacebookSDKException.md @@ -2,12 +2,12 @@ Represents an exception thrown by the SDK. -## Facebook\Exceptions\FacebookSDKException {#overview} +## 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](/docs/php/FacebookResponseException). -## Instance Methods {#instance-methods} +## 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 index 479527515..af6cdadbb 100644 --- a/docs/reference/FacebookVideo.md +++ b/docs/reference/FacebookVideo.md @@ -2,7 +2,7 @@ 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) {#overview} +## 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. @@ -24,7 +24,7 @@ $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 {#usage} +## Usage In Graph v2.3, functionality was added to [upload video files in chunks](/docs/graph-api/video-uploads#resumable). The PHP SDK provides a handy API to easily upload video files in chunks via the [`uploadVideo()` method](/docs/php/Facebook#upload-video). diff --git a/docs/reference/GraphEdge.md b/docs/reference/GraphEdge.md index 5aaf373e5..a51f580d5 100644 --- a/docs/reference/GraphEdge.md +++ b/docs/reference/GraphEdge.md @@ -2,7 +2,7 @@ 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 {#overview} +## Facebook\GraphNodes\GraphEdge You can grab a `GraphEdge` from a response from Graph. @@ -19,7 +19,7 @@ foreach ($graphEdge as $graphNode) { } ~~~~ -## Pagination {#pagination} +## Pagination With the help of the `Facebook\Facebook` super service class, the `GraphEdge` collection can grab the next and previous sets of data. @@ -34,7 +34,7 @@ $previousPageOfAlbums = $fb->previous($previousOfAlbums); When the next or previous page returns no results, `$fb->next()` will return `null`. -## Deep Pagination {#deep-pagination} +## 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`. @@ -62,9 +62,9 @@ do { } while ($pageCount < $maxPages && $pagesEdge = $fb->next($pagesEdge)); ~~~~ -## Method Reference {#method-reference} +## Method Reference -### getMetaData() {#get-meta-data} +### getMetaData() ~~~~ public array getMetaData() ~~~~ @@ -75,7 +75,7 @@ Sometimes Graph will return additional data associated with an edge. You can acc $metaData = $graphEdge->getMetaData(); ~~~~ -### getNextCursor() {#get-next-cursor} +### getNextCursor() ~~~~ public string|null getNextCursor() ~~~~ @@ -87,7 +87,7 @@ $nextCursor = $graphEdge->getNextCursor(); // Returns: MMAyDDM5NjA0OTEyMDc0OTM= ~~~~ -### getPreviousCursor() {#get-previous-cursor} +### getPreviousCursor() ~~~~ public string|null getPreviousCursor() ~~~~ @@ -99,7 +99,7 @@ $previousCursor = $graphEdge->getPreviousCursor(); // Returns: ODOxMTUzMjQzNTg5zzU5 ~~~~ -### getTotalCount() {#get-total-count} +### getTotalCount() ~~~~ public int|null getTotalCount() ~~~~ diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 07670a445..61a8edc6f 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -2,7 +2,7 @@ A `Facebook\GraphNodes\GraphNode` is a collection that represents a node returned by the Graph API. -## Facebook\GraphNodes\GraphNode {#overview} +## Facebook\GraphNodes\GraphNode This base class has several subclasses: @@ -40,7 +40,7 @@ echo $graphNode->getField('country'); // From GraphNode echo $location->getCountry(); // From GraphLocation ~~~~ -## SPL Libraries {#spl} +## 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`. @@ -61,40 +61,40 @@ foreach ($graphNode as $key => $value) { $total = count($graphNode); ~~~~ -## GraphNode Instance Methods {#instance-methods} +## GraphNode Instance Methods -### asArray {#as-array} +### asArray `asArray()` Returns the raw representation (associative arrays, nested) of the node's underlying data. -### asJson {#as-json} +### asJson `asJson()` Returns the data as a JSON string. -### getField {#get-field} +### 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 {#get-field-names} +### getFieldNames `getFieldNames()` Returns an array with the names of all fields present on the graph node. -### map {#map} +### map `map(Closure $callback)` Provides a way to map over the data within the collection just like `array_map()`. -## GraphUser Instance Methods {#user-instance-methods} +## GraphUser Instance Methods The `GraphUser` collection represents a [User](https://developers.facebook.com/docs/graph-api/reference/user) Graph node. -### Auto-cast properties {#user-auto-casting} +### Auto-cast properties The following properties on the `GraphUser` collection will get automatically cast as `GraphNode` subtypes: @@ -118,71 +118,71 @@ The following properties on the `GraphUser` collection will get automatically ca All getter methods return `null` if the property does not exist on the node. -### getId() {#user-getid} +### getId() ~~~~ public string|null getId() ~~~~ Returns the `id` property for the user as a string if present. -### getName() {#user-getname} +### getName() ~~~~ public string|null getName() ~~~~ Returns the `name` property for the user as a string if present. -### getFirstName() {#user-getfirstname} +### getFirstName() ~~~~ public string|null getFirstName() ~~~~ Returns the `first_name` property for the user as a string if present. -### getMiddleName() {#user-getmiddlename} +### getMiddleName() ~~~~ public string|null getMiddleName() ~~~~ Returns the `middle_name` property for the user as a string if present. -### getLastName() {#user-getlastname} +### getLastName() ~~~~ public string|null getLastName() ~~~~ Returns the `last_name` property for the user as a string if present. -### getLink() {#user-getlink} +### getLink() ~~~~ public string|null getLink() ~~~~ Returns the `link` property for the user as a string if present. -### getBirthday() {#user-getbirthday} +### getBirthday() ~~~~ public \Facebook\GraphNodes\Birthday|null getBirthday() ~~~~ Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](/docs/php/Birthday) if present. -### getLocation() {#user-getlocation} +### getLocation() ~~~~ public Facebook\GraphNodes\GraphPage|null getLocation() ~~~~ Returns the `location` property for the user as a `Facebook\GraphNodes\GraphPage` if present. -### getHometown() {#user-gethometown} +### getHometown() ~~~~ public Facebook\GraphNodes\GraphPage|null getHometown() ~~~~ Returns the `hometown` property for the user as a `Facebook\GraphNodes\GraphPage` if present. -### getSignificantOther() {#user-getsignificantother} +### getSignificantOther() ~~~~ public Facebook\GraphNodes\GraphUser|null getHometown() ~~~~ Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. -## GraphPage Instance Methods {#page-instance-methods} +## GraphPage Instance Methods The `GraphPage` collection represents a [Page](https://developers.facebook.com/docs/graph-api/reference/page) Graph node. -### Auto-cast properties {#page-auto-casting} +### Auto-cast properties The following properties on the `GraphPage` collection will get automatically cast as `GraphNode` subtypes: @@ -206,59 +206,59 @@ The following properties on the `GraphPage` collection will get automatically ca All getter methods return `null` if the property does not exist on the node. -### getId() {#page-getid} +### getId() ~~~~ public string|null getId() ~~~~ Returns the `id` property for the page as a string if present. -### getName() {#page-getname} +### getName() ~~~~ public string|null getName() ~~~~ Returns the `name` property for the page as a string if present. -### getCategory() {#page-getcategory} +### getCategory() ~~~~ public string|null getCategory() ~~~~ Returns the `category` property for the page as a string if present. -### getBestPage() {#page-getbestpage} +### getBestPage() ~~~~ public Facebook\GraphNodes\GraphPage|null getBestPage() ~~~~ Returns the `best_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. -### getGlobalBrandParentPage() {#page-getglobalbrandparentpage} +### getGlobalBrandParentPage() ~~~~ public Facebook\GraphNodes\GraphPage|null getGlobalBrandParentPage() ~~~~ Returns the `global_brand_parent_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. -### getLocation() {#page-getlocation} +### getLocation() ~~~~ public Facebook\GraphNodes\GraphLocation|null getLocation() ~~~~ Returns the `location` property for the page as a `Facebook\GraphNodes\GraphLocation` if present. -### getAccessToken() {#page-getaccesstoken} +### getAccessToken() ~~~~ public string|null getAccessToken() ~~~~ Returns the `access_token` property for the page if present. (Only available in the `/me/accounts` context.) -### getPerms() {#page-getperms} +### getPerms() ~~~~ 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 {#album-instance-methods} +## GraphAlbum Instance Methods The `GraphAlbum` collection represents an [Album](https://developers.facebook.com/docs/graph-api/reference/album) Graph node. -### Auto-cast properties {#album-auto-casting} +### Auto-cast properties The following properties on the `GraphAlbum` collection will get automatically cast as `GraphNode` subtypes: @@ -278,340 +278,352 @@ The following properties on the `GraphAlbum` collection will get automatically c All getter methods return `null` if the property does not exist on the node. -### getId() {#album-getid} +### getId() ~~~~ public string|null getId() ~~~~ Returns the `id` property for the album as a string if present. -### getName() {#album-getname} +### getName() ~~~~ public string|null getName() ~~~~ Returns the `name` property for the album as a string if present. -### getCanUpload() {#album-getcanupload} +### getCanUpload() ~~~~ public boolean|null getCanUpload() ~~~~ Returns the `can_upload` property for the album as a boolean if present. -### getCount() {#album-getcount} +### getCount() ~~~~ public int|null getCount() ~~~~ Returns the `count` property for the album as an integer if present. -### getCoverPhoto() {#album-getcoverphoto} +### getCoverPhoto() ~~~~ public string|null getCoverPhoto() ~~~~ Returns the `cover_photo` property for the album as a string if present. -### getCreatedTime() {#album-getcreatedtime} +### getCreatedTime() ~~~~ public \DateTime|null getCreatedTime() ~~~~ Returns the `created_time` property for the album as a `\DateTime` if present. -### getUpdatedTime() {#album-getupdatedtime} +### getUpdatedTime() ~~~~ public \DateTime|null getUpdatedTime() ~~~~ Returns the `updated_time` property for the album as a `\DateTime` if present. -### getDescription() {#album-getdescription} +### getDescription() ~~~~ public string|null getDescription() ~~~~ Returns the `description` property for the album as a string if present. -### getFrom() {#album-getfrom} +### getFrom() ~~~~ public Facebook\GraphNodes\GraphUser|null getFrom() ~~~~ Returns the `from` property for the album as a `Facebook\GraphNodes\GraphUser` if present. -### getPlace() {#album-getplace} +### getPlace() ~~~~ public Facebook\GraphNodes\GraphPage|null getPlace() ~~~~ Returns the `place` property for the album as a `Facebook\GraphNodes\GraphPage` if present. -### getLink() {#album-getlink} +### getLink() ~~~~ public string|null getLink() ~~~~ Returns the `link` property for the album as a string if present. -### getLocation() {#album-getlocation} +### getLocation() ~~~~ public Facebook\GraphNodes\GraphNode|string|null getLocation() ~~~~ Returns the `location` property for the album as a `Facebook\GraphNodes\GraphNode` or string if present. -### getPrivacy() {#album-getprivacy} +### getPrivacy() ~~~~ public string|null getPrivacy() ~~~~ Returns the `privacy` property for the album as a string if present. -### getType() {#album-gettype} +### getType() ~~~~ 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 {#location-instance-methods} +## GraphLocation Instance Methods All getter methods return `null` if the property does not exist on the node. -### getStreet() {#location-getstreet} +### getStreet() ~~~~ public string|null getStreet() ~~~~ Returns the `street` property for the location as a string if present. -### getCity() {#location-getcity} +### getCity() ~~~~ public string|null getCity() ~~~~ Returns the `city` property for the location as a string if present. -### getCountry() {#location-getcountry} +### getCountry() ~~~~ public string|null getCountry() ~~~~ Returns the `country` property for the location as a string if present. -### getZip() {#location-getzip} +### getZip() ~~~~ public string|null getZip() ~~~~ Returns the `zip` property for the location as a string if present. -### getLatitude() {#location-getlatitude} +### getLatitude() ~~~~ public float|null getLatitude() ~~~~ Returns the `latitude` property for the location as a float if present. -### getLongitude() {#location-getlongitude} +### getLongitude() ~~~~ public float|null getLongitude() ~~~~ Returns the `longitude` property for the location as a float if present. -## GraphPicture Instance Methods {#picture-instance-methods} +## GraphPicture Instance Methods All getter methods return `null` if the property does not exist on the node. -### getUrl() {#picture-geturl} +### getUrl() ~~~~ public string|null getUrl() ~~~~ Returns the `url` property for the picture as a string if present. -## GraphAchievement Instance Methods {#achievement-instance-methods} +## GraphAchievement Instance Methods All getter methods return `null` if the property does not exist on the node. -### getId() {#achievement-getid} +### getId() ~~~~ public string|null getId() ~~~~ Returns the `id` property for the achievement as a string if present. -## GraphEvent Instance Methods {#event-instance-methods} +## GraphEvent Instance Methods All getter methods return `null` if the property does not exist on the node. -### getId() {#event-id} +### getId() ~~~~ public string|null getId() ~~~~ Returns the `id` property (The event ID) for the event as a string if present. -### getCover() {#event-cover} +### getCover() ~~~~ public GraphCoverPhoto|null getCover() ~~~~ Returns the `cover` property (Cover picture) for the event as a GraphCoverPhoto if present. -### getDescription() {#event-description} +### getDescription() ~~~~ public string|null getDescription() ~~~~ Returns the `description` property (Long-form description) for the event as a string if present. -### getEndTime() {#event-end_time} +### getEndTime() ~~~~ 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() {#event-is_date_only} +### getIsDateOnly() ~~~~ 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() {#event-name} +### getName() ~~~~ public string|null getName() ~~~~ Returns the `name` property (Event name) for the event as a string if present. -### getOwner() {#event-owner} +### getOwner() ~~~~ public GraphNode|null getOwner() ~~~~ Returns the `owner` property (The profile that created the event) for the event as a GraphNode if present. -### getParentGroup() {#event-parent_group} +### getParentGroup() ~~~~ public GraphGroup|null getParentGroup() ~~~~ Returns the `parent_group` property (The group the event belongs to) for the event as a GraphGroup if present. -### getPlace() {#event-place} +### getPlace() ~~~~ public GraphPage|null getPlace() ~~~~ Returns the `place` property (Event Place information) for the event as a GraphPage if present. -### getPrivacy() {#event-privacy} +### getPrivacy() ~~~~ public string|null getPrivacy() ~~~~ Returns the `privacy` property (Who can see the event) for the event as a string if present. -### getStartTime() {#event-start_time} +### getStartTime() ~~~~ public DateTime|null getStartTime() ~~~~ Returns the `start_time` property (Start time) for the event as a DateTime if present. -### getTicketUri() {#event-ticket_uri} +### getTicketUri() ~~~~ 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() {#event-timezone} +### getTimezone() ~~~~ public string|null getTimezone() ~~~~ Returns the `timezone` property (Timezone) for the event as a string if present. -### getUpdatedTime() {#event-updated_time} +### getUpdatedTime() ~~~~ public DateTime|null getUpdatedTime() ~~~~ Returns the `updated_time` property (Last update time) for the event as a DateTime if present. -### getPicture() {#event-picture} +### getPicture() ~~~~ public GraphPicture|null getPicture() ~~~~ Returns the `picture` property (Event picture) for the event as a GraphPicture if present. -### getAttendingCount() {#event-attending_count} +### getAttendingCount() ~~~~ public int|null getAttendingCount() ~~~~ Returns the `attending_count` property (Number of people attending the event) for the event as a int if present. -### getDeclinedCount() {#event-declined_count} +### getDeclinedCount() ~~~~ 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() {#event-maybe_count} +### getMaybeCount() ~~~~ 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() {#event-noreply_count} +### getNoreplyCount() ~~~~ 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() {#event-invited_count} +### getInvitedCount() ~~~~ 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 {#group-instance-methods} +## GraphGroup Instance Methods All getter methods return `null` if the field does not exist on the node. -### getId() {#group-id} +### getId() ~~~~ public string|null getId() ~~~~ Returns the `id` field (The Group ID) for the group as a string if present. -### getCover() {#group-cover} + +### getCover() ~~~~ public GraphCoverPhoto|null getCover() ~~~~ Returns the `cover` field (The cover photo of the Group) for the group as a GraphCoverPhoto if present. -### getDescription() {#group-description} + +### getDescription() ~~~~ public string|null getDescription() ~~~~ Returns the `description` field (A brief description of the Group) for the group as a string if present. -### getEmail() {#group-email} + +### getEmail() ~~~~ 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() {#group-icon} + +### getIcon() ~~~~ public string|null getIcon() ~~~~ Returns the `icon` field (The URL for the Group's icon) for the group as a string if present. -### getLink() {#group-link} + +### getLink() ~~~~ public string|null getLink() ~~~~ Returns the `link` field (The Group's website) for the group as a string if present. -### getName() {#group-name} + +### getName() ~~~~ public string|null getName() ~~~~ Returns the `name` field (The name of the Group) for the group as a string if present. -### getMemberRequestCount() {#group-member_request_count} + +### getMemberRequestCount() ~~~~ 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() {#group-owner} + +### getOwner() ~~~~ public GraphNode|null getOwner() ~~~~ Returns the `owner` field (The profile that created this Group) for the group as a GraphNode if present. -### getParent() {#group-parent} + +### getParent() ~~~~ 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() {#group-privacy} + +### getPrivacy() ~~~~ public string|null getPrivacy() ~~~~ Returns the `privacy` field (The privacy setting of the Group) for the group as a string if present. -### getUpdatedTime() {#group-updated_time} + +### getUpdatedTime() ~~~~ 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() {#group-venue} + +### getVenue() ~~~~ public GraphLocation|null getVenue() ~~~~ diff --git a/docs/reference/PersistentDataInterface.md b/docs/reference/PersistentDataInterface.md index d12712fc6..3ab89da46 100644 --- a/docs/reference/PersistentDataInterface.md +++ b/docs/reference/PersistentDataInterface.md @@ -2,7 +2,7 @@ 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 {#overview} +## 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. @@ -55,15 +55,15 @@ $myPersistentDataHandler = new MyLaravelPersistentDataHandler(); $helper = new FacebookRedirectLoginHelper($fbApp, $myPersistentDataHandler); ~~~~ -## Method Reference {#method-reference} +## Method Reference -### get() {#get} +### get() ~~~~ public mixed get(string $key) ~~~~ Returns a value from the persistent data store or `null` if the value does not exist. -### set() {#set} +### set() ~~~~ public void set(string $key, mixed $value) ~~~~ diff --git a/docs/reference/PseudoRandomStringGeneratorInterface.md b/docs/reference/PseudoRandomStringGeneratorInterface.md index b8a986680..1ead5647b 100644 --- a/docs/reference/PseudoRandomStringGeneratorInterface.md +++ b/docs/reference/PseudoRandomStringGeneratorInterface.md @@ -2,7 +2,7 @@ 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 {#overview} +## 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. @@ -50,9 +50,9 @@ $myPseudoRandomStringGenerator = new MyCustomPseudoRandomStringGenerator(); $helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStringGenerator); ~~~~ -## Method Reference {#method-reference} +## Method Reference -### getPseudoRandomString() {#get-pseudo-random-string} +### getPseudoRandomString() ~~~~ public string getPseudoRandomString(int $length) ~~~~ diff --git a/docs/reference/SignedRequest.md b/docs/reference/SignedRequest.md index d37e152b3..5b23f900a 100644 --- a/docs/reference/SignedRequest.md +++ b/docs/reference/SignedRequest.md @@ -2,7 +2,7 @@ The `Facebook\SignedRequest` entity represents a signed request. -## Facebook\SignedRequest {#overview} +## Facebook\SignedRequest [Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) 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. @@ -31,39 +31,39 @@ $helper = $fb->getPageTabHelper(); $signedRequest = $helper->getSignedRequest(); ~~~~ -## Instance Methods {#instance-methods} +## Instance Methods -### getRawSignedRequest() {#get-raw-signed-request} +### getRawSignedRequest() ~~~~ public string|null getRawSignedRequest() ~~~~ Returns the original raw encoded signed request in the form of a string. -### getPayload() {#get-payload} +### getPayload() ~~~~ 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() {#get} +### get() ~~~~ 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() {#get-user-id} +### getUserId() ~~~~ 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() {#has-oauth-data} +### hasOAuthData() ~~~~ public boolean hasOAuthData() ~~~~ Returns `true` if the payload data contains either an `oauth_token` or `code` field. Returns `false` if neither value exists. -### make() {#make} +### make() ~~~~ public string make(array $payload) ~~~~ diff --git a/docs/reference/UrlDetectionInterface.md b/docs/reference/UrlDetectionInterface.md index 6a2fe65e2..3f510b0e8 100644 --- a/docs/reference/UrlDetectionInterface.md +++ b/docs/reference/UrlDetectionInterface.md @@ -2,7 +2,7 @@ The URL detection interface allows you to overwrite the default URL detection logic by coding to the `Facebook\Url\UrlDetectionInterface`. -## Facebook\Url\UrlDetectionInterface {#overview} +## 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. @@ -42,9 +42,9 @@ $myUrlDetectionHandler = new MyLaravelUrlDetectionHandler(); $helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); ~~~~ -## Method Reference {#method-reference} +## Method Reference -### getCurrentUrl() {#get-current-url} +### getCurrentUrl() ~~~~ public string getCurrentUrl() ~~~~ From fed584bff9a781c63e71768f7a9ae8c585ba3a12 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 12:05:47 -0700 Subject: [PATCH 299/407] convert code blocks --- docs/examples/access_token_from_canvas.md | 4 +- docs/examples/access_token_from_javascript.md | 8 +- docs/examples/access_token_from_page_tab.md | 4 +- docs/examples/batch_request.md | 12 +- docs/examples/batch_upload.md | 4 +- docs/examples/facebook_login.md | 8 +- docs/examples/pagination_basic.md | 4 +- docs/examples/post_links.md | 4 +- docs/examples/retrieve_user_profile.md | 4 +- docs/examples/upload_photo.md | 4 +- docs/examples/upload_video.md | 8 +- docs/getting_started.md | 53 ++-- docs/reference/AccessToken.md | 28 +- docs/reference/Birthday.md | 12 +- docs/reference/Facebook.md | 192 +++++------ docs/reference/FacebookApp.md | 24 +- docs/reference/FacebookBatchRequest.md | 20 +- docs/reference/FacebookBatchResponse.md | 12 +- docs/reference/FacebookCanvasHelper.md | 56 ++-- docs/reference/FacebookClient.md | 28 +- docs/reference/FacebookFile.md | 16 +- docs/reference/FacebookJavaScriptHelper.md | 46 +-- docs/reference/FacebookPageTabHelper.md | 20 +- docs/reference/FacebookRedirectLoginHelper.md | 32 +- docs/reference/FacebookRequest.md | 88 ++--- docs/reference/FacebookResponse.md | 84 ++--- docs/reference/FacebookResponseException.md | 4 +- docs/reference/FacebookVideo.md | 16 +- docs/reference/GraphEdge.md | 48 +-- docs/reference/GraphNode.md | 300 +++++++++--------- docs/reference/PersistentDataInterface.md | 20 +- .../PseudoRandomStringGeneratorInterface.md | 16 +- docs/reference/SignedRequest.md | 36 +-- docs/reference/UrlDetectionInterface.md | 16 +- 34 files changed, 616 insertions(+), 615 deletions(-) diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index 42c4098d7..7081f6a9b 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from within the 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. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -38,4 +38,4 @@ 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 index 0dcfa3bfc..88603861f 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from the Facebo 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. -~~~~ +``` @@ -43,11 +43,11 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh -~~~~ +``` 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. -~~~~ +``` # /js-login.php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', @@ -83,4 +83,4 @@ $_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 index 97e094ac7..d3639f3b8 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from within the 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. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -44,4 +44,4 @@ 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 index 5d75f41a0..bec1bca3d 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -6,7 +6,7 @@ This example covers sending a batch request with the Facebook SDK for PHP. 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). -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -74,7 +74,7 @@ foreach ($responses as $key => $response) { echo "
\n\n"; } } -~~~~ +``` There five requests being made in this batch requests. @@ -86,13 +86,13 @@ There five requests being made in this batch requests. 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. @@ -105,7 +105,7 @@ It should also contain a response containing two photos from the user. 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. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -143,4 +143,4 @@ foreach ($responses as $key => $response) { echo "
\n\n"; } } -~~~~ +``` diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index 25f1b984e..9233c564d 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -8,7 +8,7 @@ The Graph API supports [file uploads in batch requests](https://developers.faceb The following example will upload two photos and one video. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -59,4 +59,4 @@ foreach ($responses as $key => $response) { echo "
\n\n"; } } -~~~~ +``` diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index df05994c3..4f14dd327 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -10,7 +10,7 @@ In this example, the PHP script that generates the login link is called `/login. ## /login.php -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -23,11 +23,11 @@ $permissions = ['email']; // Optional permissions $loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permissions); echo 'Log in with Facebook!'; -~~~~ +``` ## /fb-callback.php -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -98,4 +98,4 @@ $_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 index 9a8f91ee4..4b3a2e2f2 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -8,7 +8,7 @@ The Graph API supports [several methods to paginate over response data](https:// 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. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -41,4 +41,4 @@ $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 index 00315f260..f90e9f9a2 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -8,7 +8,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ ## Example -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -34,6 +34,6 @@ try { $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 index e03e6bec3..3126d627e 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -8,7 +8,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ ## Example -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -31,4 +31,4 @@ $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 index a34882cde..5c000c56a 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -8,7 +8,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ ## Example -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -34,6 +34,6 @@ try { $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 index dbe91cf85..96a29dca4 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -11,7 +11,7 @@ This example covers uploading & posting a video to a user's timeline with the Fa The following example will upload a video in chunks using the [resumable upload](/docs/graph-api/video-uploads#resumable) feature added in Graph v2.3. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -36,13 +36,13 @@ try { } echo 'Video ID: ' . $response['video_id']; -~~~~ +``` See more about the [`uploadVideo()` method](/docs/php/Facebook#upload-video). For versions of Graph before v2.3, videos had to be uploaded in one request. -~~~~ +``` $fb = new Facebook\Facebook([/* . . . */]); $data = [ @@ -66,4 +66,4 @@ try { $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; -~~~~ +``` diff --git a/docs/getting_started.md b/docs/getting_started.md index 223c992fb..6c37ba88b 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -22,22 +22,23 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta [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/php-sdk-v4 -~~~ + %FB(devsite:markdown-wiki:info-card { content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", type: 'info', }) +``` 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. -~~~ +``` require_once __DIR__ . '/vendor/autoload.php'; -~~~ +``` ## Manually installing (if you really have to) @@ -52,9 +53,9 @@ First, download the source code and unzip it wherever you like in your project. Then include the autoloader provided in the SDK at the top of your script. -~~~ +``` require_once __DIR__ . '/path/to/facebook-php-sdk-v4/src/Facebook/autoload.php'; -~~~ +``` The autoloader should be able to auto-detect the proper location of the source code. @@ -76,16 +77,16 @@ The path the the core SDK files should now be located in `/var/html/facebook-sdk 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. -~~~ +``` 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. -~~~ +``` define('FACEBOOK_SDK_V4_SRC_DIR', __DIR__ . '/facebook-sdk-v5/'); require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; -~~~ +``` ## Configuration and setup @@ -96,13 +97,13 @@ require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; Before we can send requests to the Graph API, we need to load our app configuration into the `Facebook\Facebook` service. -~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', 'default_graph_version' => 'v2.6', ]); -~~~ +``` 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](/apps). @@ -129,7 +130,7 @@ For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper type: 'info', }) -~~~ +``` # login.php $fb = new Facebook\Facebook([/* . . . */]); @@ -138,14 +139,14 @@ $permissions = ['email', 'user_likes']; // optional $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions); echo 'Log in with Facebook!'; -~~~ +``` %FB(devsite:markdown-wiki:info-card { content: "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.", type: 'warning', }) -~~~ +``` # login-callback.php $fb = new Facebook\Facebook([/* . . . */]); @@ -169,7 +170,7 @@ if (isset($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 @@ -181,7 +182,7 @@ If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebo type: 'warning', }) -~~~ +``` # example-canvas-app.php $fb = new Facebook\Facebook([/* . . . */]); @@ -201,7 +202,7 @@ try { if (isset($accessToken)) { // Logged in. } -~~~ +``` %FB(devsite:markdown-wiki:info-card { content: "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`](/docs/php/FacebookPageTabHelper)", @@ -213,7 +214,7 @@ if (isset($accessToken)) { 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](/docs/php/FacebookJavaScriptHelper). The `getAccessToken()` method will return an [`AccessToken`](/docs/php/AccessToken) entity. -~~~ +``` # example-obtain-from-js-cookie-app.php $fb = new Facebook\Facebook([/* . . . */]); @@ -233,7 +234,7 @@ try { if (isset($accessToken)) { // Logged in } -~~~ +``` %FB(devsite:markdown-wiki:info-card { content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](/docs/javascript/reference/FB.init). 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.", @@ -246,13 +247,13 @@ When a user first logs into your app, the access token your app receives will be To extend an access token, you can make use of the [`OAuth2Client`](/docs/php/OAuth2Client). -~~~ +``` // 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](/docs/facebook-login/access-tokens#extending). @@ -262,7 +263,7 @@ Once you have an instance of the `Facebook\Facebook` service and obtained an acc 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](/docs/graph-api/reference/user) that references the user or Page making the request. -~~~ +``` $fb = new Facebook\Facebook([/* . . . */]); // Sets the default fallback access token so we don't have to pass it to each request @@ -282,7 +283,7 @@ try { } echo 'Logged in as ' . $userNode->getName(); -~~~ +``` The `get()` method will return a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) which is an entity that represents an HTTP response from the Graph API. @@ -290,7 +291,7 @@ To get the response in the form of a nifty collection, we call `getGraphUser()` 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. -~~~ +``` try { $response = $fb->get('/me'); } catch(Facebook\Exceptions\FacebookSDKException $e) { @@ -299,6 +300,6 @@ try { } $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](/docs/php/reference). diff --git a/docs/reference/AccessToken.md b/docs/reference/AccessToken.md index 396750886..6d7ffa063 100644 --- a/docs/reference/AccessToken.md +++ b/docs/reference/AccessToken.md @@ -7,41 +7,41 @@ Requests to the Graph API need to have an access token sent with them to identif 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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 @@ -50,7 +50,7 @@ If you already have an access token in the form of a string (from a session or d You can optionally pass an expiration date in the form of timestamp as the second argument. -~~~~ +``` $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 index 090c572d9..abbeda400 100644 --- a/docs/reference/Birthday.md +++ b/docs/reference/Birthday.md @@ -16,7 +16,7 @@ The `Facebook\GraphNodes\Birthday` entity extends `DateTime` so `format` may be Usage: -~~~~ +``` $fb = new Facebook\Facebook(\* *\); // Returns a `Facebook\FacebookResponse` object $response = $fb->get('/me'); @@ -38,18 +38,18 @@ var_dump($birthday->hasYear()); var_dump($birthday->format('m/d')); // 03/21 -~~~~ +``` ## Instance Methods ### hasDate() -~~~~ +``` public boolean hasDate() -~~~~ +``` Returns whether or not the birthday object contains the day and month of birth. ### hasYear() -~~~~ +``` 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 index 129d422b4..8fb6df5e8 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -6,18 +6,18 @@ The Facebook SDK for PHP is made up of many components. The `Facebook\Facebook` To instantiate a new `Facebook\Facebook` service, pass an array of configuration options to the constructor. -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', 'default_graph_version' => 'v2.6', // . . . ]); -~~~~ +``` Usage: -~~~~ +``` // Send a GET request $response = $fb->get('/me'); @@ -26,15 +26,15 @@ $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. -~~~~ +``` $res = $fb->get('/me', '{access-token}'); $res = $fb->post('/me/feed', ['foo' => 'bar'], '{access-token}'); $res = $fb->delete('/{node-id}', '{access-token}'); -~~~~ +``` ## Configuration options @@ -42,7 +42,7 @@ Although the `Facebook\Facebook` service tries to make the SDK as easy as possib Full configuration options list: -~~~~ +``` $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -54,7 +54,7 @@ $fb = new Facebook\Facebook([ 'url_detection_handler' => new MyUrlDetectionHandler(), 'pseudo_random_string_generator' => new MyPseudoRandomStringGenerator(), ]); -~~~~ +``` ### `app_id` The ID of your Facebook app (required). @@ -80,11 +80,11 @@ If you wish to use Guzzle, you can set this value to `guzzle`, but it requires t If you wish to write your own HTTP client, you can code your HTTP client to the `[Facebook\HttpClients\FacebookHttpClientInterface](/docs/php/FacebookHttpClientInterface)` and set this value to an instance of your custom client. -~~~~ +``` $fb = new Facebook([ 'http_client_handler' => new MyCustomHttpClient(), ]); -~~~~ +``` If any other value is provided an `InvalidArgumentException` will be thrown. @@ -95,11 +95,11 @@ By default, the SDK will try to use the native PHP session for the persistent da If you wish to write your own persistent data handler, you can code your persistent data handler to the `[Facebook\PersistentData\PersistentDataInterface](/docs/php/PersistentDataInterface)` and set the value of `persistent_data_handler` to an instance of your custom handler. -~~~~ +``` $fb = new Facebook([ 'persistent_data_handler' => new MyCustomPersistentDataHandler(), ]); -~~~~ +``` If any other value is provided an `InvalidArgumentException` will be thrown. @@ -108,11 +108,11 @@ 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](/docs/php/UrlDetectionInterface)` and set the value of `url_detection_handler` to an instance of your custom URL detector. -~~~~ +``` $fb = new Facebook([ 'url_detection_handler' => new MyUrlDetectionHandler(), ]); -~~~~ +``` If any other value is provided an `InvalidArgumentException` will be thrown. @@ -123,19 +123,19 @@ Generating random strings in PHP is easy but generating _cryptographically secur 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`. -~~~~ +``` $fb = new Facebook([ 'pseudo_random_string_generator' => 'openssl', ]); -~~~~ +``` You can write your own CSPRSG that implements the `[Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface](/docs/php/PseudoRandomStringGeneratorInterface)` and set the value of `pseudo_random_string_generator` to an instance of your custom generator. -~~~~ +``` $fb = new Facebook([ 'pseudo_random_string_generator' => new MyPseudoRandomStringGenerator(), ]); -~~~~ +``` If any other value is provided an `InvalidArgumentException` will be thrown. @@ -145,89 +145,89 @@ The only required configuration options are `app_id` and `app_secret`. However, 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. -~~~~ +``` $fb = new Facebook\Facebook(); -~~~~ +``` # Instance Methods ## getApp() -~~~~ +``` public FacebookApp getApp() -~~~~ +``` Returns the instance of `Facebook\FacebookApp` for the instantiated service. ## getClient() -~~~~ +``` public Facebook\FacebookClient getClient() -~~~~ +``` Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) for the instantiated service. ## getOAuth2Client() -~~~~ +``` public Facebook\Authentication\OAuth2Client getOAuth2Client() -~~~~ +``` Returns an instance of [`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client). ## getLastResponse() -~~~~ +``` 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() -~~~~ +``` public Facebook\Url\UrlDetectionInterface getUrlDetectionHandler() -~~~~ +``` Returns an instance of [`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface). ## getDefaultAccessToken() -~~~~ +``` public Facebook\Authentication\AccessToken|null getDefaultAccessToken() -~~~~ +``` Returns the default fallback [`AccessToken`](/docs/php/AccessToken) 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() -~~~~ +``` 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`](/docs/php/AccessToken). -~~~~ +``` $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() -~~~~ +``` 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() -~~~~ +``` 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). -~~~ +``` $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. @@ -239,7 +239,7 @@ The access token (as a string or `AccessToken` entity) to use for the request. I This will overwrite the Graph version that was set in the `default_graph_version` configuration option. ## post() -~~~~ +``` public Facebook\FacebookResponse post( string $endpoint, array $params, @@ -247,7 +247,7 @@ public Facebook\FacebookResponse post( string|null $eTag, string|null $graphVersion ) -~~~~ +``` Sends a POST request to Graph and returns a `Facebook\FacebookResponse`. @@ -256,12 +256,12 @@ 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. -~~~~ +``` $response = $fb->post('/me/feed', ['message' => 'Foo message']); -~~~~ +``` ## delete() -~~~~ +``` public Facebook\FacebookResponse delete( string $endpoint, array $params, @@ -269,18 +269,18 @@ public Facebook\FacebookResponse delete( 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. -~~~~ +``` $response = $fb->delete('/{node-id}', ['object' => '1234']); -~~~~ +``` ## request() -~~~~ +``` public Facebook\FacebookRequest request( string $method, string $endpoint, @@ -289,7 +289,7 @@ public Facebook\FacebookRequest request( 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). @@ -298,12 +298,12 @@ 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. -~~~~ +``` $request = $fb->request('GET', '/{node-id}'); -~~~~ +``` ## sendRequest() -~~~~ +``` public Facebook\FacebookResponse sendRequest( string $method, string $endpoint, @@ -312,22 +312,22 @@ public Facebook\FacebookResponse sendRequest( string|null $eTag, string|null $graphVersion ) -~~~~ +``` Sends a request to the Graph API. -~~~~ +``` $response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.6'); -~~~~ +``` ## sendBatchRequest() -~~~~ +``` 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. @@ -338,69 +338,69 @@ An array of `Facebook\FacebookRequest` entities. This can be a numeric or associ 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](/docs/graph-api/making-multiple-requests/#operations). -~~~~ +``` $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](/docs/php/howto/example_batch_request). ## getRedirectLoginHelper() -~~~~ +``` public Facebook\Helpers\FacebookRedirectLoginHelper getRedirectLoginHelper() -~~~~ +``` Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) which is used to generate a "Login with Facebook" link and obtain an access token from a redirect. -~~~~ +``` $helper = $fb->getRedirectLoginHelper(); -~~~~ +``` ## getJavaScriptHelper() -~~~~ +``` public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() -~~~~ +``` Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) which is used to access the signed request stored in the cookie set by the SDK for JavaScript. -~~~~ +``` $helper = $fb->getJavaScriptHelper(); -~~~~ +``` ## getCanvasHelper() -~~~~ +``` public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() -~~~~ +``` Returns a [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) which is used to access the signed request that is `POST`ed to canvas apps. -~~~~ +``` $helper = $fb->getCanvasHelper(); -~~~~ +``` ## getPageTabHelper() -~~~~ +``` public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() -~~~~ +``` Returns a [`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper) 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. -~~~~ +``` $helper = $fb->getPageTabHelper(); -~~~~ +``` ## next() -~~~~ +``` public Facebook\GraphNodes\GraphEdge|null next(Facebook\GraphNodes\GraphEdge $graphEdge) -~~~~ +``` Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. If the next page returns no results, `null` will be returned. -~~~~ +``` // Iterate over 5 pages max $maxPages = 5; @@ -425,23 +425,23 @@ if (count($photosEdge) > 0) { $pageCount++; } while ($pageCount < $maxPages && $photosEdge = $fb->next($photosEdge)); } -~~~~ +``` ## previous() -~~~~ +``` 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() -~~~~ +``` 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. -~~~~ +``` // Upload a photo for a user $data = [ 'message' => 'A neat photo upload example. Neat.', @@ -458,16 +458,16 @@ try { $graphNode = $response->getGraphNode(); echo 'Photo ID: ' . $graphNode['id']; -~~~~ +``` ## videoToUpload() -~~~~ +``` 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. -~~~~ +``` // Upload a video for a user $data = [ 'title' => 'My awesome video', @@ -485,10 +485,10 @@ try { $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; -~~~~ +``` ## uploadVideo() -~~~~ +``` public array videoToUpload( string $target, string $pathToFile, @@ -497,7 +497,7 @@ public array videoToUpload( int $maxTransferTries = 5, string $graphVersion = null ) -~~~~ +``` Functionality to [upload video files in chunks](/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. @@ -527,7 +527,7 @@ The array that is returned will contain two keys; `video_id` with the ID of the ### Example -~~~~ +``` // Upload a video for a user (chunked) $data = [ 'title' => 'My awesome video', @@ -542,4 +542,4 @@ try { } echo 'Video ID: ' . $response['video_id']; -~~~~ +``` diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index 97b6c983f..d639b7013 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -11,44 +11,44 @@ In order to make requests to the Graph API, you need to [create a Facebook app]( To instantiate a new `Facebook\FacebookApp` entity, pass the app ID and app secret to the constructor. -~~~~ +``` $fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); -~~~~ +``` Alternatively you can obtain the `Facebook\FacebookApp` entity from the [`Facebook\Facebook`](/docs/php/Facebook) super service class. -~~~~ +``` $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() -~~~~ +``` public Facebook\Authentication\AccessToken getAccessToken() -~~~~ +``` Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessToken) entity. ## getId() -~~~~ +``` public string getId() -~~~~ +``` Returns the app id. ## getSecret() -~~~~ +``` public string getSecret() -~~~~ +``` Returns the app secret. ## Serialization The `Facebook\FacebookApp` entity can be serialized and unserialized. -~~~~ +``` $fbApp = new Facebook\FacebookApp('foo-app-id', 'foo-app-secret'); $serializedFacebookApp = serialize($fbApp); @@ -57,4 +57,4 @@ $serializedFacebookApp = serialize($fbApp); $unserializedFacebookApp = unserialize($serializedFacebookApp); echo $unserializedFacebookApp->getAccessToken(); // foo-app-id|foo-app-secret -~~~~ +``` diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index 72328c188..5677eb35f 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -6,7 +6,7 @@ Represents a batch request that will be sent to the Graph API. You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor. -~~~~ +``` use Facebook\FacebookBatchRequest; $request = new FacebookBatchRequest( @@ -15,7 +15,7 @@ $request = new FacebookBatchRequest( string|null $accessToken, string|null $graphVersion ); -~~~~ +``` The `$requests` array is an array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent as a batch request. @@ -23,7 +23,7 @@ The `FacebookBatchRequest` entity does not actually make any calls to the Graph Usage: -~~~~ +``` $fb = new Facebook\Facebook(/* . . . */); $requests = [ @@ -52,34 +52,34 @@ foreach ($batchResponse as $key => $response) { // Success } } -~~~~ +``` ## Instance Methods Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. ### add() -~~~~ +``` 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`](/docs/php/FacebookRequest) or an array of `Facebook\FacebookRequest`'s. The `$name` argument is optional and is used to identify the request in the batch. ### getRequests() -~~~~ +``` public array getRequests() -~~~~ +``` Returns the array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) 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. -~~~~ +``` $fb = new Facebook\Facebook(/* . . . */); $requests = [ 'foo' => $fb->request('GET', '/me'), @@ -94,4 +94,4 @@ array(2) { 'request' => class Facebook\FacebookRequest . . . */ -~~~~ +``` diff --git a/docs/reference/FacebookBatchResponse.md b/docs/reference/FacebookBatchResponse.md index f91d1bbf6..c6836da1c 100644 --- a/docs/reference/FacebookBatchResponse.md +++ b/docs/reference/FacebookBatchResponse.md @@ -8,7 +8,7 @@ After sending a batch request to the Graph API, the response will be returned in Usage: -~~~~ +``` $fb = new Facebook\Facebook(/* . . . */); $requests = [ $fb->request('GET', '/me'), @@ -39,23 +39,23 @@ foreach ($batchResponse as $key => $response) { var_dump($batchResponse); // class Facebook\FacebookBatchResponse . . . -~~~~ +``` ## Instance Methods Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. ### getResponses() -~~~~ +``` public array getResponses() -~~~~ +``` Returns the array of [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) 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. -~~~~ +``` $requests = [ 'foo' => $fb->request('GET', '/me'), 'bar' => $fb->request('POST', '/me/feed', [/* */]), @@ -73,4 +73,4 @@ foreach ($batchResponse as $key => $response) { var_dump($batchResponse['foo']); // class Facebook\FacebookResponse . . . -~~~~ +``` diff --git a/docs/reference/FacebookCanvasHelper.md b/docs/reference/FacebookCanvasHelper.md index 50c0fc66d..ae6f42c4f 100644 --- a/docs/reference/FacebookCanvasHelper.md +++ b/docs/reference/FacebookCanvasHelper.md @@ -2,15 +2,15 @@ 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). -~~~ +``` 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. -~~~ +``` $fb = new Facebook\Facebook([/* */]); $canvasHelper = $fb->getCanvasHelper(); $signedRequest = $canvasHelper->getSignedRequest(); @@ -19,11 +19,11 @@ if ($signedRequest) { $payload = $signedRequest->getPayload(); var_dump($payload); } -~~~ +``` If a user has already authenticated your app, you can also obtain an access token. -~~~ +``` $fb = new Facebook\Facebook([/* */]); $canvasHelper = $fb->getCanvasHelper(); @@ -40,41 +40,41 @@ try { 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() {#construct} -~~~~ +### __construct() +``` 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() {#get-access-token} -~~~ +### getAccessToken() +``` public Facebook\AccessToken|null getAccessToken() -~~~ +``` Checks the signed request for authentication data and tries to obtain an access token access token. -### getUserId() {#get-user-id} -~~~ +### getUserId() +``` 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. -~~~ +``` $userId = $canvasHelper->getUserId(); if ($userId) { // User is logged in } -~~~ +``` This is equivalent to accessing the user ID from the signed request entity. -~~~ +``` $signedRequest = $canvasHelper->getSignedRequest(); if ($signedRequest) { @@ -82,22 +82,22 @@ if ($signedRequest) { // OR $userId = $signedRequest->get('user_id'); } -~~~ +``` -### getAppData() {#get-app-data} -~~~ +### getAppData() +``` public string|null getAppData() -~~~ +``` Gets the value that is set in the `app_data` property if present. -### getSignedRequest() {#get-signed-request} -~~~ +### getSignedRequest() +``` public Facebook\SignedRequest|null getSignedRequest() -~~~ +``` Returns the signed request as an instance of [`Facebook\SignedRequest`](/docs/php/SignedRequest) if present. -### getRawSignedRequest() {#get-raw-signed-request} -~~~ +### getRawSignedRequest() +``` 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 index 342d49c86..5b084abe2 100644 --- a/docs/reference/FacebookClient.md +++ b/docs/reference/FacebookClient.md @@ -8,16 +8,16 @@ You most likely won't be working with the `Facebook\FacebookClient` service dire You can grab an instance of a `Facebook\FacebookClient` service, from the `Facebook\Facebook` super service class. -~~~~ +``` $fb = new Facebook\Facebook([/* */]); $fbClient = $fb->getClient(); -~~~~ +``` Alternatively you could instantiate a new `Facebook\FacebookClient` service directly. -~~~~ +``` $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). @@ -26,27 +26,27 @@ The `Facebook\FacebookClient` service takes the guess-work out of managing those ## Instance Methods ### getHttpClientHandler() -~~~~ +``` public Facebook\HttpClients\FacebookHttpClientInterface getHttpClientHandler() -~~~~ +``` Returns the instance of [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface) that the service is using. ### setHttpClientHandler() -~~~~ +``` public setHttpClientHandler(Facebook\HttpClients\FacebookHttpClientInterface $client) -~~~~ +``` If you've coded your own HTTP client to the [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface), you can inject it into the service using this method. ### enableBetaMode() -~~~~ +``` 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() -~~~~ +``` public Facebook\FacebookResponse sendRequest(Facebook\FacebookRequest $request) -~~~~ +``` Sends a non-batch request to Graph. Takes a [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. @@ -58,9 +58,9 @@ If there was an error processing the request before sending, a [`Facebook\Except If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) will be thrown. ### sendBatchRequest() -~~~~ +``` public Facebook\FacebookBatchResponse sendBatchRequest(Facebook\FacebookBatchRequest $batchRequest) -~~~~ +``` Sends a batch request to Graph. Takes a [`Facebook\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. diff --git a/docs/reference/FacebookFile.md b/docs/reference/FacebookFile.md index 761849414..eb8f17fd7 100644 --- a/docs/reference/FacebookFile.md +++ b/docs/reference/FacebookFile.md @@ -8,19 +8,19 @@ The `FacebookFile` entity represents a local or remote file to be uploaded with There are two ways to instantiate a `FacebookFile` entity. One way is to instantiate it directly: -~~~~ +``` 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. -~~~~ +``` $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). @@ -28,7 +28,7 @@ Partial file uploads are possible using the `$maxLength` and `$offset` parameter The following example uploads a photo for a user. -~~~~ +``` $data = [ 'message' => 'My awesome photo upload example.', 'source' => $fb->fileToUpload('/path/to/photo.jpg'), @@ -46,11 +46,11 @@ try { $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. -~~~~ +``` // Upload a remote photo for a user without using the FacebookFile entity $data = [ 'message' => 'A neat photo upload example. Neat.', @@ -58,4 +58,4 @@ $data = [ ]; $response = $fb->post('/me/photos', $data); -~~~~ +``` diff --git a/docs/reference/FacebookJavaScriptHelper.md b/docs/reference/FacebookJavaScriptHelper.md index 799a4dad2..6b8ce7ad7 100644 --- a/docs/reference/FacebookJavaScriptHelper.md +++ b/docs/reference/FacebookJavaScriptHelper.md @@ -6,7 +6,7 @@ If you're using the [JavaScript SDK](https://developers.facebook.com/docs/javasc This helper will handle validating and decode the signed request from the cookie set by the JavaScript SDK. -~~~ +``` $fb = new Facebook\Facebook([/* */]); $jsHelper = $fb->getJavaScriptHelper(); $signedRequest = $jsHelper->getSignedRequest(); @@ -15,11 +15,11 @@ if ($signedRequest) { $payload = $signedRequest->getPayload(); var_dump($payload); } -~~~ +``` If a user has already authenticated your app, you can also obtain an access token. -~~~ +``` $fb = new Facebook\Facebook([/* */]); $jsHelper = $fb->getJavaScriptHelper(); @@ -36,41 +36,41 @@ try { 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() {#construct} -~~~~ +### __construct() +``` 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() {#get-access-token} -~~~ +### getAccessToken() +``` 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() {#get-user-id} -~~~ +### getUserId() +``` 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. -~~~ +``` $userId = $jsHelper->getUserId(); if ($userId) { // User is logged in } -~~~ +``` This is equivalent to accessing the user ID from the signed request entity. -~~~ +``` $signedRequest = $jsHelper->getSignedRequest(); if ($signedRequest) { @@ -78,16 +78,16 @@ if ($signedRequest) { // OR $userId = $signedRequest->get('user_id'); } -~~~ +``` -### getSignedRequest() {#get-signed-request} -~~~ +### getSignedRequest() +``` public Facebook\SignedRequest|null getSignedRequest() -~~~ +``` Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedRequest) entity if present. -### getRawSignedRequest() {#get-raw-signed-request} -~~~ +### getRawSignedRequest() +``` 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 index 2908a7e42..2c130d239 100644 --- a/docs/reference/FacebookPageTabHelper.md +++ b/docs/reference/FacebookPageTabHelper.md @@ -6,7 +6,7 @@ Page tabs are similar to the context to app canvases but are treated slightly di The usage of the `FacebookPageTabHelper` is exactly the same as [`FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) with additional methods to obtain the `page` data from the signed request. -~~~ +``` $fb = new Facebook\Facebook([/* */]); $pageHelper = $fb->getPageTabHelper(); $signedRequest = $pageHelper->getSignedRequest(); @@ -15,11 +15,11 @@ if ($signedRequest) { $payload = $signedRequest->getPayload(); var_dump($payload); } -~~~ +``` If a user has already authenticated your app, you can also obtain an access token. -~~~ +``` $fb = new Facebook\Facebook([/* */]); $pageHelper = $fb->getPageTabHelper(); @@ -36,24 +36,24 @@ try { if (isset($accessToken)) { // Logged in. } -~~~ +``` ## Instance Methods ### getPageData() -~~~ +``` public string|null getPageData($key, $default = null) -~~~ +``` Gets a value from the `page` property if present. ### isAdmin() -~~~ +``` public boolean isAdmin() -~~~ +``` Returns `true` is the user has authenticated your app and is an admin of the parent page. ### getPageId() -~~~ +``` 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 index 3fbd4446f..bebdf4d10 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -11,11 +11,11 @@ Facebook Login is achieved via OAuth 2.0. But you don't really have to know much You can obtain an instance of the `FacebookRedirectLoginHelper` from the `getRedirectLoginHelper()` method on the `Facebook\Facebook` service. -~~~ +``` $fb = new Facebook\Facebook([/* . . . */]); $helper = $fb->getRedirectLoginHelper(); -~~~ +``` ### Login with Facebook @@ -26,7 +26,7 @@ The basic login flow goes like this: 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. -~~~ +``` # login.php $fb = new Facebook\Facebook([/* . . . */]); @@ -35,7 +35,7 @@ $permissions = ['email', 'user_likes']; // optional $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions); echo 'Log in with Facebook!'; -~~~ +``` %FB(devsite:markdown-wiki:info-card { content: "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.", @@ -44,7 +44,7 @@ echo 'Log in with Facebook!'; Then, in your callback page (at the redirect url) when Facebook sends the user back: -~~~ +``` # login-callback.php $fb = new Facebook\Facebook([/* . . . */]); @@ -71,14 +71,14 @@ if (isset($accessToken)) { // The user denied the request exit; } -~~~ +``` ## Instance Methods ### getLoginUrl() -~~~~ +``` 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 @@ -87,27 +87,27 @@ Generates an authorization URL to ask a user for access to their profile on beha - `$separator` (_Optional_) The URL parameter separator. When working with XML documents, you can set this to `&` for example. ### getReRequestUrl() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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`. diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 148791abf..0d81458a6 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -6,7 +6,7 @@ Represents a request that will be sent to the Graph API. You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. -~~~~ +``` use Facebook\FacebookRequest; $request = new FacebookRequest( @@ -18,7 +18,7 @@ $request = new FacebookRequest( string $eTag, string $graphVersion ); -~~~~ +``` Alternatively, you can make use of the [`request()` factory provided by `Facebook\Facebook`](/docs/php/Facebook#request) to create new `FacebookRequest` instances. @@ -26,7 +26,7 @@ The `FacebookRequest` entity does not actually make any calls to the Graph API, Usage: -~~~~ +``` $fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); $request = new Facebook\FacebookRequest($fbApp, '{access-token}', 'GET', '/me'); @@ -51,129 +51,129 @@ try { $graphNode = $response->getGraphNode(); echo 'User name: ' . $graphNode['name']; -~~~~ +``` ## Instance Methods ### setAccessToken() -~~~~ +``` public setAccessToken(string|Facebook\AccessToken $accessToken) -~~~~ +``` ### getAccessToken() -~~~~ +``` public string getAccessToken() -~~~~ +``` Returns the access token to be used for the request in the form of a string. ### setApp() -~~~~ +``` public setApp(Facebook\FacebookApp $app) -~~~~ +``` Sets the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. ### getApp() -~~~~ +``` public Facebook\FacebookApp getApp() -~~~~ +``` Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. ### getAppSecretProof() -~~~~ +``` public string getAppSecretProof() -~~~~ +``` Returns the [app secret proof](https://developers.facebook.com/docs/graph-api/securing-requests/#appsecret_proof) to sign the request. ### setMethod() -~~~~ +``` public setMethod(string $method) -~~~~ +``` Sets the HTTP verb to use for the request. ### getMethod() -~~~~ +``` public string setMethod() -~~~~ +``` Returns the HTTP verb to use for the request. ### setEndpoint() -~~~~ +``` 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. -~~~~ +``` $request->setEndpoint('/me'); -~~~~ +``` ### getEndpoint() -~~~~ +``` public string getEndpoint() -~~~~ +``` Returns the Graph URL endpoint to be used with the request. ### setHeaders() -~~~~ +``` 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. -~~~~ +``` $request->setHeaders([ 'X-foo-header' => 'Something', ]); -~~~~ +``` ### getHeaders() -~~~~ +``` public array getHeaders() -~~~~ +``` Returns the request headers that will be sent with the request. The eTag headers `If-None-Match` are appended automatically. ### setETag() -~~~~ +``` public setETag(string $eTag) -~~~~ +``` Sets the eTag that will be using for matching the `If-None-Match` header. ### setParams() -~~~~ +``` public setParams(array $params) -~~~~ +``` For `GET` requests, the array of params will be converted to a query string and appended to the URL. -~~~~ +``` $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() -~~~~ +``` 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() -~~~~ +``` public string getGraphVersion() -~~~~ +``` Returns the Graph version prefix to be used with the request. ### getUrl() -~~~~ +``` 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`](/docs/php/FacebookClient). -~~~~ +``` $fb = new Facebook\Facebook(/* . . . */); $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); // /v2.6/me?fields=id,name&access_token=token&appsecret_proof=proof -~~~~ +``` diff --git a/docs/reference/FacebookResponse.md b/docs/reference/FacebookResponse.md index c52577675..48f89ad35 100644 --- a/docs/reference/FacebookResponse.md +++ b/docs/reference/FacebookResponse.md @@ -8,7 +8,7 @@ After sending a request to the Graph API, the response will be returned in the f Usage: -~~~~ +``` $fb = new Facebook\Facebook(/* . . . */); // Send the request to Graph @@ -26,124 +26,124 @@ try { var_dump($response); // class Facebook\FacebookResponse . . . -~~~~ +``` ## Instance Methods ### getRequest() -~~~~ +``` public Facebook\FacebookRequest getRequest() -~~~~ +``` Returns the original [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. ### getAccessToken() -~~~~ +``` public string getAccessToken() -~~~~ +``` Returns the access token that was used for the original request in the form of a string. ### getApp() -~~~~ +``` public Facebook\FacebookApp getApp() -~~~~ +``` Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. ### getHttpStatusCode() -~~~~ +``` public int getHttpStatusCode() -~~~~ +``` Returns the HTTP response code for this response. ### getHeaders() -~~~~ +``` public array getHeaders() -~~~~ +``` Returns the response headers that were returned. ### getBody() -~~~~ +``` public string getBody() -~~~~ +``` Returns the raw, unparsed body of the response as a string. ### getDecodedBody() -~~~~ +``` public array getDecodedBody() -~~~~ +``` Returns the parsed body of the response as an array. ### getAppSecretProof() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` public throwException() -~~~~ +``` Throws the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. ### getThrownException() -~~~~ +``` public Facebook\Exceptions\FacebookResponseException getThrownException() -~~~~ +``` Returns the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. This is mainly useful for dealing with [responses to batch requests](/docs/php/FacebookBatchResponse). ### getGraphNode() -~~~~ +``` public Facebook\GraphNodes\GraphNode getGraphNode() -~~~~ +``` Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode) collection. ### getGraphAlbum() -~~~~ +``` public Facebook\GraphNodes\GraphAlbum getGraphAlbum() -~~~~ +``` Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) collection. ### getGraphPage() -~~~~ +``` public Facebook\GraphNodes\GraphPage getGraphPage() -~~~~ +``` Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods) collection. ### getGraphSessionInfo() -~~~~ +``` public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() -~~~~ +``` Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphNode#sessioninfo-instance-methods) collection. ### getGraphUser() -~~~~ +``` public Facebook\GraphNodes\GraphUser getGraphUser() -~~~~ +``` Returns the response data in the form of a [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods) collection. ### getGraphEdge() -~~~~ +``` public Facebook\GraphNodes\GraphEdge getGraphEdge( string|null $subclassName, boolean $auto_prefix) -~~~~ +``` Returns the response data in the form of a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. `$subclassName` @@ -152,10 +152,10 @@ The `Facebook\GraphNodes\GraphNode` subclass to cast list items to. If none is p `$auto_prefix` Toggle to auto-prefix the subclass name. If none is provided, default is `true`. -~~~~ +``` $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 index d09369081..e5a483a8f 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -6,7 +6,7 @@ Represents an error response from the Graph API. 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. -~~~~ +``` try { // Some request to the Graph API } catch (Facebook\Exceptions\FacebookResponseException $e) { @@ -15,7 +15,7 @@ try { // Do some further processing on $previousException exit; } -~~~~ +``` %FB(devsite:markdown-wiki:table { columns: ['Class name','Description',], diff --git a/docs/reference/FacebookVideo.md b/docs/reference/FacebookVideo.md index af6cdadbb..6fe15e5c7 100644 --- a/docs/reference/FacebookVideo.md +++ b/docs/reference/FacebookVideo.md @@ -8,19 +8,19 @@ The `FacebookVideo` entity represents a local or remote video file to be uploade There are two ways to instantiate a `FacebookVideo` entity. One way is to instantiate it directly: -~~~~ +``` 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. -~~~~ +``` $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). @@ -28,7 +28,7 @@ Partial file uploads are possible using the `$maxLength` and `$offset` parameter In Graph v2.3, functionality was added to [upload video files in chunks](/docs/graph-api/video-uploads#resumable). The PHP SDK provides a handy API to easily upload video files in chunks via the [`uploadVideo()` method](/docs/php/Facebook#upload-video). -~~~~ +``` // Upload a video for a user (chunked) $data = [ 'title' => 'My awesome video', @@ -43,11 +43,11 @@ try { } echo 'Video ID: ' . $response['video_id']; -~~~~ +``` For versions of Graph before v2.3, videos had to be uploaded in one request. -~~~~ +``` // Upload a video for a user $data = [ 'title' => 'My awesome video', @@ -65,4 +65,4 @@ try { $graphNode = $response->getGraphNode(); echo 'Video ID: ' . $graphNode['id']; -~~~~ +``` diff --git a/docs/reference/GraphEdge.md b/docs/reference/GraphEdge.md index a51f580d5..80439dd33 100644 --- a/docs/reference/GraphEdge.md +++ b/docs/reference/GraphEdge.md @@ -6,31 +6,31 @@ When a list of nodes is returned from a Graph request, it can be cast as a `Grap You can grab a `GraphEdge` from a response from Graph. -~~~~ +``` $graphEdge = $request->getGraphEdge(); -~~~~ +``` Usage: -~~~~ +``` // 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. -~~~~ +``` $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`. @@ -40,7 +40,7 @@ Sometimes Graph will return a list of nodes within a node. Paginating on these s 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. -~~~~ +``` $pagesEdge = $response->getGraphEdge(); // Only grab 5 pages $maxPages = 5; @@ -60,55 +60,55 @@ do { } $pageCount++; } while ($pageCount < $maxPages && $pagesEdge = $fb->next($pagesEdge)); -~~~~ +``` ## Method Reference ### getMetaData() -~~~~ +``` public array getMetaData() -~~~~ +``` Sometimes Graph will return additional data associated with an edge. You can access this raw data as an array with `getMetaData()`. -~~~~ +``` $metaData = $graphEdge->getMetaData(); -~~~~ +``` ### getNextCursor() -~~~~ +``` 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. -~~~~ +``` $nextCursor = $graphEdge->getNextCursor(); // Returns: MMAyDDM5NjA0OTEyMDc0OTM= -~~~~ +``` ### getPreviousCursor() -~~~~ +``` public string|null getPreviousCursor() -~~~~ +``` Returns the `$.paging.cursors.before` value if it exists or `null` if it does not exist. -~~~~ +``` $previousCursor = $graphEdge->getPreviousCursor(); // Returns: ODOxMTUzMjQzNTg5zzU5 -~~~~ +``` ### getTotalCount() -~~~~ +``` 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. -~~~~ +``` $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 index 61a8edc6f..1c32dd37c 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -17,7 +17,7 @@ This base class has several subclasses: Usage: -~~~~ +``` $fb = new Facebook\Facebook(\* *\); // Returns a `Facebook\FacebookResponse` object $response = $fb->get('/something'); @@ -38,7 +38,7 @@ echo $user->getName(); // From GraphUser // Location example echo $graphNode->getField('country'); // From GraphNode echo $location->getCountry(); // From GraphLocation -~~~~ +``` ## SPL Libraries @@ -46,7 +46,7 @@ The `GraphNode` collection and its subclasses implement several [SPL](http://php All of the following operations are possible on a `GraphNode`. -~~~~ +``` $graphNode = $response->getGraphNode(); // Array access @@ -59,7 +59,7 @@ foreach ($graphNode as $key => $value) { // Counting $total = count($graphNode); -~~~~ +``` ## GraphNode Instance Methods @@ -119,63 +119,63 @@ The following properties on the `GraphUser` collection will get automatically ca All getter methods return `null` if the property does not exist on the node. ### getId() -~~~~ +``` public string|null getId() -~~~~ +``` Returns the `id` property for the user as a string if present. ### getName() -~~~~ +``` public string|null getName() -~~~~ +``` Returns the `name` property for the user as a string if present. ### getFirstName() -~~~~ +``` public string|null getFirstName() -~~~~ +``` Returns the `first_name` property for the user as a string if present. ### getMiddleName() -~~~~ +``` public string|null getMiddleName() -~~~~ +``` Returns the `middle_name` property for the user as a string if present. ### getLastName() -~~~~ +``` public string|null getLastName() -~~~~ +``` Returns the `last_name` property for the user as a string if present. ### getLink() -~~~~ +``` public string|null getLink() -~~~~ +``` Returns the `link` property for the user as a string if present. ### getBirthday() -~~~~ +``` public \Facebook\GraphNodes\Birthday|null getBirthday() -~~~~ +``` Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](/docs/php/Birthday) if present. ### getLocation() -~~~~ +``` public Facebook\GraphNodes\GraphPage|null getLocation() -~~~~ +``` Returns the `location` property for the user as a `Facebook\GraphNodes\GraphPage` if present. ### getHometown() -~~~~ +``` public Facebook\GraphNodes\GraphPage|null getHometown() -~~~~ +``` Returns the `hometown` property for the user as a `Facebook\GraphNodes\GraphPage` if present. ### getSignificantOther() -~~~~ +``` public Facebook\GraphNodes\GraphUser|null getHometown() -~~~~ +``` Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. ## GraphPage Instance Methods @@ -207,51 +207,51 @@ The following properties on the `GraphPage` collection will get automatically ca All getter methods return `null` if the property does not exist on the node. ### getId() -~~~~ +``` public string|null getId() -~~~~ +``` Returns the `id` property for the page as a string if present. ### getName() -~~~~ +``` public string|null getName() -~~~~ +``` Returns the `name` property for the page as a string if present. ### getCategory() -~~~~ +``` public string|null getCategory() -~~~~ +``` Returns the `category` property for the page as a string if present. ### getBestPage() -~~~~ +``` public Facebook\GraphNodes\GraphPage|null getBestPage() -~~~~ +``` Returns the `best_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. ### getGlobalBrandParentPage() -~~~~ +``` public Facebook\GraphNodes\GraphPage|null getGlobalBrandParentPage() -~~~~ +``` Returns the `global_brand_parent_page` property for the page as a `Facebook\GraphNodes\GraphPage` if present. ### getLocation() -~~~~ +``` public Facebook\GraphNodes\GraphLocation|null getLocation() -~~~~ +``` Returns the `location` property for the page as a `Facebook\GraphNodes\GraphLocation` if present. ### getAccessToken() -~~~~ +``` public string|null getAccessToken() -~~~~ +``` Returns the `access_token` property for the page if present. (Only available in the `/me/accounts` context.) ### getPerms() -~~~~ +``` 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 @@ -279,87 +279,87 @@ The following properties on the `GraphAlbum` collection will get automatically c All getter methods return `null` if the property does not exist on the node. ### getId() -~~~~ +``` public string|null getId() -~~~~ +``` Returns the `id` property for the album as a string if present. ### getName() -~~~~ +``` public string|null getName() -~~~~ +``` Returns the `name` property for the album as a string if present. ### getCanUpload() -~~~~ +``` public boolean|null getCanUpload() -~~~~ +``` Returns the `can_upload` property for the album as a boolean if present. ### getCount() -~~~~ +``` public int|null getCount() -~~~~ +``` Returns the `count` property for the album as an integer if present. ### getCoverPhoto() -~~~~ +``` public string|null getCoverPhoto() -~~~~ +``` Returns the `cover_photo` property for the album as a string if present. ### getCreatedTime() -~~~~ +``` public \DateTime|null getCreatedTime() -~~~~ +``` Returns the `created_time` property for the album as a `\DateTime` if present. ### getUpdatedTime() -~~~~ +``` public \DateTime|null getUpdatedTime() -~~~~ +``` Returns the `updated_time` property for the album as a `\DateTime` if present. ### getDescription() -~~~~ +``` public string|null getDescription() -~~~~ +``` Returns the `description` property for the album as a string if present. ### getFrom() -~~~~ +``` public Facebook\GraphNodes\GraphUser|null getFrom() -~~~~ +``` Returns the `from` property for the album as a `Facebook\GraphNodes\GraphUser` if present. ### getPlace() -~~~~ +``` public Facebook\GraphNodes\GraphPage|null getPlace() -~~~~ +``` Returns the `place` property for the album as a `Facebook\GraphNodes\GraphPage` if present. ### getLink() -~~~~ +``` public string|null getLink() -~~~~ +``` Returns the `link` property for the album as a string if present. ### getLocation() -~~~~ +``` public Facebook\GraphNodes\GraphNode|string|null getLocation() -~~~~ +``` Returns the `location` property for the album as a `Facebook\GraphNodes\GraphNode` or string if present. ### getPrivacy() -~~~~ +``` public string|null getPrivacy() -~~~~ +``` Returns the `privacy` property for the album as a string if present. ### getType() -~~~~ +``` 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 @@ -367,39 +367,39 @@ Returns the `type` property for the album as a string (`profile`, `mobile`, `wal All getter methods return `null` if the property does not exist on the node. ### getStreet() -~~~~ +``` public string|null getStreet() -~~~~ +``` Returns the `street` property for the location as a string if present. ### getCity() -~~~~ +``` public string|null getCity() -~~~~ +``` Returns the `city` property for the location as a string if present. ### getCountry() -~~~~ +``` public string|null getCountry() -~~~~ +``` Returns the `country` property for the location as a string if present. ### getZip() -~~~~ +``` public string|null getZip() -~~~~ +``` Returns the `zip` property for the location as a string if present. ### getLatitude() -~~~~ +``` public float|null getLatitude() -~~~~ +``` Returns the `latitude` property for the location as a float if present. ### getLongitude() -~~~~ +``` public float|null getLongitude() -~~~~ +``` Returns the `longitude` property for the location as a float if present. ## GraphPicture Instance Methods @@ -407,9 +407,9 @@ Returns the `longitude` property for the location as a float if present. All getter methods return `null` if the property does not exist on the node. ### getUrl() -~~~~ +``` public string|null getUrl() -~~~~ +``` Returns the `url` property for the picture as a string if present. ## GraphAchievement Instance Methods @@ -417,9 +417,9 @@ Returns the `url` property for the picture as a string if present. All getter methods return `null` if the property does not exist on the node. ### getId() -~~~~ +``` public string|null getId() -~~~~ +``` Returns the `id` property for the achievement as a string if present. ## GraphEvent Instance Methods @@ -428,123 +428,123 @@ All getter methods return `null` if the property does not exist on the node. ### getId() -~~~~ +``` public string|null getId() -~~~~ +``` Returns the `id` property (The event ID) for the event as a string if present. ### getCover() -~~~~ +``` public GraphCoverPhoto|null getCover() -~~~~ +``` Returns the `cover` property (Cover picture) for the event as a GraphCoverPhoto if present. ### getDescription() -~~~~ +``` public string|null getDescription() -~~~~ +``` Returns the `description` property (Long-form description) for the event as a string if present. ### getEndTime() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` public string|null getName() -~~~~ +``` Returns the `name` property (Event name) for the event as a string if present. ### getOwner() -~~~~ +``` public GraphNode|null getOwner() -~~~~ +``` Returns the `owner` property (The profile that created the event) for the event as a GraphNode if present. ### getParentGroup() -~~~~ +``` public GraphGroup|null getParentGroup() -~~~~ +``` Returns the `parent_group` property (The group the event belongs to) for the event as a GraphGroup if present. ### getPlace() -~~~~ +``` public GraphPage|null getPlace() -~~~~ +``` Returns the `place` property (Event Place information) for the event as a GraphPage if present. ### getPrivacy() -~~~~ +``` public string|null getPrivacy() -~~~~ +``` Returns the `privacy` property (Who can see the event) for the event as a string if present. ### getStartTime() -~~~~ +``` public DateTime|null getStartTime() -~~~~ +``` Returns the `start_time` property (Start time) for the event as a DateTime if present. ### getTicketUri() -~~~~ +``` 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() -~~~~ +``` public string|null getTimezone() -~~~~ +``` Returns the `timezone` property (Timezone) for the event as a string if present. ### getUpdatedTime() -~~~~ +``` public DateTime|null getUpdatedTime() -~~~~ +``` Returns the `updated_time` property (Last update time) for the event as a DateTime if present. ### getPicture() -~~~~ +``` public GraphPicture|null getPicture() -~~~~ +``` Returns the `picture` property (Event picture) for the event as a GraphPicture if present. ### getAttendingCount() -~~~~ +``` public int|null getAttendingCount() -~~~~ +``` Returns the `attending_count` property (Number of people attending the event) for the event as a int if present. ### getDeclinedCount() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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 @@ -552,79 +552,79 @@ Returns the `invited_count` property (Number of people invited to the event) for All getter methods return `null` if the field does not exist on the node. ### getId() -~~~~ +``` public string|null getId() -~~~~ +``` Returns the `id` field (The Group ID) for the group as a string if present. ### getCover() -~~~~ +``` public GraphCoverPhoto|null getCover() -~~~~ +``` Returns the `cover` field (The cover photo of the Group) for the group as a GraphCoverPhoto if present. ### getDescription() -~~~~ +``` public string|null getDescription() -~~~~ +``` Returns the `description` field (A brief description of the Group) for the group as a string if present. ### getEmail() -~~~~ +``` 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() -~~~~ +``` public string|null getIcon() -~~~~ +``` Returns the `icon` field (The URL for the Group's icon) for the group as a string if present. ### getLink() -~~~~ +``` public string|null getLink() -~~~~ +``` Returns the `link` field (The Group's website) for the group as a string if present. ### getName() -~~~~ +``` public string|null getName() -~~~~ +``` Returns the `name` field (The name of the Group) for the group as a string if present. ### getMemberRequestCount() -~~~~ +``` 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() -~~~~ +``` public GraphNode|null getOwner() -~~~~ +``` Returns the `owner` field (The profile that created this Group) for the group as a GraphNode if present. ### getParent() -~~~~ +``` 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() -~~~~ +``` public string|null getPrivacy() -~~~~ +``` Returns the `privacy` field (The privacy setting of the Group) for the group as a string if present. ### getUpdatedTime() -~~~~ +``` 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() -~~~~ +``` 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 index 3ab89da46..d9bd57de9 100644 --- a/docs/reference/PersistentDataInterface.md +++ b/docs/reference/PersistentDataInterface.md @@ -8,7 +8,7 @@ If you're using a web framework that handles persistent data for you, you might For example if you are using Laravel, a custom handler might look like this: -~~~~ +``` use Facebook\PersistentData\PersistentDataInterface; class MyLaravelPersistentDataHandler implements PersistentDataInterface @@ -34,37 +34,37 @@ class MyLaravelPersistentDataHandler implements PersistentDataInterface \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. -~~~~ +``` $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. -~~~~ +``` use Facebook\Helpers\FacebookRedirectLoginHelper; $myPersistentDataHandler = new MyLaravelPersistentDataHandler(); $helper = new FacebookRedirectLoginHelper($fbApp, $myPersistentDataHandler); -~~~~ +``` ## Method Reference ### get() -~~~~ +``` public mixed get(string $key) -~~~~ +``` Returns a value from the persistent data store or `null` if the value does not exist. ### set() -~~~~ +``` 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 index 1ead5647b..9e4acffd3 100644 --- a/docs/reference/PseudoRandomStringGeneratorInterface.md +++ b/docs/reference/PseudoRandomStringGeneratorInterface.md @@ -12,7 +12,7 @@ If your hosting environment does not support any of the CSPRSG methods used by t An example of implementing a custom CSPRSG: -~~~~ +``` use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; class MyCustomPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface @@ -29,31 +29,31 @@ class MyCustomPseudoRandomStringGenerator implements PseudoRandomStringGenerator 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. -~~~~ +``` $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. -~~~~ +``` use Facebook\Helpers\FacebookRedirectLoginHelper; $myPseudoRandomStringGenerator = new MyCustomPseudoRandomStringGenerator(); $helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStringGenerator); -~~~~ +``` ## Method Reference ### getPseudoRandomString() -~~~~ +``` 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 index 5b23f900a..aeab355ba 100644 --- a/docs/reference/SignedRequest.md +++ b/docs/reference/SignedRequest.md @@ -8,14 +8,14 @@ The `Facebook\SignedRequest` entity represents a signed request. To instantiate a new `Facebook\SignedRequest` entity, pass the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity and raw signed request to the constructor. -~~~~ +``` $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](/docs/php/sdk_reference#helpers). -~~~~ +``` $fb = new Facebook\Facebook([/* . . . */]); // Obtain a signed request entity from the cookie set by the JavaScript SDK @@ -29,47 +29,47 @@ $signedRequest = $helper->getSignedRequest(); // Obtain a signed request entity from a page tab $helper = $fb->getPageTabHelper(); $signedRequest = $helper->getSignedRequest(); -~~~~ +``` ## Instance Methods ### getRawSignedRequest() -~~~~ +``` public string|null getRawSignedRequest() -~~~~ +``` Returns the original raw encoded signed request in the form of a string. ### getPayload() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` 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() -~~~~ +``` public boolean hasOAuthData() -~~~~ +``` Returns `true` if the payload data contains either an `oauth_token` or `code` field. Returns `false` if neither value exists. ### make() -~~~~ +``` 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. -~~~~ +``` $fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); $signedRequest = new Facebook\SignedRequest($fbApp); @@ -82,4 +82,4 @@ $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 index 3f510b0e8..3ff199530 100644 --- a/docs/reference/UrlDetectionInterface.md +++ b/docs/reference/UrlDetectionInterface.md @@ -8,7 +8,7 @@ If you're using a web framework that handles routes and URL generation for you, For example if you are using Laravel, a custom handler might look like this: -~~~~ +``` use Facebook\Url\UrlDetectionInterface; class MyLaravelUrlDetectionHandler implements UrlDetectionInterface @@ -21,31 +21,31 @@ class MyLaravelUrlDetectionHandler implements UrlDetectionInterface 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. -~~~~ +``` $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. -~~~~ +``` use Facebook\Helpers\FacebookRedirectLoginHelper; $myUrlDetectionHandler = new MyLaravelUrlDetectionHandler(); $helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); -~~~~ +``` ## Method Reference ### getCurrentUrl() -~~~~ +``` public string getCurrentUrl() -~~~~ +``` Returns the full and currently active URL. From 8da025bcec288e62aa3331bad9fb1e237c40609c Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 12:53:59 -0700 Subject: [PATCH 300/407] convert quote blocks --- docs/examples/batch_request.md | 6 +- docs/examples/upload_video.md | 6 +- docs/getting_started.md | 56 +++++++------------ docs/reference/FacebookApp.md | 6 +- docs/reference/FacebookRedirectLoginHelper.md | 6 +- 5 files changed, 27 insertions(+), 53 deletions(-) diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index bec1bca3d..e41697e9e 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -96,10 +96,8 @@ My next 2 events are House Warming Party,Some Foo Event. It should also contain a response containing two photos from the user. -%FB(devsite:markdown-wiki:info-card { - content: "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).", - type: 'warning', -}) +> content: "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).", +> type: 'warning', ## Multiple User Example diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index 96a29dca4..df6b00793 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -4,10 +4,8 @@ This example covers uploading & posting a video to a user's timeline with the Fa ## Example -%FB(devsite:markdown-wiki:info-card { - content: "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.", - type: 'warning', -}) +> content: "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.", +> type: 'warning', The following example will upload a video in chunks using the [resumable upload](/docs/graph-api/video-uploads#resumable) feature added in Graph v2.3. diff --git a/docs/getting_started.md b/docs/getting_started.md index 6c37ba88b..84ccbd7be 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -24,12 +24,10 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta ``` composer require facebook/php-sdk-v4 +``` - -%FB(devsite:markdown-wiki:info-card { - content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", - type: 'info', -}) +content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", +type: 'info', ``` 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. @@ -64,10 +62,8 @@ The autoloader should be able to auto-detect the proper location of the source c 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. -%FB(devsite:markdown-wiki:info-card { - content: "For this example we'll assume the root of your website is `/var/html`.", - type: 'info', -}) +> content: "For this example we'll assume the root of your website is `/var/html`.", +> type: 'info', After downloading the source code with the button above, extract the files in a temporary directory. @@ -90,10 +86,8 @@ require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; ## Configuration and setup -%FB(devsite:markdown-wiki:info-card { - content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](/apps).", - type: 'warning', -}) +> content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](/apps).", +> type: 'warning', Before we can send requests to the Graph API, we need to load our app configuration into the `Facebook\Facebook` service. @@ -107,10 +101,8 @@ $fb = new Facebook\Facebook([ 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](/apps). -%FB(devsite:markdown-wiki:info-card { - content: "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.", - type: 'warning', -}) +> content: "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.", +> type: 'warning', The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). @@ -125,10 +117,8 @@ Most all request made to the Graph API require an access token. We can obtain us For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) 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`](/docs/php/AccessToken) entity. -%FB(devsite:markdown-wiki:info-card { - content: "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.", - type: 'info', -}) +> content: "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.", +> type: 'info', ``` # login.php @@ -141,10 +131,8 @@ $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $pe echo 'Log in with Facebook!'; ``` -%FB(devsite:markdown-wiki:info-card { - content: "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.", - type: 'warning', -}) +> content: "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.", +> type: 'warning', ``` # login-callback.php @@ -177,10 +165,8 @@ if (isset($accessToken)) { If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) to get an [`AccessToken`](/docs/php/AccessToken) entity for the user. -%FB(devsite:markdown-wiki:info-card { - content: "The `FacebookCanvasHelper` will detect a [signed request](/docs/reference/login/signed-request) 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](#authentication-redirect) or by using the [SDK for JavaScript](/docs/javascript) and then use the SDK for PHP to [obtain the access token from the cookie](#authentication-javascript) the SDK for JavaScript set.", - type: 'warning', -}) +> content: "The `FacebookCanvasHelper` will detect a [signed request](/docs/reference/login/signed-request) 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](#authentication-redirect) or by using the [SDK for JavaScript](/docs/javascript) and then use the SDK for PHP to [obtain the access token from the cookie](#authentication-javascript) the SDK for JavaScript set.", +> type: 'warning', ``` # example-canvas-app.php @@ -204,10 +190,8 @@ if (isset($accessToken)) { } ``` -%FB(devsite:markdown-wiki:info-card { - content: "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`](/docs/php/FacebookPageTabHelper)", - type: 'info', -}) +> content: "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`](/docs/php/FacebookPageTabHelper)", +> type: 'info', ### Obtaining an access token from the SDK for JavaScript @@ -236,10 +220,8 @@ if (isset($accessToken)) { } ``` -%FB(devsite:markdown-wiki:info-card { - content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](/docs/javascript/reference/FB.init). 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.", - type: 'warning', -}) +> content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](/docs/javascript/reference/FB.init). 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.", +> type: 'warning', ## Extending the access token diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index d639b7013..049e50ba2 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -2,10 +2,8 @@ In order to make requests to the Graph API, you need to [create a Facebook app](/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. -%FB(devsite:markdown-wiki:info-card { - content: "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.", - type: 'warning', -}) +> content: "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.", +> type: 'warning', ## Facebook\FacebookApp diff --git a/docs/reference/FacebookRedirectLoginHelper.md b/docs/reference/FacebookRedirectLoginHelper.md index bebdf4d10..e8ae3b705 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -37,10 +37,8 @@ $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $pe echo 'Log in with Facebook!'; ``` -%FB(devsite:markdown-wiki:info-card { - content: "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.", - type: 'warning', -}) +> content: "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.", +> type: 'warning', Then, in your callback page (at the redirect url) when Facebook sends the user back: From acbbfcaddfcf29eb7bdb96afed28ff9692d2964a Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 13:22:55 -0700 Subject: [PATCH 301/407] convert table blocks --- docs/reference.md | 219 +++++--------------- docs/reference/FacebookResponseException.md | 37 +--- docs/reference/GraphNode.md | 62 ++---- 3 files changed, 74 insertions(+), 244 deletions(-) diff --git a/docs/reference.md b/docs/reference.md index dff139ab2..0e89a4fd4 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -6,206 +6,89 @@ Below is the API reference for the Facebook SDK for PHP. These classes are at the core of the Facebook SDK for PHP. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\Facebook`](/docs/php/Facebook)', - 'The main service object that helps tie all the SDK components together.', - ], - [ - '[`Facebook\\FacebookApp`](/docs/php/FacebookApp)', - 'An entity that represents a Facebook app and is required to send requests to Graph.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\Facebook`](/docs/php/Facebook) | The main service object that helps tie all the SDK components together. | +| `Facebook\\FacebookApp`](/docs/php/FacebookApp) | 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. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\Helpers\\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper)', - 'An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link.', - ], - [ - '[`Facebook\\Authentication\\AccessToken`](/docs/php/AccessToken)', - '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.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\Helpers\\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) | An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link. | +| [`Facebook\\Authentication\\AccessToken`](/docs/php/AccessToken) | 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. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\FacebookRequest`](/docs/php/FacebookRequest)', - 'An entity that represents an HTTP request to be sent to Graph.', - ], - [ - '[`Facebook\\FacebookResponse`](/docs/php/FacebookResponse)', - 'An entity that represents an HTTP response from Graph.', - ], - [ - '[`Facebook\\FacebookBatchRequest`](/docs/php/FacebookBatchRequest)', - 'An entity that represents an HTTP batch request to be sent to Graph.', - ], - [ - '[`Facebook\\FacebookBatchResponse`](/docs/php/FacebookBatchResponse)', - 'An entity that represents an HTTP response from Graph after sending a batch request.', - ], - [ - '[`Facebook\\FacebookClient`](/docs/php/FacebookClient)', - 'A service object that sends HTTP requests and receives HTTP responses to and from the Graph API.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\FacebookRequest`](/docs/php/FacebookRequest) | An entity that represents an HTTP request to be sent to Graph. | +| [`Facebook\\FacebookResponse`](/docs/php/FacebookResponse) | An entity that represents an HTTP response from Graph. | +| [`Facebook\\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) | An entity that represents an HTTP batch request to be sent to Graph. | +| [`Facebook\\FacebookBatchResponse`](/docs/php/FacebookBatchResponse) | An entity that represents an HTTP response from Graph after sending a batch request. | +| [`Facebook\\FacebookClient`](/docs/php/FacebookClient) | 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. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\Helpers\\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper)', - 'Used to obtain an access token or signed request from the cookie set by the JavaScript SDK.', - ], - [ - '[`Facebook\\Helpers\\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper)', - 'Used to obtain an access token or signed request from within the context of an app canvas.', - ], - [ - '[`Facebook\\Helpers\\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper)', - 'Used to obtain an access token or signed request from within the context of a page tab.', - ], - [ - '[`Facebook\\SignedRequest`](/docs/php/SignedRequest)', - 'An entity that represents a signed request.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\Helpers\\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) | Used to obtain an access token or signed request from the cookie set by the JavaScript SDK. | +| [`Facebook\\Helpers\\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) | Used to obtain an access token or signed request from within the context of an app canvas. | +| [`Facebook\\Helpers\\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper) | Used to obtain an access token or signed request from within the context of a page tab. | +| [`Facebook\\SignedRequest`](/docs/php/SignedRequest) | An entity that represents a signed request. | # Core Exceptions These are the core exceptions that the SDK will throw when an error occurs. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\Exceptions\\FacebookSDKException`](/docs/php/FacebookSDKException)', - 'The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error.', - ], - [ - '[`Facebook\\Exceptions\\FacebookResponseException`](/docs/php/FacebookResponseException)', - 'The base exception to all Graph error responses. This exception is never thrown directly.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\Exceptions\\FacebookSDKException`](/docs/php/FacebookSDKException) | The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error. | +| [`Facebook\\Exceptions\\FacebookResponseException`](/docs/php/FacebookResponseException) | 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. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\GraphNodes\\GraphNode`](/docs/php/GraphNode)', - 'The base collection object that represents a generic node.', - ], - [ - '[`Facebook\\GraphNodes\\GraphEdge`](/docs/php/GraphEdge)', - 'A collection of GraphNode\'s with special methods to help paginate over the edge.', - ], - [ - '[`Facebook\\GraphNodes\\GraphAchievement`](/docs/php/GraphNode#achievement-instance-methods)', - 'A collection that represents an Achievement node.', - ], - [ - '[`Facebook\\GraphNodes\\GraphAlbum`](/docs/php/GraphNode#album-instance-methods)', - 'A collection that represents an Album node.', - ], - [ - '[`Facebook\\GraphNodes\\GraphLocation`](/docs/php/GraphNode#location-instance-methods)', - 'A collection that represents a Location node.', - ], - [ - '[`Facebook\\GraphNodes\\GraphPage`](/docs/php/GraphNode#page-instance-methods)', - 'A collection that represents a Page node.', - ], - [ - '[`Facebook\\GraphNodes\\GraphPicture`](/docs/php/GraphNode#picture-instance-methods)', - 'A collection that represents a Picture node.', - ], - [ - '[`Facebook\\GraphNodes\\GraphUser`](/docs/php/GraphNode#user-instance-methods)', - 'A collection that represents a User node.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\GraphNodes\\GraphNode`](/docs/php/GraphNode) | The base collection object that represents a generic node. | +| [`Facebook\\GraphNodes\\GraphEdge`](/docs/php/GraphEdge) | A collection of GraphNode\'s with special methods to help paginate over the edge. | +| [`Facebook\\GraphNodes\\GraphAchievement`](/docs/php/GraphNode#achievement-instance-methods) | A collection that represents an Achievement node. | +| [`Facebook\\GraphNodes\\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) | A collection that represents an Album node. | +| [`Facebook\\GraphNodes\\GraphLocation`](/docs/php/GraphNode#location-instance-methods) | A collection that represents a Location node. | +| [`Facebook\\GraphNodes\\GraphPage`](/docs/php/GraphNode#page-instance-methods) | A collection that represents a Page node. | +| [`Facebook\\GraphNodes\\GraphPicture`](/docs/php/GraphNode#picture-instance-methods) | A collection that represents a Picture node. | +| [`Facebook\\GraphNodes\\GraphUser`](/docs/php/GraphNode#user-instance-methods) | A collection that represents a User node. | + # File Uploads These are entities that represent files to be uploaded with a Graph request. -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '[`Facebook\\FileUpload\\FacebookFile`](/docs/php/FacebookFile)', - 'Represents a generic file to be uploaded to the Graph API.', - ], - [ - '[`Facebook\\FileUpload\\FacebookVideo`](/docs/php/FacebookVideo)', - 'Represents a video file to be uploaded to the Graph API.', - ], - ], -}) +| Class name | Description | +| ------------- | ------------- | +| [`Facebook\\FileUpload\\FacebookFile`](/docs/php/FacebookFile)' | Represents a generic file to be uploaded to the Graph API. | +| [`Facebook\\FileUpload\\FacebookVideo`](/docs/php/FacebookVideo) | 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. -%FB(devsite:markdown-wiki:table { - columns: ['Interface name','Description',], - rows: [ - [ - '`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`](/docs/php/PersistentDataInterface)', - 'An interface to code your own persistent data storage implementation.', - ], - [ - '[`Facebook\\Url\\UrlDetectionInterface`](/docs/php/UrlDetectionInterface)', - 'An interface to code your own URL detection logic.', - ], - [ - '[`Facebook\\PseudoRandomString\\ PseudoRandomStringGeneratorInterface`](/docs/php/PseudoRandomStringGeneratorInterface)', - 'An interface to code your own cryptographically secure pseudo-random string generator.', - ], - ], -}) +| 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`](/docs/php/PersistentDataInterface) | An interface to code your own persistent data storage implementation. | +| [`Facebook\\Url\\UrlDetectionInterface`](/docs/php/UrlDetectionInterface) | An interface to code your own URL detection logic. | +| [`Facebook\\PseudoRandomString\\ PseudoRandomStringGeneratorInterface`](/docs/php/PseudoRandomStringGeneratorInterface) | An interface to code your own cryptographically secure pseudo-random string generator. | diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md index e5a483a8f..6b6163df2 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -17,35 +17,14 @@ try { } ``` -%FB(devsite:markdown-wiki:table { - columns: ['Class name','Description',], - rows: [ - [ - '`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.', - ], - ], -}) +| 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](/docs/graph-api/using-graph-api/#errors). diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 1c32dd37c..5174c14a4 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -98,23 +98,11 @@ The `GraphUser` collection represents a [User](https://developers.facebook.com/d The following properties on the `GraphUser` collection will get automatically cast as `GraphNode` subtypes: -%FB(devsite:markdown-wiki:table { - columns: ['Property','GraphNode subtype',], - rows: [ - [ - '`hometown`', - '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', - ], - [ - '`location`', - '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', - ], - [ - '`significant_other`', - '[`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods)', - ], - ], -}) +| Property | GraphNode subtype | +| ------------- | ------------- | +| `hometown` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | +| `location` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | +| `significant_other` | [`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods) | All getter methods return `null` if the property does not exist on the node. @@ -186,23 +174,12 @@ The `GraphPage` collection represents a [Page](https://developers.facebook.com/d The following properties on the `GraphPage` collection will get automatically cast as `GraphNode` subtypes: -%FB(devsite:markdown-wiki:table { - columns: ['Property','GraphNode subtype',], - rows: [ - [ - '`best_page`', - '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', - ], - [ - '`global_brand_parent_page`', - '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', - ], - [ - '`location`', - '[`Facebook\\GraphNodes\\GraphLocation`](#location-instance-methods)', - ], - ], -}) +| Property | GraphNode subtype | +| ------------- | ------------- | +| `best_page` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | +| `global_brand_parent_page` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | +| `location` | [`Facebook\\GraphNodes\\GraphLocation`](#location-instance-methods) | + All getter methods return `null` if the property does not exist on the node. @@ -262,19 +239,10 @@ The `GraphAlbum` collection represents an [Album](https://developers.facebook.co The following properties on the `GraphAlbum` collection will get automatically cast as `GraphNode` subtypes: -%FB(devsite:markdown-wiki:table { - columns: ['Property','GraphNode subtype',], - rows: [ - [ - '`from`', - '[`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods)', - ], - [ - '`place`', - '[`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods)', - ], - ], -}) +| Property | GraphNode subtype | +| ------------- | ------------- | +| `from` | [`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods) | +| `place` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | All getter methods return `null` if the property does not exist on the node. From d599b09f675a5a623c754eb35c78aad14c9881ea Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 13:26:05 -0700 Subject: [PATCH 302/407] update graph API version --- docs/examples/access_token_from_canvas.md | 2 +- docs/examples/access_token_from_javascript.md | 4 ++-- docs/examples/access_token_from_page_tab.md | 2 +- docs/examples/batch_request.md | 4 ++-- docs/examples/batch_upload.md | 2 +- docs/examples/facebook_login.md | 4 ++-- docs/examples/pagination_basic.md | 2 +- docs/examples/post_links.md | 2 +- docs/examples/retrieve_user_profile.md | 2 +- docs/examples/upload_photo.md | 2 +- docs/examples/upload_video.md | 2 +- docs/getting_started.md | 2 +- docs/reference/Facebook.md | 8 ++++---- docs/reference/FacebookRequest.md | 2 +- 14 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index 7081f6a9b..0f1ff043f 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -10,7 +10,7 @@ A signed request will be sent to your app via the HTTP POST method within the co $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $helper = $fb->getCanvasHelper(); diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index 88603861f..77eaf39b4 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -29,7 +29,7 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh FB.init({ appId: 'your-app-id', cookie: true, // This is important, it's not enabled by default - version: 'v2.6' + version: 'v2.8' }); }; @@ -52,7 +52,7 @@ After the user successfully logs in, redirect the user (or make an AJAX request) $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $helper = $fb->getJavaScriptHelper(); diff --git a/docs/examples/access_token_from_page_tab.md b/docs/examples/access_token_from_page_tab.md index d3639f3b8..5094bf470 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -10,7 +10,7 @@ Page tabs behave much like the app canvas. The PHP SDK provides a helper for pag $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $helper = $fb->getPageTabHelper(); diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index e41697e9e..0e85085f2 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -10,7 +10,7 @@ The following example assumes we have the following permissions granted from the $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); // Since all the requests will be sent on behalf of the same user, @@ -107,7 +107,7 @@ Since the requests sent in a batch are unrelated by default, we can make request $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $batch = [ diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index 9233c564d..1320eb986 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -12,7 +12,7 @@ The following example will upload two photos and one video. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); // Since all the requests will be sent on behalf of the same user, diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index 4f14dd327..ff63bc4b0 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -14,7 +14,7 @@ In this example, the PHP script that generates the login link is called `/login. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $helper = $fb->getRedirectLoginHelper(); @@ -31,7 +31,7 @@ echo 'Log in with Facebook!'; $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $helper = $fb->getRedirectLoginHelper(); diff --git a/docs/examples/pagination_basic.md b/docs/examples/pagination_basic.md index 4b3a2e2f2..514512d15 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -12,7 +12,7 @@ In this example we'll pull five entries from a user's feed (assuming the user ap $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); try { diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index f90e9f9a2..373637623 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $linkData = [ diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md index 3126d627e..749a086e0 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); try { diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index 5c000c56a..dc4295c06 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](/docs/php/ $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $data = [ diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index df6b00793..6ec9bf1e7 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -13,7 +13,7 @@ The following example will upload a video in chunks using the [resumable upload] $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); $data = [ diff --git a/docs/getting_started.md b/docs/getting_started.md index 84ccbd7be..0005c8ae2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -95,7 +95,7 @@ Before we can send requests to the Graph API, we need to load our app configurat $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', ]); ``` diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md index 8fb6df5e8..71c1055da 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -10,7 +10,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', // . . . ]); ``` @@ -48,7 +48,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.6', + 'default_graph_version' => 'v2.8', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), @@ -69,7 +69,7 @@ The default fallback access token to use if one is not explicitly provided. The Enable [beta mode](/docs/support/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.6`. Defaults to the [latest version of Graph](/docs/apps/changelog). +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.8`. Defaults to the [latest version of Graph](/docs/apps/changelog). ### `http_client_handler` Allows you to overwrite the default HTTP client. @@ -317,7 +317,7 @@ public Facebook\FacebookResponse sendRequest( Sends a request to the Graph API. ``` -$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.6'); +$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.8'); ``` ## sendBatchRequest() diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 0d81458a6..7a0b53720 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -175,5 +175,5 @@ $fb = new Facebook\Facebook(/* . . . */); $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); -// /v2.6/me?fields=id,name&access_token=token&appsecret_proof=proof +// /v2.8/me?fields=id,name&access_token=token&appsecret_proof=proof ``` From 3606f3444a3e1a84346cef5e6acffc240da51678 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 13:31:22 -0700 Subject: [PATCH 303/407] fix typos --- docs/reference.md | 4 ++-- docs/reference/GraphNode.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/reference.md b/docs/reference.md index 0e89a4fd4..e8d3b819e 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -9,7 +9,7 @@ These classes are at the core of the Facebook SDK for PHP. | Class name | Description | | ------------- | ------------- | | [`Facebook\\Facebook`](/docs/php/Facebook) | The main service object that helps tie all the SDK components together. | -| `Facebook\\FacebookApp`](/docs/php/FacebookApp) | An entity that represents a Facebook app and is required to send requests to Graph. | +| [`Facebook\\FacebookApp`](/docs/php/FacebookApp) | An entity that represents a Facebook app and is required to send requests to Graph. | # Authentication @@ -78,7 +78,7 @@ These are entities that represent files to be uploaded with a Graph request. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\FileUpload\\FacebookFile`](/docs/php/FacebookFile)' | Represents a generic file to be uploaded to the Graph API. | +| [`Facebook\\FileUpload\\FacebookFile`](/docs/php/FacebookFile) | Represents a generic file to be uploaded to the Graph API. | | [`Facebook\\FileUpload\\FacebookVideo`](/docs/php/FacebookVideo) | Represents a video file to be uploaded to the Graph API. | # Extensibility diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 5174c14a4..cc4e1d9e4 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -13,7 +13,7 @@ This base class has several subclasses: [__GraphPicture__](#picture-instance-methods) [__GraphAchievement__](#achievement-instance-methods) -`GraphNode`'s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents an HTTP response from the Graph API. +`GraphNode`s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents an HTTP response from the Graph API. Usage: From 5e5499ee9c29f407a0289dab90be580fbfee66e8 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:02:10 -0700 Subject: [PATCH 304/407] update links --- docs/getting_started.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 0005c8ae2..e60411112 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -104,18 +104,18 @@ You'll need to replace the `{app-id}` and `{app-secret}` with your Facebook app' > content: "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.", > type: 'warning', -The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](/docs/php/Facebook). +The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](docs/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](/docs/php/reference#helpers). +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](docs/reference.md). ### Obtaining an access token from redirect -For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) 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`](/docs/php/AccessToken) entity. +For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper`](docs/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`](docs/reference/AccessToken.md) entity. > content: "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.", > type: 'info', @@ -163,9 +163,9 @@ if (isset($accessToken)) { ### Obtaining an access token from a Facebook Canvas context -If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) to get an [`AccessToken`](/docs/php/AccessToken) entity for the user. +If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](docs/reference/FacebookCanvasHelper.md) to get an [`AccessToken`](docs/reference/AccessToken.md) entity for the user. -> content: "The `FacebookCanvasHelper` will detect a [signed request](/docs/reference/login/signed-request) 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](#authentication-redirect) or by using the [SDK for JavaScript](/docs/javascript) and then use the SDK for PHP to [obtain the access token from the cookie](#authentication-javascript) the SDK for JavaScript set.", +> content: "The `FacebookCanvasHelper` will detect a [signed request](docs/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](#authentication-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](#authentication-javascript) the SDK for JavaScript set.", > type: 'warning', ``` @@ -190,13 +190,13 @@ if (isset($accessToken)) { } ``` -> content: "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`](/docs/php/FacebookPageTabHelper)", +> content: "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`](docs/reference/FacebookPageTabHelper.md)", > type: 'info', ### 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](/docs/php/FacebookJavaScriptHelper). The `getAccessToken()` method will return an [`AccessToken`](/docs/php/AccessToken) entity. +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](docs/reference/FacebookJavaScriptHelper.md). The `getAccessToken()` method will return an [`AccessToken`](docs/reference/AccessToken.md) entity. ``` # example-obtain-from-js-cookie-app.php @@ -220,14 +220,14 @@ if (isset($accessToken)) { } ``` -> content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](/docs/javascript/reference/FB.init). 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.", +> content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](https://developers.facebook.com/docs/javascript/reference/v2.8). 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.", > type: 'warning', ## 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`](/docs/php/OAuth2Client). +To extend an access token, you can make use of the [`OAuth2Client`](docs/reference/Facebook.md#getOAuth2Client()). ``` // OAuth 2.0 client handler @@ -237,13 +237,13 @@ $oAuth2Client = $fb->getOAuth2Client(); $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken('{access-token}'); ``` -[See more about long-lived and short-lived access tokens](/docs/facebook-login/access-tokens#extending). +[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](/docs/graph-api/reference/user) that references the user or Page making the request. +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. ``` $fb = new Facebook\Facebook([/* . . . */]); @@ -267,9 +267,9 @@ try { echo 'Logged in as ' . $userNode->getName(); ``` -The `get()` method will return a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) which is an entity that represents an HTTP response from the Graph API. +The `get()` method will return a [`Facebook\FacebookResponse`](docs/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`](/docs/php/GraphNode#user-instance-methods) entity which represents a user node. +To get the response in the form of a nifty collection, we call `getGraphUser()` which returns a [`Facebook\GraphNodes\GraphUser`](docs/reference/GraphNode.md#GraphNode-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. @@ -284,4 +284,4 @@ try { $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](/docs/php/reference). +For a full list of all of the components that make up the SDK for PHP, see the [SDK for PHP reference page](docs/reference.md). From 1dd44baaba7bc58431068c0ec025c789f0262a80 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:04:32 -0700 Subject: [PATCH 305/407] fix typos --- docs/getting_started.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index e60411112..e5fcc4f5f 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -24,10 +24,10 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta ``` composer require facebook/php-sdk-v4 -``` -content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", -type: 'info', +> content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", +> type: 'info', + ``` 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. From a6e4aa635916a36718a09ddeae88059d513e2b25 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:07:26 -0700 Subject: [PATCH 306/407] fix links --- docs/getting_started.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index e5fcc4f5f..0c8273b86 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -104,18 +104,18 @@ You'll need to replace the `{app-id}` and `{app-secret}` with your Facebook app' > content: "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.", > type: 'warning', -The `Facebook\Facebook` service ties all the components of the SDK for PHP together. [See the full reference for the `Facebook\Facebook` service](docs/reference/Facebook.md). +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](docs/reference.md). +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`](docs/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`](docs/reference/AccessToken.md) entity. +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. > content: "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.", > type: 'info', @@ -163,7 +163,7 @@ if (isset($accessToken)) { ### Obtaining an access token from a Facebook Canvas context -If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebook\Helpers\FacebookCanvasHelper`](docs/reference/FacebookCanvasHelper.md) to get an [`AccessToken`](docs/reference/AccessToken.md) entity for the user. +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. > content: "The `FacebookCanvasHelper` will detect a [signed request](docs/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](#authentication-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](#authentication-javascript) the SDK for JavaScript set.", > type: 'warning', @@ -196,7 +196,7 @@ if (isset($accessToken)) { ### 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](docs/reference/FacebookJavaScriptHelper.md). The `getAccessToken()` method will return an [`AccessToken`](docs/reference/AccessToken.md) entity. +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. ``` # example-obtain-from-js-cookie-app.php @@ -227,7 +227,7 @@ if (isset($accessToken)) { 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`](docs/reference/Facebook.md#getOAuth2Client()). +To extend an access token, you can make use of the [`OAuth2Client`](reference/Facebook.md#getOAuth2Client()). ``` // OAuth 2.0 client handler @@ -267,9 +267,9 @@ try { echo 'Logged in as ' . $userNode->getName(); ``` -The `get()` method will return a [`Facebook\FacebookResponse`](docs/reference/FacebookResponse.md) which is an entity that represents an HTTP response from the Graph API. +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`](docs/reference/GraphNode.md#GraphNode-instance-methods) entity which represents a user node. +To get the response in the form of a nifty collection, we call `getGraphUser()` which returns a [`Facebook\GraphNodes\GraphUser`](reference/GraphNode.md#GraphNode-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. @@ -284,4 +284,4 @@ try { $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](docs/reference.md). +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). From eb9a0d7848e821f25ff4c978b7827390981766d7 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:17:51 -0700 Subject: [PATCH 307/407] update links --- docs/getting_started.md | 6 ++--- docs/reference.md | 56 ++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 0c8273b86..dbfbdd316 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -16,7 +16,7 @@ It would be advantageous to familiarize yourself with the concepts of [namespaci ## 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](#install-composer). If are unable to use Composer for your project, you can still [install the SDK manually](#install-manually) by downloading the source files and including the autoloader. +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) @@ -165,7 +165,7 @@ if (isset($accessToken)) { 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. -> content: "The `FacebookCanvasHelper` will detect a [signed request](docs/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](#authentication-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](#authentication-javascript) the SDK for JavaScript set.", +> content: "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](#authentication-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](#authentication-javascript) the SDK for JavaScript set.", > type: 'warning', ``` @@ -190,7 +190,7 @@ if (isset($accessToken)) { } ``` -> content: "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`](docs/reference/FacebookPageTabHelper.md)", +> content: "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)", > type: 'info', diff --git a/docs/reference.md b/docs/reference.md index e8d3b819e..f41d7352e 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -8,8 +8,8 @@ These classes are at the core of the Facebook SDK for PHP. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\Facebook`](/docs/php/Facebook) | The main service object that helps tie all the SDK components together. | -| [`Facebook\\FacebookApp`](/docs/php/FacebookApp) | An entity that represents a Facebook app and is required to send requests to Graph. | +| [`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 @@ -17,8 +17,8 @@ These classes facilitate authenticating a Facebook user with OAuth 2.0. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\Helpers\\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) | An OAuth 2.0 service to obtain a user access token from a redirect using a "Log in with Facebook" link. | -| [`Facebook\\Authentication\\AccessToken`](/docs/php/AccessToken) | An entity that represents an access token. | +| [`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. | @@ -28,11 +28,11 @@ These classes are used in a Graph API request/response cycle. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\FacebookRequest`](/docs/php/FacebookRequest) | An entity that represents an HTTP request to be sent to Graph. | -| [`Facebook\\FacebookResponse`](/docs/php/FacebookResponse) | An entity that represents an HTTP response from Graph. | -| [`Facebook\\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) | An entity that represents an HTTP batch request to be sent to Graph. | -| [`Facebook\\FacebookBatchResponse`](/docs/php/FacebookBatchResponse) | An entity that represents an HTTP response from Graph after sending a batch request. | -| [`Facebook\\FacebookClient`](/docs/php/FacebookClient) | A service object that sends HTTP requests and receives HTTP responses to and from the Graph API. | +| [`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 @@ -41,10 +41,10 @@ Classes to help obtain and manage signed requests. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\Helpers\\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) | Used to obtain an access token or signed request from the cookie set by the JavaScript SDK. | -| [`Facebook\\Helpers\\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) | Used to obtain an access token or signed request from within the context of an app canvas. | -| [`Facebook\\Helpers\\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper) | Used to obtain an access token or signed request from within the context of a page tab. | -| [`Facebook\\SignedRequest`](/docs/php/SignedRequest) | An entity that represents a signed request. | +| [`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 @@ -52,8 +52,8 @@ These are the core exceptions that the SDK will throw when an error occurs. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\Exceptions\\FacebookSDKException`](/docs/php/FacebookSDKException) | The base exception to all exceptions thrown by the SDK. Thrown when there is a non-Graph-response-related error. | -| [`Facebook\\Exceptions\\FacebookResponseException`](/docs/php/FacebookResponseException) | The base exception to all Graph error responses. This exception is never thrown directly. | +| [`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 @@ -62,14 +62,14 @@ Graph nodes are collections that represent nodes returned by the Graph API. And | Class name | Description | | ------------- | ------------- | -| [`Facebook\\GraphNodes\\GraphNode`](/docs/php/GraphNode) | The base collection object that represents a generic node. | -| [`Facebook\\GraphNodes\\GraphEdge`](/docs/php/GraphEdge) | A collection of GraphNode\'s with special methods to help paginate over the edge. | -| [`Facebook\\GraphNodes\\GraphAchievement`](/docs/php/GraphNode#achievement-instance-methods) | A collection that represents an Achievement node. | -| [`Facebook\\GraphNodes\\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) | A collection that represents an Album node. | -| [`Facebook\\GraphNodes\\GraphLocation`](/docs/php/GraphNode#location-instance-methods) | A collection that represents a Location node. | -| [`Facebook\\GraphNodes\\GraphPage`](/docs/php/GraphNode#page-instance-methods) | A collection that represents a Page node. | -| [`Facebook\\GraphNodes\\GraphPicture`](/docs/php/GraphNode#picture-instance-methods) | A collection that represents a Picture node. | -| [`Facebook\\GraphNodes\\GraphUser`](/docs/php/GraphNode#user-instance-methods) | A collection that represents a User node. | +| [`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 @@ -78,8 +78,8 @@ These are entities that represent files to be uploaded with a Graph request. | Class name | Description | | ------------- | ------------- | -| [`Facebook\\FileUpload\\FacebookFile`](/docs/php/FacebookFile) | Represents a generic file to be uploaded to the Graph API. | -| [`Facebook\\FileUpload\\FacebookVideo`](/docs/php/FacebookVideo) | Represents a video file to be uploaded to the Graph API. | +| [`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 @@ -89,6 +89,6 @@ You can overwrite certain functionality of the SDK by coding to an interface and | ------------- | ------------- | | `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`](/docs/php/PersistentDataInterface) | An interface to code your own persistent data storage implementation. | -| [`Facebook\\Url\\UrlDetectionInterface`](/docs/php/UrlDetectionInterface) | An interface to code your own URL detection logic. | -| [`Facebook\\PseudoRandomString\\ PseudoRandomStringGeneratorInterface`](/docs/php/PseudoRandomStringGeneratorInterface) | An interface to code your own cryptographically secure pseudo-random string generator. | +| [`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. | From da4fc45b90be9dea43240c2e58b2a1e7a90590d2 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:20:46 -0700 Subject: [PATCH 308/407] fix camel case --- docs/reference.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/reference.md b/docs/reference.md index f41d7352e..d9c9eb8f5 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -64,12 +64,12 @@ Graph nodes are collections that represent nodes returned by the Graph API. And | ------------- | ------------- | | [`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. | +| [`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 From 8207e3f584d6cff5601c941dc1c0feecb389709e Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:22:23 -0700 Subject: [PATCH 309/407] fix links --- docs/getting_started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index dbfbdd316..57c4ec31a 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -227,7 +227,7 @@ if (isset($accessToken)) { 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()). +To extend an access token, you can make use of the [`OAuth2Client`](reference/Facebook.md#getoauth2client). ``` // OAuth 2.0 client handler @@ -269,7 +269,7 @@ 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#GraphNode-instance-methods) entity which represents a user node. +To get the response in the form of a nifty collection, we call `getGraphUser()` which returns a [`Facebook\GraphNodes\GraphUser`](reference/GraphNode.md#graphnode-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. From 792df4324c029b431091040b0574fe65e684a702 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:25:18 -0700 Subject: [PATCH 310/407] update links --- docs/examples/post_links.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index 373637623..348ecc4bb 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -2,9 +2,9 @@ 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](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. +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`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). +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 From 6897150ceafa1609282d4a7b3bd2b446df935f81 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 14:53:56 -0700 Subject: [PATCH 311/407] update links --- docs/examples/retrieve_user_profile.md | 4 +- docs/examples/upload_photo.md | 4 +- docs/examples/upload_video.md | 4 +- docs/reference/Facebook.md | 44 +++++++++---------- docs/reference/FacebookApp.md | 4 +- docs/reference/FacebookBatchRequest.md | 10 ++--- docs/reference/FacebookBatchResponse.md | 4 +- docs/reference/FacebookCanvasHelper.md | 2 +- docs/reference/FacebookClient.md | 20 ++++----- docs/reference/FacebookJavaScriptHelper.md | 2 +- docs/reference/FacebookPageTabHelper.md | 2 +- docs/reference/FacebookRedirectLoginHelper.md | 6 +-- docs/reference/FacebookRequest.md | 10 ++--- docs/reference/FacebookResponse.md | 18 ++++---- docs/reference/FacebookResponseException.md | 2 +- docs/reference/FacebookSDKException.md | 2 +- docs/reference/FacebookVideo.md | 2 +- docs/reference/GraphNode.md | 4 +- docs/reference/SignedRequest.md | 4 +- 19 files changed, 74 insertions(+), 74 deletions(-) diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md index 749a086e0..6bb96e35e 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -2,9 +2,9 @@ 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](/docs/php/sdk_reference#helpers). +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`](/docs/php/Facebook), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphUser`](/docs/php/GraphNode#user-instance-methods), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). +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 diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index dc4295c06..04b736f8e 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -2,9 +2,9 @@ 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](/docs/php/sdk_reference#helpers). The access token must have the `publish_actions` permission for this to work. +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`](/docs/php/Facebook), [`Facebook\FileUpload\FacebookFile`](/docs/php/FacebookFile), [`Facebook\FacebookResponse`](/docs/php/FacebookResponse), [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode), [`Facebook\Exceptions\FacebookSDKException`](/docs/php/FacebookSDKException) and [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException). +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 diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index 6ec9bf1e7..dc49673bd 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -7,7 +7,7 @@ This example covers uploading & posting a video to a user's timeline with the Fa > content: "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.", > type: 'warning', -The following example will upload a video in chunks using the [resumable upload](/docs/graph-api/video-uploads#resumable) feature added in Graph v2.3. +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. ``` $fb = new Facebook\Facebook([ @@ -36,7 +36,7 @@ try { echo 'Video ID: ' . $response['video_id']; ``` -See more about the [`uploadVideo()` method](/docs/php/Facebook#upload-video). +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. diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md index 71c1055da..8be7b6332 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -66,10 +66,10 @@ The secret of your Facebook app (required). 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](/docs/support/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`. +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.8`. Defaults to the [latest version of Graph](/docs/apps/changelog). +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.8`. 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. @@ -78,7 +78,7 @@ By default, the SDK will try to use cURL as the HTTP client. If a cURL implement 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](/docs/php/FacebookHttpClientInterface)` and set this value to an instance of your custom client. +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. ``` $fb = new Facebook([ @@ -93,7 +93,7 @@ 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](/docs/php/PersistentDataInterface)` and set the value of `persistent_data_handler` to an instance of your custom handler. +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. ``` $fb = new Facebook([ @@ -106,7 +106,7 @@ 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](/docs/php/UrlDetectionInterface)` and set the value of `url_detection_handler` to an instance of your custom URL detector. +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. ``` $fb = new Facebook([ @@ -129,7 +129,7 @@ $fb = new Facebook([ ]); ``` -You can write your own CSPRSG that implements the `[Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface](/docs/php/PseudoRandomStringGeneratorInterface)` and set the value of `pseudo_random_string_generator` to an instance of your custom generator. +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. ``` $fb = new Facebook([ @@ -161,13 +161,13 @@ Returns the instance of `Facebook\FacebookApp` for the instantiated service. ``` public Facebook\FacebookClient getClient() ``` -Returns the instance of [`Facebook\FacebookClient`](/docs/php/FacebookClient) for the instantiated service. +Returns the instance of [`Facebook\FacebookClient`](FacebookClient.md) for the instantiated service. ## getOAuth2Client() ``` public Facebook\Authentication\OAuth2Client getOAuth2Client() ``` -Returns an instance of [`Facebook\Authentication\OAuth2Client`](/docs/php/OAuth2Client). +Returns an instance of `Facebook\Authentication\OAuth2Client`. ## getLastResponse() ``` @@ -179,19 +179,19 @@ Returns the last response received from the Graph API in the form of a `Facebook ``` public Facebook\Url\UrlDetectionInterface getUrlDetectionHandler() ``` -Returns an instance of [`Facebook\Url\UrlDetectionInterface`](/docs/php/UrlDetectionInterface). +Returns an instance of [`Facebook\Url\UrlDetectionInterface`](UrlDetectionInterface.md). ## getDefaultAccessToken() ``` public Facebook\Authentication\AccessToken|null getDefaultAccessToken() ``` -Returns the default fallback [`AccessToken`](/docs/php/AccessToken) 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()`. +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() ``` 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`](/docs/php/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). ``` $fb->setDefaultAccessToken('{my-access-token}'); @@ -233,7 +233,7 @@ $fb->get('/me'); 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](/docs/reference/ads-api/etags-reference/). Set this to the eTag from a previous request to get a `304 Not Modified` response if the data has not changed. +[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. @@ -336,7 +336,7 @@ 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](/docs/graph-api/making-multiple-requests/#operations). +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). ``` $requests = [ @@ -347,14 +347,14 @@ $requests = [ $batchResponse = $fb->sendBatchRequest($requests); ``` -[See a full batch example](/docs/php/howto/example_batch_request). +[See a full batch example](../examples/batch_request.md). ## getRedirectLoginHelper() ``` public Facebook\Helpers\FacebookRedirectLoginHelper getRedirectLoginHelper() ``` -Returns a [`Facebook\Helpers\FacebookRedirectLoginHelper`](/docs/php/FacebookRedirectLoginHelper) which is used to generate a "Login with Facebook" link and obtain an access token from a redirect. +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. ``` $helper = $fb->getRedirectLoginHelper(); @@ -365,7 +365,7 @@ $helper = $fb->getRedirectLoginHelper(); public Facebook\Helpers\FacebookJavaScriptHelper getJavaScriptHelper() ``` -Returns a [`Facebook\Helpers\FacebookJavaScriptHelper`](/docs/php/FacebookJavaScriptHelper) which is used to access the signed request stored in the cookie set by the SDK for JavaScript. +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. ``` $helper = $fb->getJavaScriptHelper(); @@ -376,7 +376,7 @@ $helper = $fb->getJavaScriptHelper(); public Facebook\Helpers\FacebookCanvasHelper getCanvasHelper() ``` -Returns a [`Facebook\Helpers\FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) which is used to access the signed request that is `POST`ed to canvas apps. +Returns a [`Facebook\Helpers\FacebookCanvasHelper`](FacebookCanvasHelper.md) which is used to access the signed request that is `POST`ed to canvas apps. ``` $helper = $fb->getCanvasHelper(); @@ -387,7 +387,7 @@ $helper = $fb->getCanvasHelper(); public Facebook\Helpers\FacebookPageTabHelper getPageTabHelper() ``` -Returns a [`Facebook\Helpers\FacebookPageTabHelper`](/docs/php/FacebookPageTabHelper) 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. +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. ``` $helper = $fb->getPageTabHelper(); @@ -398,7 +398,7 @@ $helper = $fb->getPageTabHelper(); public Facebook\GraphNodes\GraphEdge|null next(Facebook\GraphNodes\GraphEdge $graphEdge) ``` -Requests and returns the next page of results in a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. If the next page returns no results, `null` will be returned. +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. ``` // Iterate over 5 pages max @@ -499,7 +499,7 @@ public array videoToUpload( ) ``` -Functionality to [upload video files in chunks](/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. +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 @@ -510,13 +510,13 @@ The ID or alias of the target node. This can be a user ID, page ID, event ID, gr The absolute or relative path to the video file to upload. `$metadata` -All the metadata associated with the [Video node](/docs/graph-api/reference/video/). +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](/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`. +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. diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index 049e50ba2..e61c798e4 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -13,7 +13,7 @@ To instantiate a new `Facebook\FacebookApp` entity, pass the app ID and app secr $fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); ``` -Alternatively you can obtain the `Facebook\FacebookApp` entity from the [`Facebook\Facebook`](/docs/php/Facebook) super service class. +Alternatively you can obtain the `Facebook\FacebookApp` entity from the [`Facebook\Facebook`](Facebook.md) super service class. ``` $fb = new Facebook\Facebook([/* . . . */]); @@ -28,7 +28,7 @@ You'll rarely be using the `FacebookApp` entity directly unless you're doing som ``` public Facebook\Authentication\AccessToken getAccessToken() ``` -Returns an app access token in the form of an [`AccessToken`](/docs/php/AccessToken) entity. +Returns an app access token in the form of an [`AccessToken`](AccessToken.md) entity. ## getId() ``` diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index 5677eb35f..2767c10b4 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -17,9 +17,9 @@ $request = new FacebookBatchRequest( ); ``` -The `$requests` array is an array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent as a batch request. +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()`](/docs/php/Facebook#send-batch-request) or [`Facebook\FacebookClient::sendBatchRequest()`](/docs/php/FacebookClient#send-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: @@ -56,7 +56,7 @@ foreach ($batchResponse as $key => $response) { ## Instance Methods -Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity, all the methods are inherited. +Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\FacebookRequest`](FacebookRequest.md) entity, all the methods are inherited. ### add() ``` @@ -65,7 +65,7 @@ public add( string|null $name ) ``` -Adds a request to be sent in the batch request. The `$request` can be a single [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) or an array of `Facebook\FacebookRequest`'s. +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. @@ -73,7 +73,7 @@ The `$name` argument is optional and is used to identify the request in the batc ``` public array getRequests() ``` -Returns the array of [`Facebook\FacebookRequest`'s](/docs/php/FacebookRequest) to be sent in the batch request. +Returns the array of [`Facebook\FacebookRequest`'s](FacebookRequest.md) to be sent in the batch request. ## Array Access diff --git a/docs/reference/FacebookBatchResponse.md b/docs/reference/FacebookBatchResponse.md index c6836da1c..959ca57a4 100644 --- a/docs/reference/FacebookBatchResponse.md +++ b/docs/reference/FacebookBatchResponse.md @@ -43,13 +43,13 @@ var_dump($batchResponse); ## Instance Methods -Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entity, all the methods are inherited. +Since the `Facebook\FacebookBatchResponse` is extended from the [`Facebook\FacebookResponse`](FacebookResponse.md) entity, all the methods are inherited. ### getResponses() ``` public array getResponses() ``` -Returns the array of [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) entities that were returned from Graph. +Returns the array of [`Facebook\FacebookResponse`](FacebookResponse.md) entities that were returned from Graph. ## Array Access diff --git a/docs/reference/FacebookCanvasHelper.md b/docs/reference/FacebookCanvasHelper.md index ae6f42c4f..f98fff2ec 100644 --- a/docs/reference/FacebookCanvasHelper.md +++ b/docs/reference/FacebookCanvasHelper.md @@ -94,7 +94,7 @@ Gets the value that is set in the `app_data` property if present. ``` public Facebook\SignedRequest|null getSignedRequest() ``` -Returns the signed request as an instance of [`Facebook\SignedRequest`](/docs/php/SignedRequest) if present. +Returns the signed request as an instance of [`Facebook\SignedRequest`](SignedRequest.md) if present. ### getRawSignedRequest() ``` diff --git a/docs/reference/FacebookClient.md b/docs/reference/FacebookClient.md index 5b084abe2..baf31a7cb 100644 --- a/docs/reference/FacebookClient.md +++ b/docs/reference/FacebookClient.md @@ -29,13 +29,13 @@ The `Facebook\FacebookClient` service takes the guess-work out of managing those ``` public Facebook\HttpClients\FacebookHttpClientInterface getHttpClientHandler() ``` -Returns the instance of [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface) that the service is using. +Returns the instance of `Facebook\HttpClients\FacebookHttpClientInterface` that the service is using. ### setHttpClientHandler() ``` public setHttpClientHandler(Facebook\HttpClients\FacebookHttpClientInterface $client) ``` -If you've coded your own HTTP client to the [`Facebook\HttpClients\FacebookHttpClientInterface`](/docs/php/FacebookHttpClientInterface), you can inject it into the service using this method. +If you've coded your own HTTP client to the `Facebook\HttpClients\FacebookHttpClientInterface`, you can inject it into the service using this method. ### enableBetaMode() ``` @@ -49,13 +49,13 @@ public Facebook\FacebookResponse sendRequest(Facebook\FacebookRequest $request) ``` Sends a non-batch request to Graph. -Takes a [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. +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`](/docs/php/FacebookResponse). +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`](/docs/php/FacebookSDKException) will be thrown. +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`](/docs/php/FacebookResponseException) will be thrown. +If an error response from Graph was returned, a [`Facebook\Exceptions\FacebookResponseException`](FacebookResponseException.md) will be thrown. ### sendBatchRequest() ``` @@ -63,10 +63,10 @@ public Facebook\FacebookBatchResponse sendBatchRequest(Facebook\FacebookBatchReq ``` Sends a batch request to Graph. -Takes a [`Facebook\FacebookBatchRequest`](/docs/php/FacebookBatchRequest) and sends it to the Graph API in the proper `application/x-www-form-urlencoded` or `multipart/form-data` encoded format. +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`](/docs/php/FacebookBatchResponse). +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`](/docs/php/FacebookSDKException) will be thrown. +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`](/docs/php/FacebookResponseException) 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/FacebookJavaScriptHelper.md b/docs/reference/FacebookJavaScriptHelper.md index 6b8ce7ad7..7c8ead443 100644 --- a/docs/reference/FacebookJavaScriptHelper.md +++ b/docs/reference/FacebookJavaScriptHelper.md @@ -84,7 +84,7 @@ if ($signedRequest) { ``` public Facebook\SignedRequest|null getSignedRequest() ``` -Returns the signed request as a [`Facebook\SignedRequest`](/docs/php/SignedRequest) entity if present. +Returns the signed request as a [`Facebook\SignedRequest`](SignedRequest.md) entity if present. ### getRawSignedRequest() ``` diff --git a/docs/reference/FacebookPageTabHelper.md b/docs/reference/FacebookPageTabHelper.md index 2c130d239..abeee0980 100644 --- a/docs/reference/FacebookPageTabHelper.md +++ b/docs/reference/FacebookPageTabHelper.md @@ -4,7 +4,7 @@ Page tabs are similar to the context to app canvases but are treated slightly di ## Usage -The usage of the `FacebookPageTabHelper` is exactly the same as [`FacebookCanvasHelper`](/docs/php/FacebookCanvasHelper) with additional methods to obtain the `page` data from the signed request. +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. ``` $fb = new Facebook\Facebook([/* */]); diff --git a/docs/reference/FacebookRedirectLoginHelper.md b/docs/reference/FacebookRedirectLoginHelper.md index e8ae3b705..5204b6326 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -122,14 +122,14 @@ The `FacebookRedirectLoginHelper` has to orchestrate a number of components from 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`](/docs/php/PersistentDataInterface). +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`](/docs/php/PseudoRandomStringGeneratorInterface) allows you to inject your own custom 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`](/docs/php/UrlDetectionInterface). +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 index 7a0b53720..1f84e367e 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -20,9 +20,9 @@ $request = new FacebookRequest( ); ``` -Alternatively, you can make use of the [`request()` factory provided by `Facebook\Facebook`](/docs/php/Facebook#request) to create new `FacebookRequest` instances. +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()`](/docs/php/Facebook#send-batch-request) or [`Facebook\FacebookClient::sendBatchRequest()`](/docs/php/FacebookClient#send-batch-request). +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: @@ -70,13 +70,13 @@ Returns the access token to be used for the request in the form of a string. ``` public setApp(Facebook\FacebookApp $app) ``` -Sets the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. +Sets the [`Facebook\FacebookApp`](FacebookApp.md) entity used with this request. ### getApp() ``` public Facebook\FacebookApp getApp() ``` -Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity used with this request. +Returns the [`Facebook\FacebookApp`](FacebookApp.md) entity used with this request. ### getAppSecretProof() ``` @@ -168,7 +168,7 @@ Returns the Graph version prefix to be used with the request. ``` 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`](/docs/php/FacebookClient). +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). ``` $fb = new Facebook\Facebook(/* . . . */); diff --git a/docs/reference/FacebookResponse.md b/docs/reference/FacebookResponse.md index 48f89ad35..67b9b23df 100644 --- a/docs/reference/FacebookResponse.md +++ b/docs/reference/FacebookResponse.md @@ -34,7 +34,7 @@ var_dump($response); ``` public Facebook\FacebookRequest getRequest() ``` -Returns the original [`Facebook\FacebookRequest`](/docs/php/FacebookRequest) entity that was used to solicit this response. +Returns the original [`Facebook\FacebookRequest`](FacebookRequest.md) entity that was used to solicit this response. ### getAccessToken() ``` @@ -46,7 +46,7 @@ Returns the access token that was used for the original request in the form of a ``` public Facebook\FacebookApp getApp() ``` -Returns the [`Facebook\FacebookApp`](/docs/php/FacebookApp) entity that was used with the original request. +Returns the [`Facebook\FacebookApp`](FacebookApp.md) entity that was used with the original request. ### getHttpStatusCode() ``` @@ -100,37 +100,37 @@ If the Graph API returned an error response `isError()` will return `true`. If a ``` public throwException() ``` -Throws the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. +Throws the [`Facebook\Exceptions\FacebookResponseException`](FacebookResponseException.md) that was generated by an error response from Graph. ### getThrownException() ``` public Facebook\Exceptions\FacebookResponseException getThrownException() ``` -Returns the [`Facebook\Exceptions\FacebookResponseException`](/docs/php/FacebookResponseException) that was generated by an error response from Graph. This is mainly useful for dealing with [responses to batch requests](/docs/php/FacebookBatchResponse). +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() ``` public Facebook\GraphNodes\GraphNode getGraphNode() ``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](/docs/php/GraphNode) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphNode`](GraphNode.md) collection. ### getGraphAlbum() ``` public Facebook\GraphNodes\GraphAlbum getGraphAlbum() ``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](/docs/php/GraphNode#album-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphAlbum`](GraphNode.md#graphalbum-instance-methods) collection. ### getGraphPage() ``` public Facebook\GraphNodes\GraphPage getGraphPage() ``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](/docs/php/GraphNode#page-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphPage`](GraphNode.md#graphpage-instance-methods) collection. ### getGraphSessionInfo() ``` public Facebook\GraphNodes\GraphSessionInfo getGraphSessionInfo() ``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](/docs/php/GraphNode#sessioninfo-instance-methods) collection. +Returns the response data in the form of a [`Facebook\GraphNodes\GraphSessionInfo`](GraphNode.md) collection. ### getGraphUser() ``` @@ -144,7 +144,7 @@ public Facebook\GraphNodes\GraphEdge getGraphEdge( string|null $subclassName, boolean $auto_prefix) ``` -Returns the response data in the form of a [`Facebook\GraphNodes\GraphEdge`](/docs/php/GraphEdge) collection. +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`. diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md index 6b6163df2..a96ccfe02 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -26,7 +26,7 @@ try { | `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](/docs/graph-api/using-graph-api/#errors). +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 diff --git a/docs/reference/FacebookSDKException.md b/docs/reference/FacebookSDKException.md index 683b3779c..2166ec148 100644 --- a/docs/reference/FacebookSDKException.md +++ b/docs/reference/FacebookSDKException.md @@ -6,7 +6,7 @@ Represents an exception thrown by the SDK. 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](/docs/php/FacebookResponseException). +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 diff --git a/docs/reference/FacebookVideo.md b/docs/reference/FacebookVideo.md index 6fe15e5c7..cdde8b713 100644 --- a/docs/reference/FacebookVideo.md +++ b/docs/reference/FacebookVideo.md @@ -26,7 +26,7 @@ Partial file uploads are possible using the `$maxLength` and `$offset` parameter ## Usage -In Graph v2.3, functionality was added to [upload video files in chunks](/docs/graph-api/video-uploads#resumable). The PHP SDK provides a handy API to easily upload video files in chunks via the [`uploadVideo()` method](/docs/php/Facebook#upload-video). +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). ``` // Upload a video for a user (chunked) diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index cc4e1d9e4..62380a30a 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -13,7 +13,7 @@ This base class has several subclasses: [__GraphPicture__](#picture-instance-methods) [__GraphAchievement__](#achievement-instance-methods) -`GraphNode`s are obtained from a [`Facebook\FacebookResponse`](/docs/php/FacebookResponse) object which represents an HTTP response from the Graph API. +`GraphNode`s are obtained from a [`Facebook\FacebookResponse`](FacebookResponse.md) object which represents an HTTP response from the Graph API. Usage: @@ -146,7 +146,7 @@ Returns the `link` property for the user as a string if present. ``` public \Facebook\GraphNodes\Birthday|null getBirthday() ``` -Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](/docs/php/Birthday) if present. +Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](Birthday.md) if present. ### getLocation() ``` diff --git a/docs/reference/SignedRequest.md b/docs/reference/SignedRequest.md index aeab355ba..78e785b92 100644 --- a/docs/reference/SignedRequest.md +++ b/docs/reference/SignedRequest.md @@ -6,14 +6,14 @@ The `Facebook\SignedRequest` entity represents a signed request. [Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) 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`](/docs/php/FacebookApp) entity and raw signed request to the constructor. +To instantiate a new `Facebook\SignedRequest` entity, pass the [`Facebook\FacebookApp`](FacebookApp.md) entity and raw signed request to the constructor. ``` $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](/docs/php/sdk_reference#helpers). +Usually `Facebook\SignedRequest` entities are obtained using one of the [helpers](../reference.md). ``` $fb = new Facebook\Facebook([/* . . . */]); From fc9cfa1f99f8ef54ed009d3d556a45311878b10c Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 15:28:59 -0700 Subject: [PATCH 312/407] add syntax highlighting --- docs/getting_started.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 57c4ec31a..99465ea6c 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -22,7 +22,7 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta [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. -``` +```php composer require facebook/php-sdk-v4 > content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", @@ -34,7 +34,7 @@ Once you do this, composer will edit your `composer.json` file and download the Make sure to include the Composer autoloader at the top of your script. -``` +```php require_once __DIR__ . '/vendor/autoload.php'; ``` @@ -51,7 +51,7 @@ First, download the source code and unzip it wherever you like in your project. Then include the autoloader provided in the SDK at the top of your script. -``` +```php require_once __DIR__ . '/path/to/facebook-php-sdk-v4/src/Facebook/autoload.php'; ``` @@ -73,13 +73,13 @@ The path the the core SDK files should now be located in `/var/html/facebook-sdk 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'; ``` @@ -91,7 +91,7 @@ require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; 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}', @@ -120,7 +120,7 @@ For most websites, you'll use the [`Facebook\Helpers\FacebookRedirectLoginHelper > content: "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.", > type: 'info', -``` +```php # login.php $fb = new Facebook\Facebook([/* . . . */]); @@ -134,7 +134,7 @@ echo 'Log in with Facebook!'; > content: "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.", > type: 'warning', -``` +```php # login-callback.php $fb = new Facebook\Facebook([/* . . . */]); @@ -168,7 +168,7 @@ If your app is on Facebook Canvas, use the `getAccessToken()` method on [`Facebo > content: "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](#authentication-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](#authentication-javascript) the SDK for JavaScript set.", > type: 'warning', -``` +```php # example-canvas-app.php $fb = new Facebook\Facebook([/* . . . */]); @@ -198,7 +198,7 @@ if (isset($accessToken)) { 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([/* . . . */]); @@ -229,7 +229,7 @@ When a user first logs into your app, the access token your app receives will be 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(); @@ -245,7 +245,7 @@ Once you have an instance of the `Facebook\Facebook` service and obtained an acc 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 @@ -273,7 +273,7 @@ To get the response in the form of a nifty collection, we call `getGraphUser()` 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) { From ad20f47d7560fcc041bcfcebd2a882b93eaeb8fd Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 15:43:26 -0700 Subject: [PATCH 313/407] add syntax highlighting --- docs/examples/access_token_from_canvas.md | 2 +- docs/examples/access_token_from_javascript.md | 4 +- docs/examples/access_token_from_page_tab.md | 2 +- docs/examples/batch_request.md | 6 +- docs/examples/batch_upload.md | 2 +- docs/examples/facebook_login.md | 4 +- docs/examples/pagination_basic.md | 2 +- docs/examples/post_links.md | 2 +- docs/examples/retrieve_user_profile.md | 2 +- docs/examples/upload_photo.md | 2 +- docs/examples/upload_video.md | 4 +- docs/reference/AccessToken.md | 14 +- docs/reference/Birthday.md | 6 +- docs/reference/Facebook.md | 96 +++++------ docs/reference/FacebookApp.md | 12 +- docs/reference/FacebookBatchRequest.md | 10 +- docs/reference/FacebookBatchResponse.md | 6 +- docs/reference/FacebookCanvasHelper.md | 22 +-- docs/reference/FacebookClient.md | 14 +- docs/reference/FacebookFile.md | 8 +- docs/reference/FacebookJavaScriptHelper.md | 18 +-- docs/reference/FacebookPageTabHelper.md | 10 +- docs/reference/FacebookRedirectLoginHelper.md | 16 +- docs/reference/FacebookRequest.md | 44 ++--- docs/reference/FacebookResponse.md | 44 ++--- docs/reference/FacebookResponseException.md | 2 +- docs/reference/FacebookVideo.md | 8 +- docs/reference/GraphEdge.md | 24 +-- docs/reference/GraphNode.md | 150 +++++++++--------- docs/reference/PersistentDataInterface.md | 10 +- .../PseudoRandomStringGeneratorInterface.md | 8 +- docs/reference/SignedRequest.md | 18 +-- docs/reference/UrlDetectionInterface.md | 8 +- 33 files changed, 290 insertions(+), 290 deletions(-) diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index 0f1ff043f..6429322e9 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from within the 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}', diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index 77eaf39b4..0c0b2a9ec 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from the Facebo 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. -``` +```php @@ -47,7 +47,7 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh 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}', diff --git a/docs/examples/access_token_from_page_tab.md b/docs/examples/access_token_from_page_tab.md index 5094bf470..1bf4f6cd2 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from within the 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}', diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index 0e85085f2..a944bb558 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -6,7 +6,7 @@ This example covers sending a batch request with the Facebook SDK for PHP. 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 $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -86,7 +86,7 @@ There five requests being made in this batch requests. If the request was successful, the user should have a new status update similar to this: -``` +```php My name is Foo User. I like this page: Facebook Developers. @@ -103,7 +103,7 @@ It should also contain a response containing two photos from the user. 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 $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index 1320eb986..386e3da7e 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -8,7 +8,7 @@ The Graph API supports [file uploads in batch requests](https://developers.faceb The following example will upload two photos and one video. -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index ff63bc4b0..5a7941b4c 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -10,7 +10,7 @@ In this example, the PHP script that generates the login link is called `/login. ## /login.php -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -27,7 +27,7 @@ echo 'Log in with Facebook!'; ## /fb-callback.php -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', diff --git a/docs/examples/pagination_basic.md b/docs/examples/pagination_basic.md index 514512d15..4390c653c 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -8,7 +8,7 @@ The Graph API supports [several methods to paginate over response data](https:// 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}', diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index 348ecc4bb..0c866044b 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -8,7 +8,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen ## Example -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md index 6bb96e35e..74619e0e2 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -8,7 +8,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen ## Example -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index 04b736f8e..4730ff803 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -8,7 +8,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen ## Example -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index dc49673bd..548b7c212 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -9,7 +9,7 @@ This example covers uploading & posting a video to a user's timeline with the Fa 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}', @@ -40,7 +40,7 @@ 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 = [ diff --git a/docs/reference/AccessToken.md b/docs/reference/AccessToken.md index 6d7ffa063..ec4539086 100644 --- a/docs/reference/AccessToken.md +++ b/docs/reference/AccessToken.md @@ -7,39 +7,39 @@ Requests to the Graph API need to have an access token sent with them to identif 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. @@ -50,7 +50,7 @@ If you already have an access token in the form of a string (from a session or d 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 index abbeda400..20901da68 100644 --- a/docs/reference/Birthday.md +++ b/docs/reference/Birthday.md @@ -16,7 +16,7 @@ The `Facebook\GraphNodes\Birthday` entity extends `DateTime` so `format` may be Usage: -``` +```php $fb = new Facebook\Facebook(\* *\); // Returns a `Facebook\FacebookResponse` object $response = $fb->get('/me'); @@ -43,13 +43,13 @@ var_dump($birthday->format('m/d')); ## 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 index 8be7b6332..216465290 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -6,7 +6,7 @@ The Facebook SDK for PHP is made up of many components. The `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}', @@ -17,7 +17,7 @@ $fb = new Facebook\Facebook([ Usage: -``` +```php // Send a GET request $response = $fb->get('/me'); @@ -30,7 +30,7 @@ $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}'); @@ -42,7 +42,7 @@ Although the `Facebook\Facebook` service tries to make the SDK as easy as possib Full configuration options list: -``` +```php $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', @@ -80,7 +80,7 @@ If you wish to use Guzzle, you can set this value to `guzzle`, but it requires t 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(), ]); @@ -95,7 +95,7 @@ By default, the SDK will try to use the native PHP session for the persistent da 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(), ]); @@ -108,7 +108,7 @@ 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(), ]); @@ -123,7 +123,7 @@ Generating random strings in PHP is easy but generating _cryptographically secur 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', ]); @@ -131,7 +131,7 @@ $fb = new Facebook([ 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(), ]); @@ -145,55 +145,55 @@ The only required configuration options are `app_id` and `app_secret`. However, 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 . . . @@ -205,13 +205,13 @@ $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, @@ -225,7 +225,7 @@ 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'); ``` @@ -239,7 +239,7 @@ The access token (as a string or `AccessToken` entity) to use for the request. I 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, @@ -256,12 +256,12 @@ 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, @@ -275,12 +275,12 @@ 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, @@ -298,12 +298,12 @@ 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, @@ -316,12 +316,12 @@ public Facebook\FacebookResponse sendRequest( Sends a request to the Graph API. -``` +```php $response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.8'); ``` ## sendBatchRequest() -``` +```php public Facebook\FacebookBatchResponse sendBatchRequest( array $requests, string|AccessToken|null $accessToken, @@ -338,7 +338,7 @@ An array of `Facebook\FacebookRequest` entities. This can be a numeric or associ 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}'), @@ -350,57 +350,57 @@ $batchResponse = $fb->sendBatchRequest($requests); [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; @@ -428,20 +428,20 @@ if (count($photosEdge) > 0) { ``` ## 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.', @@ -461,13 +461,13 @@ 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', @@ -488,7 +488,7 @@ echo 'Video ID: ' . $graphNode['id']; ``` ## uploadVideo() -``` +```php public array videoToUpload( string $target, string $pathToFile, @@ -527,7 +527,7 @@ The array that is returned will contain two keys; `video_id` with the ID of the ### Example -``` +```php // Upload a video for a user (chunked) $data = [ 'title' => 'My awesome video', diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index e61c798e4..280527a69 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -9,13 +9,13 @@ In order to make requests to the Graph API, you need to [create a Facebook app]( 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(); ``` @@ -25,19 +25,19 @@ You'll rarely be using the `FacebookApp` entity directly unless you're doing som ## 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. @@ -46,7 +46,7 @@ Returns the app secret. The `Facebook\FacebookApp` entity can be serialized and unserialized. -``` +```php $fbApp = new Facebook\FacebookApp('foo-app-id', 'foo-app-secret'); $serializedFacebookApp = serialize($fbApp); diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index 2767c10b4..6f3e44823 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -6,7 +6,7 @@ Represents a batch request that will be sent to the Graph API. You can instantiate a new `FacebookBatchRequest` entity directly by sending the arguments to the constructor. -``` +```php use Facebook\FacebookBatchRequest; $request = new FacebookBatchRequest( @@ -23,7 +23,7 @@ The `FacebookBatchRequest` entity does not actually make any calls to the Graph Usage: -``` +```php $fb = new Facebook\Facebook(/* . . . */); $requests = [ @@ -59,7 +59,7 @@ foreach ($batchResponse as $key => $response) { 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 @@ -70,7 +70,7 @@ Adds a request to be sent in the batch request. The `$request` can be a single [ 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. @@ -79,7 +79,7 @@ Returns the array of [`Facebook\FacebookRequest`'s](FacebookRequest.md) to be se 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'), diff --git a/docs/reference/FacebookBatchResponse.md b/docs/reference/FacebookBatchResponse.md index 959ca57a4..e71b24f20 100644 --- a/docs/reference/FacebookBatchResponse.md +++ b/docs/reference/FacebookBatchResponse.md @@ -8,7 +8,7 @@ After sending a batch request to the Graph API, the response will be returned in Usage: -``` +```php $fb = new Facebook\Facebook(/* . . . */); $requests = [ $fb->request('GET', '/me'), @@ -46,7 +46,7 @@ var_dump($batchResponse); 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. @@ -55,7 +55,7 @@ Returns the array of [`Facebook\FacebookResponse`](FacebookResponse.md) entities 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', [/* */]), diff --git a/docs/reference/FacebookCanvasHelper.md b/docs/reference/FacebookCanvasHelper.md index f98fff2ec..18624574c 100644 --- a/docs/reference/FacebookCanvasHelper.md +++ b/docs/reference/FacebookCanvasHelper.md @@ -2,7 +2,7 @@ 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 ) ``` @@ -10,7 +10,7 @@ Facebook\Helpers\FacebookCanvasHelper( Facebook\FacebookApp $facebookApp ) 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(); @@ -23,7 +23,7 @@ if ($signedRequest) { If a user has already authenticated your app, you can also obtain an access token. -``` +```php $fb = new Facebook\Facebook([/* */]); $canvasHelper = $fb->getCanvasHelper(); @@ -47,24 +47,24 @@ The `$accessToken` will be `null` if the signed request did not contain any OAut ## 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) { @@ -74,7 +74,7 @@ if ($userId) { This is equivalent to accessing the user ID from the signed request entity. -``` +```php $signedRequest = $canvasHelper->getSignedRequest(); if ($signedRequest) { @@ -85,19 +85,19 @@ if ($signedRequest) { ``` ### 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 index baf31a7cb..91e4be8c9 100644 --- a/docs/reference/FacebookClient.md +++ b/docs/reference/FacebookClient.md @@ -8,14 +8,14 @@ You most likely won't be working with the `Facebook\FacebookClient` service dire 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); ``` @@ -26,25 +26,25 @@ The `Facebook\FacebookClient` service takes the guess-work out of managing those ## 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. @@ -58,7 +58,7 @@ If there was an error processing the request before sending, a [`Facebook\Except 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. diff --git a/docs/reference/FacebookFile.md b/docs/reference/FacebookFile.md index eb8f17fd7..304699538 100644 --- a/docs/reference/FacebookFile.md +++ b/docs/reference/FacebookFile.md @@ -8,7 +8,7 @@ The `FacebookFile` entity represents a local or remote file to be uploaded with 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'); @@ -16,7 +16,7 @@ $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'); @@ -28,7 +28,7 @@ Partial file uploads are possible using the `$maxLength` and `$offset` parameter The following example uploads a photo for a user. -``` +```php $data = [ 'message' => 'My awesome photo upload example.', 'source' => $fb->fileToUpload('/path/to/photo.jpg'), @@ -50,7 +50,7 @@ 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.', diff --git a/docs/reference/FacebookJavaScriptHelper.md b/docs/reference/FacebookJavaScriptHelper.md index 7c8ead443..d9520c779 100644 --- a/docs/reference/FacebookJavaScriptHelper.md +++ b/docs/reference/FacebookJavaScriptHelper.md @@ -6,7 +6,7 @@ If you're using the [JavaScript SDK](https://developers.facebook.com/docs/javasc 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(); @@ -19,7 +19,7 @@ if ($signedRequest) { If a user has already authenticated your app, you can also obtain an access token. -``` +```php $fb = new Facebook\Facebook([/* */]); $jsHelper = $fb->getJavaScriptHelper(); @@ -43,24 +43,24 @@ You will likely want to make an Ajax request when the login state changes in the ## 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) { @@ -70,7 +70,7 @@ if ($userId) { This is equivalent to accessing the user ID from the signed request entity. -``` +```php $signedRequest = $jsHelper->getSignedRequest(); if ($signedRequest) { @@ -81,13 +81,13 @@ if ($signedRequest) { ``` ### 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 index abeee0980..3666a8cc6 100644 --- a/docs/reference/FacebookPageTabHelper.md +++ b/docs/reference/FacebookPageTabHelper.md @@ -6,7 +6,7 @@ Page tabs are similar to the context to app canvases but are treated slightly di 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(); @@ -19,7 +19,7 @@ if ($signedRequest) { If a user has already authenticated your app, you can also obtain an access token. -``` +```php $fb = new Facebook\Facebook([/* */]); $pageHelper = $fb->getPageTabHelper(); @@ -41,19 +41,19 @@ if (isset($accessToken)) { ## 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 index 5204b6326..7a1b08787 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -11,7 +11,7 @@ Facebook Login is achieved via OAuth 2.0. But you don't really have to know much 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(); @@ -26,7 +26,7 @@ The basic login flow goes like this: 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([/* . . . */]); @@ -42,7 +42,7 @@ echo 'Log in with Facebook!'; Then, in your callback page (at the redirect url) when Facebook sends the user back: -``` +```php # login-callback.php $fb = new Facebook\Facebook([/* . . . */]); @@ -74,7 +74,7 @@ if (isset($accessToken)) { ## 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. @@ -85,25 +85,25 @@ Generates an authorization URL to ask a user for access to their profile on beha - `$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. diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 1f84e367e..eb71b7034 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -6,7 +6,7 @@ Represents a request that will be sent to the Graph API. You can instantiate a new `FacebookRequest` entity directly by sending the arguments to the constructor. -``` +```php use Facebook\FacebookRequest; $request = new FacebookRequest( @@ -26,7 +26,7 @@ The `FacebookRequest` entity does not actually make any calls to the Graph API, Usage: -``` +```php $fbApp = new Facebook\FacebookApp('{app-id}', '{app-secret}'); $request = new Facebook\FacebookRequest($fbApp, '{access-token}', 'GET', '/me'); @@ -56,93 +56,93 @@ echo 'User name: ' . $graphNode['name']; ## Instance Methods ### setAccessToken() -``` +```php public setAccessToken(string|Facebook\AccessToken $accessToken) ``` ### 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, @@ -153,24 +153,24 @@ $request->setParams([ 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']); diff --git a/docs/reference/FacebookResponse.md b/docs/reference/FacebookResponse.md index 67b9b23df..8a60a76ce 100644 --- a/docs/reference/FacebookResponse.md +++ b/docs/reference/FacebookResponse.md @@ -8,7 +8,7 @@ After sending a request to the Graph API, the response will be returned in the f Usage: -``` +```php $fb = new Facebook\Facebook(/* . . . */); // Send the request to Graph @@ -31,115 +31,115 @@ var_dump($response); ## 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`](/docs/php/GraphNode#user-instance-methods) collection. +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) @@ -152,7 +152,7 @@ The `Facebook\GraphNodes\GraphNode` subclass to cast list items to. If none is p `$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 index a96ccfe02..f7c7807bd 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -6,7 +6,7 @@ Represents an error response from the Graph API. 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) { diff --git a/docs/reference/FacebookVideo.md b/docs/reference/FacebookVideo.md index cdde8b713..df7e424c1 100644 --- a/docs/reference/FacebookVideo.md +++ b/docs/reference/FacebookVideo.md @@ -8,7 +8,7 @@ The `FacebookVideo` entity represents a local or remote video file to be uploade 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'); @@ -16,7 +16,7 @@ $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'), @@ -28,7 +28,7 @@ Partial file uploads are possible using the `$maxLength` and `$offset` parameter 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', @@ -47,7 +47,7 @@ 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', diff --git a/docs/reference/GraphEdge.md b/docs/reference/GraphEdge.md index 80439dd33..30508d37b 100644 --- a/docs/reference/GraphEdge.md +++ b/docs/reference/GraphEdge.md @@ -6,13 +6,13 @@ When a list of nodes is returned from a Graph request, it can be cast as a `Grap 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) { // . . . @@ -23,7 +23,7 @@ foreach ($graphEdge as $graphNode) { 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 @@ -40,7 +40,7 @@ Sometimes Graph will return a list of nodes within a node. Paginating on these s 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; @@ -65,48 +65,48 @@ do { ## 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(); diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 62380a30a..9341ca7d2 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -17,7 +17,7 @@ This base class has several subclasses: Usage: -``` +```php $fb = new Facebook\Facebook(\* *\); // Returns a `Facebook\FacebookResponse` object $response = $fb->get('/something'); @@ -46,7 +46,7 @@ The `GraphNode` collection and its subclasses implement several [SPL](http://php All of the following operations are possible on a `GraphNode`. -``` +```php $graphNode = $response->getGraphNode(); // Array access @@ -107,61 +107,61 @@ The following properties on the `GraphUser` collection will get automatically ca 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 getHometown() ``` Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. @@ -184,49 +184,49 @@ The following properties on the `GraphPage` collection will get automatically ca 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.) @@ -247,85 +247,85 @@ The following properties on the `GraphAlbum` collection will get automatically c 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. @@ -335,37 +335,37 @@ Returns the `type` property for the album as a string (`profile`, `mobile`, `wal 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. @@ -375,7 +375,7 @@ Returns the `longitude` property for the location as a float if present. 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. @@ -385,7 +385,7 @@ Returns the `url` property for the picture as a string if present. 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. @@ -396,121 +396,121 @@ 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. @@ -520,79 +520,79 @@ Returns the `invited_count` property (Number of people invited to the event) for 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 index d9bd57de9..9f2283981 100644 --- a/docs/reference/PersistentDataInterface.md +++ b/docs/reference/PersistentDataInterface.md @@ -8,7 +8,7 @@ If you're using a web framework that handles persistent data for you, you might For example if you are using Laravel, a custom handler might look like this: -``` +```php use Facebook\PersistentData\PersistentDataInterface; class MyLaravelPersistentDataHandler implements PersistentDataInterface @@ -38,7 +38,7 @@ class MyLaravelPersistentDataHandler implements PersistentDataInterface 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(), @@ -48,7 +48,7 @@ $fb = new Facebook\Facebook([ 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(); @@ -58,13 +58,13 @@ $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 index 9e4acffd3..a6409ed30 100644 --- a/docs/reference/PseudoRandomStringGeneratorInterface.md +++ b/docs/reference/PseudoRandomStringGeneratorInterface.md @@ -12,7 +12,7 @@ If your hosting environment does not support any of the CSPRSG methods used by t An example of implementing a custom CSPRSG: -``` +```php use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; class MyCustomPseudoRandomStringGenerator implements PseudoRandomStringGeneratorInterface @@ -33,7 +33,7 @@ class MyCustomPseudoRandomStringGenerator implements PseudoRandomStringGenerator 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(), @@ -43,7 +43,7 @@ $fb = new Facebook\Facebook([ 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(); @@ -53,7 +53,7 @@ $helper = new FacebookRedirectLoginHelper($fbApp, null, null, $myPseudoRandomStr ## 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 index 78e785b92..098dffe93 100644 --- a/docs/reference/SignedRequest.md +++ b/docs/reference/SignedRequest.md @@ -8,14 +8,14 @@ The `Facebook\SignedRequest` entity represents a signed request. 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 @@ -34,42 +34,42 @@ $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); diff --git a/docs/reference/UrlDetectionInterface.md b/docs/reference/UrlDetectionInterface.md index 3ff199530..7e14b2445 100644 --- a/docs/reference/UrlDetectionInterface.md +++ b/docs/reference/UrlDetectionInterface.md @@ -8,7 +8,7 @@ If you're using a web framework that handles routes and URL generation for you, For example if you are using Laravel, a custom handler might look like this: -``` +```php use Facebook\Url\UrlDetectionInterface; class MyLaravelUrlDetectionHandler implements UrlDetectionInterface @@ -25,7 +25,7 @@ class MyLaravelUrlDetectionHandler implements UrlDetectionInterface 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(), @@ -35,7 +35,7 @@ $fb = new Facebook\Facebook([ 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(); @@ -45,7 +45,7 @@ $helper = new FacebookRedirectLoginHelper($fbApp, null, $myUrlDetectionHandler); ## Method Reference ### getCurrentUrl() -``` +```php public string getCurrentUrl() ``` Returns the full and currently active URL. From 97ed3ee6109a9e1a7f5043c970078e1aee6eebf9 Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 18 Oct 2016 15:49:28 -0700 Subject: [PATCH 314/407] remove highlight for non php blocks --- docs/examples/access_token_from_javascript.md | 2 +- docs/examples/batch_request.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index 0c0b2a9ec..5df9db58e 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from the Facebo 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. -```php +``` diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index a944bb558..50d1513b1 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -86,7 +86,7 @@ There five requests being made in this batch requests. If the request was successful, the user should have a new status update similar to this: -```php +``` My name is Foo User. I like this page: Facebook Developers. From e4270f49d4fb8b8576a887b1589384fb56b8555d Mon Sep 17 00:00:00 2001 From: nayafia Date: Tue, 25 Oct 2016 12:27:34 -0700 Subject: [PATCH 315/407] first round of changes from review --- docs/examples/access_token_from_javascript.md | 2 +- docs/examples/upload_video.md | 2 +- docs/getting_started.md | 7 +- docs/reference.md | 64 +++++++++---------- docs/reference/FacebookApp.md | 2 +- docs/reference/FacebookResponseException.md | 12 ++-- docs/reference/GraphNode.md | 16 ++--- 7 files changed, 52 insertions(+), 53 deletions(-) diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index 5df9db58e..f248cfffc 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -6,7 +6,7 @@ This example covers obtaining an access token and signed request from the Facebo 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 diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index 548b7c212..cde1b5548 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -36,7 +36,7 @@ try { echo 'Video ID: ' . $response['video_id']; ``` -See more about the [`uploadVideo()` method](..reference/Facebook.md#uploadvideo). +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. diff --git a/docs/getting_started.md b/docs/getting_started.md index 99465ea6c..bcba6a054 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -22,13 +22,12 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta [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. -```php +``` composer require facebook/php-sdk-v4 +``` -> content: "The Facebook SDK starting adhering to [SemVer](http://semver.org/) with version 5. Previous to version 5, the SDK did not follow SemVer.", -> type: 'info', +> 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. diff --git a/docs/reference.md b/docs/reference.md index d9c9eb8f5..d6618ee80 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -8,8 +8,8 @@ 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. | +| [`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 @@ -17,10 +17,10 @@ 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. | +| [`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 @@ -28,11 +28,11 @@ 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. | +| [`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 @@ -41,10 +41,10 @@ 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. | +| [`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 @@ -52,8 +52,8 @@ 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. | +| [`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 @@ -62,14 +62,14 @@ Graph nodes are collections that represent nodes returned by the Graph API. And | 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. | +| [`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 @@ -78,8 +78,8 @@ 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. | +| [`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 @@ -87,8 +87,8 @@ You can overwrite certain functionality of the SDK by coding to an interface and | 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. | +| `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/FacebookApp.md b/docs/reference/FacebookApp.md index 280527a69..9650efb4a 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -2,7 +2,7 @@ In order to make requests to the Graph API, you need to [create a Facebook app](/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. -> content: "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.", +> content: "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.", > type: 'warning', ## Facebook\FacebookApp diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md index f7c7807bd..2bd848fbb 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -19,12 +19,12 @@ try { | 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. | +| `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). diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 9341ca7d2..7f088c015 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -100,9 +100,9 @@ The following properties on the `GraphUser` collection will get automatically ca | Property | GraphNode subtype | | ------------- | ------------- | -| `hometown` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | -| `location` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | -| `significant_other` | [`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods) | +| `hometown` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | +| `location` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | +| `significant_other` | [`Facebook\GraphNodes\GraphUser`](#user-instance-methods) | All getter methods return `null` if the property does not exist on the node. @@ -176,9 +176,9 @@ The following properties on the `GraphPage` collection will get automatically ca | Property | GraphNode subtype | | ------------- | ------------- | -| `best_page` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | -| `global_brand_parent_page` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | -| `location` | [`Facebook\\GraphNodes\\GraphLocation`](#location-instance-methods) | +| `best_page` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | +| `global_brand_parent_page` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | +| `location` | [`Facebook\GraphNodes\GraphLocation`](#location-instance-methods) | All getter methods return `null` if the property does not exist on the node. @@ -241,8 +241,8 @@ The following properties on the `GraphAlbum` collection will get automatically c | Property | GraphNode subtype | | ------------- | ------------- | -| `from` | [`Facebook\\GraphNodes\\GraphUser`](#user-instance-methods) | -| `place` | [`Facebook\\GraphNodes\\GraphPage`](#page-instance-methods) | +| `from` | [`Facebook\GraphNodes\GraphUser`](#user-instance-methods) | +| `place` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | All getter methods return `null` if the property does not exist on the node. From cb4a35281a3402e13216127305775a96b7a80c27 Mon Sep 17 00:00:00 2001 From: nayafia Date: Fri, 28 Oct 2016 16:46:37 -0700 Subject: [PATCH 316/407] fix blockquotes --- docs/examples/batch_request.md | 3 +- docs/examples/upload_video.md | 3 +- docs/getting_started.md | 31 ++++++------------- docs/reference/FacebookApp.md | 3 +- docs/reference/FacebookRedirectLoginHelper.md | 3 +- 5 files changed, 13 insertions(+), 30 deletions(-) diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index 50d1513b1..ce27cd899 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -96,8 +96,7 @@ My next 2 events are House Warming Party,Some Foo Event. It should also contain a response containing two photos from the user. -> content: "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).", -> type: 'warning', +> **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). ## Multiple User Example diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index cde1b5548..97592a9d8 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -4,8 +4,7 @@ This example covers uploading & posting a video to a user's timeline with the Fa ## Example -> content: "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.", -> type: 'warning', +> **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. diff --git a/docs/getting_started.md b/docs/getting_started.md index bcba6a054..35af1c300 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -41,12 +41,7 @@ require_once __DIR__ . '/vendor/autoload.php'; First, download the source code and unzip it wherever you like in your project. -%FB(devsite:markdown-wiki:button { - text: 'Download the SDK for PHP v5.0', - href: 'https://github.com/facebook/facebook-php-sdk-v4/archive/5.0-dev.zip', - size: 'large', - use: 'special', -}) +[Download the SDK for PHP v5.0](https://github.com/facebook/facebook-php-sdk-v4/archive/5.0-dev.zip) Then include the autoloader provided in the SDK at the top of your script. @@ -61,8 +56,7 @@ The autoloader should be able to auto-detect the proper location of the source c 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. -> content: "For this example we'll assume the root of your website is `/var/html`.", -> type: 'info', +> 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. @@ -85,8 +79,7 @@ require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; ## Configuration and setup -> content: "This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](/apps).", -> type: 'warning', +> **Warning:** This assumes you have already created and configured a Facebook App, which you can obtain from the [App Dashboard](/apps). Before we can send requests to the Graph API, we need to load our app configuration into the `Facebook\Facebook` service. @@ -100,8 +93,7 @@ $fb = new Facebook\Facebook([ 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](/apps). -> content: "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.", -> type: 'warning', +> **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). @@ -116,8 +108,7 @@ Most all request made to the Graph API require an access token. We can obtain us 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. -> content: "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.", -> type: 'info', +> 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 @@ -130,8 +121,7 @@ $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $pe echo 'Log in with Facebook!'; ``` -> content: "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.", -> type: 'warning', +> **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 @@ -164,8 +154,7 @@ if (isset($accessToken)) { 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. -> content: "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](#authentication-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](#authentication-javascript) the SDK for JavaScript set.", -> type: 'warning', +> **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](#authentication-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](#authentication-javascript) the SDK for JavaScript set. ```php # example-canvas-app.php @@ -189,8 +178,7 @@ if (isset($accessToken)) { } ``` -> content: "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)", -> type: 'info', +> 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 @@ -219,8 +207,7 @@ if (isset($accessToken)) { } ``` -> content: "Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](https://developers.facebook.com/docs/javascript/reference/v2.8). 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.", -> type: 'warning', +> **Warning:** Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](https://developers.facebook.com/docs/javascript/reference/v2.8). 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 diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index 9650efb4a..573d3d0bb 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -2,8 +2,7 @@ In order to make requests to the Graph API, you need to [create a Facebook app](/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. -> content: "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.", -> type: 'warning', +> **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 diff --git a/docs/reference/FacebookRedirectLoginHelper.md b/docs/reference/FacebookRedirectLoginHelper.md index 7a1b08787..9a908f475 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -37,8 +37,7 @@ $loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $pe echo 'Log in with Facebook!'; ``` -> content: "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.", -> type: 'warning', +> **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: From 003fe14ea138bb79aa67dfb98f7d5a069e63d843 Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Fri, 2 Dec 2016 23:39:47 +0000 Subject: [PATCH 317/407] Fix some links in the docs --- docs/getting_started.md | 10 +++++----- docs/reference/FacebookApp.md | 2 +- docs/reference/FacebookRequest.md | 1 + docs/reference/GraphNode.md | 28 ++++++++++++++-------------- docs/reference/SignedRequest.md | 2 +- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 35af1c300..27c5e5b7a 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -79,7 +79,7 @@ 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](/apps). +> **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. @@ -91,7 +91,7 @@ $fb = new Facebook\Facebook([ ]); ``` -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](/apps). +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. @@ -154,7 +154,7 @@ if (isset($accessToken)) { 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](#authentication-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](#authentication-javascript) the SDK for JavaScript set. +> **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 @@ -207,7 +207,7 @@ if (isset($accessToken)) { } ``` -> **Warning:** Make sure you set the `{cookie:true}` option when you [initialize the SDK for JavaScript](https://developers.facebook.com/docs/javascript/reference/v2.8). 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. +> **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.8). 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 @@ -255,7 +255,7 @@ 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#graphnode-instance-methods) entity which represents a user node. +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. diff --git a/docs/reference/FacebookApp.md b/docs/reference/FacebookApp.md index 573d3d0bb..2506fd301 100644 --- a/docs/reference/FacebookApp.md +++ b/docs/reference/FacebookApp.md @@ -1,6 +1,6 @@ # FacebookApp for the Facebook SDK for PHP -In order to make requests to the Graph API, you need to [create a Facebook app](/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. +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. diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index eb71b7034..dd8ba6d16 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -59,6 +59,7 @@ echo 'User name: ' . $graphNode['name']; ```php public setAccessToken(string|Facebook\AccessToken $accessToken) ``` +Sets the access token to be used for the request. ### getAccessToken() ```php diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 7f088c015..ea2577502 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -6,12 +6,12 @@ A `Facebook\GraphNodes\GraphNode` is a collection that represents a node returne This base class has several subclasses: -[__GraphUser__](#user-instance-methods) -[__GraphPage__](#page-instance-methods) -[__GraphAlbum__](#album-instance-methods) -[__GraphLocation__](#location-instance-methods) -[__GraphPicture__](#picture-instance-methods) -[__GraphAchievement__](#achievement-instance-methods) +[__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. @@ -100,9 +100,9 @@ The following properties on the `GraphUser` collection will get automatically ca | Property | GraphNode subtype | | ------------- | ------------- | -| `hometown` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | -| `location` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | -| `significant_other` | [`Facebook\GraphNodes\GraphUser`](#user-instance-methods) | +| `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. @@ -176,9 +176,9 @@ The following properties on the `GraphPage` collection will get automatically ca | Property | GraphNode subtype | | ------------- | ------------- | -| `best_page` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | -| `global_brand_parent_page` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | -| `location` | [`Facebook\GraphNodes\GraphLocation`](#location-instance-methods) | +| `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. @@ -241,8 +241,8 @@ The following properties on the `GraphAlbum` collection will get automatically c | Property | GraphNode subtype | | ------------- | ------------- | -| `from` | [`Facebook\GraphNodes\GraphUser`](#user-instance-methods) | -| `place` | [`Facebook\GraphNodes\GraphPage`](#page-instance-methods) | +| `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. diff --git a/docs/reference/SignedRequest.md b/docs/reference/SignedRequest.md index 098dffe93..70539f69c 100644 --- a/docs/reference/SignedRequest.md +++ b/docs/reference/SignedRequest.md @@ -4,7 +4,7 @@ The `Facebook\SignedRequest` entity represents a signed request. ## Facebook\SignedRequest -[Signed requests](https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin) 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. +[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. From 52ef69a89221925320b50e1f8e2bccec51b73e0d Mon Sep 17 00:00:00 2001 From: Alexandre Azevedo Date: Thu, 15 Dec 2016 17:48:00 +0100 Subject: [PATCH 318/407] Fix the exception message --- docs/examples/facebook_login.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index 5a7941b4c..823c1ce03 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -85,7 +85,7 @@ if (! $accessToken->isLongLived()) { try { $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken); } catch (Facebook\Exceptions\FacebookSDKException $e) { - echo "

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

\n\n"; + echo "

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

\n\n"; exit; } From 9ee5295af7d88f1fbfbc66e296d704cc848dcb90 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 23 Dec 2016 09:34:01 -0600 Subject: [PATCH 319/407] Fix reference link in docs --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 0223a7a39..229a2d763 100644 --- a/docs/README.md +++ b/docs/README.md @@ -31,4 +31,4 @@ The following examples demonstrate how you would accomplish common tasks with th ## API Reference -For a full list of classes, see the API [reference page](./sdk_reference.md). +For a full list of classes, see the API [reference page](./reference.md). From 678151d41bd57d9aaab2bdacae95d352cb3fdabb Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 23 Dec 2016 09:51:35 -0600 Subject: [PATCH 320/407] Fix link in docs --- docs/examples/upload_photo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index 4730ff803..180f82f55 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -4,7 +4,7 @@ This example covers uploading a photo to the current User's profile using the Gr 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). +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 From e243ba33ad96c4a393ab9f3f9416daf4e7de68e2 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 23 Dec 2016 09:54:35 -0600 Subject: [PATCH 321/407] Remove reference to mbstring requirement in the docs --- docs/getting_started.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 27c5e5b7a..bb4819893 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -11,7 +11,6 @@ It would be advantageous to familiarize yourself with the concepts of [namespaci ## System requirements - PHP 5.4 or greater -- The [mbstring](http://php.net/manual/en/book.mbstring.php) extension - [Composer](https://getcomposer.org/) *(optional)* ## Installing the Facebook SDK for PHP From 0f367aade2aa64bd1324a9c00de1e595ef4a2783 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 23 Dec 2016 10:00:34 -0600 Subject: [PATCH 322/407] Update references to old repo and packagist names to the new ones --- docs/getting_started.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index bb4819893..bfe8d328e 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -22,7 +22,7 @@ There are two methods to install the Facebook SDK for PHP. The recommended insta [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/php-sdk-v4 +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. @@ -40,12 +40,12 @@ require_once __DIR__ . '/vendor/autoload.php'; First, download the source code and unzip it wherever you like in your project. -[Download the SDK for PHP v5.0](https://github.com/facebook/facebook-php-sdk-v4/archive/5.0-dev.zip) +[Download the SDK for PHP v5.0](https://github.com/facebook/php-graph-sdk/archive/5.4.zip) Then include the autoloader provided in the SDK at the top of your script. ```php -require_once __DIR__ . '/path/to/facebook-php-sdk-v4/src/Facebook/autoload.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. From 4c4817c273c6bfa8b9072fe44036b56a1559f63d Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 23 Dec 2016 10:02:25 -0600 Subject: [PATCH 323/407] Remove minor version from link anchor --- docs/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index bfe8d328e..6f6303bf6 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -40,7 +40,7 @@ require_once __DIR__ . '/vendor/autoload.php'; First, download the source code and unzip it wherever you like in your project. -[Download the SDK for PHP v5.0](https://github.com/facebook/php-graph-sdk/archive/5.4.zip) +[Download the SDK for PHP v5](https://github.com/facebook/php-graph-sdk/archive/5.4.zip) Then include the autoloader provided in the SDK at the top of your script. From 73b8b441abedd1baad5a8ee736df20b8dde427ab Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 23 Dec 2016 10:29:10 -0600 Subject: [PATCH 324/407] Add "Security Vulnerabilities" section to README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index b02ecc1dd..fa8353f2d 100644 --- a/README.md +++ b/README.md @@ -87,3 +87,8 @@ For us to accept contributions you will have to first have signed the [Contribut ## License Please see the [license file](https://github.com/facebook/php-graph-sdk/blob/master/LICENSE) for more information. + + +## Security Vulnerabilities + +If you have found a security issue, please contact the maintainers directly at [me@sammyk.me](mailto:me@sammyk.me). From 5de90f666a7db32ec64f08aa02a257a033a73b2a Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Thu, 1 Dec 2016 12:28:10 +0000 Subject: [PATCH 325/407] Add FacebookBatchRequest factory method --- src/Facebook/Facebook.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 76ed77984..35bb7463d 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -494,6 +494,27 @@ public function sendBatchRequest(array $requests, $accessToken = null, $graphVer return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); } + /** + * Instantiates an empty FacebookBatchRequest entity. + * + * @param AccessToken|string|null $accessToken The top-level access token. Requests with no access token + * will fallback to this. + * @param string|null $graphVersion The Graph API version to use. + * @return FacebookBatchRequest + */ + public function newBatchRequest($accessToken = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + + return new FacebookBatchRequest( + $this->app, + [], + $accessToken, + $graphVersion + ); + } + /** * Instantiates a new FacebookRequest entity. * From 1355b8299b6312516d2d4768dc5a29884038ba66 Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 29 Dec 2016 14:06:18 +0100 Subject: [PATCH 326/407] Fix map implementation in GraphEdge class. --- src/Facebook/GraphNodes/GraphEdge.php | 14 ++++++++++++++ tests/GraphNodes/GraphEdgeTest.php | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/Facebook/GraphNodes/GraphEdge.php b/src/Facebook/GraphNodes/GraphEdge.php index 7c46c577c..730f855a0 100644 --- a/src/Facebook/GraphNodes/GraphEdge.php +++ b/src/Facebook/GraphNodes/GraphEdge.php @@ -235,4 +235,18 @@ public function getTotalCount() return null; } + + /** + * @{inherited} + */ + public function map(\Closure $callback) + { + return new static( + $this->request, + array_map($callback, $this->items, array_keys($this->items)), + $this->metaData, + $this->parentEdgeEndpoint, + $this->subclassName + ); + } } diff --git a/tests/GraphNodes/GraphEdgeTest.php b/tests/GraphNodes/GraphEdgeTest.php index 93c91a3fa..02b352199 100644 --- a/tests/GraphNodes/GraphEdgeTest.php +++ b/tests/GraphNodes/GraphEdgeTest.php @@ -26,6 +26,7 @@ use Facebook\FacebookApp; use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphEdge; +use Facebook\GraphNodes\GraphNode; class GraphEdgeTest extends \PHPUnit_Framework_TestCase { @@ -96,4 +97,28 @@ public function testCanInstantiateNewPaginationRequest() $this->assertEquals('/v1337/998899/photos?access_token=foo_token&after=foo_after_cursor&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&foo=bar&limit=25&pretty=0', $nextPage->getUrl()); $this->assertEquals('/v1337/998899/photos?access_token=foo_token&appsecret_proof=857d5f035a894f16b4180f19966e055cdeab92d4d53017b13dccd6d43b6497af&before=foo_before_cursor&foo=bar&limit=25&pretty=0', $prevPage->getUrl()); } + + public function testCanMapOverNodes() + { + $graphEdge = new GraphEdge( + $this->request, + [new GraphNode(['name' => 'dummy'])], + ['paging' => $this->pagination], + '/1234567890/likes' + ); + + $graphEdge = $graphEdge->map(function (GraphNode $node) { + $node['name'] = str_replace('dummy', 'foo', $node['name']); + return $node; + }); + + $graphEdgeToCompare = new GraphEdge( + $this->request, + [new GraphNode(['name' => 'foo'])], + ['paging' => $this->pagination], + '/1234567890/likes' + ); + + $this->assertEquals($graphEdgeToCompare, $graphEdge); + } } From 739e43570b3b781903ef400fb591451f9efcc1a9 Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 29 Dec 2016 15:38:48 +0100 Subject: [PATCH 327/407] Fix php doc block. --- src/Facebook/GraphNodes/GraphEdge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphEdge.php b/src/Facebook/GraphNodes/GraphEdge.php index 730f855a0..07117df98 100644 --- a/src/Facebook/GraphNodes/GraphEdge.php +++ b/src/Facebook/GraphNodes/GraphEdge.php @@ -237,7 +237,7 @@ public function getTotalCount() } /** - * @{inherited} + * @inheritDoc */ public function map(\Closure $callback) { From 34bf65026bf452e649aadd5765a33b0c2ce023cd Mon Sep 17 00:00:00 2001 From: Quentin Date: Thu, 29 Dec 2016 15:40:20 +0100 Subject: [PATCH 328/407] Improve test. --- tests/GraphNodes/GraphEdgeTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/GraphNodes/GraphEdgeTest.php b/tests/GraphNodes/GraphEdgeTest.php index 02b352199..d85a56662 100644 --- a/tests/GraphNodes/GraphEdgeTest.php +++ b/tests/GraphNodes/GraphEdgeTest.php @@ -102,7 +102,10 @@ public function testCanMapOverNodes() { $graphEdge = new GraphEdge( $this->request, - [new GraphNode(['name' => 'dummy'])], + [ + new GraphNode(['name' => 'dummy']), + new GraphNode(['name' => 'dummy']), + ], ['paging' => $this->pagination], '/1234567890/likes' ); @@ -114,7 +117,10 @@ public function testCanMapOverNodes() $graphEdgeToCompare = new GraphEdge( $this->request, - [new GraphNode(['name' => 'foo'])], + [ + new GraphNode(['name' => 'foo']), + new GraphNode(['name' => 'foo']) + ], ['paging' => $this->pagination], '/1234567890/likes' ); From eeab858c6f2afb8c2d5cd2668ea924c249c4b409 Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Thu, 1 Dec 2016 15:00:01 +0000 Subject: [PATCH 329/407] Add full batch support without breaking BC --- src/Facebook/FacebookBatchRequest.php | 65 ++++++++++++++++++--------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/Facebook/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php index d61d35779..46ecf8434 100644 --- a/src/Facebook/FacebookBatchRequest.php +++ b/src/Facebook/FacebookBatchRequest.php @@ -62,16 +62,17 @@ public function __construct(FacebookApp $app = null, array $requests = [], $acce } /** - * A a new request to the array. + * Adds a new request to the array. * * @param FacebookRequest|array $request - * @param string|null $name + * @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. * * @return FacebookBatchRequest * * @throws \InvalidArgumentException */ - public function add($request, $name = null) + public function add($request, $options = null) { if (is_array($request)) { foreach ($request as $key => $req) { @@ -85,17 +86,28 @@ public function add($request, $name = null) throw new \InvalidArgumentException('Argument for add() must be of type array or FacebookRequest.'); } + if (null === $options) { + $options = []; + } elseif (!is_array($options)) { + $options = ['name' => $options]; + } + $this->addFallbackDefaults($request); + + // File uploads + $attachedFiles = $this->extractFileAttachments($request); + + $name = isset($options['name']) ? $options['name'] : null; + + unset($options['name']); + $requestToAdd = [ 'name' => $name, 'request' => $request, + 'options' => $options, + 'attached_files' => $attachedFiles, ]; - // File uploads - $attachedFiles = $this->extractFileAttachments($request); - if ($attachedFiles) { - $requestToAdd['attached_files'] = $attachedFiles; - } $this->requests[] = $requestToAdd; return $this; @@ -189,8 +201,15 @@ public function convertRequestsToJson() { $requests = []; foreach ($this->requests as $request) { - $attachedFiles = isset($request['attached_files']) ? $request['attached_files'] : null; - $requests[] = $this->requestEntityToBatchArray($request['request'], $request['name'], $attachedFiles); + $options = []; + + if (null !== $request['name']) { + $options['name'] = $request['name']; + } + + $options += $request['options']; + + $requests[] = $this->requestEntityToBatchArray($request['request'], $options, $request['attached_files']); } return json_encode($requests); @@ -215,14 +234,22 @@ 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 $requestName The name of the request. - * @param string|null $attachedFiles Names of files associated with the request. + * @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 */ - public function requestEntityToBatchArray(FacebookRequest $request, $requestName = null, $attachedFiles = null) + public function requestEntityToBatchArray(FacebookRequest $request, $options = null, $attachedFiles = null) { + + if (null === $options) { + $options = []; + } elseif (!is_array($options)) { + $options = ['name' => $options]; + } + $compiledHeaders = []; $headers = $request->getHeaders(); foreach ($headers as $name => $value) { @@ -242,18 +269,12 @@ public function requestEntityToBatchArray(FacebookRequest $request, $requestName $batch['body'] = $body; } - if (isset($requestName)) { - $batch['name'] = $requestName; - } + $batch += $options; - if (isset($attachedFiles)) { + if (null !== $attachedFiles) { $batch['attached_files'] = $attachedFiles; } - // @TODO Add support for "omit_response_on_success" - // @TODO Add support for "depends_on" - // @TODO Add support for JSONP with "callback" - return $batch; } From 27e959b394a5a199075c1f84b06415cd3c6e9fbf Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Thu, 1 Dec 2016 17:29:08 +0000 Subject: [PATCH 330/407] Add test for FacebookBatchRequest factory method --- tests/FacebookTest.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/FacebookTest.php b/tests/FacebookTest.php index 1e6a4ab1c..5af4b72c2 100644 --- a/tests/FacebookTest.php +++ b/tests/FacebookTest.php @@ -304,6 +304,28 @@ public function testCreatingANewRequestWillDefaultToTheProperConfig() ); } + public function testCreatingANewBatchRequestWillDefaultToTheProperConfig() + { + $config = array_merge($this->config, [ + 'default_access_token' => 'foo_token', + 'enable_beta_mode' => true, + 'default_graph_version' => 'v1337', + ]); + $fb = new Facebook($config); + + $batchRequest = $fb->newBatchRequest(); + $this->assertEquals('1337', $batchRequest->getApp()->getId()); + $this->assertEquals('foo_secret', $batchRequest->getApp()->getSecret()); + $this->assertEquals('foo_token', (string)$batchRequest->getAccessToken()); + $this->assertEquals('v1337', $batchRequest->getGraphVersion()); + $this->assertEquals( + FacebookClient::BASE_GRAPH_URL_BETA, + $fb->getClient()->getBaseGraphUrl() + ); + $this->assertInstanceOf('Facebook\FacebookBatchRequest', $batchRequest); + $this->assertEquals(0, count($batchRequest->getRequests())); + } + public function testCanInjectCustomHandlers() { $config = array_merge($this->config, [ From f9e7d9936adbe7aa7c615ecc332d46dc6773cce7 Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Thu, 1 Dec 2016 16:05:22 +0000 Subject: [PATCH 331/407] Add tests for omit_response_on_success batch option --- tests/FacebookBatchRequestTest.php | 53 +++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/FacebookBatchRequestTest.php b/tests/FacebookBatchRequestTest.php index 4d41a6f4d..cf8a4d81b 100755 --- a/tests/FacebookBatchRequestTest.php +++ b/tests/FacebookBatchRequestTest.php @@ -280,6 +280,31 @@ public function testBatchRequestsWithFilesGetConvertedToAnArray() ], $batchRequestArray); } + public function testBatchRequestsWithOptionsGetConvertedToAnArray() + { + $request = new FacebookRequest(null, null, 'GET', '/bar'); + $batchRequest = $this->createBatchRequest(); + $batchRequest->add($request, [ + 'name' => 'foo_name', + 'omit_response_on_success' => false, + ]); + + $requests = $batchRequest->getRequests(); + + $options = $requests[0]['options']; + $options['name'] = $requests[0]['name']; + + $batchRequestArray = $batchRequest->requestEntityToBatchArray($requests[0]['request'], $options); + + $this->assertEquals([ + 'headers' => $this->defaultHeaders(), + 'method' => 'GET', + 'relative_url' => '/' . Facebook::DEFAULT_GRAPH_VERSION . '/bar?access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + 'name' => 'foo_name', + 'omit_response_on_success' => false, + ], $batchRequestArray); + } + public function testPreppingABatchRequestProperlySetsThePostParams() { $batchRequest = $this->createBatchRequest(); @@ -328,6 +353,30 @@ public function testPreppingABatchRequestProperlyMovesTheFiles() $this->assertEquals($expectedBatchParams, $params); } + public function testPreppingABatchRequestWithOptionsProperlySetsThePostParams() + { + $batchRequest = $this->createBatchRequest(); + $batchRequest->add(new FacebookRequest(null, null, 'GET', '/foo'), [ + 'name' => 'foo_name', + 'omit_response_on_success' => false, + ]); + + $batchRequest->prepareRequestsForBatch(); + $params = $batchRequest->getParams(); + + $expectedHeaders = json_encode($this->defaultHeaders()); + $version = Facebook::DEFAULT_GRAPH_VERSION; + + $expectedBatchParams = [ + 'batch' => '[{"headers":' . $expectedHeaders . ',"method":"GET","relative_url":"\\/' . $version . '\\/foo?access_token=foo_token&appsecret_proof=df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9",' + . '"name":"foo_name","omit_response_on_success":false}]', + 'include_headers' => true, + 'access_token' => 'foo_token', + 'appsecret_proof' => 'df4256903ba4e23636cc142117aa632133d75c642bd2a68955be1443bd14deb9', + ]; + $this->assertEquals($expectedBatchParams, $params); + } + private function assertRequestContainsAppAndToken(FacebookRequest $request, FacebookApp $expectedApp, $expectedToken) { $app = $request->getApp(); @@ -373,7 +422,9 @@ private function assertRequestsMatch($requests, $formattedRequests) foreach ($requests as $name => $request) { $expectedRequests[] = [ 'name' => $name, - 'request' => $request + 'request' => $request, + 'attached_files' => null, + 'options' => [], ]; } $this->assertEquals($expectedRequests, $formattedRequests); From 977e610797d954b95e90245982568d3723f3c6aa Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 30 Dec 2016 11:52:53 -0600 Subject: [PATCH 332/407] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5645f21f9..70de1afa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.4.3 (2016-12-30) + - 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) - 5.4.1 (2016-10-18) From 3e0f78787556375bb6ed52beaabfedbc16b5a4e8 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 30 Dec 2016 11:54:16 -0600 Subject: [PATCH 333/407] Update version number to 5.4.3 --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa8353f2d..a8eb74023 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.4.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.4)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.4) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.2-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.3-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 76ed77984..e77d886e5 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.4.2'; + const VERSION = '5.4.3'; /** * @const string Default Graph API version for requests. From e72810790afb7d195a7aba8b209789131a670891 Mon Sep 17 00:00:00 2001 From: freek Date: Mon, 2 Jan 2017 22:36:32 +0100 Subject: [PATCH 334/407] update copyright headers --- LICENSE | 2 +- src/Facebook/Authentication/AccessToken.php | 2 +- src/Facebook/Authentication/AccessTokenMetadata.php | 2 +- src/Facebook/Authentication/OAuth2Client.php | 2 +- src/Facebook/Exceptions/FacebookAuthenticationException.php | 2 +- src/Facebook/Exceptions/FacebookAuthorizationException.php | 2 +- src/Facebook/Exceptions/FacebookClientException.php | 2 +- src/Facebook/Exceptions/FacebookOtherException.php | 2 +- src/Facebook/Exceptions/FacebookResponseException.php | 2 +- src/Facebook/Exceptions/FacebookResumableUploadException.php | 2 +- src/Facebook/Exceptions/FacebookSDKException.php | 2 +- src/Facebook/Exceptions/FacebookServerException.php | 2 +- src/Facebook/Exceptions/FacebookThrottleException.php | 2 +- src/Facebook/Facebook.php | 2 +- src/Facebook/FacebookApp.php | 2 +- src/Facebook/FacebookBatchRequest.php | 2 +- src/Facebook/FacebookBatchResponse.php | 2 +- src/Facebook/FacebookClient.php | 2 +- src/Facebook/FacebookRequest.php | 2 +- src/Facebook/FacebookResponse.php | 2 +- src/Facebook/FileUpload/FacebookFile.php | 2 +- src/Facebook/FileUpload/FacebookResumableUploader.php | 2 +- src/Facebook/FileUpload/FacebookTransferChunk.php | 2 +- src/Facebook/FileUpload/FacebookVideo.php | 2 +- src/Facebook/FileUpload/Mimetypes.php | 2 +- src/Facebook/GraphNodes/Birthday.php | 2 +- src/Facebook/GraphNodes/Collection.php | 2 +- src/Facebook/GraphNodes/GraphAchievement.php | 2 +- src/Facebook/GraphNodes/GraphAlbum.php | 2 +- src/Facebook/GraphNodes/GraphApplication.php | 2 +- src/Facebook/GraphNodes/GraphCoverPhoto.php | 2 +- src/Facebook/GraphNodes/GraphEdge.php | 2 +- src/Facebook/GraphNodes/GraphEvent.php | 2 +- src/Facebook/GraphNodes/GraphGroup.php | 2 +- src/Facebook/GraphNodes/GraphList.php | 2 +- src/Facebook/GraphNodes/GraphLocation.php | 2 +- src/Facebook/GraphNodes/GraphNode.php | 2 +- src/Facebook/GraphNodes/GraphNodeFactory.php | 2 +- src/Facebook/GraphNodes/GraphObject.php | 2 +- src/Facebook/GraphNodes/GraphObjectFactory.php | 2 +- src/Facebook/GraphNodes/GraphPage.php | 2 +- src/Facebook/GraphNodes/GraphPicture.php | 2 +- src/Facebook/GraphNodes/GraphSessionInfo.php | 2 +- src/Facebook/GraphNodes/GraphUser.php | 2 +- src/Facebook/Helpers/FacebookCanvasHelper.php | 2 +- src/Facebook/Helpers/FacebookJavaScriptHelper.php | 2 +- src/Facebook/Helpers/FacebookPageTabHelper.php | 2 +- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 2 +- src/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php | 2 +- src/Facebook/Http/GraphRawResponse.php | 2 +- src/Facebook/Http/RequestBodyInterface.php | 2 +- src/Facebook/Http/RequestBodyMultipart.php | 2 +- src/Facebook/Http/RequestBodyUrlEncoded.php | 2 +- src/Facebook/HttpClients/FacebookCurl.php | 2 +- src/Facebook/HttpClients/FacebookCurlHttpClient.php | 2 +- src/Facebook/HttpClients/FacebookGuzzleHttpClient.php | 2 +- src/Facebook/HttpClients/FacebookHttpClientInterface.php | 2 +- src/Facebook/HttpClients/FacebookStream.php | 2 +- src/Facebook/HttpClients/FacebookStreamHttpClient.php | 2 +- src/Facebook/HttpClients/HttpClientsFactory.php | 2 +- .../PersistentData/FacebookMemoryPersistentDataHandler.php | 2 +- .../PersistentData/FacebookSessionPersistentDataHandler.php | 2 +- src/Facebook/PersistentData/PersistentDataFactory.php | 2 +- src/Facebook/PersistentData/PersistentDataInterface.php | 2 +- .../PseudoRandomString/McryptPseudoRandomStringGenerator.php | 2 +- .../PseudoRandomString/OpenSslPseudoRandomStringGenerator.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorFactory.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorInterface.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorTrait.php | 2 +- .../RandomBytesPseudoRandomStringGenerator.php | 2 +- .../PseudoRandomString/UrandomPseudoRandomStringGenerator.php | 2 +- src/Facebook/SignedRequest.php | 2 +- src/Facebook/Url/FacebookUrlDetectionHandler.php | 2 +- src/Facebook/Url/FacebookUrlManipulator.php | 2 +- src/Facebook/Url/UrlDetectionInterface.php | 2 +- src/Facebook/autoload.php | 2 +- src/Facebook/polyfills.php | 2 +- tests/Authentication/AccessTokenMetadataTest.php | 2 +- tests/Authentication/AccessTokenTest.php | 2 +- tests/Authentication/FooFacebookClientForOAuth2Test.php | 2 +- tests/Authentication/OAuth2ClientTest.php | 2 +- tests/Exceptions/FacebookResponseExceptionTest.php | 2 +- tests/FacebookAppTest.php | 2 +- tests/FacebookBatchRequestTest.php | 2 +- tests/FacebookBatchResponseTest.php | 2 +- tests/FacebookClientTest.php | 2 +- tests/FacebookRequestTest.php | 2 +- tests/FacebookResponseTest.php | 2 +- tests/FacebookTest.php | 2 +- tests/FacebookTestCredentials.php.dist | 2 +- tests/FileUpload/FacebookFileTest.php | 2 +- tests/FileUpload/FacebookResumableUploaderTest.php | 2 +- tests/FileUpload/MimetypesTest.php | 2 +- tests/Fixtures/FakeGraphApiForResumableUpload.php | 2 +- tests/Fixtures/FooBarPseudoRandomStringGenerator.php | 2 +- tests/Fixtures/FooClientInterface.php | 2 +- tests/Fixtures/FooPersistentDataInterface.php | 2 +- tests/Fixtures/FooPseudoRandomStringGenerator.php | 2 +- tests/Fixtures/FooRedirectLoginOAuth2Client.php | 2 +- tests/Fixtures/FooSignedRequestHelper.php | 2 +- tests/Fixtures/FooSignedRequestHelperFacebookClient.php | 2 +- tests/Fixtures/FooUrlDetectionInterface.php | 2 +- tests/Fixtures/MyFooBarPseudoRandomStringGenerator.php | 2 +- tests/Fixtures/MyFooBatchClientHandler.php | 2 +- tests/Fixtures/MyFooClientHandler.php | 2 +- tests/Fixtures/MyFooGraphNode.php | 2 +- tests/Fixtures/MyFooSubClassGraphNode.php | 2 +- tests/GraphNodes/AbstractGraphNode.php | 2 +- tests/GraphNodes/CollectionTest.php | 2 +- tests/GraphNodes/GraphAchievementTest.php | 2 +- tests/GraphNodes/GraphAlbumTest.php | 2 +- tests/GraphNodes/GraphEdgeTest.php | 2 +- tests/GraphNodes/GraphEventTest.php | 2 +- tests/GraphNodes/GraphGroupTest.php | 2 +- tests/GraphNodes/GraphNodeFactoryTest.php | 2 +- tests/GraphNodes/GraphNodeTest.php | 2 +- tests/GraphNodes/GraphObjectFactoryTest.php | 2 +- tests/GraphNodes/GraphPageTest.php | 2 +- tests/GraphNodes/GraphSessionInfoTest.php | 2 +- tests/GraphNodes/GraphUserTest.php | 2 +- tests/Helpers/FacebookCanvasHelperTest.php | 2 +- tests/Helpers/FacebookJavaScriptHelperTest.php | 2 +- tests/Helpers/FacebookPageTabHelperTest.php | 2 +- tests/Helpers/FacebookRedirectLoginHelperTest.php | 2 +- tests/Helpers/FacebookSignedRequestFromInputHelperTest.php | 2 +- tests/Http/GraphRawResponseTest.php | 2 +- tests/Http/RequestBodyMultipartTest.php | 2 +- tests/Http/RequestUrlEncodedTest.php | 2 +- tests/HttpClients/AbstractTestHttpClient.php | 2 +- tests/HttpClients/FacebookCurlHttpClientTest.php | 2 +- tests/HttpClients/FacebookGuzzleHttpClientTest.php | 2 +- tests/HttpClients/FacebookStreamHttpClientTest.php | 2 +- tests/HttpClients/HttpClientsFactoryTest.php | 2 +- .../PersistentData/FacebookMemoryPersistentDataHandlerTest.php | 2 +- .../PersistentData/FacebookSessionPersistentDataHandlerTest.php | 2 +- tests/PersistentData/PersistentDataFactoryTest.php | 2 +- .../McryptPseudoRandomStringGeneratorTest.php | 2 +- .../OpenSslPseudoRandomStringGeneratorTest.php | 2 +- tests/PseudoRandomString/PseudoRandomStringFactoryTest.php | 2 +- .../PseudoRandomString/PseudoRandomStringGeneratorTraitTest.php | 2 +- .../RandomBytesPseudoRandomStringGeneratorTest.php | 2 +- .../UrandomPseudoRandomStringGeneratorTest.php | 2 +- tests/SignedRequestTest.php | 2 +- tests/Url/FacebookUrlDetectionHandlerTest.php | 2 +- tests/Url/FacebookUrlManipulatorTest.php | 2 +- tests/bootstrap.php | 2 +- 146 files changed, 146 insertions(+), 146 deletions(-) diff --git a/LICENSE b/LICENSE index 458f22e92..8b93109ab 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2016 Facebook, Inc. +Copyright 2017 Facebook, Inc. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary diff --git a/src/Facebook/Authentication/AccessToken.php b/src/Facebook/Authentication/AccessToken.php index 867f752eb..5d7007334 100644 --- a/src/Facebook/Authentication/AccessToken.php +++ b/src/Facebook/Authentication/AccessToken.php @@ -1,6 +1,6 @@ Date: Thu, 19 Jan 2017 09:07:50 -0600 Subject: [PATCH 335/407] Add MIME type for SRT files --- src/Facebook/FileUpload/Mimetypes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Facebook/FileUpload/Mimetypes.php b/src/Facebook/FileUpload/Mimetypes.php index 1eb9af141..95d399245 100644 --- a/src/Facebook/FileUpload/Mimetypes.php +++ b/src/Facebook/FileUpload/Mimetypes.php @@ -724,6 +724,7 @@ class Mimetypes 'spq' => 'application/scvp-vp-request', 'spx' => 'audio/ogg', 'src' => 'application/x-wais-source', + 'srt' => 'application/octet-stream', 'sru' => 'application/sru+xml', 'srx' => 'application/sparql-results+xml', 'sse' => 'application/vnd.kodak-descriptor', From 5d0c4865e80e231d48a4571841bd018828fe58e1 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Thu, 19 Jan 2017 09:42:20 -0600 Subject: [PATCH 336/407] Update CHANGELOG and version bump --- CHANGELOG.md | 2 ++ README.md | 2 +- src/Facebook/Facebook.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70de1afa9..dd1e67f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.4.4 (2017-01-19) + - 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) - 5.4.2 (2016-11-15) diff --git a/README.md b/README.md index a8eb74023..f7343be25 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.4.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.4)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.4) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.3-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.4-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index df30bdb21..18d0213f8 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.4.3'; + const VERSION = '5.4.4'; /** * @const string Default Graph API version for requests. From db7cb879963951f8ba7024a44bcb2a5fc9a6f32d Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Sat, 31 Dec 2016 01:36:00 +0200 Subject: [PATCH 337/407] Add docs for batch request factory method --- docs/reference/Facebook.md | 17 +++++++++++++++++ docs/reference/FacebookBatchRequest.md | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md index 216465290..848ccae02 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -349,6 +349,23 @@ $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() diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index 6f3e44823..587dd19ba 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -4,7 +4,8 @@ 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. +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; From 177b2e9c82b5fa654f62bb797553fb76168629cb Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Sat, 31 Dec 2016 01:33:00 +0200 Subject: [PATCH 338/407] Update docs of FacebookBatchRequest::add method --- docs/reference/FacebookBatchRequest.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/reference/FacebookBatchRequest.md b/docs/reference/FacebookBatchRequest.md index 587dd19ba..c3d40dc53 100644 --- a/docs/reference/FacebookBatchRequest.md +++ b/docs/reference/FacebookBatchRequest.md @@ -62,9 +62,9 @@ Since the `Facebook\FacebookBatchRequest` is extended from the [`Facebook\Facebo ### add() ```php public add( - array|Facebook\FacebookBatchRequest $request, - string|null $name - ) + 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. From 7f8685fad7a001a9d089f3b7ba969dd79a1e90d6 Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Sat, 31 Dec 2016 01:40:00 +0200 Subject: [PATCH 339/407] Add example for 'omit_response_on_success' option --- docs/examples/batch_request.md | 65 +++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index ce27cd899..bf695d5b2 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -96,7 +96,70 @@ 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). +> **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.8', +]); + +// 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"; + } +} + +``` ## Multiple User Example From 16a6a0ca5ee43eb84038266453de2f5ebc29a34f Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Sat, 31 Dec 2016 01:53:00 +0200 Subject: [PATCH 340/407] Add example for 'depends_on' option --- docs/examples/batch_request.md | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index bf695d5b2..2e4441d71 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -161,6 +161,75 @@ foreach ($responses as $key => $response) { ``` +## 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.8', +]); + +// 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. From 4980f3a9981da7b3b150b5281aee0fbf4b7a3504 Mon Sep 17 00:00:00 2001 From: Aristotelis Dossas Date: Thu, 12 Jan 2017 20:43:42 +0000 Subject: [PATCH 341/407] Fix batch examples to comply with PSR2 --- docs/examples/batch_request.md | 97 ++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index 2e4441d71..518e97d42 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -7,11 +7,12 @@ This example covers sending a batch request with the Facebook SDK for PHP. 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.8', - ]); + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.8', +]); // Since all the requests will be sent on behalf of the same user, // we'll set the default fallback access token here. @@ -51,29 +52,30 @@ $batch = [ 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; + $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"; - } + 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. @@ -235,41 +237,42 @@ foreach ($responses as $key => $response) { 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.8', - ]); + 'app_id' => '{app-id}', + 'app_secret' => '{app-secret}', + 'default_graph_version' => 'v2.8', +]); $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; + $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"; - } + 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"; + } } ``` From 44ba4951dba17ab842e6fd5d54f894d2483181dd Mon Sep 17 00:00:00 2001 From: Klaus Breyer Date: Mon, 20 Mar 2017 06:17:36 +0100 Subject: [PATCH 342/407] Update README.md Updated README for clearer Guzzle compatibility like discussed here: https://github.com/facebook/php-graph-sdk/issues/754#issuecomment-285962509 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f7343be25..53fe1b989 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). composer require facebook/graph-sdk ``` +Please be aware, that there are issues when using the Facebook SDK together witz [Guzzle](https://github.com/guzzle/guzzle) 6.x. php-graph-sdk v5.x only works with Guzzle 5.x out of the box. However, [there is a workaround to make it work with Guzzle 6.x](https://www.sammyk.me/how-to-inject-your-own-http-client-in-the-facebook-php-sdk-v5#writing-a-guzzle-6-http-client-implementation-from-scratch). + ## Upgrading to v5.x Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [read the upgrade guide](https://www.sammyk.me/upgrading-the-facebook-php-sdk-from-v4-to-v5) before upgrading. From dfeb533d33d236da2c9059ab3e2baf80c741ed7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emir=20Beganovi=C4=87?= Date: Fri, 14 Apr 2017 17:49:08 +0200 Subject: [PATCH 343/407] Add PHP 7.1 to Travis build --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index ee6153074..f83d30778 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ php: - 5.5 - 5.6 - 7.0 + - 7.1 - hhvm sudo: false From a854eb0f0168cbe5ee29f6c068f45a1db88ba76c Mon Sep 17 00:00:00 2001 From: Emir Beganovic Date: Fri, 14 Apr 2017 18:31:21 +0200 Subject: [PATCH 344/407] Mark test as skipped from 7.1 --- .../McryptPseudoRandomStringGeneratorTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php b/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php index cdb05ba4c..f5e033675 100644 --- a/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php +++ b/tests/PseudoRandomString/McryptPseudoRandomStringGeneratorTest.php @@ -29,6 +29,10 @@ class McryptPseudoRandomStringGeneratorTest extends \PHPUnit_Framework_TestCase { public function testCanGenerateRandomStringOfArbitraryLength() { + if (version_compare(PHP_VERSION, '7.1', '>=')) { + $this->markTestSkipped('Skipping test mcrypt is deprecated from 7.1'); + } + if (!function_exists('mcrypt_create_iv')) { $this->markTestSkipped( 'Mcrypt must be installed to test mcrypt_create_iv().' From c0e6d8287566a57bc32f4ef85b5c0b6ff476e4d0 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Thu, 20 Apr 2017 09:09:10 -0500 Subject: [PATCH 345/407] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd1e67f21..1bd15d158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.5.0 (2017-04-20) + - Added support for batch options (#713) - 5.4.4 (2017-01-19) - Added the `application/octet-stream` MIME type for SRT files (#734) - 5.4.3 (2016-12-30) From aaee490423d428b115401f03792508e701c81ddc Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Thu, 20 Apr 2017 09:12:49 -0500 Subject: [PATCH 346/407] Bump Graph API version to v2.9 --- README.md | 2 +- docs/examples/access_token_from_canvas.md | 2 +- docs/examples/access_token_from_javascript.md | 4 ++-- docs/examples/access_token_from_page_tab.md | 2 +- docs/examples/batch_request.md | 8 ++++---- docs/examples/batch_upload.md | 2 +- docs/examples/facebook_login.md | 4 ++-- docs/examples/pagination_basic.md | 2 +- docs/examples/post_links.md | 2 +- docs/examples/retrieve_user_profile.md | 2 +- docs/examples/upload_photo.md | 2 +- docs/examples/upload_video.md | 2 +- docs/getting_started.md | 4 ++-- docs/reference/Facebook.md | 8 ++++---- docs/reference/FacebookRequest.md | 2 +- src/Facebook/Facebook.php | 2 +- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 53fe1b989..e770989f8 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Simple GET example of a user's profile. $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', //'default_access_token' => '{access-token}', // optional ]); diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index 6429322e9..27b655cee 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -10,7 +10,7 @@ A signed request will be sent to your app via the HTTP POST method within the co $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $helper = $fb->getCanvasHelper(); diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index f248cfffc..738c83956 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -29,7 +29,7 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh FB.init({ appId: 'your-app-id', cookie: true, // This is important, it's not enabled by default - version: 'v2.8' + version: 'v2.9' }); }; @@ -52,7 +52,7 @@ After the user successfully logs in, redirect the user (or make an AJAX request) $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $helper = $fb->getJavaScriptHelper(); diff --git a/docs/examples/access_token_from_page_tab.md b/docs/examples/access_token_from_page_tab.md index 1bf4f6cd2..0d3936e6d 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -10,7 +10,7 @@ Page tabs behave much like the app canvas. The PHP SDK provides a helper for pag $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $helper = $fb->getPageTabHelper(); diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index 518e97d42..8e3987f18 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -11,7 +11,7 @@ The following example assumes we have the following permissions granted from the $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); // Since all the requests will be sent on behalf of the same user, @@ -109,7 +109,7 @@ The following example is a subset of the [first example](#example). We will only $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); // Since all the requests will be sent on behalf of the same user, @@ -176,7 +176,7 @@ Since we want the second request to be executed after the first one is completed $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); // Since all the requests will be sent on behalf of the same user, @@ -241,7 +241,7 @@ Since the requests sent in a batch are unrelated by default, we can make request $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $batch = [ diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index 386e3da7e..29a641c4f 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -12,7 +12,7 @@ The following example will upload two photos and one video. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); // Since all the requests will be sent on behalf of the same user, diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index 823c1ce03..86c373b3f 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -14,7 +14,7 @@ In this example, the PHP script that generates the login link is called `/login. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $helper = $fb->getRedirectLoginHelper(); @@ -31,7 +31,7 @@ echo 'Log in with Facebook!'; $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $helper = $fb->getRedirectLoginHelper(); diff --git a/docs/examples/pagination_basic.md b/docs/examples/pagination_basic.md index 4390c653c..ecce8892e 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -12,7 +12,7 @@ In this example we'll pull five entries from a user's feed (assuming the user ap $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); try { diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index 0c866044b..30cf7eaa6 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $linkData = [ diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md index 74619e0e2..5b6c79f21 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); try { diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index 180f82f55..28dd585df 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $data = [ diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index 97592a9d8..8b68a6f58 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -12,7 +12,7 @@ The following example will upload a video in chunks using the [resumable upload] $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); $data = [ diff --git a/docs/getting_started.md b/docs/getting_started.md index 6f6303bf6..8a4804b3c 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -86,7 +86,7 @@ Before we can send requests to the Graph API, we need to load our app configurat $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', ]); ``` @@ -206,7 +206,7 @@ if (isset($accessToken)) { } ``` -> **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.8). 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. +> **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.9). 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 diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md index 848ccae02..bacb9c4a9 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -10,7 +10,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', // . . . ]); ``` @@ -48,7 +48,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.8', + 'default_graph_version' => 'v2.9', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), @@ -69,7 +69,7 @@ The default fallback access token to use if one is not explicitly provided. The 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.8`. Defaults to the [latest version of Graph](https://developers.facebook.com/docs/apps/changelog). +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.9`. 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. @@ -317,7 +317,7 @@ public Facebook\FacebookResponse sendRequest( Sends a request to the Graph API. ```php -$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.8'); +$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.9'); ``` ## sendBatchRequest() diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index dd8ba6d16..8d69e46b9 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -176,5 +176,5 @@ $fb = new Facebook\Facebook(/* . . . */); $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); -// /v2.8/me?fields=id,name&access_token=token&appsecret_proof=proof +// /v2.9/me?fields=id,name&access_token=token&appsecret_proof=proof ``` diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index ae7cd68a2..22cd41232 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -58,7 +58,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.8'; + const DEFAULT_GRAPH_VERSION = 'v2.9'; /** * @const string The name of the environment variable that contains the app ID. From bacd9025f19d67f47a982a4e7a6d46dd839672a1 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Thu, 20 Apr 2017 09:13:10 -0500 Subject: [PATCH 347/407] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bd15d158..a3bd7e735 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 5.5.0 (2017-04-20) - 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) - 5.4.3 (2016-12-30) From 93d7dc87e55a541d2e27d38f3aed40abbffdf6e1 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Thu, 20 Apr 2017 09:15:02 -0500 Subject: [PATCH 348/407] Bump SDK version to 5.5.0 --- README.md | 6 +++--- src/Facebook/Facebook.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e770989f8..ca12379ef 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Facebook SDK for PHP (v5) -[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.4.svg)](https://travis-ci.org/facebook/php-graph-sdk) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.4)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.4) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.4.4-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.5.svg)](https://travis-ci.org/facebook/php-graph-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.5)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.5) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.5.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 22cd41232..d132973f2 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.4.4'; + const VERSION = '5.5.0'; /** * @const string Default Graph API version for requests. From d1a402667443a5dd5ac0e3298d40aebcc7985baa Mon Sep 17 00:00:00 2001 From: Dan Kruss Date: Tue, 30 May 2017 16:02:35 +0200 Subject: [PATCH 349/407] Update README.md random spelling thing. Eye caught it. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca12379ef..542bb8d8c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). composer require facebook/graph-sdk ``` -Please be aware, that there are issues when using the Facebook SDK together witz [Guzzle](https://github.com/guzzle/guzzle) 6.x. php-graph-sdk v5.x only works with Guzzle 5.x out of the box. However, [there is a workaround to make it work with Guzzle 6.x](https://www.sammyk.me/how-to-inject-your-own-http-client-in-the-facebook-php-sdk-v5#writing-a-guzzle-6-http-client-implementation-from-scratch). +Please be aware, that there are issues when using the Facebook SDK together with [Guzzle](https://github.com/guzzle/guzzle) 6.x. php-graph-sdk v5.x only works with Guzzle 5.x out of the box. However, [there is a workaround to make it work with Guzzle 6.x](https://www.sammyk.me/how-to-inject-your-own-http-client-in-the-facebook-php-sdk-v5#writing-a-guzzle-6-http-client-implementation-from-scratch). ## Upgrading to v5.x From 3769e967ce1165790f92e4a10f7f7849876daaf0 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Tue, 27 Jun 2017 16:14:47 -0400 Subject: [PATCH 350/407] Wrong method call documentation --- docs/reference/GraphNode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index ea2577502..5c05f68a5 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -162,7 +162,7 @@ Returns the `hometown` property for the user as a `Facebook\GraphNodes\GraphPage ### getSignificantOther() ```php -public Facebook\GraphNodes\GraphUser|null getHometown() +public Facebook\GraphNodes\GraphUser|null getSignificantOther() ``` Returns the `significant_other` property for the user as a `Facebook\GraphNodes\GraphUser` if present. From 29e3b9e4d155144ae02b7432c842829a9aa515e1 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Fri, 30 Jun 2017 13:50:46 +0200 Subject: [PATCH 351/407] Fix Travis build for 5.5 --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f83d30778..a7877aee4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ php: - 5.6 - 7.0 - 7.1 - - hhvm sudo: false @@ -14,6 +13,11 @@ cache: directories: - $HOME/.composer/cache +matrix: + include: + - php: hhvm + dist: trusty + before_install: - travis_retry composer self-update From eb4b61be9067af6db0a9afed8781b447aa6c80e5 Mon Sep 17 00:00:00 2001 From: Jean Baptiste Noblot Date: Fri, 30 Jun 2017 20:03:21 +0200 Subject: [PATCH 352/407] Fix documentation #789 Fix #789 --- docs/reference/GraphNode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 5c05f68a5..557030325 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -26,7 +26,7 @@ $response = $fb->get('/something'); $graphNode = $response->getGraphNode(); // Get the response typed as a GraphUser -$user = $response->getGraphUser()); +$user = $response->getGraphUser(); // Get the response typed as a GraphPage $page = $response->getGraphPage(); From 7300943d07fec1ecbf574b8a78db7d09a0a9c743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20=C3=85kerberg?= Date: Wed, 5 Jul 2017 23:55:53 +0200 Subject: [PATCH 353/407] getFanCount() method to GraphPage. (get pagelikes) --- src/Facebook/GraphNodes/GraphPage.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Facebook/GraphNodes/GraphPage.php b/src/Facebook/GraphNodes/GraphPage.php index 3dfb0e031..503b96b55 100644 --- a/src/Facebook/GraphNodes/GraphPage.php +++ b/src/Facebook/GraphNodes/GraphPage.php @@ -144,4 +144,14 @@ public function getPerms() { return $this->getField('perms'); } + + /** + * Returns the `fan_count` (Number of people who likes to page) as int if present. + * + * @return int|null + */ + public function getFanCount() + { + return $this->getField('fan_count'); + } } From 7c62b6a73d443e0a39ab071c3d88593f94ed83ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Mat=C4=9Bj=C4=8Dek?= Date: Fri, 14 Jul 2017 09:06:13 +0200 Subject: [PATCH 354/407] Fix phpdoc --- src/Facebook/Authentication/OAuth2Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/Authentication/OAuth2Client.php b/src/Facebook/Authentication/OAuth2Client.php index 19773ea0f..94df9b7b5 100644 --- a/src/Facebook/Authentication/OAuth2Client.php +++ b/src/Facebook/Authentication/OAuth2Client.php @@ -125,8 +125,8 @@ 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 array $scope An array of permissions to request. * @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(). * From ff0226eec0661d10221f32f0076d1da43f8ea69b Mon Sep 17 00:00:00 2001 From: dylan_DPC Date: Sun, 23 Jul 2017 16:51:20 +0530 Subject: [PATCH 355/407] default version bumped to 2.10 everywhere --- README.md | 2 +- docs/examples/access_token_from_canvas.md | 2 +- docs/examples/access_token_from_javascript.md | 4 ++-- docs/examples/access_token_from_page_tab.md | 2 +- docs/examples/batch_request.md | 8 ++++---- docs/examples/batch_upload.md | 2 +- docs/examples/facebook_login.md | 4 ++-- docs/examples/pagination_basic.md | 2 +- docs/examples/post_links.md | 2 +- docs/examples/retrieve_user_profile.md | 2 +- docs/examples/upload_photo.md | 2 +- docs/examples/upload_video.md | 2 +- docs/getting_started.md | 4 ++-- docs/reference/Facebook.md | 8 ++++---- docs/reference/FacebookRequest.md | 2 +- src/Facebook/Facebook.php | 2 +- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 542bb8d8c..a7a89c56b 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Simple GET example of a user's profile. $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', //'default_access_token' => '{access-token}', // optional ]); diff --git a/docs/examples/access_token_from_canvas.md b/docs/examples/access_token_from_canvas.md index 27b655cee..447582f09 100644 --- a/docs/examples/access_token_from_canvas.md +++ b/docs/examples/access_token_from_canvas.md @@ -10,7 +10,7 @@ A signed request will be sent to your app via the HTTP POST method within the co $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $helper = $fb->getCanvasHelper(); diff --git a/docs/examples/access_token_from_javascript.md b/docs/examples/access_token_from_javascript.md index 738c83956..f67ab5a59 100644 --- a/docs/examples/access_token_from_javascript.md +++ b/docs/examples/access_token_from_javascript.md @@ -29,7 +29,7 @@ In order to have the JavaScript SDK set a cookie containing a signed request (wh FB.init({ appId: 'your-app-id', cookie: true, // This is important, it's not enabled by default - version: 'v2.9' + version: 'v2.10' }); }; @@ -52,7 +52,7 @@ After the user successfully logs in, redirect the user (or make an AJAX request) $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $helper = $fb->getJavaScriptHelper(); diff --git a/docs/examples/access_token_from_page_tab.md b/docs/examples/access_token_from_page_tab.md index 0d3936e6d..26748337d 100644 --- a/docs/examples/access_token_from_page_tab.md +++ b/docs/examples/access_token_from_page_tab.md @@ -10,7 +10,7 @@ Page tabs behave much like the app canvas. The PHP SDK provides a helper for pag $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $helper = $fb->getPageTabHelper(); diff --git a/docs/examples/batch_request.md b/docs/examples/batch_request.md index 8e3987f18..64b296e8e 100644 --- a/docs/examples/batch_request.md +++ b/docs/examples/batch_request.md @@ -11,7 +11,7 @@ The following example assumes we have the following permissions granted from the $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); // Since all the requests will be sent on behalf of the same user, @@ -109,7 +109,7 @@ The following example is a subset of the [first example](#example). We will only $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); // Since all the requests will be sent on behalf of the same user, @@ -176,7 +176,7 @@ Since we want the second request to be executed after the first one is completed $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); // Since all the requests will be sent on behalf of the same user, @@ -241,7 +241,7 @@ Since the requests sent in a batch are unrelated by default, we can make request $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $batch = [ diff --git a/docs/examples/batch_upload.md b/docs/examples/batch_upload.md index 29a641c4f..25dc87467 100644 --- a/docs/examples/batch_upload.md +++ b/docs/examples/batch_upload.md @@ -12,7 +12,7 @@ The following example will upload two photos and one video. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); // Since all the requests will be sent on behalf of the same user, diff --git a/docs/examples/facebook_login.md b/docs/examples/facebook_login.md index 86c373b3f..d1a6a3403 100644 --- a/docs/examples/facebook_login.md +++ b/docs/examples/facebook_login.md @@ -14,7 +14,7 @@ In this example, the PHP script that generates the login link is called `/login. $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $helper = $fb->getRedirectLoginHelper(); @@ -31,7 +31,7 @@ echo 'Log in with Facebook!'; $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $helper = $fb->getRedirectLoginHelper(); diff --git a/docs/examples/pagination_basic.md b/docs/examples/pagination_basic.md index ecce8892e..635798f3c 100644 --- a/docs/examples/pagination_basic.md +++ b/docs/examples/pagination_basic.md @@ -12,7 +12,7 @@ In this example we'll pull five entries from a user's feed (assuming the user ap $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); try { diff --git a/docs/examples/post_links.md b/docs/examples/post_links.md index 30cf7eaa6..29cd09bbb 100644 --- a/docs/examples/post_links.md +++ b/docs/examples/post_links.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $linkData = [ diff --git a/docs/examples/retrieve_user_profile.md b/docs/examples/retrieve_user_profile.md index 5b6c79f21..6df0d8a56 100644 --- a/docs/examples/retrieve_user_profile.md +++ b/docs/examples/retrieve_user_profile.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); try { diff --git a/docs/examples/upload_photo.md b/docs/examples/upload_photo.md index 28dd585df..6b6041907 100644 --- a/docs/examples/upload_photo.md +++ b/docs/examples/upload_photo.md @@ -12,7 +12,7 @@ For more information, see the documentation for [`Facebook\Facebook`](../referen $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $data = [ diff --git a/docs/examples/upload_video.md b/docs/examples/upload_video.md index 8b68a6f58..2aea43eb7 100644 --- a/docs/examples/upload_video.md +++ b/docs/examples/upload_video.md @@ -12,7 +12,7 @@ The following example will upload a video in chunks using the [resumable upload] $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); $data = [ diff --git a/docs/getting_started.md b/docs/getting_started.md index 8a4804b3c..b03176560 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -86,7 +86,7 @@ Before we can send requests to the Graph API, we need to load our app configurat $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', ]); ``` @@ -206,7 +206,7 @@ if (isset($accessToken)) { } ``` -> **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.9). 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. +> **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 diff --git a/docs/reference/Facebook.md b/docs/reference/Facebook.md index bacb9c4a9..732f9abf6 100644 --- a/docs/reference/Facebook.md +++ b/docs/reference/Facebook.md @@ -10,7 +10,7 @@ To instantiate a new `Facebook\Facebook` service, pass an array of configuration $fb = new Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', // . . . ]); ``` @@ -48,7 +48,7 @@ $fb = new Facebook\Facebook([ 'app_secret' => '{app-secret}', 'default_access_token' => '{access-token}', 'enable_beta_mode' => true, - 'default_graph_version' => 'v2.9', + 'default_graph_version' => 'v2.10', 'http_client_handler' => 'guzzle', 'persistent_data_handler' => 'memory', 'url_detection_handler' => new MyUrlDetectionHandler(), @@ -69,7 +69,7 @@ The default fallback access token to use if one is not explicitly provided. The 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.9`. Defaults to the [latest version of Graph](https://developers.facebook.com/docs/apps/changelog). +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. @@ -317,7 +317,7 @@ public Facebook\FacebookResponse sendRequest( Sends a request to the Graph API. ```php -$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.9'); +$response = $fb->sendRequest('GET', '/me', [], '{access-token}', 'eTag', 'v2.10'); ``` ## sendBatchRequest() diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 8d69e46b9..31c0dfcf2 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -176,5 +176,5 @@ $fb = new Facebook\Facebook(/* . . . */); $request = $fb->request('GET', '/me', ['fields' => 'id,name']); $url = $request->getUrl(); -// /v2.9/me?fields=id,name&access_token=token&appsecret_proof=proof +// /v2.10/me?fields=id,name&access_token=token&appsecret_proof=proof ``` diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index d132973f2..8f8b54400 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -58,7 +58,7 @@ class Facebook /** * @const string Default Graph API version for requests. */ - const DEFAULT_GRAPH_VERSION = 'v2.9'; + const DEFAULT_GRAPH_VERSION = 'v2.10'; /** * @const string The name of the environment variable that contains the app ID. From ea41a595fdf497e83cd6d16b98e849011b89912a Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sun, 23 Jul 2017 09:04:52 -0500 Subject: [PATCH 356/407] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3bd7e735..ca471dda4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.6.0 (2017-07-23) + - 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. From 34f5e5993c67acd264017373f23848961585dcac Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Sun, 23 Jul 2017 09:06:52 -0500 Subject: [PATCH 357/407] Bump SDK version to 5.6.0 --- README.md | 6 +++--- src/Facebook/Facebook.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a7a89c56b..74854b501 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Facebook SDK for PHP (v5) -[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.5.svg)](https://travis-ci.org/facebook/php-graph-sdk) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.5)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.5) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.5.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.6.svg)](https://travis-ci.org/facebook/php-graph-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.6)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.6) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 8f8b54400..305667892 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.5.0'; + const VERSION = '5.6.0'; /** * @const string Default Graph API version for requests. From 8d727436dfa322e96a5ff2fcfcda9038db8ccd28 Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:03:24 +0000 Subject: [PATCH 358/407] add require autoload.php to example (fixes #842) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a7a89c56b..10748049f 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ Simple GET example of a user's profile. ```php +require_once 'vendor/autoload.php'; // change path as needed + $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', From 5255187a3c0c5d5dc68fd59eb9b761448c5ca9fd Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:28:45 +0000 Subject: [PATCH 359/407] add __DIR__ to require path --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10748049f..54f1569aa 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ Simple GET example of a user's profile. ```php -require_once 'vendor/autoload.php'; // change path as needed +require_once __DIR__.'vendor/autoload.php'; // change path as needed $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', From 4d9dd838d0a3241563693ecb451488bd9077ed35 Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:32:26 +0000 Subject: [PATCH 360/407] add __DIR__ to path properly (d'oh) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54f1569aa..bd7afc4f1 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ 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'; // change path as needed $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', From 89c86a77c47ff99a395e015bd35ec5a4fc6282c9 Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:39:27 +0000 Subject: [PATCH 361/407] concat syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd7afc4f1..932e5db40 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ 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'; // change path as needed $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', From f548114c95846826ad2850a6c7389b70056c7e6a Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:03:24 +0000 Subject: [PATCH 362/407] add require autoload.php to example (fixes #842) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 74854b501..323778a25 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ Simple GET example of a user's profile. ```php +require_once 'vendor/autoload.php'; // change path as needed + $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', 'app_secret' => '{app-secret}', From 301bf1b48b636a66ac2fcaf1d12401b1ffe0b0f8 Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:28:45 +0000 Subject: [PATCH 363/407] add __DIR__ to require path --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 323778a25..8022cd4fb 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ Simple GET example of a user's profile. ```php -require_once 'vendor/autoload.php'; // change path as needed +require_once __DIR__.'vendor/autoload.php'; // change path as needed $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', From 2f762ced1f8ef5e2042a741806c2224782a333d9 Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:32:26 +0000 Subject: [PATCH 364/407] add __DIR__ to path properly (d'oh) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8022cd4fb..12df8474d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ 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'; // change path as needed $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', From c84a01355a61bcb1806fbcd812b615bb4326047b Mon Sep 17 00:00:00 2001 From: Dominic Bordelon Date: Wed, 16 Aug 2017 16:39:27 +0000 Subject: [PATCH 365/407] concat syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12df8474d..bac9d3fd3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [ 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'; // change path as needed $fb = new \Facebook\Facebook([ 'app_id' => '{app-id}', From cee7c307889eda18c8ebf73d426919e575095136 Mon Sep 17 00:00:00 2001 From: "Nathanael d. Noblet" Date: Wed, 16 Aug 2017 11:08:28 -0600 Subject: [PATCH 366/407] Fix phpdoc @return instead of @returns PhpDoc expects @return, @returns was being used instead --- src/Facebook/SignedRequest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Facebook/SignedRequest.php b/src/Facebook/SignedRequest.php index ceed30278..6a175a0a2 100644 --- a/src/Facebook/SignedRequest.php +++ b/src/Facebook/SignedRequest.php @@ -164,7 +164,7 @@ protected function parse() /** * Splits a raw signed request into signature and payload. * - * @returns array + * @return array * * @throws FacebookSDKException */ @@ -182,7 +182,7 @@ protected function split() * * @param string $encodedSig * - * @returns string + * @return string * * @throws FacebookSDKException */ @@ -202,7 +202,7 @@ protected function decodeSignature($encodedSig) * * @param string $encodedPayload * - * @returns array + * @return array * * @throws FacebookSDKException */ From a13d1fbb213ce4ef5b8250e7a3faf148bdb4c208 Mon Sep 17 00:00:00 2001 From: "Nathanael d. Noblet" Date: Wed, 16 Aug 2017 11:08:28 -0600 Subject: [PATCH 367/407] Fix phpdoc @return instead of @returns PhpDoc expects @return, @returns was being used instead --- src/Facebook/SignedRequest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Facebook/SignedRequest.php b/src/Facebook/SignedRequest.php index ceed30278..6a175a0a2 100644 --- a/src/Facebook/SignedRequest.php +++ b/src/Facebook/SignedRequest.php @@ -164,7 +164,7 @@ protected function parse() /** * Splits a raw signed request into signature and payload. * - * @returns array + * @return array * * @throws FacebookSDKException */ @@ -182,7 +182,7 @@ protected function split() * * @param string $encodedSig * - * @returns string + * @return string * * @throws FacebookSDKException */ @@ -202,7 +202,7 @@ protected function decodeSignature($encodedSig) * * @param string $encodedPayload * - * @returns array + * @return array * * @throws FacebookSDKException */ From 2f9639c15ae043911f40ffe44080b32bac2c5280 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Wed, 16 Aug 2017 12:28:07 -0500 Subject: [PATCH 368/407] Update changelog and version bump --- CHANGELOG.md | 2 ++ README.md | 6 +++--- src/Facebook/Facebook.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca471dda4..94b456373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.6.1 (2017-08-16) + - Fixed doc block syntax that interfered with Doctrine (#844) - 5.6.0 (2017-07-23) - Bump Graph API version to v2.10 (#829) - 5.5.0 (2017-04-20) diff --git a/README.md b/README.md index bac9d3fd3..f00348f35 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Facebook SDK for PHP (v5) -[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.6.svg)](https://travis-ci.org/facebook/php-graph-sdk) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.6)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.6) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.x.svg)](https://travis-ci.org/facebook/php-graph-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 305667892..4b4445309 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.6.0'; + const VERSION = '5.6.1'; /** * @const string Default Graph API version for requests. From d811ada304122147fb51ed956ae730909113911a Mon Sep 17 00:00:00 2001 From: Jean Baptiste Noblot Date: Tue, 7 Nov 2017 23:50:03 +0100 Subject: [PATCH 369/407] Add "new" API Throttle code https://developers.facebook.com/docs/graph-api/advanced/rate-limiting At the end of this page you see list of rate limiting code. I keep code "341" cause in an other page of the docs : https://developers.facebook.com/docs/graph-api/using-graph-api#errors We can see 341 code --- src/Facebook/Exceptions/FacebookResponseException.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 60fd5cfca..61f51cdc9 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -70,6 +70,7 @@ public static function create(FacebookResponse $response) { $data = $response->getDecodedBody(); + if (!isset($data['error']['code']) && isset($data['code'])) { $data = ['error' => $data]; } @@ -113,7 +114,9 @@ public static function create(FacebookResponse $response) // API Throttling case 4: case 17: + case 32: case 341: + case 613: return new static($response, new FacebookThrottleException($message, $code)); // Duplicate Post From 15ec3c5a71cd0dd9bf9ba883a798fe0accfb6362 Mon Sep 17 00:00:00 2001 From: Julien Bornstein Date: Tue, 21 Nov 2017 11:39:29 +0100 Subject: [PATCH 370/407] Fix PHPDoc return type #857 --- src/Facebook/GraphNodes/GraphUser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphUser.php b/src/Facebook/GraphNodes/GraphUser.php index c50d7efd2..6e1ed8f54 100644 --- a/src/Facebook/GraphNodes/GraphUser.php +++ b/src/Facebook/GraphNodes/GraphUser.php @@ -123,7 +123,7 @@ public function getLink() /** * Returns the users birthday, if available. * - * @return \DateTime|null + * @return Birthday|null */ public function getBirthday() { From 5568c740ff82e92fc5abce4f207907999db0ca81 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Sun, 26 Nov 2017 16:02:12 -0800 Subject: [PATCH 371/407] Add link to COC from `CONTRIBUTING.md` We are about to add a `CODE_OF_CONDUCT.md` and it makes sense to link to it from here. --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d922863e..c6ac4b3f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,9 @@ Contributions are **welcome** and will be fully **credited**. We accept contributions via Pull Requests on [Github](https://github.com/facebook/facebook-php-sdk-v4). +## Code of Conduct +The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) + ## Pull Requests From e74a871f3a006492ff7a805179ac16e9ead3ee97 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Sun, 26 Nov 2017 16:03:46 -0800 Subject: [PATCH 372/407] Add `CODE_OF_CONDUCT.md` **what is the change?:** Adding a document linking to the Facebook Open Source Code of Conduct, for visibility and to meet Github community standards. **why make this change?:** Facebook Open Source provides a Code of Conduct statement for all projects to follow. Exposing the COC via a separate markdown file is a standard being promoted by Github via the Community Profile in order to meet their Open Source Guide's recommended community standards. As you can see, adding this file will improve [php-graph-sdk's Community Profile](https://github.com/facebook/php-graph-sdk/community) checklist and increase the visibility of our COC. **test plan:** Viewing it on my branch - (Flarnie will insert screenshots) **issue:** internal task t23481323 --- CODE_OF_CONDUCT.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0a45f9bd5 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. From e1f1ebad139cbf292410bbedb9e8072c5cf75b36 Mon Sep 17 00:00:00 2001 From: ryanml Date: Sun, 3 Dec 2017 14:18:10 -0700 Subject: [PATCH 373/407] Enabling the follow location option for cURL --- src/Facebook/HttpClients/FacebookCurlHttpClient.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index 059e75a50..b15e120d0 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -98,7 +98,8 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) CURLOPT_URL => $url, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => $timeOut, - CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects + CURLOPT_RETURNTRANSFER => true, // Return response as string + CURLOPT_FOLLOWLOCATION => true, // Follow 30x redirects CURLOPT_HEADER => true, // Enable header processing CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, From db24fc253956227a91128e060e4cadf4c5930282 Mon Sep 17 00:00:00 2001 From: ryanml Date: Sun, 3 Dec 2017 14:21:10 -0700 Subject: [PATCH 374/407] Updating FacebookCurkHttpClientTest for cURL location following --- tests/HttpClients/FacebookCurlHttpClientTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index 47cc0274e..de1a05366 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -72,6 +72,7 @@ public function testCanOpenGetCurlConnection() CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 123, CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, CURLOPT_HEADER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, @@ -115,6 +116,7 @@ public function testCanOpenCurlConnectionWithPostBody() CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, CURLOPT_HEADER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, From 9b4cc4c47ee793fc81ecb09c719bc216ed556921 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Sun, 3 Dec 2017 23:42:10 +0100 Subject: [PATCH 375/407] Update pull request link --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6ac4b3f8..1a7e9faf2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ Contributing Contributions are **welcome** and will be fully **credited**. -We accept contributions via Pull Requests on [Github](https://github.com/facebook/facebook-php-sdk-v4). +We accept contributions via Pull Requests on [Github](https://github.com/facebook/php-graph-sdk/pull/new). ## Code of Conduct The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) From 38825e19624cc673c1d5dc4fc6207bbbb1ad109e Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Mon, 4 Dec 2017 00:18:49 +0100 Subject: [PATCH 376/407] Add maintainance instructions --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a7e9faf2..6e913aedf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,12 @@ Contributions are **welcome** and will be fully **credited**. We accept contributions via Pull Requests on [Github](https://github.com/facebook/php-graph-sdk/pull/new). +The current stable major version is v5. The v6 is under active development. + +This means any new feature MUST target v6 (`master` branch). + +The v5 (`5.x` branch) is maintained only for bug fixes, node/edge updates or documentation improvements. + ## Code of Conduct The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) From 300f9c82cd91b529bc8e9b189048b81f19020be6 Mon Sep 17 00:00:00 2001 From: ryanml Date: Sun, 3 Dec 2017 16:25:31 -0700 Subject: [PATCH 377/407] Removing follow location --- src/Facebook/HttpClients/FacebookCurlHttpClient.php | 1 - tests/HttpClients/FacebookCurlHttpClientTest.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/Facebook/HttpClients/FacebookCurlHttpClient.php b/src/Facebook/HttpClients/FacebookCurlHttpClient.php index b15e120d0..9516cc835 100644 --- a/src/Facebook/HttpClients/FacebookCurlHttpClient.php +++ b/src/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -99,7 +99,6 @@ public function openConnection($url, $method, $body, array $headers, $timeOut) CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => $timeOut, CURLOPT_RETURNTRANSFER => true, // Return response as string - CURLOPT_FOLLOWLOCATION => true, // Follow 30x redirects CURLOPT_HEADER => true, // Enable header processing CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, diff --git a/tests/HttpClients/FacebookCurlHttpClientTest.php b/tests/HttpClients/FacebookCurlHttpClientTest.php index de1a05366..47cc0274e 100644 --- a/tests/HttpClients/FacebookCurlHttpClientTest.php +++ b/tests/HttpClients/FacebookCurlHttpClientTest.php @@ -72,7 +72,6 @@ public function testCanOpenGetCurlConnection() CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 123, CURLOPT_RETURNTRANSFER => true, - CURLOPT_FOLLOWLOCATION => true, CURLOPT_HEADER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, @@ -116,7 +115,6 @@ public function testCanOpenCurlConnectionWithPostBody() CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 60, CURLOPT_RETURNTRANSFER => true, - CURLOPT_FOLLOWLOCATION => true, CURLOPT_HEADER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYPEER => true, From b5ec18003bb7b0e5e15fbd30f217f5c14f9bc742 Mon Sep 17 00:00:00 2001 From: Jean Baptiste Noblot Date: Mon, 4 Dec 2017 09:09:29 +0100 Subject: [PATCH 378/407] delete empty line --- src/Facebook/Exceptions/FacebookResponseException.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 61f51cdc9..4a135db16 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -70,7 +70,6 @@ public static function create(FacebookResponse $response) { $data = $response->getDecodedBody(); - if (!isset($data['error']['code']) && isset($data['code'])) { $data = ['error' => $data]; } From 6a8580ed928880379742fe9a3228e21d6a6abc4a Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Tue, 9 Jan 2018 13:18:45 +0100 Subject: [PATCH 379/407] Correctly return an AccessToken instance The method (in OAuth2Client) is expected to return an AccessToken instance --- tests/Fixtures/FooRedirectLoginOAuth2Client.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Fixtures/FooRedirectLoginOAuth2Client.php b/tests/Fixtures/FooRedirectLoginOAuth2Client.php index 0c4760d10..2a2aeed65 100644 --- a/tests/Fixtures/FooRedirectLoginOAuth2Client.php +++ b/tests/Fixtures/FooRedirectLoginOAuth2Client.php @@ -23,12 +23,13 @@ */ namespace Facebook\Tests\Fixtures; +use Facebook\Authentication\AccessToken; use Facebook\Authentication\OAuth2Client; class FooRedirectLoginOAuth2Client extends OAuth2Client { public function getAccessTokenFromCode($code, $redirectUri = '', $machineId = null) { - return 'foo_token_from_code|' . $code . '|' . $redirectUri; + return new AccessToken('foo_token_from_code|' . $code . '|' . $redirectUri); } } From 2762670363c86e1d28c34d0918bbbdeb04bbe689 Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Tue, 9 Jan 2018 13:28:48 +0100 Subject: [PATCH 380/407] Specify correct behavior in test --- tests/Helpers/FacebookRedirectLoginHelperTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 62cbfbfbd..e9b627704 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -97,9 +97,14 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $_GET['state'] = 'foo_state'; $_GET['code'] = 'foo_code'; - $accessToken = $this->redirectLoginHelper->getAccessToken(self::REDIRECT_URL); + $fullUrl = self::REDIRECT_URL . '?state=foo_state&code=foo_code&some_param=blah'; - $this->assertEquals('foo_token_from_code|foo_code|' . self::REDIRECT_URL, (string)$accessToken); + $accessToken = $this->redirectLoginHelper->getAccessToken($fullUrl); + + // code and state should be stripped from the URL + $expectedUrl = $fullUrl = self::REDIRECT_URL . '?some_param=blah'; + + $this->assertEquals('foo_token_from_code|foo_code|' . $expectedUrl, $accessToken->getValue()); } public function testACustomCsprsgCanBeInjected() From b4c3f7c05531e0f1347244e77029e1b122b6c632 Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Tue, 9 Jan 2018 13:32:18 +0100 Subject: [PATCH 381/407] Remove 'code' param It gets set by Facebook. If it stays in the redirect URL, strict mode won't work. --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 4a0755a44..430e8dbbd 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -222,8 +222,9 @@ public function getAccessToken($redirectUrl = null) $this->resetCsrf(); $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); - // At minimum we need to remove the state param - $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']); + + // At minimum we need to remove the 'state' and 'code' params + $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['code', 'state']); return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl); } From 53a3d0503c7c6fded11449512e38ebb45aedb6da Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Tue, 9 Jan 2018 14:25:49 +0100 Subject: [PATCH 382/407] Remove stupid code --- tests/Helpers/FacebookRedirectLoginHelperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index e9b627704..8d9c77c9e 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -102,7 +102,7 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $accessToken = $this->redirectLoginHelper->getAccessToken($fullUrl); // code and state should be stripped from the URL - $expectedUrl = $fullUrl = self::REDIRECT_URL . '?some_param=blah'; + $expectedUrl = self::REDIRECT_URL . '?some_param=blah'; $this->assertEquals('foo_token_from_code|foo_code|' . $expectedUrl, $accessToken->getValue()); } From 56d4c3f7e550cf519b7dc3fa801abe19170155c0 Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Thu, 8 Feb 2018 15:43:04 +0100 Subject: [PATCH 383/407] Remove newline --- src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 430e8dbbd..3240ba81d 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -222,7 +222,6 @@ public function getAccessToken($redirectUrl = null) $this->resetCsrf(); $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); - // At minimum we need to remove the 'state' and 'code' params $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['code', 'state']); From a335ed83b959aaeff59aeb666c17072940a649e5 Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Thu, 8 Feb 2018 16:07:42 +0100 Subject: [PATCH 384/407] Use const for URL parts --- tests/Helpers/FacebookRedirectLoginHelperTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 8d9c77c9e..5b0aaa0c0 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -44,6 +44,9 @@ class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase protected $redirectLoginHelper; const REDIRECT_URL = 'http://invalid.zzz'; + const FOO_CODE = "foo_code"; + const FOO_STATE = "foo_state"; + const FOO_PARAM = "some_param=blah"; protected function setUp() { @@ -94,10 +97,10 @@ public function testLogoutURL() public function testAnAccessTokenCanBeObtainedFromRedirect() { $this->persistentDataHandler->set('state', 'foo_state'); - $_GET['state'] = 'foo_state'; - $_GET['code'] = 'foo_code'; + $_GET['state'] = static::FOO_STATE; + $_GET['code'] = static::FOO_CODE; - $fullUrl = self::REDIRECT_URL . '?state=foo_state&code=foo_code&some_param=blah'; + $fullUrl = self::REDIRECT_URL . '?state=' . static::FOO_STATE . '&code=' . static::FOO_CODE . '&' . static::FOO_PARAM; $accessToken = $this->redirectLoginHelper->getAccessToken($fullUrl); From 91b15a155f792df3a367e1a45fe02fa60a7ac241 Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Thu, 8 Feb 2018 16:12:05 +0100 Subject: [PATCH 385/407] Use constants also for expected value --- tests/Helpers/FacebookRedirectLoginHelperTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 5b0aaa0c0..344e0df58 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -105,9 +105,9 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() $accessToken = $this->redirectLoginHelper->getAccessToken($fullUrl); // code and state should be stripped from the URL - $expectedUrl = self::REDIRECT_URL . '?some_param=blah'; + $expectedUrl = self::REDIRECT_URL . '?' . static::FOO_PARAM; - $this->assertEquals('foo_token_from_code|foo_code|' . $expectedUrl, $accessToken->getValue()); + $this->assertEquals('foo_token_from_code|' . static::FOO_CODE . '|' . $expectedUrl, $accessToken->getValue()); } public function testACustomCsprsgCanBeInjected() From 711fe77319cd905ef36db53f9581dc58882f4e3b Mon Sep 17 00:00:00 2001 From: Martin Stuecklschwaiger Date: Thu, 8 Feb 2018 16:13:22 +0100 Subject: [PATCH 386/407] Simplify line --- tests/Helpers/FacebookRedirectLoginHelperTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 344e0df58..5df9afa99 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -106,8 +106,9 @@ public function testAnAccessTokenCanBeObtainedFromRedirect() // code and state should be stripped from the URL $expectedUrl = self::REDIRECT_URL . '?' . static::FOO_PARAM; + $expectedString = 'foo_token_from_code|' . static::FOO_CODE . '|' . $expectedUrl; - $this->assertEquals('foo_token_from_code|' . static::FOO_CODE . '|' . $expectedUrl, $accessToken->getValue()); + $this->assertEquals($expectedString, $accessToken->getValue()); } public function testACustomCsprsgCanBeInjected() From 090ffe5c6af3a1e8065f6edbbca201296bbcde03 Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Thu, 15 Feb 2018 00:17:50 +0100 Subject: [PATCH 387/407] Prepare 5.6.2 release --- CHANGELOG.md | 2 ++ README.md | 2 +- src/Facebook/Facebook.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94b456373..b6d64e63f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.6.2 (2018-02-15) + - Strip 'code' param (#913) - 5.6.1 (2017-08-16) - Fixed doc block syntax that interfered with Doctrine (#844) - 5.6.0 (2017-07-23) diff --git a/README.md b/README.md index f00348f35..101a0e39e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.x.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.1-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.2-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 4b4445309..bf93119ac 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.6.1'; + const VERSION = '5.6.2'; /** * @const string Default Graph API version for requests. From f85ffc2aed4b345cb2411de3c90c07517bd02962 Mon Sep 17 00:00:00 2001 From: Jean Baptiste Noblot Date: Wed, 21 Feb 2018 10:14:45 +0100 Subject: [PATCH 388/407] Add 'joined' field to cast in DateTime --- src/Facebook/GraphNodes/GraphNode.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphNode.php b/src/Facebook/GraphNodes/GraphNode.php index 061e74494..a81c47b7b 100644 --- a/src/Facebook/GraphNodes/GraphNode.php +++ b/src/Facebook/GraphNodes/GraphNode.php @@ -150,7 +150,8 @@ public function shouldCastAsDateTime($key) 'backdated_time', 'issued_at', 'expires_at', - 'publish_time' + 'publish_time', + 'joined' ], true); } From 7542d5f8e8f74a47c94f3639ffa6acdf71924c7d Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Sat, 6 Jan 2018 23:20:59 -0200 Subject: [PATCH 389/407] Trailing whitespaces Signed-off-by: Gabriel Caruso --- README.md | 2 +- docs/reference/FacebookRequest.md | 2 +- docs/reference/FacebookResponseException.md | 8 ++++---- docs/reference/GraphNode.md | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 101a0e39e..38dc40a1d 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). composer require facebook/graph-sdk ``` -Please be aware, that there are issues when using the Facebook SDK together with [Guzzle](https://github.com/guzzle/guzzle) 6.x. php-graph-sdk v5.x only works with Guzzle 5.x out of the box. However, [there is a workaround to make it work with Guzzle 6.x](https://www.sammyk.me/how-to-inject-your-own-http-client-in-the-facebook-php-sdk-v5#writing-a-guzzle-6-http-client-implementation-from-scratch). +Please be aware, that there are issues when using the Facebook SDK together with [Guzzle](https://github.com/guzzle/guzzle) 6.x. php-graph-sdk v5.x only works with Guzzle 5.x out of the box. However, [there is a workaround to make it work with Guzzle 6.x](https://www.sammyk.me/how-to-inject-your-own-http-client-in-the-facebook-php-sdk-v5#writing-a-guzzle-6-http-client-implementation-from-scratch). ## Upgrading to v5.x diff --git a/docs/reference/FacebookRequest.md b/docs/reference/FacebookRequest.md index 31c0dfcf2..cc8b7b203 100644 --- a/docs/reference/FacebookRequest.md +++ b/docs/reference/FacebookRequest.md @@ -9,7 +9,7 @@ You can instantiate a new `FacebookRequest` entity directly by sending the argum ```php use Facebook\FacebookRequest; -$request = new FacebookRequest( +$request = new FacebookRequest( Facebook\FacebookApp $app, string $accessToken, string $method, diff --git a/docs/reference/FacebookResponseException.md b/docs/reference/FacebookResponseException.md index 2bd848fbb..6fe777cbf 100644 --- a/docs/reference/FacebookResponseException.md +++ b/docs/reference/FacebookResponseException.md @@ -33,15 +33,15 @@ These exceptions are derived from the [error responses from the Graph API](https `FacebookResponseException` extends from the base `\Exception` class, so `getCode()` and `getMessage()` are available by default. ### getHttpStatusCode -`getHttpStatusCode()` +`getHttpStatusCode()` Returns the HTTP status code returned with this exception. ### getSubErrorCode -`getSubErrorCode()` +`getSubErrorCode()` Returns the numeric sub-error code returned from the Graph API. ### getErrorType -`getErrorType()` +`getErrorType()` Returns the type of error as a string. ### getResponseData @@ -49,7 +49,7 @@ Returns the type of error as a string. Returns the decoded response body used to create the exception as an array. ### getRawResponse -`getRawResponse()` +`getRawResponse()` Returns the raw response body used to create the exception as a string. ### getResponse diff --git a/docs/reference/GraphNode.md b/docs/reference/GraphNode.md index 557030325..87b3e7d3b 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -65,7 +65,7 @@ $total = count($graphNode); ### asArray -`asArray()` +`asArray()` Returns the raw representation (associative arrays, nested) of the node's underlying data. From 72df66644772243996452c2f1cdc23cbc0b325b5 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Sat, 6 Jan 2018 23:21:31 -0200 Subject: [PATCH 390/407] Clean extra lines Signed-off-by: Gabriel Caruso --- CHANGELOG.md | 3 --- CONTRIBUTING.md | 3 --- README.md | 7 ------- docs/getting_started.md | 5 ----- docs/reference.md | 3 --- docs/reference/FacebookRedirectLoginHelper.md | 4 ---- docs/reference/GraphNode.md | 7 ------- 7 files changed, 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d64e63f..66d6fe8fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org/). - ## 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. @@ -87,12 +86,10 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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` - ## 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. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e913aedf..3081751f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,6 @@ The v5 (`5.x` branch) is maintained only for bug fixes, node/edge updates or doc ## Code of Conduct The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) - ## Pull Requests - **Sign the CLA** - For us to accept contributions you will have to first have signed the @@ -38,14 +37,12 @@ The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) - **Ensure no coding standards violations** - Please [run PHP Code Sniffer](#running-php-code-sniffer) using the PSR-2 standard before submitting your pull request. A violation will cause the build to fail, so please make sure there are no violations. We can't accept a patch if the build fails. - ## Running Tests ``` bash $ ./vendor/bin/phpunit ``` - ## Running PHP Code Sniffer You can install [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) globally with composer. diff --git a/README.md b/README.md index 38dc40a1d..05506d860 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,8 @@ [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) [![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.2-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) - This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. - ## Installation The Facebook PHP SDK can be installed with [Composer](https://getcomposer.org/). Run this command: @@ -22,7 +20,6 @@ Please be aware, that there are issues when using the Facebook SDK together with Upgrading from v4.x? Facebook PHP SDK v5.x introduced breaking changes. Please [read the upgrade guide](https://www.sammyk.me/upgrading-the-facebook-php-sdk-from-v4-to-v5) before upgrading. - ## Usage > **Note:** This version of the Facebook SDK for PHP requires PHP 5.4 or greater. @@ -65,7 +62,6 @@ 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. @@ -82,17 +78,14 @@ By default the tests will send live HTTP requests to the Graph API. If you are w $ ./vendor/bin/phpunit --exclude-group integration ``` - ## Contributing For us to accept contributions you will have to first have signed the [Contributor License Agreement](https://developers.facebook.com/opensource/cla). Please see [CONTRIBUTING](https://github.com/facebook/php-graph-sdk/blob/master/CONTRIBUTING.md) for details. - ## License Please see the [license file](https://github.com/facebook/php-graph-sdk/blob/master/LICENSE) for more information. - ## Security Vulnerabilities If you have found a security issue, please contact the maintainers directly at [me@sammyk.me](mailto:me@sammyk.me). diff --git a/docs/getting_started.md b/docs/getting_started.md index b03176560..b1e5f641c 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -27,7 +27,6 @@ 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. @@ -50,7 +49,6 @@ 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. @@ -102,7 +100,6 @@ The SDK can be used to support logging a Facebook user into your site using Face 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. @@ -148,7 +145,6 @@ if (isset($accessToken)) { } ``` - ### 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. @@ -179,7 +175,6 @@ if (isset($accessToken)) { > 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. diff --git a/docs/reference.md b/docs/reference.md index d6618ee80..a98acfc57 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -34,7 +34,6 @@ These classes are used in a Graph API request/response cycle. | [`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. @@ -55,7 +54,6 @@ These are the core exceptions that the SDK will throw when an error occurs. | [`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. @@ -71,7 +69,6 @@ Graph nodes are collections that represent nodes returned by the Graph API. And | [`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. diff --git a/docs/reference/FacebookRedirectLoginHelper.md b/docs/reference/FacebookRedirectLoginHelper.md index 9a908f475..5639177f3 100644 --- a/docs/reference/FacebookRedirectLoginHelper.md +++ b/docs/reference/FacebookRedirectLoginHelper.md @@ -6,7 +6,6 @@ The most commonly used helper is the `FacebookRedirectLoginHelper` which allows 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. @@ -116,19 +115,16 @@ If no authorization code could be found from the `code` param in the URL, this m 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/GraphNode.md b/docs/reference/GraphNode.md index 87b3e7d3b..a60940247 100644 --- a/docs/reference/GraphNode.md +++ b/docs/reference/GraphNode.md @@ -63,29 +63,24 @@ $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()`. @@ -180,7 +175,6 @@ The following properties on the `GraphPage` collection will get automatically ca | `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() @@ -394,7 +388,6 @@ Returns the `id` property for the achievement as a string if present. All getter methods return `null` if the property does not exist on the node. - ### getId() ```php public string|null getId() From 4a1c99fc2f2d263ca6cc6c8707788e1046568290 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 2 Jul 2018 21:56:20 -0400 Subject: [PATCH 391/407] Refactor out creepy test data --- tests/GraphNodes/GraphNodeFactoryTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index a4aa5e19d..0fd385029 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -258,22 +258,22 @@ public function testAGraphEdgeWillBeCastRecursively() [ 'id' => '1', 'name' => 'Sammy Kaye Powers', - 'is_sexy' => true, + 'is_friendly' => true, ], [ 'id' => '2', 'name' => 'Yassine Guedidi', - 'is_sexy' => true, + 'is_friendly' => true, ], [ 'id' => '3', 'name' => 'Fosco Marotto', - 'is_sexy' => true, + 'is_friendly' => true, ], [ 'id' => '4', - 'name' => 'Foo McUgly', - 'is_sexy' => false, + 'name' => 'Foo McUnfriendly', + 'is_friendly' => false, ], ], 'paging' => [ From 06a55460b8dd6b42c6dd78b5eee66f72254fce53 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 2 Jul 2018 21:58:39 -0400 Subject: [PATCH 392/407] Fix countable error in PHP 7.2; thanks to @andreybolonin in #969 --- .travis.yml | 1 + src/Facebook/FacebookBatchRequest.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a7877aee4..1b7eea631 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ php: - 5.6 - 7.0 - 7.1 + - 7.2 sudo: false diff --git a/src/Facebook/FacebookBatchRequest.php b/src/Facebook/FacebookBatchRequest.php index 3d5d5d563..9297e77d7 100644 --- a/src/Facebook/FacebookBatchRequest.php +++ b/src/Facebook/FacebookBatchRequest.php @@ -39,7 +39,7 @@ class FacebookBatchRequest extends FacebookRequest implements IteratorAggregate, /** * @var array An array of FacebookRequest entities to send. */ - protected $requests; + protected $requests = []; /** * @var array An array of files to upload. From 90e92bd1816fe718e55184ab85910dfcf488432c Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Mon, 2 Jul 2018 22:25:00 -0400 Subject: [PATCH 393/407] Update changelog and bump version --- CHANGELOG.md | 2 ++ README.md | 2 +- src/Facebook/Facebook.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66d6fe8fb..3c2e0d48d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.6.3 (2018-07-01) + - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) - Strip 'code' param (#913) - 5.6.1 (2017-08-16) diff --git a/README.md b/README.md index 05506d860..4a1515b8f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.x.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.2-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.3-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index bf93119ac..2e789ca2a 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.6.2'; + const VERSION = '5.6.3'; /** * @const string Default Graph API version for requests. From 753aa770632331320572cc02900f0644ae9ec1ce Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 6 Jul 2018 12:52:14 -0400 Subject: [PATCH 394/407] Update CHANGELOG with #950 change --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c2e0d48d..601ac6827 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.0 (2018-00-00) + - Add `joined` to list of fields to be cast to `\DateTime` (#950) - 5.6.3 (2018-07-01) - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) From 80328ae0d9657a83904ca0c6f1fbd757208b4f6a Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 6 Jul 2018 12:53:22 -0400 Subject: [PATCH 395/407] Bump version for next tag release --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a1515b8f..ba764e906 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.x.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.3-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.7.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 2e789ca2a..03a523480 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.6.3'; + const VERSION = '5.7.0'; /** * @const string Default Graph API version for requests. From e0a5fe139a1b56059c407cd49bbda9899425a1fe Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 6 Jul 2018 13:23:12 -0400 Subject: [PATCH 396/407] Update CHANGELOG for #815 change --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 601ac6827..354aded5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 5.7.0 (2018-00-00) - 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) - 5.6.3 (2018-07-01) - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) From 3138249d85e8dc040f15bedd3581a3c616f49005 Mon Sep 17 00:00:00 2001 From: Sammy Kaye Powers Date: Fri, 6 Jul 2018 13:58:28 -0400 Subject: [PATCH 397/407] Revert "Bump version for next tag release"; Sorry, got a little excited This reverts commit 80328ae0d9657a83904ca0c6f1fbd757208b4f6a. --- README.md | 2 +- src/Facebook/Facebook.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ba764e906..4a1515b8f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.x.svg)](https://travis-ci.org/facebook/php-graph-sdk) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.7.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.3-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 03a523480..2e789ca2a 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.7.0'; + const VERSION = '5.6.3'; /** * @const string Default Graph API version for requests. From 18ea305e714e3a18ccb4aa30c59c5def364f503e Mon Sep 17 00:00:00 2001 From: Andrey Bolonin Date: Sat, 27 Oct 2018 11:25:08 +0300 Subject: [PATCH 398/407] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 1b7eea631..a5d059210 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ php: - 7.0 - 7.1 - 7.2 + - 7.3 sudo: false From 60847fd83702fb8676460ff8d2544f4c90f48736 Mon Sep 17 00:00:00 2001 From: Kieran Brahney Date: Thu, 8 Nov 2018 19:19:24 +0000 Subject: [PATCH 399/407] Fix #1076 --- CHANGELOG.md | 1 + src/Facebook/Http/GraphRawResponse.php | 5 +++-- tests/Http/GraphRawResponseTest.php | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 354aded5e..b99ee624c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 5.7.0 (2018-00-00) - 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) - 5.6.3 (2018-07-01) - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) diff --git a/src/Facebook/Http/GraphRawResponse.php b/src/Facebook/Http/GraphRawResponse.php index d1a7241c8..44105c495 100644 --- a/src/Facebook/Http/GraphRawResponse.php +++ b/src/Facebook/Http/GraphRawResponse.php @@ -104,8 +104,9 @@ public function getHttpResponseCode() */ public function setHttpResponseCodeFromHeader($rawResponseHeader) { - preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $rawResponseHeader, $match); - $this->httpResponseCode = (int)$match[1]; + // 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; } /** diff --git a/tests/Http/GraphRawResponseTest.php b/tests/Http/GraphRawResponseTest.php index 3b18b5613..fcb71f480 100644 --- a/tests/Http/GraphRawResponseTest.php +++ b/tests/Http/GraphRawResponseTest.php @@ -90,4 +90,21 @@ public function testCanTransformJsonHeaderValues() $this->assertEquals($this->jsonFakeHeaderAsArray['x-fb-ads-insights-throttle'], $headers['x-fb-ads-insights-throttle']); } + + public function testHttpResponseCode() + { + // HTTP/1.0 + $headers = str_replace('HTTP/1.1', 'HTTP/1.0', $this->fakeRawHeader); + $response = new GraphRawResponse($headers, ''); + $this->assertEquals(200, $response->getHttpResponseCode()); + + // HTTP/1.1 + $response = new GraphRawResponse($this->fakeRawHeader, ''); + $this->assertEquals(200, $response->getHttpResponseCode()); + + // HTTP/2 + $headers = str_replace('HTTP/1.1', 'HTTP/2', $this->fakeRawHeader); + $response = new GraphRawResponse($headers, ''); + $this->assertEquals(200, $response->getHttpResponseCode()); + } } From dd8f1a7eaaefdbe66cd494db438a3bda260407c6 Mon Sep 17 00:00:00 2001 From: Ainur Date: Fri, 1 Jun 2018 14:26:18 +0300 Subject: [PATCH 400/407] Fix resumable upload error "There was a problem uploading your video. Please try again. --- src/Facebook/FileUpload/FacebookResumableUploader.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 92a22f140..c55ac499e 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -121,6 +121,16 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow throw $e; } + if ($e->getSubErrorCode() === 1363037) { + return new FacebookTransferChunk( + $chunk->getFile(), + $chunk->getUploadSessionId(), + $chunk->getVideoId(), + $e->getResponseData()['error']['error_data']['start_offset'], + $e->getResponseData()['error']['error_data']['end_offset'] + ); + } + // Return the same chunk entity so it can be retried. return $chunk; } From 179eec3fbf130d96e89bb6a14a6a211941fd66a5 Mon Sep 17 00:00:00 2001 From: Ainur Date: Wed, 4 Jul 2018 02:00:21 +0300 Subject: [PATCH 401/407] Added offset fields to FacebookResumableUploadException. Added test for resumable upload. --- .../Exceptions/FacebookResponseException.php | 13 ++++++- .../FacebookResumableUploadException.php | 35 +++++++++++++++++++ .../FileUpload/FacebookResumableUploader.php | 6 ++-- .../FacebookResumableUploaderTest.php | 10 ++++++ .../FakeGraphApiForResumableUpload.php | 14 ++++++++ 5 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 4a135db16..4d6b5bc36 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -90,11 +90,22 @@ public static function create(FacebookResponse $response) // Video upload resumable error case 1363030: case 1363019: - case 1363037: case 1363033: case 1363021: case 1363041: return new static($response, new FacebookResumableUploadException($message, $code)); + case 1363037: + $previousException = new FacebookResumableUploadException($message, $code); + + $startOffset = isset($data['error']['error_data']['start_offset']) ? + $data['error']['error_data']['start_offset'] : null; + $previousException->setStartOffset($startOffset); + + $endOffset = isset($data['error']['error_data']['end_offset']) ? + $data['error']['error_data']['end_offset'] : null; + $previousException->setEndOffset($endOffset); + + return new static($response, $previousException); } } diff --git a/src/Facebook/Exceptions/FacebookResumableUploadException.php b/src/Facebook/Exceptions/FacebookResumableUploadException.php index 6f4706623..67ab8bc8b 100644 --- a/src/Facebook/Exceptions/FacebookResumableUploadException.php +++ b/src/Facebook/Exceptions/FacebookResumableUploadException.php @@ -30,4 +30,39 @@ */ class FacebookResumableUploadException extends FacebookSDKException { + protected $startOffset; + + protected $endOffset; + + /** + * @return int + */ + public function getStartOffset() + { + return $this->startOffset; + } + + /** + * @param int $startOffset + */ + public function setStartOffset($startOffset) + { + $this->startOffset = $startOffset; + } + + /** + * @return int + */ + public function getEndOffset() + { + return $this->endOffset; + } + + /** + * @param int $endOffset + */ + public function setEndOffset($endOffset) + { + $this->endOffset = $endOffset; + } } diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index c55ac499e..743e5dc2d 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -121,13 +121,13 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow throw $e; } - if ($e->getSubErrorCode() === 1363037) { + if (!is_null($preException->getStartOffset()) && !is_null($preException->getEndOffset())) { return new FacebookTransferChunk( $chunk->getFile(), $chunk->getUploadSessionId(), $chunk->getVideoId(), - $e->getResponseData()['error']['error_data']['start_offset'], - $e->getResponseData()['error']['error_data']['end_offset'] + $preException->getStartOffset(), + $preException->getEndOffset() ); } diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index c32b7fbac..98aa2aa82 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -98,4 +98,14 @@ public function testFailedResumableTransferWillNotThrowAndReturnSameChunk() $newChunk = $uploader->transfer('/me/videos', $chunk); $this->assertSame($newChunk, $chunk); } + + public function testFailedResumableTransferWillNotThrowAndReturnNewChunk() + { + $this->graphApi->failOnTransferAndUploadNewChunk(); + $uploader = new FacebookResumableUploader($this->fbApp, $this->client, 'access_token', 'v2.4'); + + $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); + $newChunk = $uploader->transfer('/me/videos', $chunk); + $this->assertEquals('40', $newChunk->getStartOffset()); + } } diff --git a/tests/Fixtures/FakeGraphApiForResumableUpload.php b/tests/Fixtures/FakeGraphApiForResumableUpload.php index 1c2d0f875..29f56446c 100644 --- a/tests/Fixtures/FakeGraphApiForResumableUpload.php +++ b/tests/Fixtures/FakeGraphApiForResumableUpload.php @@ -42,6 +42,11 @@ public function failOnTransfer() $this->respondWith = 'FAIL_ON_TRANSFER'; } + public function failOnTransferAndUploadNewChunk() + { + $this->respondWith = 'FAIL_ON_TRANSFER_AND_UPLOAD_NEW_CHUNK'; + } + public function send($url, $method, $body, array $headers, $timeOut) { // Could be start, transfer or finish @@ -81,6 +86,15 @@ private function respondTransfer() ); } + if ($this->respondWith == 'FAIL_ON_TRANSFER_AND_UPLOAD_NEW_CHUNK') { + return new GraphRawResponse( + "HTTP/1.1 500 OK\r\nFoo: Bar", + '{"error":{"message":"There was a problem uploading your video. Please try uploading it again.",' . + '"type":"OAuthException","code":6001,"error_subcode":1363037,' . + '"error_data":{"start_offset":40,"end_offset":50}}}' + ); + } + switch ($this->transferCount) { case 0: $data = ['start_offset' => 20, 'end_offset' => 40]; From b4ee993f8345f5255b19d0d5826f0c5540da0119 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 20 Nov 2018 22:42:20 +0300 Subject: [PATCH 402/407] Update CHANGELOG for #1001 and fixed review --- CHANGELOG.md | 1 + src/Facebook/Exceptions/FacebookResponseException.php | 6 ++---- .../Exceptions/FacebookResumableUploadException.php | 8 ++++---- src/Facebook/FileUpload/FacebookResumableUploader.php | 2 +- src/Facebook/FileUpload/FacebookTransferChunk.php | 8 ++++++++ tests/FileUpload/FacebookResumableUploaderTest.php | 3 ++- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b99ee624c..c2cd50a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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) - 5.6.3 (2018-07-01) - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) diff --git a/src/Facebook/Exceptions/FacebookResponseException.php b/src/Facebook/Exceptions/FacebookResponseException.php index 4d6b5bc36..e51f1c840 100644 --- a/src/Facebook/Exceptions/FacebookResponseException.php +++ b/src/Facebook/Exceptions/FacebookResponseException.php @@ -97,12 +97,10 @@ public static function create(FacebookResponse $response) case 1363037: $previousException = new FacebookResumableUploadException($message, $code); - $startOffset = isset($data['error']['error_data']['start_offset']) ? - $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']) ? - $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); diff --git a/src/Facebook/Exceptions/FacebookResumableUploadException.php b/src/Facebook/Exceptions/FacebookResumableUploadException.php index 67ab8bc8b..6d41c63cc 100644 --- a/src/Facebook/Exceptions/FacebookResumableUploadException.php +++ b/src/Facebook/Exceptions/FacebookResumableUploadException.php @@ -35,7 +35,7 @@ class FacebookResumableUploadException extends FacebookSDKException protected $endOffset; /** - * @return int + * @return int|null */ public function getStartOffset() { @@ -43,7 +43,7 @@ public function getStartOffset() } /** - * @param int $startOffset + * @param int|null $startOffset */ public function setStartOffset($startOffset) { @@ -51,7 +51,7 @@ public function setStartOffset($startOffset) } /** - * @return int + * @return int|null */ public function getEndOffset() { @@ -59,7 +59,7 @@ public function getEndOffset() } /** - * @param int $endOffset + * @param int|null $endOffset */ public function setEndOffset($endOffset) { diff --git a/src/Facebook/FileUpload/FacebookResumableUploader.php b/src/Facebook/FileUpload/FacebookResumableUploader.php index 743e5dc2d..46a2727b9 100644 --- a/src/Facebook/FileUpload/FacebookResumableUploader.php +++ b/src/Facebook/FileUpload/FacebookResumableUploader.php @@ -121,7 +121,7 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow throw $e; } - if (!is_null($preException->getStartOffset()) && !is_null($preException->getEndOffset())) { + if (null !== $preException->getStartOffset() && null !== $preException->getEndOffset()) { return new FacebookTransferChunk( $chunk->getFile(), $chunk->getUploadSessionId(), diff --git a/src/Facebook/FileUpload/FacebookTransferChunk.php b/src/Facebook/FileUpload/FacebookTransferChunk.php index a909e8751..99ea7752a 100644 --- a/src/Facebook/FileUpload/FacebookTransferChunk.php +++ b/src/Facebook/FileUpload/FacebookTransferChunk.php @@ -121,6 +121,14 @@ public function getStartOffset() return $this->startOffset; } + /** + * @return int + */ + public function getEndOffset() + { + return $this->endOffset; + } + /** * Get uploaded video Id * diff --git a/tests/FileUpload/FacebookResumableUploaderTest.php b/tests/FileUpload/FacebookResumableUploaderTest.php index 98aa2aa82..dfdbe6f41 100644 --- a/tests/FileUpload/FacebookResumableUploaderTest.php +++ b/tests/FileUpload/FacebookResumableUploaderTest.php @@ -106,6 +106,7 @@ public function testFailedResumableTransferWillNotThrowAndReturnNewChunk() $chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4'); $newChunk = $uploader->transfer('/me/videos', $chunk); - $this->assertEquals('40', $newChunk->getStartOffset()); + $this->assertEquals(40, $newChunk->getStartOffset()); + $this->assertEquals(50, $newChunk->getEndOffset()); } } From 5f4a062890f56107d8bb4a58f15d4d8f04cb079f Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Wed, 14 Nov 2018 08:07:45 +0100 Subject: [PATCH 403/407] Strip 'enforce_https' param --- CHANGELOG.md | 1 + src/Facebook/Helpers/FacebookRedirectLoginHelper.php | 4 ++-- tests/Helpers/FacebookRedirectLoginHelperTest.php | 11 +++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2cd50a69..3bb5bfcd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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) - 5.6.3 (2018-07-01) - Add fix for countable error in PHP 7.2 (originally #969 by @andreybolonin) - 5.6.2 (2018-02-15) diff --git a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php index 3240ba81d..6003a20f3 100644 --- a/src/Facebook/Helpers/FacebookRedirectLoginHelper.php +++ b/src/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -222,8 +222,8 @@ public function getAccessToken($redirectUrl = null) $this->resetCsrf(); $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); - // At minimum we need to remove the 'state' and 'code' params - $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['code', 'state']); + // At minimum we need to remove the 'code', 'enforce_https' and 'state' params + $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['code', 'enforce_https', 'state']); return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl); } diff --git a/tests/Helpers/FacebookRedirectLoginHelperTest.php b/tests/Helpers/FacebookRedirectLoginHelperTest.php index 5df9afa99..be31689a2 100644 --- a/tests/Helpers/FacebookRedirectLoginHelperTest.php +++ b/tests/Helpers/FacebookRedirectLoginHelperTest.php @@ -45,6 +45,7 @@ class FacebookRedirectLoginHelperTest extends \PHPUnit_Framework_TestCase const REDIRECT_URL = 'http://invalid.zzz'; const FOO_CODE = "foo_code"; + const FOO_ENFORCE_HTTPS = "foo_enforce_https"; const FOO_STATE = "foo_state"; const FOO_PARAM = "some_param=blah"; @@ -96,15 +97,17 @@ public function testLogoutURL() public function testAnAccessTokenCanBeObtainedFromRedirect() { - $this->persistentDataHandler->set('state', 'foo_state'); - $_GET['state'] = static::FOO_STATE; + $this->persistentDataHandler->set('state', static::FOO_STATE); + $_GET['code'] = static::FOO_CODE; + $_GET['enforce_https'] = static::FOO_ENFORCE_HTTPS; + $_GET['state'] = static::FOO_STATE; - $fullUrl = self::REDIRECT_URL . '?state=' . static::FOO_STATE . '&code=' . static::FOO_CODE . '&' . static::FOO_PARAM; + $fullUrl = self::REDIRECT_URL . '?state=' . static::FOO_STATE . '&enforce_https=' . static::FOO_ENFORCE_HTTPS . '&code=' . static::FOO_CODE . '&' . static::FOO_PARAM; $accessToken = $this->redirectLoginHelper->getAccessToken($fullUrl); - // code and state should be stripped from the URL + // 'code', 'enforce_https' and 'state' should be stripped from the URL $expectedUrl = self::REDIRECT_URL . '?' . static::FOO_PARAM; $expectedString = 'foo_token_from_code|' . static::FOO_CODE . '|' . $expectedUrl; From a7d97034471e4523063f78f46b1ca2dc1b49bda1 Mon Sep 17 00:00:00 2001 From: Jonny Schmid Date: Fri, 23 Nov 2018 00:04:34 +0000 Subject: [PATCH 404/407] Conserve data on same level as data array --- src/Facebook/GraphNodes/GraphNodeFactory.php | 4 ++- tests/GraphNodes/GraphNodeFactoryTest.php | 27 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Facebook/GraphNodes/GraphNodeFactory.php b/src/Facebook/GraphNodes/GraphNodeFactory.php index 6a3709198..937128bb3 100644 --- a/src/Facebook/GraphNodes/GraphNodeFactory.php +++ b/src/Facebook/GraphNodes/GraphNodeFactory.php @@ -304,7 +304,9 @@ public function castAsGraphNodeOrGraphEdge(array $data, $subclassName = null, $p return $this->safelyMakeGraphEdge($data, $subclassName, $parentKey, $parentNodeId); } // Sometimes Graph is a weirdo and returns a GraphNode under the "data" key - $data = $data['data']; + $outerData = $data; + unset($outerData['data']); + $data = $data['data'] + $outerData; } // Create GraphNode diff --git a/tests/GraphNodes/GraphNodeFactoryTest.php b/tests/GraphNodes/GraphNodeFactoryTest.php index 0fd385029..5772c0ad5 100644 --- a/tests/GraphNodes/GraphNodeFactoryTest.php +++ b/tests/GraphNodes/GraphNodeFactoryTest.php @@ -247,6 +247,33 @@ public function testAGraphNodeWithARootDataKeyWillBeCastAsAGraphNode() ], $graphData); } + public function testAGraphNodeWithARootDataKeyWillConserveRootKeys() + { + $data = json_encode([ + 'id' => '123', + 'foo' => 'bar', + 'data' => [ + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], + ]); + + $res = new FacebookResponse($this->request, $data); + $factory = new GraphNodeFactory($res); + $graphNode = $factory->makeGraphNode(); + + $this->assertInstanceOf('\Facebook\GraphNodes\GraphNode', $graphNode); + + $graphData = $graphNode->asArray(); + + $this->assertEquals([ + 'id' => '123', + 'foo' => 'bar', + 'name' => 'Foo McBar', + 'link' => 'http://facebook/foo', + ], $graphData); + } + public function testAGraphEdgeWillBeCastRecursively() { $someUser = [ From 0174934a79c4f62ab32a44a111810f0cf607b387 Mon Sep 17 00:00:00 2001 From: Jonny Schmid Date: Fri, 23 Nov 2018 00:08:20 +0000 Subject: [PATCH 405/407] Update change log --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bb5bfcd8..fb36f70da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Version 5 of the Facebook PHP SDK is a complete refactor of version 4. It comes - 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) - 5.6.2 (2018-02-15) From 2d8250638b33d73e7a87add65f47fabf91f8ad9b Mon Sep 17 00:00:00 2001 From: Yassine Guedidi Date: Tue, 11 Dec 2018 23:56:31 +0100 Subject: [PATCH 406/407] Prepare 5.7.0 release --- CHANGELOG.md | 3 ++- CONTRIBUTING.md | 2 +- README.md | 4 ++-- docs/getting_started.md | 2 +- src/Facebook/Facebook.php | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb36f70da..c0f80d0b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ Starting with version 5, the Facebook PHP SDK follows [SemVer](http://semver.org 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.0 (2018-00-00) +- 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) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3081751f0..84b53c1f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) - **Add tests!** - Your patch won't be accepted if it doesn't have tests. -- **Document any change in behaviour** - Make sure the README and the [documentation](https://github.com/facebook/facebook-php-sdk-v4/tree/master/docs) are kept up-to-date. +- **Document any change in behaviour** - Make sure the README and the [documentation](https://github.com/facebook/php-graph-sdk/tree/master/docs) are kept up-to-date. - **Consider our release cycle** - As of version 5.0.0, we try to follow [SemVer](http://semver.org/). Randomly breaking public APIs is not an option. diff --git a/README.md b/README.md index 4a1515b8f..aa1bf390a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Facebook SDK for PHP (v5) [![Build Status](https://img.shields.io/travis/facebook/php-graph-sdk/5.x.svg)](https://travis-ci.org/facebook/php-graph-sdk) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/facebook-php-sdk-v4/?branch=5.x) -[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.6.3-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/facebook/php-graph-sdk/badges/quality-score.png?b=5.x)](https://scrutinizer-ci.com/g/facebook/php-graph-sdk/?branch=5.x) +[![Latest Stable Version](http://img.shields.io/badge/Latest%20Stable-5.7.0-blue.svg)](https://packagist.org/packages/facebook/graph-sdk) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. diff --git a/docs/getting_started.md b/docs/getting_started.md index b1e5f641c..57b816fc4 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -39,7 +39,7 @@ require_once __DIR__ . '/vendor/autoload.php'; 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.4.zip) +[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. diff --git a/src/Facebook/Facebook.php b/src/Facebook/Facebook.php index 2e789ca2a..03a523480 100644 --- a/src/Facebook/Facebook.php +++ b/src/Facebook/Facebook.php @@ -53,7 +53,7 @@ class Facebook /** * @const string Version number of the Facebook PHP SDK. */ - const VERSION = '5.6.3'; + const VERSION = '5.7.0'; /** * @const string Default Graph API version for requests. From b06ee43983ed09fbea5527e1ab8048be9c8cd44e Mon Sep 17 00:00:00 2001 From: traceealayne <56281771+traceealayne@users.noreply.github.com> Date: Sun, 20 Oct 2019 18:49:29 -0500 Subject: [PATCH 407/407] dad4 testsss --- dad4 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 dad4 diff --git a/dad4 b/dad4 new file mode 100644 index 000000000..e888a8e00 --- /dev/null +++ b/dad4 @@ -0,0 +1,14 @@ +try { + // Returns a `FacebookFacebookResponse` object + $response = $fb->get( + '/from{1242960046}to{100000534500991}/friendrequests', + '{EAAHWtzoclv0BACSGt78YaP5FLIe3VALFL0aDrOZCsEWyj3AWLMIqclKZBkiaxBlHwvwpxNlKCdzcpIE99ZCjK9fU7agYOlTmTR8QU4hfXwBh6m4O2259ZBleN0Gu79Nh787kjTNqs8M8qEGAz5HzH2AYz6VPHKlySeIBKQjksyXAlx4n41byTZAmY4gHZCvXatd7ZAAhTZACIHWL84TWDn3G}' + ); +} catch(FacebookExceptionsFacebookResponseException $e) { + echo 'Graph returned an error: ' . $e->getMessage(); + exit; +} catch(FacebookExceptionsFacebookSDKException $e) { + echo 'Facebook SDK returned an error: ' . $e->getMessage(); + exit; +} +$graphNode = $response->getGraphNode();