1<?php 2namespace Kunnu\Dropbox; 3 4use Kunnu\Dropbox\Http\Clients\DropboxHttpClientInterface; 5 6/** 7 * DropboxClient 8 */ 9class DropboxClient 10{ 11 /** 12 * Dropbox API Root URL. 13 * 14 * @const string 15 */ 16 const BASE_PATH = 'https://api.dropboxapi.com/2'; 17 18 /** 19 * Dropbox API Content Root URL. 20 * 21 * @const string 22 */ 23 const CONTENT_PATH = 'https://content.dropboxapi.com/2'; 24 25 /** 26 * DropboxHttpClientInterface Implementation 27 * 28 * @var \Kunnu\Dropbox\Http\Clients\DropboxHttpClientInterface 29 */ 30 protected $httpClient; 31 32 /** 33 * Create a new DropboxClient instance 34 * 35 * @param DropboxHttpClientInterface $httpClient 36 */ 37 public function __construct(DropboxHttpClientInterface $httpClient) 38 { 39 //Set the HTTP Client 40 $this->setHttpClient($httpClient); 41 } 42 43 /** 44 * Get the HTTP Client 45 * 46 * @return \Kunnu\Dropbox\Http\Clients\DropboxHttpClientInterface $httpClient 47 */ 48 public function getHttpClient() 49 { 50 return $this->httpClient; 51 } 52 53 /** 54 * Set the HTTP Client 55 * 56 * @param \Kunnu\Dropbox\Http\Clients\DropboxHttpClientInterface $httpClient 57 * 58 * @return \Kunnu\Dropbox\DropboxClient 59 */ 60 public function setHttpClient(DropboxHttpClientInterface $httpClient) 61 { 62 $this->httpClient = $httpClient; 63 64 return $this; 65 } 66 67 /** 68 * Get the API Base Path. 69 * 70 * @return string API Base Path 71 */ 72 public function getBasePath() 73 { 74 return static::BASE_PATH; 75 } 76 77 /** 78 * Get the API Content Path. 79 * 80 * @return string API Content Path 81 */ 82 public function getContentPath() 83 { 84 return static::CONTENT_PATH; 85 } 86 87 /** 88 * Get the Authorization Header with the Access Token. 89 * 90 * @param string $accessToken Access Token 91 * 92 * @return array Authorization Header 93 */ 94 protected function buildAuthHeader($accessToken = "") 95 { 96 return ['Authorization' => 'Bearer '. $accessToken]; 97 } 98 99 /** 100 * Get the Content Type Header. 101 * 102 * @param string $contentType Request Content Type 103 * 104 * @return array Content Type Header 105 */ 106 protected function buildContentTypeHeader($contentType = "") 107 { 108 return ['Content-Type' => $contentType]; 109 } 110 111 /** 112 * Build URL for the Request 113 * 114 * @param string $endpoint Relative API endpoint 115 * @param string $type Endpoint Type 116 * 117 * @link https://www.dropbox.com/developers/documentation/http/documentation#formats Request and response formats 118 * 119 * @return string The Full URL to the API Endpoints 120 */ 121 protected function buildUrl($endpoint = '', $type = 'api') 122 { 123 //Get the base path 124 $base = $this->getBasePath(); 125 126 //If the endpoint type is 'content' 127 if ($type === 'content') { 128 //Get the Content Path 129 $base = $this->getContentPath(); 130 } 131 132 //Join and return the base and api path/endpoint 133 return $base . $endpoint; 134 } 135 136 /** 137 * Send the Request to the Server and return the Response 138 * 139 * @param DropboxRequest $request 140 * @param DropboxResponse $response 141 * 142 * @return \Kunnu\Dropbox\DropboxResponse 143 * 144 * @throws \Kunnu\Dropbox\Exceptions\DropboxClientException 145 */ 146 public function sendRequest(DropboxRequest $request, DropboxResponse $response = null) 147 { 148 //Method 149 $method = $request->getMethod(); 150 151 //Prepare Request 152 list($url, $headers, $requestBody) = $this->prepareRequest($request); 153 154 $options = []; 155 if ($response instanceof DropboxResponseToFile) { 156 $options['sink'] = $response->getFilePath(); 157 } 158 159 //Send the Request to the Server through the HTTP Client 160 //and fetch the raw response as DropboxRawResponse 161 $rawResponse = $this->getHttpClient()->send($url, $method, $requestBody, $headers, $options); 162 163 //Create DropboxResponse from DropboxRawResponse 164 $response = $response ?: new DropboxResponse($request); 165 $response->setHttpStatusCode($rawResponse->getHttpResponseCode()); 166 $response->setHeaders($rawResponse->getHeaders()); 167 if (!$response instanceof DropboxResponseToFile) { 168 $response->setBody($rawResponse->getBody()); 169 } 170 171 //Return the DropboxResponse 172 return $response; 173 } 174 175 /** 176 * Prepare a Request before being sent to the HTTP Client 177 * 178 * @param \Kunnu\Dropbox\DropboxRequest $request 179 * 180 * @return array [Request URL, Request Headers, Request Body] 181 */ 182 protected function prepareRequest(DropboxRequest $request) 183 { 184 //Build URL 185 $url = $this->buildUrl($request->getEndpoint(), $request->getEndpointType()); 186 187 //The Endpoint is content 188 if ($request->getEndpointType() === 'content') { 189 //Dropbox requires the parameters to be passed 190 //through the 'Dropbox-API-Arg' header 191 $request->setHeaders(['Dropbox-API-Arg' => json_encode($request->getParams())]); 192 193 //If a File is also being uploaded 194 if ($request->hasFile()) { 195 //Content Type 196 $request->setContentType("application/octet-stream"); 197 198 //Request Body (File Contents) 199 $requestBody = $request->getStreamBody()->getBody(); 200 } else { 201 //Empty Body 202 $requestBody = null; 203 } 204 } else { 205 //The endpoint is 'api' 206 //Request Body (Parameters) 207 $requestBody = $request->getJsonBody()->getBody(); 208 } 209 210 //Empty body 211 if (is_null($requestBody)) { 212 //Content Type needs to be kept empty 213 $request->setContentType(""); 214 } 215 216 //Build headers 217 $headers = array_merge( 218 $this->buildAuthHeader($request->getAccessToken()), 219 $this->buildContentTypeHeader($request->getContentType()), 220 $request->getHeaders() 221 ); 222 223 //Return the URL, Headers and Request Body 224 return [$url, $headers, $requestBody]; 225 } 226} 227