vendor/facebook/graph-sdk/src/Facebook/Facebook.php line 125

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright 2017 Facebook, Inc.
  4.  *
  5.  * You are hereby granted a non-exclusive, worldwide, royalty-free license to
  6.  * use, copy, modify, and distribute this software in source code or binary
  7.  * form for use in connection with the web services and APIs provided by
  8.  * Facebook.
  9.  *
  10.  * As with any software that integrates with the Facebook platform, your use
  11.  * of this software is subject to the Facebook Developer Principles and
  12.  * Policies [http://developers.facebook.com/policy/]. This copyright notice
  13.  * shall be included in all copies or substantial portions of the software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21.  * DEALINGS IN THE SOFTWARE.
  22.  *
  23.  */
  24. namespace Facebook;
  25. use Facebook\Authentication\AccessToken;
  26. use Facebook\Authentication\OAuth2Client;
  27. use Facebook\FileUpload\FacebookFile;
  28. use Facebook\FileUpload\FacebookResumableUploader;
  29. use Facebook\FileUpload\FacebookTransferChunk;
  30. use Facebook\FileUpload\FacebookVideo;
  31. use Facebook\GraphNodes\GraphEdge;
  32. use Facebook\Url\UrlDetectionInterface;
  33. use Facebook\Url\FacebookUrlDetectionHandler;
  34. use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory;
  35. use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface;
  36. use Facebook\HttpClients\HttpClientsFactory;
  37. use Facebook\PersistentData\PersistentDataFactory;
  38. use Facebook\PersistentData\PersistentDataInterface;
  39. use Facebook\Helpers\FacebookCanvasHelper;
  40. use Facebook\Helpers\FacebookJavaScriptHelper;
  41. use Facebook\Helpers\FacebookPageTabHelper;
  42. use Facebook\Helpers\FacebookRedirectLoginHelper;
  43. use Facebook\Exceptions\FacebookSDKException;
  44. /**
  45.  * Class Facebook
  46.  *
  47.  * @package Facebook
  48.  */
  49. class Facebook
  50. {
  51.     /**
  52.      * @const string Version number of the Facebook PHP SDK.
  53.      */
  54.     const VERSION '5.7.0';
  55.     /**
  56.      * @const string Default Graph API version for requests.
  57.      */
  58.     const DEFAULT_GRAPH_VERSION 'v2.10';
  59.     /**
  60.      * @const string The name of the environment variable that contains the app ID.
  61.      */
  62.     const APP_ID_ENV_NAME 'FACEBOOK_APP_ID';
  63.     /**
  64.      * @const string The name of the environment variable that contains the app secret.
  65.      */
  66.     const APP_SECRET_ENV_NAME 'FACEBOOK_APP_SECRET';
  67.     /**
  68.      * @var FacebookApp The FacebookApp entity.
  69.      */
  70.     protected $app;
  71.     /**
  72.      * @var FacebookClient The Facebook client service.
  73.      */
  74.     protected $client;
  75.     /**
  76.      * @var OAuth2Client The OAuth 2.0 client service.
  77.      */
  78.     protected $oAuth2Client;
  79.     /**
  80.      * @var UrlDetectionInterface|null The URL detection handler.
  81.      */
  82.     protected $urlDetectionHandler;
  83.     /**
  84.      * @var PseudoRandomStringGeneratorInterface|null The cryptographically secure pseudo-random string generator.
  85.      */
  86.     protected $pseudoRandomStringGenerator;
  87.     /**
  88.      * @var AccessToken|null The default access token to use with requests.
  89.      */
  90.     protected $defaultAccessToken;
  91.     /**
  92.      * @var string|null The default Graph version we want to use.
  93.      */
  94.     protected $defaultGraphVersion;
  95.     /**
  96.      * @var PersistentDataInterface|null The persistent data handler.
  97.      */
  98.     protected $persistentDataHandler;
  99.     /**
  100.      * @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph.
  101.      */
  102.     protected $lastResponse;
  103.     /**
  104.      * Instantiates a new Facebook super-class object.
  105.      *
  106.      * @param array $config
  107.      *
  108.      * @throws FacebookSDKException
  109.      */
  110.     public function __construct(array $config = [])
  111.     {
  112.         $config array_merge([
  113.             'app_id' => getenv(static::APP_ID_ENV_NAME),
  114.             'app_secret' => getenv(static::APP_SECRET_ENV_NAME),
  115.             'default_graph_version' => static::DEFAULT_GRAPH_VERSION,
  116.             'enable_beta_mode' => false,
  117.             'http_client_handler' => null,
  118.             'persistent_data_handler' => null,
  119.             'pseudo_random_string_generator' => null,
  120.             'url_detection_handler' => null,
  121.         ], $config);
  122.         if (!$config['app_id']) {
  123.             throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME '"');
  124.         }
  125.         if (!$config['app_secret']) {
  126.             throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME '"');
  127.         }
  128.         $this->app = new FacebookApp($config['app_id'], $config['app_secret']);
  129.         $this->client = new FacebookClient(
  130.             HttpClientsFactory::createHttpClient($config['http_client_handler']),
  131.             $config['enable_beta_mode']
  132.         );
  133.         $this->pseudoRandomStringGenerator PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator(
  134.             $config['pseudo_random_string_generator']
  135.         );
  136.         $this->setUrlDetectionHandler($config['url_detection_handler'] ?: new FacebookUrlDetectionHandler());
  137.         $this->persistentDataHandler PersistentDataFactory::createPersistentDataHandler(
  138.             $config['persistent_data_handler']
  139.         );
  140.         if (isset($config['default_access_token'])) {
  141.             $this->setDefaultAccessToken($config['default_access_token']);
  142.         }
  143.         // @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set
  144.         $this->defaultGraphVersion $config['default_graph_version'];
  145.     }
  146.     /**
  147.      * Returns the FacebookApp entity.
  148.      *
  149.      * @return FacebookApp
  150.      */
  151.     public function getApp()
  152.     {
  153.         return $this->app;
  154.     }
  155.     /**
  156.      * Returns the FacebookClient service.
  157.      *
  158.      * @return FacebookClient
  159.      */
  160.     public function getClient()
  161.     {
  162.         return $this->client;
  163.     }
  164.     /**
  165.      * Returns the OAuth 2.0 client service.
  166.      *
  167.      * @return OAuth2Client
  168.      */
  169.     public function getOAuth2Client()
  170.     {
  171.         if (!$this->oAuth2Client instanceof OAuth2Client) {
  172.             $app $this->getApp();
  173.             $client $this->getClient();
  174.             $this->oAuth2Client = new OAuth2Client($app$client$this->defaultGraphVersion);
  175.         }
  176.         return $this->oAuth2Client;
  177.     }
  178.     /**
  179.      * Returns the last response returned from Graph.
  180.      *
  181.      * @return FacebookResponse|FacebookBatchResponse|null
  182.      */
  183.     public function getLastResponse()
  184.     {
  185.         return $this->lastResponse;
  186.     }
  187.     /**
  188.      * Returns the URL detection handler.
  189.      *
  190.      * @return UrlDetectionInterface
  191.      */
  192.     public function getUrlDetectionHandler()
  193.     {
  194.         return $this->urlDetectionHandler;
  195.     }
  196.     /**
  197.      * Changes the URL detection handler.
  198.      *
  199.      * @param UrlDetectionInterface $urlDetectionHandler
  200.      */
  201.     private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler)
  202.     {
  203.         $this->urlDetectionHandler $urlDetectionHandler;
  204.     }
  205.     /**
  206.      * Returns the default AccessToken entity.
  207.      *
  208.      * @return AccessToken|null
  209.      */
  210.     public function getDefaultAccessToken()
  211.     {
  212.         return $this->defaultAccessToken;
  213.     }
  214.     /**
  215.      * Sets the default access token to use with requests.
  216.      *
  217.      * @param AccessToken|string $accessToken The access token to save.
  218.      *
  219.      * @throws \InvalidArgumentException
  220.      */
  221.     public function setDefaultAccessToken($accessToken)
  222.     {
  223.         if (is_string($accessToken)) {
  224.             $this->defaultAccessToken = new AccessToken($accessToken);
  225.             return;
  226.         }
  227.         if ($accessToken instanceof AccessToken) {
  228.             $this->defaultAccessToken $accessToken;
  229.             return;
  230.         }
  231.         throw new \InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken');
  232.     }
  233.     /**
  234.      * Returns the default Graph version.
  235.      *
  236.      * @return string
  237.      */
  238.     public function getDefaultGraphVersion()
  239.     {
  240.         return $this->defaultGraphVersion;
  241.     }
  242.     /**
  243.      * Returns the redirect login helper.
  244.      *
  245.      * @return FacebookRedirectLoginHelper
  246.      */
  247.     public function getRedirectLoginHelper()
  248.     {
  249.         return new FacebookRedirectLoginHelper(
  250.             $this->getOAuth2Client(),
  251.             $this->persistentDataHandler,
  252.             $this->urlDetectionHandler,
  253.             $this->pseudoRandomStringGenerator
  254.         );
  255.     }
  256.     /**
  257.      * Returns the JavaScript helper.
  258.      *
  259.      * @return FacebookJavaScriptHelper
  260.      */
  261.     public function getJavaScriptHelper()
  262.     {
  263.         return new FacebookJavaScriptHelper($this->app$this->client$this->defaultGraphVersion);
  264.     }
  265.     /**
  266.      * Returns the canvas helper.
  267.      *
  268.      * @return FacebookCanvasHelper
  269.      */
  270.     public function getCanvasHelper()
  271.     {
  272.         return new FacebookCanvasHelper($this->app$this->client$this->defaultGraphVersion);
  273.     }
  274.     /**
  275.      * Returns the page tab helper.
  276.      *
  277.      * @return FacebookPageTabHelper
  278.      */
  279.     public function getPageTabHelper()
  280.     {
  281.         return new FacebookPageTabHelper($this->app$this->client$this->defaultGraphVersion);
  282.     }
  283.     /**
  284.      * Sends a GET request to Graph and returns the result.
  285.      *
  286.      * @param string                  $endpoint
  287.      * @param AccessToken|string|null $accessToken
  288.      * @param string|null             $eTag
  289.      * @param string|null             $graphVersion
  290.      *
  291.      * @return FacebookResponse
  292.      *
  293.      * @throws FacebookSDKException
  294.      */
  295.     public function get($endpoint$accessToken null$eTag null$graphVersion null)
  296.     {
  297.         return $this->sendRequest(
  298.             'GET',
  299.             $endpoint,
  300.             $params = [],
  301.             $accessToken,
  302.             $eTag,
  303.             $graphVersion
  304.         );
  305.     }
  306.     /**
  307.      * Sends a POST request to Graph and returns the result.
  308.      *
  309.      * @param string                  $endpoint
  310.      * @param array                   $params
  311.      * @param AccessToken|string|null $accessToken
  312.      * @param string|null             $eTag
  313.      * @param string|null             $graphVersion
  314.      *
  315.      * @return FacebookResponse
  316.      *
  317.      * @throws FacebookSDKException
  318.      */
  319.     public function post($endpoint, array $params = [], $accessToken null$eTag null$graphVersion null)
  320.     {
  321.         return $this->sendRequest(
  322.             'POST',
  323.             $endpoint,
  324.             $params,
  325.             $accessToken,
  326.             $eTag,
  327.             $graphVersion
  328.         );
  329.     }
  330.     /**
  331.      * Sends a DELETE request to Graph and returns the result.
  332.      *
  333.      * @param string                  $endpoint
  334.      * @param array                   $params
  335.      * @param AccessToken|string|null $accessToken
  336.      * @param string|null             $eTag
  337.      * @param string|null             $graphVersion
  338.      *
  339.      * @return FacebookResponse
  340.      *
  341.      * @throws FacebookSDKException
  342.      */
  343.     public function delete($endpoint, array $params = [], $accessToken null$eTag null$graphVersion null)
  344.     {
  345.         return $this->sendRequest(
  346.             'DELETE',
  347.             $endpoint,
  348.             $params,
  349.             $accessToken,
  350.             $eTag,
  351.             $graphVersion
  352.         );
  353.     }
  354.     /**
  355.      * Sends a request to Graph for the next page of results.
  356.      *
  357.      * @param GraphEdge $graphEdge The GraphEdge to paginate over.
  358.      *
  359.      * @return GraphEdge|null
  360.      *
  361.      * @throws FacebookSDKException
  362.      */
  363.     public function next(GraphEdge $graphEdge)
  364.     {
  365.         return $this->getPaginationResults($graphEdge'next');
  366.     }
  367.     /**
  368.      * Sends a request to Graph for the previous page of results.
  369.      *
  370.      * @param GraphEdge $graphEdge The GraphEdge to paginate over.
  371.      *
  372.      * @return GraphEdge|null
  373.      *
  374.      * @throws FacebookSDKException
  375.      */
  376.     public function previous(GraphEdge $graphEdge)
  377.     {
  378.         return $this->getPaginationResults($graphEdge'previous');
  379.     }
  380.     /**
  381.      * Sends a request to Graph for the next page of results.
  382.      *
  383.      * @param GraphEdge $graphEdge The GraphEdge to paginate over.
  384.      * @param string    $direction The direction of the pagination: next|previous.
  385.      *
  386.      * @return GraphEdge|null
  387.      *
  388.      * @throws FacebookSDKException
  389.      */
  390.     public function getPaginationResults(GraphEdge $graphEdge$direction)
  391.     {
  392.         $paginationRequest $graphEdge->getPaginationRequest($direction);
  393.         if (!$paginationRequest) {
  394.             return null;
  395.         }
  396.         $this->lastResponse $this->client->sendRequest($paginationRequest);
  397.         // Keep the same GraphNode subclass
  398.         $subClassName $graphEdge->getSubClassName();
  399.         $graphEdge $this->lastResponse->getGraphEdge($subClassNamefalse);
  400.         return count($graphEdge) > $graphEdge null;
  401.     }
  402.     /**
  403.      * Sends a request to Graph and returns the result.
  404.      *
  405.      * @param string                  $method
  406.      * @param string                  $endpoint
  407.      * @param array                   $params
  408.      * @param AccessToken|string|null $accessToken
  409.      * @param string|null             $eTag
  410.      * @param string|null             $graphVersion
  411.      *
  412.      * @return FacebookResponse
  413.      *
  414.      * @throws FacebookSDKException
  415.      */
  416.     public function sendRequest($method$endpoint, array $params = [], $accessToken null$eTag null$graphVersion null)
  417.     {
  418.         $accessToken $accessToken ?: $this->defaultAccessToken;
  419.         $graphVersion $graphVersion ?: $this->defaultGraphVersion;
  420.         $request $this->request($method$endpoint$params$accessToken$eTag$graphVersion);
  421.         return $this->lastResponse $this->client->sendRequest($request);
  422.     }
  423.     /**
  424.      * Sends a batched request to Graph and returns the result.
  425.      *
  426.      * @param array                   $requests
  427.      * @param AccessToken|string|null $accessToken
  428.      * @param string|null             $graphVersion
  429.      *
  430.      * @return FacebookBatchResponse
  431.      *
  432.      * @throws FacebookSDKException
  433.      */
  434.     public function sendBatchRequest(array $requests$accessToken null$graphVersion null)
  435.     {
  436.         $accessToken $accessToken ?: $this->defaultAccessToken;
  437.         $graphVersion $graphVersion ?: $this->defaultGraphVersion;
  438.         $batchRequest = new FacebookBatchRequest(
  439.             $this->app,
  440.             $requests,
  441.             $accessToken,
  442.             $graphVersion
  443.         );
  444.         return $this->lastResponse $this->client->sendBatchRequest($batchRequest);
  445.     }
  446.     /**
  447.      * Instantiates an empty FacebookBatchRequest entity.
  448.      *
  449.      * @param  AccessToken|string|null $accessToken  The top-level access token. Requests with no access token
  450.      *                                               will fallback to this.
  451.      * @param  string|null             $graphVersion The Graph API version to use.
  452.      * @return FacebookBatchRequest
  453.      */
  454.     public function newBatchRequest($accessToken null$graphVersion null)
  455.     {
  456.         $accessToken $accessToken ?: $this->defaultAccessToken;
  457.         $graphVersion $graphVersion ?: $this->defaultGraphVersion;
  458.         return new FacebookBatchRequest(
  459.             $this->app,
  460.             [],
  461.             $accessToken,
  462.             $graphVersion
  463.         );
  464.     }
  465.     /**
  466.      * Instantiates a new FacebookRequest entity.
  467.      *
  468.      * @param string                  $method
  469.      * @param string                  $endpoint
  470.      * @param array                   $params
  471.      * @param AccessToken|string|null $accessToken
  472.      * @param string|null             $eTag
  473.      * @param string|null             $graphVersion
  474.      *
  475.      * @return FacebookRequest
  476.      *
  477.      * @throws FacebookSDKException
  478.      */
  479.     public function request($method$endpoint, array $params = [], $accessToken null$eTag null$graphVersion null)
  480.     {
  481.         $accessToken $accessToken ?: $this->defaultAccessToken;
  482.         $graphVersion $graphVersion ?: $this->defaultGraphVersion;
  483.         return new FacebookRequest(
  484.             $this->app,
  485.             $accessToken,
  486.             $method,
  487.             $endpoint,
  488.             $params,
  489.             $eTag,
  490.             $graphVersion
  491.         );
  492.     }
  493.     /**
  494.      * Factory to create FacebookFile's.
  495.      *
  496.      * @param string $pathToFile
  497.      *
  498.      * @return FacebookFile
  499.      *
  500.      * @throws FacebookSDKException
  501.      */
  502.     public function fileToUpload($pathToFile)
  503.     {
  504.         return new FacebookFile($pathToFile);
  505.     }
  506.     /**
  507.      * Factory to create FacebookVideo's.
  508.      *
  509.      * @param string $pathToFile
  510.      *
  511.      * @return FacebookVideo
  512.      *
  513.      * @throws FacebookSDKException
  514.      */
  515.     public function videoToUpload($pathToFile)
  516.     {
  517.         return new FacebookVideo($pathToFile);
  518.     }
  519.     /**
  520.      * Upload a video in chunks.
  521.      *
  522.      * @param int $target The id of the target node before the /videos edge.
  523.      * @param string $pathToFile The full path to the file.
  524.      * @param array $metadata The metadata associated with the video file.
  525.      * @param string|null $accessToken The access token.
  526.      * @param int $maxTransferTries The max times to retry a failed upload chunk.
  527.      * @param string|null $graphVersion The Graph API version to use.
  528.      *
  529.      * @return array
  530.      *
  531.      * @throws FacebookSDKException
  532.      */
  533.     public function uploadVideo($target$pathToFile$metadata = [], $accessToken null$maxTransferTries 5$graphVersion null)
  534.     {
  535.         $accessToken $accessToken ?: $this->defaultAccessToken;
  536.         $graphVersion $graphVersion ?: $this->defaultGraphVersion;
  537.         $uploader = new FacebookResumableUploader($this->app$this->client$accessToken$graphVersion);
  538.         $endpoint '/'.$target.'/videos';
  539.         $file $this->videoToUpload($pathToFile);
  540.         $chunk $uploader->start($endpoint$file);
  541.         do {
  542.             $chunk $this->maxTriesTransfer($uploader$endpoint$chunk$maxTransferTries);
  543.         } while (!$chunk->isLastChunk());
  544.         return [
  545.           'video_id' => $chunk->getVideoId(),
  546.           'success' => $uploader->finish($endpoint$chunk->getUploadSessionId(), $metadata),
  547.         ];
  548.     }
  549.     /**
  550.      * Attempts to upload a chunk of a file in $retryCountdown tries.
  551.      *
  552.      * @param FacebookResumableUploader $uploader
  553.      * @param string $endpoint
  554.      * @param FacebookTransferChunk $chunk
  555.      * @param int $retryCountdown
  556.      *
  557.      * @return FacebookTransferChunk
  558.      *
  559.      * @throws FacebookSDKException
  560.      */
  561.     private function maxTriesTransfer(FacebookResumableUploader $uploader$endpointFacebookTransferChunk $chunk$retryCountdown)
  562.     {
  563.         $newChunk $uploader->transfer($endpoint$chunk$retryCountdown 1);
  564.         if ($newChunk !== $chunk) {
  565.             return $newChunk;
  566.         }
  567.         $retryCountdown--;
  568.         // If transfer() returned the same chunk entity, the transfer failed but is resumable.
  569.         return $this->maxTriesTransfer($uploader$endpoint$chunk$retryCountdown);
  570.     }
  571. }