├── .gitignore ├── README.md ├── composer.json ├── example.php └── src ├── SCurl.php ├── SelectelContainer.php ├── SelectelStorage.php └── SelectelStorageException.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /vendor/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | selectel-storage-php-class 2 | ========================== 3 | 4 | composer.json 5 | 6 | ```js 7 | 8 | "require": { 9 | "easmith/selectel-storage": "~1.0", 10 | } 11 | 12 | ``` 13 | 14 | ```php 15 | 16 | createContainer('selectel', array("X-Container-Meta-Type: public")); 26 | // get container info 27 | $container->getInfo() 28 | ``` 29 | 30 | ### Containers list 31 | ```php 32 | $containerList = $selectelStorage->listContainers(); 33 | ``` 34 | 35 | ### Create directory 36 | ```php 37 | $container->createDirectory('php/test') 38 | ``` 39 | 40 | ### List 41 | ```php 42 | $dirList = $container->listFiles($limit = 10000, $marker = null, $prefix = null, $path = ""); 43 | // files 44 | $fileList = $container->listFiles($limit = 10000, $marker = null, $prefix = null, $path = 'php/'); 45 | ``` 46 | 47 | ### Put File 48 | ```php 49 | $res = $container->putFile(__FILE__, 'example.php',["Content-Type: text/html"]); 50 | ``` 51 | 52 | ### File info 53 | ```php 54 | $fileInfo = $container->getFileInfo('example.php'); 55 | ``` 56 | 57 | ### Get file 58 | ```php 59 | $file = $container->getFile($fileList[0]); 60 | ``` 61 | 62 | ### Copy file 63 | ```php 64 | $copyRes = $container->copy('example.php', 'php/test/Examples_copy.php5'); 65 | ``` 66 | 67 | ### Delete 68 | ```php 69 | $deleteRes = $container->delete('example.php'); 70 | ``` -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easmith/selectel-storage", 3 | "description": "Selectel Storage API php wrapper", 4 | "minimum-stability": "stable", 5 | "license": "LGPL-3.0+", 6 | "authors": [ 7 | { 8 | "name": "Eugene Smith", 9 | "role": "Developer" 10 | } 11 | ], 12 | "support": { 13 | "issues": "https://github.com/easmith/selectel-storage-php-class/issues", 14 | "source": "https://github.com/easmith/selectel-storage-php-class" 15 | }, 16 | "require": { 17 | "php": ">=5.4" 18 | }, 19 | "version": "1.0.3", 20 | "autoload": { 21 | "psr-4": { 22 | "easmith\\selectel\\storage\\": "src" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | createContainer('selectel', array("X-Container-Meta-Type: public")); 10 | // print_r($container->getInfo()); 11 | 12 | echo "Containers list\n"; 13 | $containerList = $selectelStorage->listContainers(); 14 | // print_r($containerList); 15 | 16 | echo "\n\nContainer Info:\n"; 17 | $cInfo = $selectelStorage->getContainer($containerList[0])->getInfo(); 18 | // print_r($cInfo); 19 | 20 | echo "\n\nCreate directory:\n"; 21 | $container = $selectelStorage->getContainer($containerList[0]); 22 | $container->createDirectory('php/test'); 23 | 24 | echo "\n\nDirectories:\n"; 25 | $dirList = $container->listFiles($limit = 10000, $marker = null, $prefix = null, $path = ""); 26 | // print_r($dirList); 27 | 28 | echo "\n\nPutting File:\n"; 29 | $res = $container->putFile(__FILE__, 'example.php'); 30 | print_r($res); 31 | 32 | echo "\n\nFiles in directory:\n"; 33 | $fileList = $container->listFiles($limit = 10000, $marker = null, $prefix = null, $path = 'php/'); 34 | print_r($fileList); 35 | 36 | echo "\n\nFile info:\n"; 37 | $fileInfo = $container->getFileInfo('example.php'); 38 | print_r($fileInfo); 39 | 40 | echo "\n\nGetting file (base64):\n"; 41 | $file = $container->getFile($fileInfo['name']); 42 | print_r($file); 43 | 44 | echo "\n\nCopy: \n"; 45 | $copyRes = $container->copy('example.php', 'php/test/Examples_copy.php5'); 46 | print_r($copyRes); 47 | 48 | echo "\n\nDelete: \n"; 49 | $deleteRes = $container->delete('example.php'); 50 | print_r($deleteRes); 51 | $deleteRes = $container->delete('php/test/Examples_copy.php5'); 52 | print_r($deleteRes); 53 | 54 | echo "\n\nAccountMetaTempURL: \n"; 55 | $MetaTempURLKeyRes = $container->setAccountMetaTempURLKey("test"); 56 | print_r($MetaTempURLKeyRes); 57 | echo "\n\n"; 58 | 59 | } catch (Exception $e) { 60 | print_r($e->getTrace()); 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/SCurl.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class SCurl 15 | { 16 | 17 | private static $instance = null; 18 | 19 | /** 20 | * Curl resource 21 | * 22 | * @var null|resource 23 | */ 24 | private $ch; 25 | 26 | /** 27 | * Current URL 28 | * 29 | * @var string 30 | */ 31 | private $url; 32 | 33 | /** 34 | * Last request result 35 | * 36 | * @var array 37 | */ 38 | private $result = array(); 39 | 40 | /** 41 | * Request params 42 | * 43 | * @var array 44 | */ 45 | private $params = array(); 46 | 47 | /** 48 | * Curl wrapper 49 | * 50 | * @param string $url 51 | */ 52 | private function __construct($url) 53 | { 54 | $this->setUrl($url); 55 | $this->curlInit(); 56 | } 57 | 58 | private function curlInit() 59 | { 60 | $this->ch = curl_init($this->url); 61 | curl_setopt($this->ch, CURLOPT_ENCODING, 'gzip,deflate'); 62 | curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, false); 63 | curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); 64 | curl_setopt($this->ch, CURLOPT_HEADER, true); 65 | curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); 66 | curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 2); 67 | // Проверяем существование константы перед использованием для совместимости c php 8.4 68 | if (defined('CURLOPT_BINARYTRANSFER')) { 69 | curl_setopt($this->ch, CURLOPT_BINARYTRANSFER, true); 70 | } 71 | // TODO: big files 72 | // curl_setopt($this->ch, CURLOPT_RANGE, "0-100"); 73 | } 74 | 75 | /** 76 | * 77 | * @param string $url 78 | * 79 | * @return SCurl 80 | */ 81 | public static function init($url) 82 | { 83 | if (self::$instance == null) { 84 | self::$instance = new SCurl($url); 85 | } 86 | return self::$instance->setUrl($url); 87 | } 88 | 89 | /** 90 | * Set url for request 91 | * 92 | * @param string $url URL 93 | * 94 | * @return SCurl|null 95 | */ 96 | public function setUrl($url) 97 | { 98 | $this->url = $url; 99 | return self::$instance; 100 | } 101 | 102 | /** 103 | * @param $file 104 | * @return mixed 105 | * @throws SelectelStorageException 106 | */ 107 | public function putFile($file) 108 | { 109 | if (!file_exists($file)) { 110 | throw new SelectelStorageException("File '{$file}' does not exist"); 111 | } 112 | $fp = fopen($file, "r"); 113 | curl_setopt($this->ch, CURLOPT_INFILE, $fp); 114 | curl_setopt($this->ch, CURLOPT_INFILESIZE, filesize($file)); 115 | $this->request('PUT'); 116 | fclose($fp); 117 | return self::$instance; 118 | } 119 | 120 | /** 121 | * Set method and request 122 | * 123 | * @param string $method 124 | * 125 | * @return SCurl 126 | */ 127 | public function request($method) 128 | { 129 | $this->method($method); 130 | $this->params = array(); 131 | curl_setopt($this->ch, CURLOPT_URL, $this->url); 132 | 133 | $response = explode("\r\n\r\n", curl_exec($this->ch)); 134 | 135 | $this->result['info'] = curl_getinfo($this->ch); 136 | $this->result['header'] = $this->parseHead($response[0]); 137 | unset($response[0]); 138 | $this->result['content'] = join("\r\n\r\n", $response); 139 | 140 | // reinit 141 | $this->curlInit(); 142 | 143 | return self::$instance; 144 | } 145 | 146 | /** 147 | * Set request method 148 | * 149 | * @param string $method 150 | * 151 | * @return SCurl 152 | */ 153 | private function method($method) 154 | { 155 | switch ($method) { 156 | case "GET" : { 157 | $this->url .= "?" . http_build_query($this->params); 158 | curl_setopt($this->ch, CURLOPT_HTTPGET, true); 159 | break; 160 | } 161 | case "HEAD" : { 162 | $this->url .= "?" . http_build_query($this->params); 163 | curl_setopt($this->ch, CURLOPT_NOBODY, true); 164 | break; 165 | } 166 | case "POST" : { 167 | curl_setopt($this->ch, CURLOPT_POST, true); 168 | curl_setopt($this->ch, CURLOPT_POSTFIELDS, http_build_query($this->params)); 169 | break; 170 | } 171 | case "PUT" : { 172 | curl_setopt($this->ch, CURLOPT_PUT, true); 173 | break; 174 | } 175 | default : { 176 | curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $method); 177 | break; 178 | } 179 | } 180 | return self::$instance; 181 | } 182 | 183 | /** 184 | * Header Parser 185 | * 186 | * @param array $head 187 | * 188 | * @return array 189 | */ 190 | private function parseHead($head) 191 | { 192 | $result = array(); 193 | $code = explode("\r\n", $head); 194 | preg_match('/HTTP\/(.+) (\d+)/', $code[0], $codeMatches); 195 | 196 | $result['HTTP-Version'] = $codeMatches[1]; 197 | $result['HTTP-Code'] = (int)$codeMatches[2]; 198 | preg_match_all("/([A-z\-]+)\: (.*)\r\n/", $head, $matches, PREG_SET_ORDER); 199 | 200 | foreach ($matches as $match) { 201 | $result[strtolower($match[1])] = $match[2]; 202 | } 203 | 204 | return $result; 205 | } 206 | 207 | public function putFileContents($contents) 208 | { 209 | $fp = fopen("php://temp", "rb+"); 210 | fputs($fp, $contents); 211 | rewind($fp); 212 | curl_setopt($this->ch, CURLOPT_INFILE, $fp); 213 | curl_setopt($this->ch, CURLOPT_INFILESIZE, strlen($contents)); 214 | $this->request('PUT'); 215 | fclose($fp); 216 | return self::$instance; 217 | } 218 | 219 | /** 220 | * Set headers 221 | * 222 | * @param array $headers 223 | * 224 | * @return SCurl 225 | */ 226 | public function setHeaders($headers) 227 | { 228 | $headers = array_merge(array("Expect:"), $headers); 229 | curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers); 230 | return self::$instance; 231 | } 232 | 233 | /** 234 | * Set request parameters 235 | * 236 | * @param array $params 237 | * 238 | * @return SCurl 239 | */ 240 | public function setParams($params) 241 | { 242 | $this->params = $params; 243 | return self::$instance; 244 | } 245 | 246 | /** 247 | * Getting info, headers and content of last response 248 | * 249 | * @return array 250 | */ 251 | public function getResult() 252 | { 253 | return $this->result; 254 | } 255 | 256 | /** 257 | * Getting headers of last response 258 | * 259 | * @param string $header Header 260 | * 261 | * @return array 262 | */ 263 | public function getHeaders($header = null) 264 | { 265 | if (!is_null($header)) 266 | $this->result['header'][$header]; 267 | return $this->result['header']; 268 | } 269 | 270 | /** 271 | * Getting content of last response 272 | * 273 | * @return array 274 | */ 275 | public function getContent() 276 | { 277 | return $this->result['content']; 278 | } 279 | 280 | /** 281 | * Getting info of last response 282 | * 283 | * @param string $info Info's field 284 | * 285 | * @return array 286 | */ 287 | public function getInfo($info = null) 288 | { 289 | if (!is_null($info)) { 290 | $this->result['info'][$info]; 291 | } 292 | return $this->result['info']; 293 | } 294 | 295 | private function __clone() 296 | { 297 | 298 | } 299 | 300 | } 301 | -------------------------------------------------------------------------------- /src/SelectelContainer.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class SelectelContainer extends SelectelStorage 13 | { 14 | 15 | /** 16 | * 'x-' Headers of container 17 | * 18 | * @var array 19 | */ 20 | private $info; 21 | 22 | public function __construct($url, $token = array(), $format = null, $info = array()) 23 | { 24 | $this->url = $url . "/"; 25 | $this->token = $token; 26 | $this->format = (!in_array($format, $this->formats, true) ? $this->format : $format); 27 | $this->info = (count($info) === 0 ? $this->getInfo(true) : $info); 28 | } 29 | 30 | /** 31 | * Getting container info 32 | * 33 | * @param boolean $refresh Refresh? Default false 34 | * 35 | * @return array 36 | */ 37 | public function getInfo($refresh = false) 38 | { 39 | if (!$refresh) { 40 | return $this->info; 41 | } 42 | 43 | $headers = SCurl::init($this->url) 44 | ->setHeaders($this->token) 45 | ->request("HEAD") 46 | ->getHeaders(); 47 | 48 | if (!in_array($headers["HTTP-Code"], array(204))) { 49 | return $this->error($headers["HTTP-Code"], __METHOD__); 50 | } 51 | 52 | return $this->info = $this->getX($headers); 53 | } 54 | 55 | /** 56 | * Getting file with info and headers 57 | * 58 | * Supported headers: 59 | * If-Match 60 | * If-None-Match 61 | * If-Modified-Since 62 | * If-Unmodified-Since 63 | * 64 | * @param string $name 65 | * @param array $headers 66 | * 67 | * @return array 68 | */ 69 | public function getFile($name, $headers = array()) 70 | { 71 | $headers = array_merge($headers, $this->token); 72 | $res = SCurl::init($this->url . $name) 73 | ->setHeaders($headers) 74 | ->request("GET") 75 | ->getResult(); 76 | return $res; 77 | } 78 | 79 | /** 80 | * Getting file info 81 | * 82 | * @param string $name File name 83 | * 84 | * @return array 85 | */ 86 | public function getFileInfo($name) 87 | { 88 | $res = $this->listFiles(1, '', $name, null, null, 'json'); 89 | $info = current(json_decode($res, true)); 90 | return $this->format == 'json' ? json_encode($info) : $info; 91 | } 92 | 93 | /** 94 | * Getting file list 95 | * 96 | * @param int $limit Limit 97 | * @param string $marker Marker 98 | * @param string $prefix Prefix 99 | * @param string $path Path 100 | * @param string $delimiter Delimiter 101 | * @param string $format Format 102 | * 103 | * @return array|string 104 | */ 105 | public function listFiles($limit = 10000, $marker = null, $prefix = null, $path = null, $delimiter = null, $format = null) 106 | { 107 | $params = array( 108 | 'limit' => $limit, 109 | 'marker' => $marker, 110 | 'prefix' => $prefix, 111 | 'path' => $path, 112 | 'delimiter' => $delimiter, 113 | 'format' => (!in_array($format, $this->formats, true) ? $this->format : $format) 114 | ); 115 | 116 | $res = SCurl::init($this->url) 117 | ->setHeaders($this->token) 118 | ->setParams($params) 119 | ->request("GET") 120 | ->getContent(); 121 | 122 | if ($params['format'] == '') { 123 | return explode("\n", trim($res)); 124 | } 125 | 126 | return trim($res); 127 | } 128 | 129 | /** 130 | * Upload local file 131 | * 132 | * @param string $localFileName The name of a local file 133 | * @param string $remoteFileName The name of storage file 134 | * 135 | * @return array 136 | */ 137 | public function putFile($localFileName, $remoteFileName = null, $headers = array()) 138 | { 139 | if (is_null($remoteFileName)) { 140 | $remoteFileName = array_pop(explode(DIRECTORY_SEPARATOR, $localFileName)); 141 | } 142 | $headers = array_merge($headers, $this->token); 143 | $info = SCurl::init($this->url . $remoteFileName) 144 | ->setHeaders($headers) 145 | ->putFile($localFileName) 146 | ->getInfo(); 147 | 148 | if (!in_array($info["http_code"], array(201))) { 149 | return $this->error($info["http_code"], __METHOD__); 150 | } 151 | 152 | return $info; 153 | } 154 | 155 | /** 156 | * Upload binary string as file 157 | * 158 | * @param string $contents 159 | * @param string|null $remoteFileName 160 | * @return array 161 | */ 162 | public function putFileContents($contents, $remoteFileName = null) 163 | { 164 | $info = SCurl::init($this->url . $remoteFileName) 165 | ->setHeaders($this->token) 166 | ->putFileContents($contents) 167 | ->getInfo(); 168 | 169 | if (!in_array($info["http_code"], array(201))) { 170 | return $this->error($info["http_code"], __METHOD__); 171 | } 172 | 173 | return $info; 174 | } 175 | 176 | /** 177 | * Set meta info for file 178 | * 179 | * @param string $name File name 180 | * @param array $headers Headers 181 | * 182 | * @return integer 183 | */ 184 | public function setFileHeaders($name, $headers) 185 | { 186 | $headers = $this->getX($headers, "X-Container-Meta-"); 187 | if (get_class($this) != 'SelectelContainer') { 188 | return 0; 189 | } 190 | 191 | return $this->setMetaInfo($name, $headers); 192 | } 193 | 194 | /** 195 | * Creating directory 196 | * 197 | * @param string $name Directory name 198 | * 199 | * @return array 200 | */ 201 | public function createDirectory($name) 202 | { 203 | $headers = array_merge(array("Content-Type: application/directory"), $this->token); 204 | $info = SCurl::init($this->url . $name) 205 | ->setHeaders($headers) 206 | ->request("PUT") 207 | ->getInfo(); 208 | 209 | return $info; 210 | } 211 | 212 | } 213 | -------------------------------------------------------------------------------- /src/SelectelStorage.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class SelectelStorage 13 | { 14 | 15 | /** 16 | * Throw exception on Error 17 | * 18 | * @var boolean 19 | */ 20 | protected static $throwExceptions = true; 21 | /** 22 | * Header string in array for authtorization. 23 | * 24 | * @var array() 25 | */ 26 | protected $token = array(); 27 | /** 28 | * Storage url 29 | * 30 | * @var string 31 | */ 32 | protected $url = ''; 33 | /** 34 | * The response format 35 | * 36 | * @var string 37 | */ 38 | protected $format = ''; 39 | /** 40 | * Allowed response formats 41 | * 42 | * @var array 43 | */ 44 | protected $formats = array('', 'json', 'xml'); 45 | 46 | /** 47 | * Creating Selectel Storage PHP class 48 | * 49 | * @param string $user Account id 50 | * @param string $key Storage key 51 | * @param string $format Allowed response formats 52 | * 53 | * @return SelectelStorage 54 | */ 55 | public function __construct($user, $key, $format = null) 56 | { 57 | $header = SCurl::init("https://auth.selcdn.ru/") 58 | ->setHeaders(array("Host: auth.selcdn.ru", "X-Auth-User: {$user}", "X-Auth-Key: {$key}")) 59 | ->request("GET") 60 | ->getHeaders(); 61 | 62 | if ($header["HTTP-Code"] != 204) { 63 | if ($header["HTTP-Code"] == 403) 64 | return $this->error($header["HTTP-Code"], "Forbidden for user '{$user}'"); 65 | 66 | return $this->error($header["HTTP-Code"], __METHOD__); 67 | } 68 | 69 | $this->format = (!in_array($format, $this->formats, true) ? $this->format : $format); 70 | $this->url = $header['x-storage-url']; 71 | $this->token = array("X-Auth-Token: {$header['x-storage-token']}"); 72 | } 73 | 74 | /** 75 | * Handle errors 76 | * 77 | * @param integer $code 78 | * @param string $message 79 | * 80 | * @return mixed 81 | * @throws SelectelStorageException 82 | */ 83 | protected function error($code, $message) 84 | { 85 | if (self::$throwExceptions) 86 | throw new SelectelStorageException($message, $code); 87 | return $code; 88 | } 89 | 90 | /** 91 | * Getting storage info 92 | * 93 | * @return array 94 | */ 95 | public function getInfo() 96 | { 97 | $head = SCurl::init($this->url) 98 | ->setHeaders($this->token) 99 | ->request("HEAD") 100 | ->getHeaders(); 101 | return $this->getX($head); 102 | } 103 | 104 | /** 105 | * Select only 'x-' from headers 106 | * 107 | * @param array $headers Array of headers 108 | * @param string $prefix Frefix for filtering 109 | * 110 | * @return array 111 | */ 112 | protected static function getX($headers, $prefix = 'x-') 113 | { 114 | $result = array(); 115 | foreach ($headers as $key => $value) { 116 | if (stripos($key, $prefix) === 0) { 117 | $result[$key] = $value; 118 | } 119 | } 120 | return $result; 121 | } 122 | 123 | /** 124 | * Getting containers list 125 | * 126 | * @param int $limit Limit (Default 10000) 127 | * @param string $marker Marker (Default '') 128 | * @param string $format Format ('', 'json', 'xml') (Default self::$format) 129 | * 130 | * @return string 131 | */ 132 | public function listContainers($limit = 10000, $marker = '', $format = null) 133 | { 134 | $params = array( 135 | 'limit' => $limit, 136 | 'marker' => $marker, 137 | 'format' => (!in_array($format, $this->formats, true) ? $this->format : $format) 138 | ); 139 | 140 | $cont = SCurl::init($this->url) 141 | ->setHeaders($this->token) 142 | ->setParams($params) 143 | ->request("GET") 144 | ->getContent(); 145 | 146 | if ($params['format'] == '') { 147 | return explode("\n", trim($cont)); 148 | } 149 | 150 | return trim($cont); 151 | } 152 | 153 | /** 154 | * Create container by name. 155 | * Headers for 156 | * 157 | * @param string $name 158 | * @param array $headers 159 | * 160 | * @return SelectelContainer 161 | */ 162 | public function createContainer($name, $headers = array()) 163 | { 164 | $headers = array_merge($this->token, $headers); 165 | $info = SCurl::init($this->url . $name) 166 | ->setHeaders($headers) 167 | ->request("PUT") 168 | ->getInfo(); 169 | 170 | if (!in_array($info["http_code"], array(201, 202))) { 171 | return $this->error($info["http_code"], __METHOD__); 172 | } 173 | 174 | return $this->getContainer($name); 175 | } 176 | 177 | /** 178 | * Select container by name 179 | * 180 | * @param string $name 181 | * 182 | * @return SelectelContainer 183 | */ 184 | public function getContainer($name) 185 | { 186 | $url = $this->url . $name; 187 | $headers = SCurl::init($url) 188 | ->setHeaders($this->token) 189 | ->request("HEAD") 190 | ->getHeaders(); 191 | 192 | if (!in_array($headers["HTTP-Code"], array(204))) { 193 | return $this->error($headers["HTTP-Code"], __METHOD__); 194 | } 195 | 196 | return new SelectelContainer($url, $this->token, $this->format, $this->getX($headers)); 197 | } 198 | 199 | /** 200 | * Delete container or object by name 201 | * 202 | * @param string $name 203 | * 204 | * @return integera 205 | */ 206 | public function delete($name) 207 | { 208 | $info = SCurl::init($this->url . $name) 209 | ->setHeaders($this->token) 210 | ->request("DELETE") 211 | ->getInfo(); 212 | 213 | if (!in_array($info["http_code"], array(204))) { 214 | return $this->error($info["http_code"], __METHOD__); 215 | } 216 | 217 | return $info; 218 | } 219 | 220 | /** 221 | * Copy 222 | * 223 | * @param string $origin Origin object 224 | * @param string $destin Destination 225 | * 226 | * @return array 227 | */ 228 | public function copy($origin, $destin) 229 | { 230 | $url = parse_url($this->url); 231 | $destin = $url['path'] . $destin; 232 | $headers = array_merge($this->token, array("Destination: {$destin}")); 233 | $info = SCurl::init($this->url . $origin) 234 | ->setHeaders($headers) 235 | ->request("COPY") 236 | ->getResult(); 237 | 238 | return $info; 239 | } 240 | 241 | public function setContainerHeaders($name, $headers) 242 | { 243 | $headers = $this->getX($headers, "X-Container-Meta-"); 244 | if (get_class($this) != 'SelectelStorage') { 245 | return 0; 246 | } 247 | 248 | return $this->setMetaInfo($name, $headers); 249 | } 250 | 251 | /** 252 | * Setting meta info 253 | * 254 | * @param string $name Name of object 255 | * @param array $headers Headers 256 | * 257 | * @return integer 258 | */ 259 | protected function setMetaInfo($name, $headers) 260 | { 261 | if (get_class($this) == 'SelectelStorage') { 262 | $headers = $this->getX($headers, "X-Container-Meta-"); 263 | } elseif (get_class($this) == 'SelectelContainer') { 264 | $headers = $this->getX($headers, "X-Container-Meta-"); 265 | } else { 266 | return 0; 267 | } 268 | 269 | $info = SCurl::init($this->url . $name) 270 | ->setHeaders($headers) 271 | ->request("POST") 272 | ->getInfo(); 273 | 274 | if (!in_array($info["http_code"], array(204))) { 275 | return $this->error($info["http_code"], __METHOD__); 276 | } 277 | 278 | return $info["http_code"]; 279 | } 280 | 281 | /** 282 | * Upload and extract archive 283 | * 284 | * @param string $archiveFileName The name of a local file 285 | * @param string $remotePath The path to extract archive 286 | * @return array 287 | */ 288 | public function putArchive($archive, $path = null) 289 | { 290 | $url = $this->url . $path . '?extract-archive=' . pathinfo($archive, PATHINFO_EXTENSION); 291 | 292 | 293 | switch ($this->format) { 294 | case 'json': 295 | $headers = array_merge($this->token, ['Accept: application/json']); 296 | break; 297 | case 'xml': 298 | $headers = array_merge($this->token, ['Accept: application/xml']); 299 | break; 300 | default: 301 | $headers = array_merge($this->token, ['Accept: text/plain']); 302 | break; 303 | } 304 | 305 | $info = SCurl::init($url) 306 | ->setHeaders($headers) 307 | ->putFile($archive) 308 | ->getContent(); 309 | 310 | if ($this->format == '') { 311 | return explode("\n", trim($info)); 312 | } 313 | 314 | 315 | return $this->format == 'json' ? json_decode($info, TRUE) : trim($info); 316 | } 317 | 318 | /** 319 | * Set X-Account-Meta-Temp-URL-Key for temp file download link generation. Run it once and use key forever. 320 | * 321 | * @param string $key 322 | * 323 | * @return integer 324 | */ 325 | public function setAccountMetaTempURLKey($key) 326 | { 327 | $url = $this->url; 328 | $headers = array_merge($this->token, array("X-Account-Meta-Temp-URL-Key: " . $key)); 329 | $res = SCurl::init($url) 330 | ->setHeaders($headers) 331 | ->request("POST") 332 | ->getHeaders(); 333 | 334 | if (!in_array($res["HTTP-Code"], array(202))) { 335 | return $this->error($res ["HTTP-Code"], __METHOD__); 336 | } 337 | 338 | return $res["HTTP-Code"]; 339 | } 340 | 341 | /** 342 | * Get temp file download link 343 | * 344 | * @param string $key X-Account-Meta-Temp-URL-Key specified by setAccountMetaTempURLKey method 345 | * @param string $path to file, including container name 346 | * @param integer $expires time in UNIX-format, after this time link will be voided 347 | * @param string $otherFileName custom filename if needed 348 | * 349 | * @return string 350 | */ 351 | public function getTempURL($key, $path, $expires, $otherFileName = null) 352 | { 353 | $url = substr($this->url, 0, strlen($this->url) - 1); 354 | 355 | $sig_body = "GET\n$expires\n$path"; 356 | 357 | $sig = hash_hmac('sha1', $sig_body, $key); 358 | 359 | $res = $url . $path . '?temp_url_sig=' . $sig . '&temp_url_expires=' . $expires; 360 | 361 | if ($otherFileName != null) { 362 | $res .= '&filename=' . urlencode($otherFileName); 363 | } 364 | 365 | return $res; 366 | } 367 | 368 | } 369 | -------------------------------------------------------------------------------- /src/SelectelStorageException.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | class SelectelStorageException extends \Exception 15 | { 16 | 17 | } 18 | --------------------------------------------------------------------------------