├── .gitignore ├── README.md ├── composer.json ├── docker ├── .env.example ├── docker-compose.yml ├── nginx │ ├── Dockerfile │ └── default.conf └── php-fpm │ ├── Dockerfile │ └── local.ini ├── example.php ├── src ├── CloudAuthorizer.php ├── CloudFile.php ├── CloudFolder.php ├── CloudMailRu.php ├── CloudMailRuException.php ├── CloudMailRuInterface.php ├── FolderHelper.php └── HttpClient.php └── testfile.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # composer vendor dir 5 | /vendor 6 | 7 | # composer itself is not needed 8 | composer.phar 9 | composer.lock 10 | 11 | /docker/local/.env 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP библиотека для работы с облаком [cloud.mail.ru](http://cloud.mail.ru) 2 | 3 | ## Описание 4 | Реализована работа с некоторыми функциями облака [cloud.mail.ru](http://cloud.mail.ru). 5 | 6 | Для работы потребуются данные для входа в учетную запись на mail.ru. 7 | 8 | Перед использованием ознакомьтесь с [лицензионным соглашением по использованию Сервиса Облако@mail.ru](https://cloud.mail.ru/LA/) 9 | 10 | ## Методы 11 | * folderList - получение списка каталогов и файлов 12 | * folderAdd - добавление каталога в облако 13 | * fileUpload - загрузка файла 14 | * fileRemove - удаление файла 15 | * filePublish - публикация файла 16 | 17 | ## Использование 18 | ```php 19 | require('vendor/autoload.php'); 20 | 21 | use SergPopov\CloudMailRu\CloudMailRu; 22 | use SergPopov\CloudMailRu\CloudMailRuException; 23 | 24 | $username = 'username'; // учетная запись username 25 | $domain = 'mail.ru'; 26 | $password = 'password'; 27 | 28 | $pathLocalFile = __DIR__.'/testfile.txt'; 29 | $pathFileOnCloud = '/testdir/testfile.txt'; 30 | 31 | $cloud = new CloudMailRu($username, $domain, $password); 32 | try { 33 | $url = $cloud->login() 34 | ->fileRemove($pathLocalFile) 35 | ->fileUpload($pathLocalFile, $pathFileOnCloud) 36 | ->filePublish($pathFileOnCloud); 37 | var_dump($url); 38 | } catch (CloudMailRuException $e) { 39 | echo $e->getMessage(); 40 | } 41 | ``` 42 | 43 | [Пример использования example.php](example.php) 44 | 45 | ## Установка с [Composer](https://getcomposer.org/). 46 | ```bash 47 | composer require sergpopov/cloudmailruphp 48 | ``` 49 | 50 | ## Описание изменений 51 | 52 | ### 3.0.0 53 | Исправлено получение токена. 54 | Обновлена библиотека Guzzle. 55 | Обновлен docker контейнер. 56 | Протестировано на PHP 8.2. 57 | 58 | ### 2.0.0 59 | Библиотека полностью переписана. 60 | Требуется версия PHP 7.0 и выше 61 | 62 | ### 1.0.0 63 | Устаревшая версия. 64 | 65 | ## Licence 66 | GNU GPL v2.0 -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sergpopov/cloudmailruphp", 3 | "type": "library", 4 | "description": "Пакет для работы с облаком cloud.mail.ru", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Sergey Popov", 9 | "email": "popov_si@mail.ru" 10 | } 11 | ], 12 | "require": { 13 | "guzzlehttp/guzzle": "^7.2" 14 | }, 15 | "autoload": { 16 | "psr-4": { 17 | "SergPopov\\CloudMailRu\\": "src/" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docker/.env.example: -------------------------------------------------------------------------------- 1 | # В рамках одной host машины указанные ниже параметры не должны совпадать 2 | # При совпадении с аналогичными параметрами из других контейнеров укажите здесь другие 3 | 4 | # Порты, которые используются на host машине 5 | APP_WEB_PORT=44180 6 | PHP_FPM_PORT=44190 7 | 8 | #Номер внутренней сети (указываются первые 3 числа, номер узла не указывается) 9 | SUBNET_IP=190.144.0 -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | 5 | cloud-mail-ru-webserver: 6 | build: 7 | context: .. 8 | dockerfile: nginx/Dockerfile 9 | container_name: "cloud-mail-ru-webserver" 10 | depends_on: 11 | - cloud-mail-ru-app 12 | ports: 13 | - "${APP_WEB_PORT}:80" 14 | environment: 15 | PHP_FPM_PORT: ${PHP_FPM_PORT} 16 | volumes: 17 | - ../:/var/www 18 | - ./nginx/default.conf:/etc/nginx/templates/default.conf.template 19 | networks: 20 | - cloud-mail-ru-network 21 | 22 | cloud-mail-ru-app: 23 | build: 24 | context: .. 25 | dockerfile: php-fpm/Dockerfile 26 | container_name: "cloud-mail-ru-app" 27 | environment: 28 | XDEBUG_MODE: "debug" 29 | XDEBUG_CONFIG: "client_host=${SUBNET_IP}.1" 30 | PHP_IDE_CONFIG: "serverName=cloud-mail-ru-app" 31 | ports: 32 | - "${PHP_FPM_PORT}:9000" 33 | working_dir: /var/www 34 | volumes: 35 | - ../:/var/www 36 | - ./php-fpm/local.ini:/usr/local/etc/php/conf.d/local.ini 37 | networks: 38 | - cloud-mail-ru-network 39 | 40 | networks: 41 | cloud-mail-ru-network: 42 | driver: bridge 43 | ipam: 44 | driver: default 45 | config: 46 | - subnet: ${SUBNET_IP}.0/28 47 | -------------------------------------------------------------------------------- /docker/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.23 2 | 3 | # install Midnight Commander 4 | RUN apt-get update && apt-get install mc -y -------------------------------------------------------------------------------- /docker/nginx/default.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | 4 | index index.php; 5 | 6 | error_log /var/log/nginx/error.log; 7 | access_log /var/log/nginx/access.log; 8 | 9 | server_name localhost; 10 | 11 | client_max_body_size 100M; 12 | 13 | root /var/www; 14 | 15 | location ~ \.php$ { 16 | try_files $uri =404; 17 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 18 | fastcgi_pass 172.17.0.1:${PHP_FPM_PORT}; 19 | fastcgi_index index.php; 20 | include fastcgi_params; 21 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 22 | fastcgi_param PATH_INFO $fastcgi_path_info; 23 | } 24 | location / { 25 | try_files $uri $uri/ /index.php?$query_string; 26 | gzip_static on; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /docker/php-fpm/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.2-fpm 2 | 3 | # Install dependencies 4 | RUN apt-get update \ 5 | && apt-get -y install g++ git curl unzip libzip-dev libcurl3-dev\ 6 | && pecl install xdebug \ 7 | && docker-php-ext-enable xdebug 8 | 9 | # install composer 10 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer 11 | 12 | WORKDIR /var/www 13 | RUN usermod -u 1000 www-data && groupmod -g 1000 www-data -------------------------------------------------------------------------------- /docker/php-fpm/local.ini: -------------------------------------------------------------------------------- 1 | upload_max_filesize = 100M 2 | post_max_size = 100M 3 | max_execution_time = 600 4 | memory_limit = 800M 5 | #xdebug.profiler_enable = 1; 6 | error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | login()->folderList('/'); 16 | var_dump($list); 17 | } catch (CloudMailRuException $e) { 18 | echo $e->getMessage(); 19 | } 20 | 21 | $pathLocalFile = __DIR__.'/testfile.txt'; 22 | $pathFileOnCloud = '/testdir/testfile.txt'; 23 | try { 24 | $url = $cloud->login() 25 | ->fileRemove($pathFileOnCloud) 26 | ->fileUpload($pathLocalFile, $pathFileOnCloud) 27 | ->filePublish($pathFileOnCloud); 28 | var_dump($url); 29 | } catch (CloudMailRuException $e) { 30 | echo $e->getMessage(); 31 | } -------------------------------------------------------------------------------- /src/CloudAuthorizer.php: -------------------------------------------------------------------------------- 1 | user = $user; 28 | $this->pass = $password; 29 | $this->domain = $domain; 30 | $this->token = ''; 31 | $this->xPageId = ''; 32 | $this->build = ''; 33 | 34 | $this->httpClient = new HttpClient(); 35 | } 36 | 37 | /** 38 | * @return HttpClient 39 | */ 40 | public function getHttpClient(): HttpClient 41 | { 42 | return $this->httpClient; 43 | } 44 | 45 | /** 46 | * @return string 47 | */ 48 | public function getUser(): string 49 | { 50 | return $this->user; 51 | } 52 | 53 | /** 54 | * @return string 55 | */ 56 | public function getPass(): string 57 | { 58 | return $this->pass; 59 | } 60 | 61 | /** 62 | * @return string 63 | */ 64 | public function getDomain(): string 65 | { 66 | return $this->domain; 67 | } 68 | 69 | /** 70 | * @return string 71 | */ 72 | public function getEmail(): string 73 | { 74 | return $this->user . '@' . $this->domain; 75 | } 76 | 77 | /** 78 | * @return string 79 | */ 80 | public function getBuild(): string 81 | { 82 | return $this->build; 83 | } 84 | 85 | /** 86 | * @return string 87 | */ 88 | public function getXPageId(): string 89 | { 90 | return $this->xPageId; 91 | } 92 | 93 | /** 94 | * @return string 95 | */ 96 | public function getToken(): string 97 | { 98 | return $this->token; 99 | } 100 | 101 | /** 102 | * @throws CloudMailRuException 103 | */ 104 | public function login(): void 105 | { 106 | $this->loginStepOne(); 107 | $this->loginStepTwo(); 108 | $this->checkLogin(); 109 | } 110 | 111 | /** 112 | * @throws CloudMailRuException 113 | */ 114 | private function loginStepOne(): void 115 | { 116 | $url = 'https://auth.mail.ru/cgi-bin/auth?from=splash'; 117 | $params = [ 118 | 'Password' => $this->pass, 119 | 'new_auth_form' => '1', 120 | 'Login' => $this->user, 121 | 'FailPage' => '', 122 | 'Domain' => $this->domain, 123 | ]; 124 | $this->httpClient->requestPost($url, $params); 125 | } 126 | 127 | /** 128 | * @throws CloudMailRuException 129 | */ 130 | private function loginStepTwo(): void 131 | { 132 | $url = 'https://cloud.mail.ru/home'; 133 | $response = $this->httpClient->requestGet($url); 134 | $str = $response->getBody()->getContents(); 135 | $this->token = self::getTokenFromText($str); 136 | $this->xPageId = self::getXPageIdFromText($str); 137 | $this->build = self::getBuildFromText($str); 138 | } 139 | 140 | /** 141 | * @throws CloudMailRuException 142 | */ 143 | private function checkLogin(): void 144 | { 145 | if ($this->token == '' || $this->xPageId == '' || $this->build == '') { 146 | throw new CloudMailRuException('Authorization data is not received'); 147 | } 148 | } 149 | 150 | /** 151 | * @param string $str 152 | * @param string $find 153 | * @return string 154 | */ 155 | private static function getValue(string $str, string $find): string 156 | { 157 | $pattern = '/"' . $find . '":"(?[\w\-\.]*)"/mu'; 158 | $matches = []; 159 | try { 160 | $result = preg_match($pattern, $str, $matches); 161 | } catch (Exception $e) { 162 | return ''; 163 | } 164 | 165 | if ($result === false) { 166 | return ''; 167 | } 168 | 169 | if (isset($matches['value']) === false) { 170 | return ''; 171 | } 172 | 173 | return $matches['value']; 174 | } 175 | 176 | /** 177 | * @param string $str 178 | * @return string 179 | */ 180 | private static function getXPageIdFromText(string $str): string 181 | { 182 | return self::getValue($str, 'x-page-id'); 183 | } 184 | 185 | /** 186 | * @param string $str 187 | * @return string 188 | */ 189 | private static function getBuildFromText(string $str): string 190 | { 191 | return self::getValue($str, 'BUILD'); 192 | } 193 | 194 | /** 195 | * @param string $str 196 | * @return string 197 | */ 198 | private static function getTokenFromText(string $str): string 199 | { 200 | return self::getValue($str, 'csrf'); 201 | } 202 | } -------------------------------------------------------------------------------- /src/CloudFile.php: -------------------------------------------------------------------------------- 1 | authorizer = $authorizer; 20 | } 21 | 22 | /** 23 | * @param string $pathLocalFile 24 | * @param string $pathFileOnCloud 25 | * @throws CloudMailRuException 26 | */ 27 | public function fileUpload(string $pathLocalFile, string $pathFileOnCloud) 28 | { 29 | $size = filesize($pathLocalFile); 30 | if ($size === false) { 31 | throw new CloudMailRuException('File not found'); 32 | } 33 | 34 | $uploadUrl = $this->getUploadUrl(); 35 | $hash = $this->putFile($uploadUrl, $pathLocalFile); 36 | 37 | $this->addFile($hash, $size, $pathFileOnCloud); 38 | } 39 | 40 | /** 41 | * @param string $hash 42 | * @param int $size 43 | * @param string $pathOnCloud 44 | * @throws CloudMailRuException 45 | */ 46 | private function addFile(string $hash, int $size, string $pathOnCloud) 47 | { 48 | $url = 'https://cloud.mail.ru/api/v2/file/add'; 49 | 50 | $postParams = [ 51 | 'api' => '2', 52 | 'conflict' => 'strict', 53 | 'home' => $pathOnCloud, 54 | 'hash' => $hash, 55 | 'size' => $size, 56 | 'build' => $this->authorizer->getBuild(), 57 | 'x-page-id' => $this->authorizer->getXPageId(), 58 | 'email' => $this->authorizer->getEmail(), 59 | 'x-email' => $this->authorizer->getEmail(), 60 | '_' => time() . '810', 61 | ]; 62 | 63 | $headers = [ 64 | 'X-CSRF-Token' => $this->authorizer->getToken(), 65 | ]; 66 | 67 | try { 68 | $this->authorizer->getHttpClient()->requestPost($url, $postParams, $headers); 69 | } catch (CloudMailRuException $e) { 70 | $error = $e->getMessage(); 71 | if (strpos($error, '"exists"') === false) { 72 | throw new CloudMailRuException($error); 73 | } 74 | } 75 | } 76 | 77 | /** 78 | * @param string $uploadUrl URL of node for file upload. Must be get before uploading the file 79 | * @param string $pathLocalFile 80 | * @return string HASH of uploaded file 81 | * @throws CloudMailRuException 82 | */ 83 | private function putFile(string $uploadUrl, string $pathLocalFile) 84 | { 85 | $url = $uploadUrl . '?cloud_domain=2&x-email=' . $this->authorizer->getEmail(); 86 | 87 | $body = fopen($pathLocalFile, 'r'); 88 | 89 | if ($body === false) { 90 | throw new CloudMailRuException('File not found'); 91 | } 92 | 93 | $response = $this->authorizer->getHttpClient()->requestPut($url, $body); 94 | 95 | if ($response->getStatusCode() !== 201) { 96 | throw new CloudMailRuException('Error uploading file'); 97 | } 98 | 99 | return $response->getBody()->getContents(); 100 | } 101 | 102 | /** 103 | * @return string URL of node for file upload 104 | * @throws CloudMailRuException 105 | */ 106 | private function getUploadUrl() 107 | { 108 | $url = 'https://cloud.mail.ru/api/v2/dispatcher/'; 109 | 110 | $postParams = [ 111 | 'api' => '2', 112 | 'build' => $this->authorizer->getBuild(), 113 | 'x-page-id' => $this->authorizer->getXPageId(), 114 | 'email' => $this->authorizer->getEmail(), 115 | 'x-email' => $this->authorizer->getEmail(), 116 | '_' => time() . '810', 117 | ]; 118 | 119 | $headers = [ 120 | 'X-CSRF-Token' => $this->authorizer->getToken(), 121 | ]; 122 | 123 | $response = $this->authorizer->getHttpClient()->requestPost($url, $postParams, $headers); 124 | 125 | try { 126 | $data = json_decode($this->authorizer->getHttpClient()->checkResponse($response)); 127 | } catch (\Exception $e) { 128 | throw new CloudMailRuException('Json decode upload url error'); 129 | } 130 | 131 | $uploadUrl = $data->body->upload[0]->url ?? ''; 132 | 133 | if ($uploadUrl === '') { 134 | throw new CloudMailRuException('Get upload url error'); 135 | } 136 | 137 | return $uploadUrl; 138 | } 139 | 140 | /** 141 | * @param string $pathOnCloud 142 | * @return string 143 | * @throws CloudMailRuException 144 | */ 145 | public function filePublish(string $pathOnCloud) 146 | { 147 | $url = 'https://cloud.mail.ru/api/v2/file/publish'; 148 | 149 | $postParams = [ 150 | 'api' => '2', 151 | 'conflict' => '', 152 | 'home' => $pathOnCloud, 153 | 'build' => $this->authorizer->getBuild(), 154 | 'x-page-id' => $this->authorizer->getXPageId(), 155 | 'email' => $this->authorizer->getEmail(), 156 | 'x-email' => $this->authorizer->getEmail(), 157 | '_' => time() . '810', 158 | ]; 159 | 160 | $headers = [ 161 | 'X-CSRF-Token' => $this->authorizer->getToken(), 162 | ]; 163 | 164 | try { 165 | $response = $this->authorizer->getHttpClient()->requestPost($url, $postParams, $headers); 166 | return 'https://cloud.mail.ru/public/' . $this->getBodyFromResponse($response->getBody()->getContents()); 167 | } catch (CloudMailRuException $e) { 168 | throw new CloudMailRuException($e->getMessage()); 169 | } 170 | } 171 | 172 | /** 173 | * @param string $response 174 | * @return string 175 | * @throws CloudMailRuException 176 | */ 177 | private function getBodyFromResponse(string $response) 178 | { 179 | $jsonObj = json_decode($response); 180 | $body = $jsonObj->body ?? ''; 181 | if ($body !== '') { 182 | return $body; 183 | } else { 184 | throw new CloudMailRuException('Error parsing body'); 185 | } 186 | } 187 | 188 | /** 189 | * @param string $pathOnCloud 190 | * @throws CloudMailRuException 191 | */ 192 | public function fileRemove(string $pathOnCloud) 193 | { 194 | $url = 'https://cloud.mail.ru/api/v2/file/remove'; 195 | 196 | $postParams = [ 197 | 'api' => '2', 198 | 'conflict' => '', 199 | 'home' => $pathOnCloud, 200 | 'build' => $this->authorizer->getBuild(), 201 | 'x-page-id' => $this->authorizer->getXPageId(), 202 | 'email' => $this->authorizer->getEmail(), 203 | 'x-email' => $this->authorizer->getEmail(), 204 | '_' => time() . '810', 205 | ]; 206 | 207 | $headers = [ 208 | 'X-CSRF-Token' => $this->authorizer->getToken(), 209 | ]; 210 | 211 | try { 212 | $this->authorizer->getHttpClient()->requestPost($url, $postParams, $headers); 213 | } catch (CloudMailRuException $e) { 214 | throw new CloudMailRuException($e->getMessage()); 215 | } 216 | } 217 | } -------------------------------------------------------------------------------- /src/CloudFolder.php: -------------------------------------------------------------------------------- 1 | authorizer = $authorizer; 20 | } 21 | 22 | /** 23 | * @param string $pathFolderOnCloud 24 | * @return string 25 | * @throws CloudMailRuException 26 | */ 27 | public function folderList(string $pathFolderOnCloud): string 28 | { 29 | $url = 'https://cloud.mail.ru/api/v2/folder?home=%2F' 30 | . '&sort={%22type%22%3A%22name%22%2C%22order%22%3A%22asc%22}' 31 | . '&offset=0' 32 | . '&limit=500' 33 | . '&home=' . $pathFolderOnCloud 34 | . '&api=2' 35 | . '&build=' . $this->authorizer->getBuild() 36 | . '&x-page-id=' . $this->authorizer->getXPageId() 37 | . '&email=' . $this->authorizer->getEmail() 38 | . '&x-email=' . $this->authorizer->getEmail() 39 | . '&_=' . time() . '810'; 40 | 41 | $headers = [ 42 | 'X-CSRF-Token' => $this->authorizer->getToken(), 43 | ]; 44 | 45 | $response = $this->authorizer->getHttpClient()->requestGet($url, $headers); 46 | return $this->authorizer->getHttpClient()->checkResponse($response); 47 | } 48 | 49 | /** 50 | * @param $pathFolderOnCloud 51 | * @throws CloudMailRuException 52 | */ 53 | public function folderAdd($pathFolderOnCloud): void 54 | { 55 | $url = 'https://cloud.mail.ru/api/v2/folder/add'; 56 | 57 | $postParams = [ 58 | 'api' => '2', 59 | 'conflict' => '', 60 | 'home' => $pathFolderOnCloud, 61 | 'build' => $this->authorizer->getBuild(), 62 | 'x-page-id' => $this->authorizer->getXPageId(), 63 | 'email' => $this->authorizer->getEmail(), 64 | 'x-email' => $this->authorizer->getEmail(), 65 | '_' => time() . '810', 66 | ]; 67 | 68 | $headers = [ 69 | 'X-CSRF-Token' => $this->authorizer->getToken(), 70 | ]; 71 | 72 | try { 73 | $this->authorizer->getHttpClient()->requestPost($url, $postParams, $headers); 74 | } catch (CloudMailRuException $e) { 75 | $error = $e->getMessage(); 76 | if (!str_contains($error, '"exists"')) { 77 | throw new CloudMailRuException($error); 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /src/CloudMailRu.php: -------------------------------------------------------------------------------- 1 | authorizer = new CloudAuthorizer($user, $domain, $password); 26 | $this->folder = new CloudFolder($this->authorizer); 27 | $this->file = new CloudFile($this->authorizer); 28 | } 29 | 30 | /** 31 | * Authorization in the cloud. 32 | * This method must be performed at the beginning of working with the cloud. 33 | * @return CloudMailRu 34 | * @throws CloudMailRuException 35 | */ 36 | public function login(): static 37 | { 38 | $this->authorizer->login(); 39 | return $this; 40 | } 41 | 42 | /** 43 | * Getting a list of directories and files in a specified directory. 44 | * @param string $pathOnCloud 45 | * @return array An array describing the contents of the directory. 46 | * [ 47 | * 'folders' => [ 48 | * 'folder1', 49 | * 'folder2', 50 | * ], 51 | * 'files' => [ 52 | * 'file1.txt', 53 | * 'file2.jpg', 54 | * ], 55 | * ]; 56 | * @throws CloudMailRuException 57 | */ 58 | public function folderList(string $pathOnCloud): array 59 | { 60 | $responseStr = $this->folder->folderList($pathOnCloud); 61 | return FolderHelper::parseFolderList($responseStr); 62 | } 63 | 64 | /** 65 | * Adding a directory to the cloud. 66 | * If nonexistent directories are present in the path, they will be created. 67 | * @param string $pathFolderOnCloud Full path of the created directory in the cloud. 68 | * '/' - root directory. 69 | * @return CloudMailRu 70 | * @throws CloudMailRuException 71 | */ 72 | public function folderAdd(string $pathFolderOnCloud): static 73 | { 74 | $this->folder->folderAdd($pathFolderOnCloud); 75 | return $this; 76 | } 77 | 78 | /** 79 | * Uploading a file to the cloud. 80 | * If nonexistent directories are present in the path, they will be created. 81 | * If a file with the same name already exists in the cloud, 82 | * then the new file will NOT be replaced, 83 | * and an exception will NOT be thrown. 84 | * @param string $pathLocalFile Path in the filesystem to the downloaded file. 85 | * @param string $pathFileOnCloud Full path to the file in the cloud. 86 | * '/' - root directory. 87 | * @return CloudMailRu 88 | * @throws CloudMailRuException 89 | */ 90 | public function fileUpload(string $pathLocalFile, string $pathFileOnCloud): static 91 | { 92 | $this->file->fileUpload($pathLocalFile, $pathFileOnCloud); 93 | return $this; 94 | } 95 | 96 | /** 97 | * Deleting a file from the cloud. 98 | * @param string $pathOnCloud Full path to the file in the cloud. 99 | * '/' - root directory. 100 | * @return CloudMailRu 101 | * @throws CloudMailRuException 102 | */ 103 | public function fileRemove(string $pathOnCloud): static 104 | { 105 | $this->file->fileRemove($pathOnCloud); 106 | return $this; 107 | } 108 | 109 | 110 | /** 111 | * Obtaining a public link for downloading a file by any unauthorized user. 112 | * Example URL: https://cloud.mail.ru/public/5gww/3RUS5aTTT 113 | * @param string $pathOnCloud Full path to the file in the cloud. 114 | * '/' - root directory. 115 | * @return string 116 | * @throws CloudMailRuException 117 | */ 118 | public function filePublish(string $pathOnCloud): string 119 | { 120 | return $this->file->filePublish($pathOnCloud); 121 | } 122 | } -------------------------------------------------------------------------------- /src/CloudMailRuException.php: -------------------------------------------------------------------------------- 1 | [ 21 | * 'folder1', 22 | * 'folder2', 23 | * ], 24 | * 'files' => [ 25 | * 'file1.txt', 26 | * 'file2.jpg', 27 | * ], 28 | * ]; 29 | * @throws CloudMailRuException 30 | */ 31 | public function folderList(string $pathOnCloud): array; 32 | 33 | /** 34 | * Adding a directory to the cloud. 35 | * If nonexistent directories are present in the path, they will be created. 36 | * @param string $pathFolderOnCloud Full path of the created directory in the cloud. 37 | * '/' - root directory. 38 | * @return CloudMailRu 39 | * @throws CloudMailRuException 40 | */ 41 | public function folderAdd(string $pathFolderOnCloud): CloudMailRu; 42 | 43 | /** 44 | * Uploading a file to the cloud. 45 | * If nonexistent directories are present in the path, they will be created. 46 | * If a file with the same name already exists in the cloud, 47 | * then the new file will NOT be replaced, 48 | * and an exception will NOT be thrown. 49 | * @param string $pathLocalFile Path in the filesystem to the downloaded file. 50 | * @param string $pathFileOnCloud Full path to the file in the cloud. 51 | * '/' - root directory. 52 | * @return CloudMailRu 53 | * @throws CloudMailRuException 54 | */ 55 | public function fileUpload(string $pathLocalFile, string $pathFileOnCloud): CloudMailRu; 56 | 57 | /** 58 | * Deleting a file from the cloud. 59 | * @param string $pathOnCloud Full path to the file in the cloud. 60 | * '/' - root directory. 61 | * @return CloudMailRu 62 | * @throws CloudMailRuException 63 | */ 64 | public function fileRemove(string $pathOnCloud): CloudMailRu; 65 | 66 | /** 67 | * Obtaining a public link for downloading a file by any unauthorized user. 68 | * Example URL: https://cloud.mail.ru/public/5gww/3RUS5aTTT 69 | * @param string $pathOnCloud Full path to the file in the cloud. 70 | * '/' - root directory. 71 | * @return string 72 | * @throws CloudMailRuException 73 | */ 74 | public function filePublish(string $pathOnCloud): string; 75 | } -------------------------------------------------------------------------------- /src/FolderHelper.php: -------------------------------------------------------------------------------- 1 | [ 12 | * 'folder1', 13 | * 'folder2', 14 | * ], 15 | * 'files' => [ 16 | * 'file1.txt', 17 | * 'file2.jpg', 18 | * ], 19 | * ]; 20 | * @throws CloudMailRuException 21 | */ 22 | public static function parseFolderList(string $str): array 23 | { 24 | $list = json_decode($str)->body->list; 25 | 26 | if (!is_array($list)) { 27 | throw new CloudMailRuException('Error parsing data of folder list'); 28 | } 29 | 30 | $folders = []; 31 | $files = []; 32 | foreach ($list as $item) { 33 | 34 | if ($item->type == null || $item->name == null) { 35 | throw new CloudMailRuException('Error parsing data of folder list - unknown data'); 36 | } 37 | 38 | switch ($item->type) { 39 | case 'folder' : 40 | $folders[] = $item->name; 41 | break; 42 | case 'file' : 43 | $files[] = $item->name; 44 | break; 45 | } 46 | } 47 | 48 | return [ 49 | 'folders' => $folders, 50 | 'files' => $files, 51 | ]; 52 | } 53 | } -------------------------------------------------------------------------------- /src/HttpClient.php: -------------------------------------------------------------------------------- 1 | client = new Client(); 21 | $this->cookie = new CookieJar(); 22 | } 23 | 24 | /** 25 | * @param string $url 26 | * @param array $postParams 27 | * @param array $headers 28 | * @return ResponseInterface 29 | * @throws CloudMailRuException 30 | */ 31 | public function requestPost(string $url, array $postParams, array $headers = []): ResponseInterface 32 | { 33 | try { 34 | return $this->client->request('POST', $url, [ 35 | 'form_params' => $postParams, 36 | 'cookies' => $this->cookie, 37 | 'verify' => false, 38 | 'headers' => $headers, 39 | ]); 40 | } catch (GuzzleException $e) { 41 | throw new CloudMailRuException($e->getMessage()); 42 | } 43 | } 44 | 45 | /** 46 | * @param string $url 47 | * @param mixed $body 48 | * @param array $headers 49 | * @return ResponseInterface 50 | * @throws CloudMailRuException 51 | */ 52 | public function requestPut(string $url, $body, array $headers = []): ResponseInterface 53 | { 54 | try { 55 | return $this->client->request('PUT', $url, [ 56 | 'body' => $body, 57 | 'cookies' => $this->cookie, 58 | 'verify' => false, 59 | 'headers' => $headers, 60 | ]); 61 | } catch (GuzzleException $e) { 62 | throw new CloudMailRuException($e->getMessage()); 63 | } 64 | } 65 | 66 | /** 67 | * @param string $url 68 | * @param array $headers 69 | * @return ResponseInterface 70 | * @throws CloudMailRuException 71 | */ 72 | public function requestGet(string $url, array $headers = []): ResponseInterface 73 | { 74 | try { 75 | return $this->client->request('GET', $url, [ 76 | 'cookies' => $this->cookie, 77 | 'verify' => false, 78 | 'headers' => $headers, 79 | ]); 80 | } catch (GuzzleException $e) { 81 | throw new CloudMailRuException($e->getMessage()); 82 | } 83 | } 84 | 85 | /** 86 | * @param ResponseInterface $response 87 | * @return string 88 | * @throws CloudMailRuException 89 | */ 90 | public function checkResponse(ResponseInterface $response): string 91 | { 92 | if ($response->getStatusCode() == 200) { 93 | return $response->getBody()->getContents(); 94 | } else { 95 | throw new CloudMailRuException('Bad response ' . $response->getStatusCode()); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /testfile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SerjPopov/cloud-mail-ru-php/1d8da2a1115f58abd7b0b695a4667d17c09a5bd3/testfile.txt --------------------------------------------------------------------------------