├── README.md ├── composer.json └── src ├── AuthTrait.php ├── Cloud.php └── Exceptions └── BadRequest.php /README.md: -------------------------------------------------------------------------------- 1 | # Sdk для работы с облаком mail.ru 2 | 3 | ## Установка с помощью composer: 4 | ``` bash 5 | composer require friday14/cloud-mail-ru dev-master 6 | ``` 7 | 8 | ## Использование 9 | 10 | ``` php 11 | $cloud = new \Friday14\Mailru\Cloud('yourLogin', 'yourPassword', 'yourDomain'); 12 | ``` 13 | Пример: 14 | ``` php 15 | $cloud = new \Friday14\Mailru\Cloud('friday14', 'password', 'mail.ru'); 16 | ``` 17 | 18 | ### Методы 19 | 20 | **files($path)** - Получить все файлы из заданного каталога 21 | ``` php 22 | $cloud->files('/cloud-root'); 23 | ``` 24 | 25 | **createFile($path, $content)** - Создать файл с заданным контентом 26 | ``` php 27 | $cloud->createFile('/ololo.txt','Hello World'); 28 | ``` 29 | 30 | **createFolder($path)** - Создать папку в облаке 31 | ``` php 32 | $cloud->createFolder('/foldername'); 33 | ``` 34 | 35 | **delete($path)** - Удалить папку/файл 36 | ``` php 37 | $cloud->delete('/wallaper.jpg'); 38 | ``` 39 | 40 | **rename($path, $name)** - Переименновать папку/файл 41 | ``` php 42 | $cloud->rename('/cloud-folder/wallaper.jpg', 'newName.jpg'); 43 | ``` 44 | 45 | **upload(SplFileObject $file, $filename = null)** - Uploads your files in Cloud (If you specify a folder in the path that does not exist, it will be created before the download) 46 | ``` php 47 | $file = new SplFileObject($_SERVER['DOCUMENT_ROOT'] . '/teremok.jpg'); 48 | $cloud->upload($file, '/wallapers/super-teremok.jpg'); 49 | ``` 50 | 51 | **download($path, $savePath)** - Загрузить файл. 52 | ``` php 53 | $cloud->download('/wallapers/super-teremok.jpg', $_SERVER['DOCUMENT_ROOT'] . '/folder/filename.format'); 54 | ``` 55 | 56 | **publishFile($path)** - Сделать файл общедоступным 57 | ``` php 58 | $cloud->publishFile('/wallapers/super-teremok.jpg'); 59 | ``` 60 | 61 | **getLink($path)** - Сделать файл общедоступным и получить ссылку на файл 62 | ``` php 63 | $cloud->getLink('/wallapers/super-teremok.jpg') // return https://cloclo4.cloud.mail.ru/thumb/xw1/wallapers/super-teremok.jpg 64 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "friday14/cloud-mail-ru", 3 | "description": "Client for Cloud mail.ru", 4 | "keywords": ["mail.ru", "cloud"], 5 | "type": "library", 6 | "authors": [ 7 | { 8 | "name": "Evgeniy Marthenov", 9 | "email": "evgeniy.marthenov@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.6.4", 14 | "guzzlehttp/guzzle": "~6.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Friday14\\Mailru\\": "/src" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AuthTrait.php: -------------------------------------------------------------------------------- 1 | request('https://auth.mail.ru/cgi-bin/auth', 'POST', [ 22 | 'Login' => $this->login, 23 | 'Password' => $this->password, 24 | 'Domain' => $this->domain, 25 | ], 'multipart', false); 26 | 27 | $this->isAuth = true; 28 | $this->client->request('GET', 'https://cloud.mail.ru'); 29 | $this->fetchToken(); 30 | return $this; 31 | } 32 | 33 | 34 | public function fetchToken() 35 | { 36 | $res = $this->client->request('GET', self::FETCH_TOKEN_URL, [ 37 | 'form_params' => [ 38 | 'api' => 'v2', 39 | 'email' => $this->login, 40 | 'x-email' => $this->login, 41 | ] 42 | ]); 43 | $this->parseToken($res->getBody()->getContents()); 44 | } 45 | 46 | 47 | protected function parseToken($token) 48 | { 49 | $data = json_decode($token); 50 | $this->token = $data->body->token; 51 | $this->tokenLifeTime = $data->time; 52 | $this->email = $data->email; 53 | } 54 | } -------------------------------------------------------------------------------- /src/Cloud.php: -------------------------------------------------------------------------------- 1 | 14 | * 15 | */ 16 | 17 | class Cloud 18 | { 19 | /** 20 | * Consts 21 | */ 22 | const VERSION_API = 2; 23 | const CLOUD_DOMAIN = 'https://cloud.mail.ru/api/v2'; 24 | const FETCH_TOKEN_URL = 'https://cloud.mail.ru/api/v2/tokens/csrf'; 25 | const UPLOAD_URL = 'https://cloclo3-upload.cloud.mail.ru/upload/'; 26 | const DOWNLOAD_URL = 'https://cloclo17.datacloudmail.ru/'; 27 | 28 | protected $client; 29 | 30 | //Traits 31 | use AuthTrait; 32 | 33 | 34 | public function __construct($login, $password, $domain) 35 | { 36 | $this->login = $login; 37 | $this->password = $password; 38 | $this->domain = $domain; 39 | 40 | $this->client = new GuzzleClient( 41 | [ 42 | 'headers' => [ 43 | 'Accept' => '*/*', 44 | 'User-Agent' => $this->userAgent 45 | ], 46 | 'cookies' => new \GuzzleHttp\Cookie\CookieJar() 47 | ]); 48 | $this->authorization(); 49 | } 50 | 51 | 52 | /** 53 | * Move the file 54 | * 55 | * @param string $path Path to file 56 | * @param string $newFolder Path to new folder 57 | * @return mixed Request response 58 | */ 59 | public function move($path, $newFolder) 60 | { 61 | return $this->request('/file/move', 'POST', [ 62 | 'folder' => $newFolder, 63 | 'conflict' => 'rename', 64 | 'home' => $path, 65 | ]); 66 | } 67 | 68 | /** 69 | * Copy file to folder 70 | * 71 | * @param string $path Path the file 72 | * @param string $copyToFolder Copy to this folder 73 | * @return mixed 74 | */ 75 | public function copy($path, $copyToFolder) 76 | { 77 | return $this->request('/file/copy', 'POST', [ 78 | 'folder' => $copyToFolder, 79 | 'conflict' => 'rename', 80 | 'home' => $path, 81 | ]); 82 | } 83 | 84 | 85 | /** 86 | * Delete this file 87 | * 88 | * @param string $path Path this file which need delete 89 | * @return mixed 90 | */ 91 | public function delete($path) 92 | { 93 | return $this->request('/file/remove', 'POST', ['home' => $path]); 94 | } 95 | 96 | 97 | /** 98 | * Get all files which in this folder 99 | * 100 | * @param $directory 101 | * @return mixed 102 | */ 103 | public function files($directory) 104 | { 105 | return $this->request('/folder', 'GET', [ 106 | 'home' => $directory, 107 | 'sort' => '{"type":"name","order":"asc"}' 108 | ]); 109 | } 110 | 111 | 112 | /** 113 | * @param $path 114 | * @param $content 115 | * @return mixed 116 | */ 117 | public function createFile($path, $content) 118 | { 119 | $tmpfile = tmpfile(); 120 | fwrite($tmpfile, $content); 121 | $tmpfilePath = stream_get_meta_data($tmpfile); 122 | $file = new SplFileObject($tmpfilePath['uri']); 123 | return $this->upload($file, $path); 124 | } 125 | 126 | 127 | /** 128 | * Create a folder in Cloud 129 | * 130 | * @param string $path Path new folder 131 | * @return mixed 132 | */ 133 | public function createFolder($path) 134 | { 135 | return $this->request('/folder/add', 'GET', [ 136 | 'home' => $path 137 | ]); 138 | } 139 | 140 | 141 | /** 142 | * Rename file 143 | * 144 | * @param string $path 145 | * @param string $name 146 | * 147 | * @return mixed 148 | * @throws \GuzzleHttp\Exception\GuzzleException 149 | */ 150 | public function rename($path, $name) 151 | { 152 | return $this->request('/file/rename', 'GET', [ 153 | 'home' => $path, 154 | 'name' => $name 155 | ]); 156 | } 157 | 158 | 159 | /** 160 | * Uploads your files in Cloud 161 | * 162 | * @param SplFileObject $file 163 | * @param string|null $filename 164 | * @param string $saveFolder 165 | * 166 | * @return mixed 167 | * @throws \GuzzleHttp\Exception\GuzzleException 168 | */ 169 | public function upload(SplFileObject $file, $filename = null, $saveFolder = '/') 170 | { 171 | $fileName = ($filename == null) ? $file->getBasename() : $filename; 172 | $fileSize = $file->getSize(); 173 | $stream = fopen($file->getRealPath(), 'rb'); 174 | $boundary = uniqid($fileName . $fileSize, true); 175 | 176 | $params = [ 177 | 'query' => [ 178 | 'cloud_domain' => 2, 179 | 'x-email' => $this->email, 180 | 'fileapi15004124608926' => '' 181 | ], 182 | 'body' => new MultipartStream([ 183 | [ 184 | 'name' => 'file', 185 | 'contents' => $stream, 186 | ] 187 | ], $boundary), 188 | 'headers' => [ 189 | 'Content-Disposition' => 'form-data; name="file"; filename="epp.txt"', 190 | 'Content-Type' => 'multipart/form-data; boundary=' . $boundary, 191 | ] 192 | ]; 193 | 194 | $res = $this->client->request('POST', self::UPLOAD_URL, $params); 195 | $hash = strstr($res->getBody()->getContents(), ';', true); 196 | 197 | return $this->confirmUpload($saveFolder, $fileName, $hash, $fileSize); 198 | } 199 | 200 | 201 | /** 202 | * Download your files of Cloud 203 | * 204 | * @param string $path File which the your want download 205 | * @param string $savePath Local Path for save the file 206 | * 207 | * @return bool 208 | * @throws \GuzzleHttp\Exception\GuzzleException 209 | */ 210 | public function download($path, $savePath) 211 | { 212 | $res = $this->client->request('GET', self::DOWNLOAD_URL . "get{$path}", ['sink' => $savePath]); 213 | return $res->getStatusCode() === 200; 214 | } 215 | 216 | 217 | /** 218 | * Set publish flag a file or folder 219 | * 220 | * @param string $path 221 | * 222 | * @return mixed 223 | * @throws \GuzzleHttp\Exception\GuzzleException 224 | */ 225 | public function publishFile($path) 226 | { 227 | return $this->request('/file/publish', 'GET', [ 228 | 'home' => $path 229 | ]); 230 | } 231 | 232 | 233 | /** 234 | * Set publish flag and get public link a file 235 | * @param string $path Path file/folder 236 | * @return string Public link the file 237 | */ 238 | public function getLink($path) 239 | { 240 | $link = $this->publishFile($path)->body; 241 | return self::DOWNLOAD_URL . 'weblink/thumb/xw1/' . $link; 242 | } 243 | 244 | 245 | /** 246 | * @param $folder 247 | * @param $filename 248 | * @param $hash 249 | * @param $filesize 250 | * 251 | * @return mixed 252 | * @throws \GuzzleHttp\Exception\GuzzleException 253 | */ 254 | protected function confirmUpload($folder, $filename, $hash, $filesize) 255 | { 256 | return $this->request('/file/add', 'POST', [ 257 | 'home' => $folder . '/' . $filename, 258 | 'hash' => $hash, 259 | 'size' => $filesize, 260 | 'conflict' => 'rename' 261 | ]); 262 | } 263 | 264 | /** 265 | * @param $uri 266 | * @param $method 267 | * @param array $params 268 | * @param null $enctype 269 | * @param bool $defaultParams 270 | * 271 | * @return mixed 272 | * @throws \GuzzleHttp\Exception\GuzzleException 273 | */ 274 | protected function request($uri, $method, array $params, $enctype = null, $defaultParams = true) 275 | { 276 | $url = $this->formatUrl($uri); 277 | 278 | $default = $this->structureRequestParams(); 279 | $payload = ($defaultParams) ? array_merge($default, $params) : $params; 280 | 281 | if ($enctype === 'multipart') 282 | $params = $this->formatMultipartData($payload); 283 | else 284 | $params = (strtoupper($method) === 'GET') ? ['query' => $payload] : ['form_params' => $payload]; 285 | 286 | $res = $this->client->request($method, $url, $params); 287 | return json_decode($res->getBody()->getContents()); 288 | } 289 | 290 | 291 | protected function formatUrl($uri) 292 | { 293 | return (strstr($uri, '://')) ? $uri : self::CLOUD_DOMAIN . $uri; 294 | } 295 | 296 | 297 | protected function formatMultipartData($data) 298 | { 299 | $result = []; 300 | foreach ($data as $key => $datum) 301 | $result[] = [ 302 | 'name' => $key, 303 | 'contents' => $datum 304 | ]; 305 | return ['multipart' => $result]; 306 | } 307 | 308 | 309 | protected function structureRequestParams() 310 | { 311 | return [ 312 | 'home' => null, 313 | 'api' => self::VERSION_API, 314 | 'email' => $this->email, 315 | 'x-email' => $this->email, 316 | 'token' => $this->token, 317 | '_' => $this->tokenLifeTime, 318 | ]; 319 | } 320 | } -------------------------------------------------------------------------------- /src/Exceptions/BadRequest.php: -------------------------------------------------------------------------------- 1 |