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 */ 24namespace Facebook\FileUpload; 25 26use Facebook\Authentication\AccessToken; 27use Facebook\Exceptions\FacebookResponseException; 28use Facebook\Exceptions\FacebookResumableUploadException; 29use Facebook\Exceptions\FacebookSDKException; 30use Facebook\FacebookApp; 31use Facebook\FacebookClient; 32use Facebook\FacebookRequest; 33 34/** 35 * Class FacebookResumableUploader 36 * 37 * @package Facebook 38 */ 39class FacebookResumableUploader 40{ 41 /** 42 * @var FacebookApp 43 */ 44 protected $app; 45 46 /** 47 * @var string 48 */ 49 protected $accessToken; 50 51 /** 52 * @var FacebookClient The Facebook client service. 53 */ 54 protected $client; 55 56 /** 57 * @var string Graph version to use for this request. 58 */ 59 protected $graphVersion; 60 61 /** 62 * @param FacebookApp $app 63 * @param FacebookClient $client 64 * @param AccessToken|string|null $accessToken 65 * @param string $graphVersion 66 */ 67 public function __construct(FacebookApp $app, FacebookClient $client, $accessToken, $graphVersion) 68 { 69 $this->app = $app; 70 $this->client = $client; 71 $this->accessToken = $accessToken; 72 $this->graphVersion = $graphVersion; 73 } 74 75 /** 76 * Upload by chunks - start phase 77 * 78 * @param string $endpoint 79 * @param FacebookFile $file 80 * 81 * @return FacebookTransferChunk 82 * 83 * @throws FacebookSDKException 84 */ 85 public function start($endpoint, FacebookFile $file) 86 { 87 $params = [ 88 'upload_phase' => 'start', 89 'file_size' => $file->getSize(), 90 ]; 91 $response = $this->sendUploadRequest($endpoint, $params); 92 93 return new FacebookTransferChunk($file, $response['upload_session_id'], $response['video_id'], $response['start_offset'], $response['end_offset']); 94 } 95 96 /** 97 * Upload by chunks - transfer phase 98 * 99 * @param string $endpoint 100 * @param FacebookTransferChunk $chunk 101 * @param boolean $allowToThrow 102 * 103 * @return FacebookTransferChunk 104 * 105 * @throws FacebookResponseException 106 */ 107 public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow = false) 108 { 109 $params = [ 110 'upload_phase' => 'transfer', 111 'upload_session_id' => $chunk->getUploadSessionId(), 112 'start_offset' => $chunk->getStartOffset(), 113 'video_file_chunk' => $chunk->getPartialFile(), 114 ]; 115 116 try { 117 $response = $this->sendUploadRequest($endpoint, $params); 118 } catch (FacebookResponseException $e) { 119 $preException = $e->getPrevious(); 120 if ($allowToThrow || !$preException instanceof FacebookResumableUploadException) { 121 throw $e; 122 } 123 124 // Return the same chunk entity so it can be retried. 125 return $chunk; 126 } 127 128 return new FacebookTransferChunk($chunk->getFile(), $chunk->getUploadSessionId(), $chunk->getVideoId(), $response['start_offset'], $response['end_offset']); 129 } 130 131 /** 132 * Upload by chunks - finish phase 133 * 134 * @param string $endpoint 135 * @param string $uploadSessionId 136 * @param array $metadata The metadata associated with the file. 137 * 138 * @return boolean 139 * 140 * @throws FacebookSDKException 141 */ 142 public function finish($endpoint, $uploadSessionId, $metadata = []) 143 { 144 $params = array_merge($metadata, [ 145 'upload_phase' => 'finish', 146 'upload_session_id' => $uploadSessionId, 147 ]); 148 $response = $this->sendUploadRequest($endpoint, $params); 149 150 return $response['success']; 151 } 152 153 /** 154 * Helper to make a FacebookRequest and send it. 155 * 156 * @param string $endpoint The endpoint to POST to. 157 * @param array $params The params to send with the request. 158 * 159 * @return array 160 */ 161 private function sendUploadRequest($endpoint, $params = []) 162 { 163 $request = new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion); 164 165 return $this->client->sendRequest($request)->getDecodedBody(); 166 } 167} 168