├── Action.php
├── Mysql.sql
├── Plugin.php
├── README.md
├── SQLite.sql
├── cloud
├── cos
│ ├── include.php
│ └── qcloudcos
│ │ ├── auth.php
│ │ ├── conf.php
│ │ ├── cosapi.php
│ │ ├── error_code.php
│ │ ├── http_client.php
│ │ ├── libcurl_helper.php
│ │ ├── libcurl_wrapper.php
│ │ └── slice_uploading.php
├── nos
│ ├── autoload.php
│ └── src
│ │ └── NOS
│ │ ├── Core
│ │ ├── MimeTypes.php
│ │ ├── NosException.php
│ │ └── NosUtil.php
│ │ ├── Http
│ │ ├── LICENSE
│ │ ├── RequestCore.php
│ │ ├── RequestCore_Exception.php
│ │ └── ResponseCore.php
│ │ ├── Model
│ │ ├── BucketInfo.php
│ │ ├── BucketListInfo.php
│ │ ├── DeleteFailedInfo.php
│ │ ├── ListMultipartUploadInfo.php
│ │ ├── ListPartsInfo.php
│ │ ├── ObjectInfo.php
│ │ ├── ObjectListInfo.php
│ │ ├── PartInfo.php
│ │ ├── UploadInfo.php
│ │ └── XmlConfig.php
│ │ ├── NosClient.php
│ │ └── Result
│ │ ├── BodyResult.php
│ │ ├── ExistResult.php
│ │ ├── GetLocationResult.php
│ │ ├── GetObjectMetaResult.php
│ │ ├── InitiateMultipartUploadResult.php
│ │ ├── ListBucketsResult.php
│ │ ├── ListMultipartUploadResult.php
│ │ ├── ListObjectsResult.php
│ │ ├── ListPartsResult.php
│ │ ├── MultiDeleteResult.php
│ │ ├── ObjDeduplicateResult.php
│ │ ├── PutSetDeleteResult.php
│ │ ├── Result.php
│ │ ├── UploadPartResult.php
│ │ ├── aclResult.php
│ │ └── statusResult.php
├── qiniu
│ ├── autoload.php
│ └── src
│ │ └── Qiniu
│ │ ├── Auth.php
│ │ ├── Config.php
│ │ ├── Etag.php
│ │ ├── Http
│ │ ├── Client.php
│ │ ├── Error.php
│ │ ├── Request.php
│ │ └── Response.php
│ │ ├── Processing
│ │ ├── ImageUrlBuilder.php
│ │ ├── Operation.php
│ │ └── PersistentFop.php
│ │ ├── Storage
│ │ ├── BucketManager.php
│ │ ├── FormUploader.php
│ │ ├── ResumeUploader.php
│ │ └── UploadManager.php
│ │ ├── Zone.php
│ │ └── functions.php
└── scs
│ └── SCS.php
├── css
├── border-anim-h.gif
├── border-anim-v.gif
├── graphics
│ ├── close.png
│ ├── closeX.png
│ ├── controlbar-black-border.gif
│ ├── controlbar-text-buttons.png
│ ├── controlbar-white-small.gif
│ ├── controlbar-white.gif
│ ├── controlbar2.gif
│ ├── controlbar3.gif
│ ├── controlbar4-hover.gif
│ ├── controlbar4.gif
│ ├── fullexpand.gif
│ ├── geckodimmer.png
│ ├── icon.gif
│ ├── loader.gif
│ ├── loader.white.gif
│ ├── outlines
│ │ ├── beveled.png
│ │ ├── drop-shadow.png
│ │ ├── glossy-dark.png
│ │ ├── outer-glow.png
│ │ ├── rounded-black.png
│ │ └── rounded-white.png
│ ├── resize.gif
│ ├── scrollarrows.png
│ ├── zoomin.cur
│ └── zoomout.cur
├── highslide-ie6.css
├── highslide.css
└── imgareaselect-animated.css
├── js
├── highslide-full.packed.js
├── highslide-with-gallery.packed.js
├── highslide-with-html.packed.js
├── highslide.packed.js
└── imgareaselect.js
└── manage-gallery.php
/Action.php:
--------------------------------------------------------------------------------
1 | validate()) {
18 | $this->response->goBack();
19 | }
20 |
21 | $gallery = $this->request->from('thumb','image','description','sort','name');
22 | $gallery['order'] = $this->db->fetchObject($this->db->select(array('MAX(order)'=>'maxOrder'))->from('table.gallery'))->maxOrder+1;
23 | $gallery['gid'] = $this->db->query($this->db->insert('table.gallery')->rows($gallery));
24 |
25 | //返回提示信息
26 | $this->widget('Widget_Notice')->highlight('gid-'.$gallery['gid']);
27 | $this->widget('Widget_Notice')->set(_t('相册组%s图片 %s 添加成功',''.$gallery['sort'].'',''.$gallery['name'].''),'success');
28 | $this->response->redirect(Typecho_Common::url('extending.php?panel=HighSlide%2Fmanage-gallery.php&group='.$gallery['sort'],$this->options->adminUrl));
29 | }
30 |
31 | /**
32 | * 更新相册图片
33 | *
34 | * @access public
35 | * @return void
36 | */
37 | public function updategallery()
38 | {
39 | if (HighSlide_Plugin::form('update')->validate()) {
40 | $this->response->goBack();
41 | }
42 |
43 | $gallery = $this->request->from('gid','thumb','image','description','sort','name');
44 | $this->db->query($this->db->update('table.gallery')->rows($gallery)->where('gid = ?',$gallery['gid']));
45 |
46 | //返回提示信息
47 | $this->widget('Widget_Notice')->highlight('gid-'.$gallery['gid']);
48 | $this->widget('Widget_Notice')->set(_t('相册组%s图片 %s 修改成功',''.$gallery['sort'].'',''.$gallery['name'].''),'success');
49 | $this->response->redirect(Typecho_Common::url('extending.php?panel=HighSlide%2Fmanage-gallery.php&group='.$gallery['sort'],$this->options->adminUrl));
50 | }
51 |
52 | /**
53 | * 移除相册图片
54 | *
55 | * @access public
56 | * @return void
57 | */
58 | public function deletegallery()
59 | {
60 | $gids = $this->request->filter('int')->getArray('gid');
61 | $group = isset($this->request->group) ? $this->request->filter('int')->group : HighSlide_Plugin::defaultsort();
62 |
63 | $deletecount = 0;
64 | foreach ($gids as $gid) {
65 | if ($this->db->query($this->db->delete('table.gallery')->where('gid = ?',$gid))) {
66 | ++$deletecount;
67 | }
68 | }
69 |
70 | //返回提示信息
71 | $this->widget('Widget_Notice')->set($deletecount>0 ? _t('图片已从相册移除') : _t('没有图片被移除'),$deletecount>0 ? 'success' : 'notice');
72 | $this->response->redirect(Typecho_Common::url('extending.php?panel=HighSlide%2Fmanage-gallery.php&group='.$group,$this->options->adminUrl));
73 | }
74 |
75 | /**
76 | * 排序相册图片
77 | *
78 | * @access public
79 | * @return void
80 | */
81 | public function sortgallery()
82 | {
83 | $gids = $this->request->filter('int')->getArray('gid');
84 |
85 | foreach ($gids as $sort=>$gid) {
86 | $this->db->query($this->db->update('table.gallery')->rows(array('order'=>$sort+1))->where('gid = ?',$gid));
87 | }
88 |
89 | //返回提示信息
90 | if (!$this->request->isAjax()) {
91 | $this->response->goBack();
92 | } else {
93 | $this->response->throwJson(array('success'=>1,'message'=>_t('图片排序完成')));
94 | }
95 | }
96 |
97 | /**
98 | * 执行上传图片
99 | *
100 | * @access public
101 | * @return void
102 | */
103 | public function uploadimage()
104 | {
105 | if (!empty($_FILES)) {
106 | $file = array_pop($_FILES);
107 | if (0==$file['error'] && is_uploaded_file($file['tmp_name'])) {
108 | //xhr的send无法支持utf8
109 | if ($this->request->isAjax()) {
110 | $file['name'] = urldecode($file['name']);
111 | }
112 |
113 | $result = HighSlide_Plugin::uploadhandle($file);
114 |
115 | if (false!==$result) {
116 | $this->response->throwJson(array(array(
117 | 'name'=>$result['name'],
118 | 'title'=>$result['title'],
119 | 'bytes'=>number_format(ceil($result['size']/1024)).' Kb'
120 | )));
121 | }
122 | }
123 | }
124 |
125 | $this->response->throwJson(false);
126 | }
127 |
128 | /**
129 | * 执行删除图片
130 | *
131 | * @access public
132 | * @return void
133 | */
134 | public function removeimage()
135 | {
136 | $requests = $this->request->from('imgname','url');
137 |
138 | if ($requests['imgname']) {
139 | HighSlide_Plugin::removehandle($requests['imgname'],false,$requests['url']);
140 | }
141 |
142 | $this->response->throwJson(false);
143 | }
144 |
145 | /**
146 | * 执行缩略图片
147 | *
148 | * @access public
149 | * @return void
150 | */
151 | public function cropthumbnail()
152 | {
153 | $requests = $this->request->from('imgname','w','h','x1','y1','url');
154 | $isatt = isset($this->request->tid);
155 |
156 | if ($requests['imgname']) {
157 | $result = HighSlide_Plugin::crophandle($requests['imgname'],$requests['w'],$requests['h'],$requests['x1'],$requests['y1'],$requests['url'],$isatt);
158 | $bytes = number_format(ceil($result['size']/1024)).' Kb';
159 | $tid = '';
160 |
161 | //附件模式归档
162 | if ($isatt) {
163 | $tid = $this->request->filter('int')->tid;
164 | $widget = Typecho_Widget::widget('Widget_Abstract_Contents');
165 |
166 | if ($tid) { //修改
167 | $widget->update(array('text'=>serialize($result)),$this->db->sql()->where('cid = ?',$tid));
168 | $this->db->fetchRow($widget->select()->where('table.contents.cid = ?',$tid)
169 | ->where('table.contents.type = ?', 'attachment'), array($widget, 'push'));
170 | } else { //新建
171 | $struct = array(
172 | 'title'=>$result['name'],
173 | 'slug' =>$result['name'],
174 | 'type' =>'attachment',
175 | 'status'=>'publish',
176 | 'text' =>serialize($result),
177 | 'allowComment' =>1,
178 | 'allowPing'=>0,
179 | 'allowFeed'=>1
180 | );
181 | if (isset($this->request->cid)) {
182 | $cid = $this->request->filter('int')->cid;
183 | if ($widget->isWriteable($this->db->sql()->where('cid = ?', $cid))) {
184 | $struct['parent'] = $cid;
185 | }
186 | }
187 |
188 | $tid = $widget->insert($struct);
189 | $this->db->fetchRow($widget->select()->where('table.contents.cid = ?', $tid)
190 | ->where('table.contents.type = ?', 'attachment'), array($widget, 'push'));
191 | }
192 | }
193 |
194 | $this->response->throwJson(array('cid'=>$tid,'bytes'=>$bytes,'aurl'=>$result['aurl']));
195 | }
196 |
197 | $this->response->throwJson(false);
198 | }
199 |
200 | /**
201 | * 同步插件设置
202 | *
203 | * @access public
204 | * @return void
205 | */
206 | public function syncsettings()
207 | {
208 | //验证规格表单
209 | $validator = new Typecho_Validate();
210 | $validator->addRule('fixedwidth','isInteger',_t('固定宽度请填写整数数字'));
211 | $validator->addRule('fixedheight','isInteger',_t('固定高度请填写整数数字'));
212 | $validator->addRule('fixedratio',array(new HighSlide_Plugin,'ratioformat'),_t('固定比例请填写:号与数字'));
213 | $validator->addRule('fixedwidth','required',_t('固定宽度不能为空'));
214 | $validator->addRule('fixedheight','required',_t('固定高度不能为空'));
215 | $validator->addRule('fixedratio','required',_t('固定比例不能为空'));
216 | if ($error = $validator->run($this->request->from('fixedwidth','fixedheight','fixedratio'))) {
217 | $this->widget('Widget_Notice')->set($error,'error');
218 | $this->response->goBack();
219 | }
220 |
221 | //保存提交数据
222 | Helper::configPlugin('HighSlide',$this->request->from(
223 | 'gallery','thumbfix','fixedwidth','fixedheight','fixedratio',
224 | 'storage','thumbapi','path','cloudtoo',
225 | 'qiniubucket','qiniudomain','qiniuak','qiniusk',
226 | 'scsbucket','scsdomain','scsimgx','scsak','scssk',
227 | 'nosbucket','nosdomain','nosak','nosas','nosep',
228 | 'cosbucket','cosdomain','cosai','cossi','cossk','cosrg'
229 | ));
230 |
231 | //返回提示信息
232 | $this->widget('Widget_Notice')->set(_t('相册设置已保存'),'success');
233 | $this->response->goBack();
234 | }
235 |
236 | /**
237 | * 预览内文附件
238 | *
239 | * @access public
240 | * @return void
241 | */
242 | public function postpreview()
243 | {
244 | $settings = $this->options->plugin('HighSlide');
245 | $local = $this->options->siteUrl;
246 |
247 | //获取附件对象
248 | if (isset($this->request->cid)) {
249 | $cid = $this->request->filter('int')->cid;
250 | $attachment = Typecho_Widget::widget('Widget_Contents_Attachment_Related','parentId='.$cid);
251 | } else {
252 | $attachment = Typecho_Widget::widget('Widget_Contents_Attachment_Unattached');
253 | }
254 |
255 | //重构响应数据
256 | $aurl = '';
257 | $attachurl = '';
258 | $title= '';
259 | $name = '';
260 | $parse = '';
261 | $path = '';
262 | $url = '';
263 | $imgurl = '';
264 | $struct =array();
265 | while ($attachment->next()) {
266 | $aurl = $attachment->attachment->aurl;
267 | $attachurl = $attachment->attachment->url;
268 | $title= $attachment->attachment->name;
269 | $name = basename($attachurl);
270 | //获取API文件名
271 | if ($aurl) {
272 | $parse = parse_url($attachurl);
273 | $name = basename($parse['path']);
274 | }
275 | $path = strstr($attachment->attachment->path,$name,true);
276 | $url = Typecho_Common::url($path,$settings->cloudtoo ? HighSlide_Plugin::route()->site : $local);
277 | //探测绝对地址
278 | if (!$aurl) {
279 | $imgurl = HighSlide_Plugin::ifexist($attachurl);
280 | if (!$imgurl) {
281 | $imgurl = HighSlide_Plugin::ifexist($url.$name);
282 | if (!$imgurl) {
283 | $imgurl = $local.$path.$name;
284 | }
285 | }
286 | }
287 | $struct[] = array(
288 | 'cid'=>$attachment->cid,
289 | 'isimg'=>$attachment->attachment->isImage ? 1 : 0,
290 | 'name'=>$name,
291 | 'title'=>$title,
292 | 'url'=>$aurl ? $aurl : $imgurl,
293 | 'size'=>number_format(ceil($attachment->attachment->size/1024)).' KB',
294 | 'turl'=>$settings->cloudtoo && $settings->thumbapi ? str_replace('thumb_','',$name) : $url.(0===strpos($name,'thumb_') ? $name : 'thumb_'.$name),
295 | 'aurl'=>$aurl
296 | );
297 | }
298 | if (!isset($this->request->cid)) {
299 | sort($struct); //修正排序
300 | }
301 |
302 | $this->response->throwJson(Json::encode($struct));
303 | }
304 |
305 | /**
306 | * 绑定动作
307 | *
308 | * @access public
309 | * @return void
310 | */
311 | public function action()
312 | {
313 | $this->db = Typecho_Db::get();
314 | $this->options = Helper::options();
315 | $this->security = Helper::security();
316 |
317 | $this->security->protect();
318 | $this->on($this->request->is('do=insert'))->insertgallery();
319 | $this->on($this->request->is('do=update'))->updategallery();
320 | $this->on($this->request->is('do=delete'))->deletegallery();
321 | $this->on($this->request->is('do=sort'))->sortgallery();
322 | $this->on($this->request->is('do=upload'))->uploadimage();
323 | $this->on($this->request->is('do=remove'))->removeimage();
324 | $this->on($this->request->is('do=crop'))->cropthumbnail();
325 | $this->on($this->request->is('do=sync'))->syncsettings();
326 | $this->on($this->request->is('do=preview'))->postpreview();
327 |
328 | $this->response->redirect($this->options->adminUrl);
329 | }
330 |
331 | }
--------------------------------------------------------------------------------
/Mysql.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `typecho_gallery` (
2 | `gid` int(10) unsigned NOT NULL auto_increment COMMENT 'gallery表主键',
3 | `thumb` varchar(200) default NULL COMMENT '缩略图',
4 | `image` varchar(200) default NULL COMMENT '原图',
5 | `sort` int(10) default '0' COMMENT '相册组',
6 | `name` varchar(200) default NULL COMMENT '图片名称',
7 | `description` varchar(200) default NULL COMMENT '图片描述',
8 | `order` int(10) unsigned default '0' COMMENT '图片排序',
9 | PRIMARY KEY (`gid`)
10 | ) ENGINE=MYISAM DEFAULT CHARSET=%charset%;
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Typecho弹窗相册插件HighSlide
2 | 2018年7月16日更新至**v1.4.7**:
3 | - 使用5.0.0packed双内核
4 | - 附件栏内集成缩略图模式
5 | - 附件缩略图支持归档联动
6 | - 优化相册的修改模式机制
7 | - 支持4家免费云储存及API
8 | - 增加html弹窗编辑器按钮
9 | - 修正MD转义及检测等bug
10 |
11 | #### 详细说明与效果演示见blog发布地址:
12 | > http://www.yzmb.me/archives/net/highslide-for-typecho
--------------------------------------------------------------------------------
/SQLite.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `typecho_gallery` (
2 | `gid` INTEGER NOT NULL PRIMARY KEY,
3 | `thumb` varchar(200) default NULL,
4 | `image` varchar(200) default NULL,
5 | `sort` int(10) default '0',
6 | `name` varchar(200) default NULL,
7 | `description` varchar(200) default NULL,
8 | `order` int(10) default '0'
9 | );
10 |
--------------------------------------------------------------------------------
/cloud/cos/include.php:
--------------------------------------------------------------------------------
1 | plugin('HighSlide');
22 | self::$APPID = $settings->cosai;
23 | self::$SECRET_ID = $settings->cossi;
24 | self::$SECRET_KEY = $settings->cossk;
25 | }
26 |
27 | /**
28 | * Get the User-Agent string to send to COS server.
29 | */
30 | public static function getUserAgent() {
31 | return 'cos-php-sdk-' . self::VERSION;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cloud/cos/qcloudcos/error_code.php:
--------------------------------------------------------------------------------
1 | value fields to post.
6 | * @return $boundary and encoded post fields.
7 | */
8 | function buildCustomPostFields($fields) {
9 | // invalid characters for "name" and "filename"
10 | static $disallow = array("\0", "\"", "\r", "\n");
11 |
12 | // initialize body
13 | $body = array();
14 |
15 | // build normal parameters
16 | foreach ($fields as $key => $value) {
17 | $key = str_replace($disallow, "_", $key);
18 | $body[] = implode("\r\n", array(
19 | "Content-Disposition: form-data; name=\"{$key}\"",
20 | '',
21 | filter_var($value),
22 | ));
23 | }
24 |
25 | // generate safe boundary
26 | do {
27 | $boundary = "---------------------" . md5(mt_rand() . microtime());
28 | } while (preg_grep("/{$boundary}/", $body));
29 |
30 | // add boundary for each parameters
31 | foreach ($body as &$part) {
32 | $part = "--{$boundary}\r\n{$part}";
33 | }
34 | unset($part);
35 |
36 | // add final boundary
37 | $body[] = "--{$boundary}--";
38 | $body[] = '';
39 |
40 | return array($boundary, implode("\r\n", $body));
41 | }
42 |
--------------------------------------------------------------------------------
/cloud/cos/qcloudcos/libcurl_wrapper.php:
--------------------------------------------------------------------------------
1 | curlMultiHandle = curl_multi_init();
30 | $this->idleCurlHandle = array();
31 | }
32 |
33 | public function __destruct() {
34 | curl_multi_close($this->curlMultiHandle);
35 | foreach ($this->idleCurlHandle as $handle) {
36 | curl_close($handle);
37 | }
38 | $this->idleCurlHandle = array();
39 | }
40 |
41 | public function startSendingRequest($httpRequest, $done) {
42 | if (count($this->idleCurlHandle) !== 0) {
43 | $curlHandle = array_pop($this->idleCurlHandle);
44 | } else {
45 | $curlHandle = curl_init();
46 | if ($curlHandle === false) {
47 | return false;
48 | }
49 | }
50 |
51 | curl_setopt($curlHandle, CURLOPT_TIMEOUT_MS, $httpRequest->timeoutMs);
52 | curl_setopt($curlHandle, CURLOPT_URL, $httpRequest->url);
53 | curl_setopt($curlHandle, CURLOPT_HEADER, 1);
54 | curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
55 | $headers = $httpRequest->customHeaders;
56 | array_push($headers, 'User-Agent:'.Conf::getUserAgent());
57 | if ($httpRequest->method === 'POST') {
58 | if (defined('CURLOPT_SAFE_UPLOAD')) {
59 | curl_setopt($curlHandle, CURLOPT_SAFE_UPLOAD, true);
60 | }
61 |
62 | curl_setopt($curlHandle, CURLOPT_POST, true);
63 | $arr = buildCustomPostFields($httpRequest->dataToPost);
64 | array_push($headers, 'Expect: 100-continue');
65 | array_push($headers, 'Content-Type: multipart/form-data; boundary=' . $arr[0]);
66 | curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $arr[1]);
67 | }
68 | curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $headers);
69 |
70 | curl_multi_add_handle($this->curlMultiHandle, $curlHandle);
71 |
72 | $this->curlHandleInfo[$curlHandle]['done'] = $done;
73 | $this->curlHandleInfo[$curlHandle]['request'] = $httpRequest;
74 | }
75 |
76 | public function performSendingRequest() {
77 | for (;;) {
78 | $active = null;
79 |
80 | do {
81 | $mrc = curl_multi_exec($this->curlMultiHandle, $active);
82 | $info = curl_multi_info_read($this->curlMultiHandle);
83 | if ($info !== false) {
84 | $this->processResult($info);
85 | }
86 | } while ($mrc == CURLM_CALL_MULTI_PERFORM);
87 |
88 | while ($active && $mrc == CURLM_OK) {
89 | if (curl_multi_select($this->curlMultiHandle) == -1) {
90 | usleep(1);
91 | }
92 |
93 | do {
94 | $mrc = curl_multi_exec($this->curlMultiHandle, $active);
95 | $info = curl_multi_info_read($this->curlMultiHandle);
96 | if ($info !== false) {
97 | $this->processResult($info);
98 | }
99 | } while ($mrc == CURLM_CALL_MULTI_PERFORM);
100 | }
101 |
102 | if (count($this->curlHandleInfo) == 0) {
103 | break;
104 | }
105 | }
106 | }
107 |
108 | private function processResult($info) {
109 | $result = $info['result'];
110 | $handle = $info['handle'];
111 | $request = $this->curlHandleInfo[$handle]['request'];
112 | $done = $this->curlHandleInfo[$handle]['done'];
113 | $response = new HttpResponse();
114 |
115 | if ($result !== CURLE_OK) {
116 | $response->curlErrorCode = $result;
117 | $response->curlErrorMessage = curl_error($handle);
118 |
119 | call_user_func($done, $request, $response);
120 | } else {
121 | $responseStr = curl_multi_getcontent($handle);
122 | $headerSize = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
123 | $headerStr = substr($responseStr, 0, $headerSize);
124 | $body = substr($responseStr, $headerSize);
125 |
126 | $response->curlErrorCode = curl_errno($handle);
127 | $response->curlErrorMessage = curl_error($handle);
128 | $response->statusCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
129 | $headLines = explode("\r\n", $headerStr);
130 | foreach ($headLines as $head) {
131 | $arr = explode(':', $head);
132 | if (count($arr) >= 2) {
133 | $response->headers[trim($arr[0])] = trim($arr[1]);
134 | }
135 | }
136 | $response->body = $body;
137 |
138 | call_user_func($done, $request, $response);
139 | }
140 |
141 | unset($this->curlHandleInfo[$handle]);
142 | curl_multi_remove_handle($this->curlMultiHandle, $handle);
143 |
144 | array_push($this->idleCurlHandle, $handle);
145 | }
146 |
147 | private function resetCurl($handle) {
148 | if (function_exists('curl_reset')) {
149 | curl_reset($handle);
150 | } else {
151 | curl_setopt($handler, CURLOPT_URL, '');
152 | curl_setopt($handler, CURLOPT_HTTPHEADER, array());
153 | curl_setopt($handler, CURLOPT_POSTFIELDS, array());
154 | curl_setopt($handler, CURLOPT_TIMEOUT, 0);
155 | curl_setopt($handler, CURLOPT_SSL_VERIFYPEER, false);
156 | curl_setopt($handler, CURLOPT_SSL_VERIFYHOST, 0);
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/cloud/cos/qcloudcos/slice_uploading.php:
--------------------------------------------------------------------------------
1 | timeoutMs = $timeoutMs;
45 | $this->maxRetryCount = $maxRetryCount;
46 | $this->errorCode = COSAPI_SUCCESS;
47 | $this->errorMessage = '';
48 | $this->concurrentTaskNumber = self::DEFAULT_CONCURRENT_TASK_NUMBER;
49 |
50 | $this->offset = 0;
51 |
52 | $this->libcurlWrapper = new LibcurlWrapper();
53 | }
54 |
55 | public function __destruct() {
56 | }
57 |
58 | public function getLastErrorCode() {
59 | return $this->errorCode;
60 | }
61 |
62 | public function getLastErrorMessage() {
63 | return $this->errorMessage;
64 | }
65 |
66 | public function getRequestId() {
67 | return $this->requestId;
68 | }
69 |
70 | public function getAccessUrl() {
71 | return $this->accessUrl;
72 | }
73 |
74 | public function getResourcePath() {
75 | return $this->resourcePath;
76 | }
77 |
78 | public function getSourceUrl() {
79 | return $this->sourceUrl;
80 | }
81 |
82 | /**
83 | * Return true on success and return false on failure.
84 | */
85 | public function initUploading(
86 | $signature, $srcFpath, $url, $fileSize, $sliceSize, $bizAttr, $insertOnly) {
87 | $this->signature = $signature;
88 | $this->srcFpath = $srcFpath;
89 | $this->url = $url;
90 | $this->fileSize = $fileSize;
91 | $this->sliceSize = $sliceSize;
92 |
93 | // Clear error so caller can successfully retry.
94 | $this->clearError();
95 |
96 | $request = array(
97 | 'url' => $url,
98 | 'method' => 'post',
99 | 'timeout' => $this->timeoutMs / 1000,
100 | 'data' => array(
101 | 'op' => 'upload_slice_init',
102 | 'filesize' => $fileSize,
103 | 'slice_size' => $sliceSize,
104 | 'insertOnly' => $insertOnly,
105 | ),
106 | 'header' => array(
107 | 'Authorization: ' . $signature,
108 | ),
109 | );
110 |
111 | if (isset($bizAttr) && strlen($bizAttr)) {
112 | $request['data']['biz_attr'] = $bizAttr;
113 | }
114 |
115 | $response = $this->sendRequest($request);
116 | if ($response === false) {
117 | return false;
118 | }
119 | $this->session = $response['data']['session'];
120 |
121 | if (isset($response['data']['slice_size'])) {
122 | $this->sliceSize = $response['data']['slice_size'];
123 | }
124 |
125 | if (isset($response['data']['serial_upload']) && $response['data']['serial_upload'] == 1) {
126 | $this->concurrentTaskNumber = 1;
127 | }
128 |
129 | return true;
130 | }
131 |
132 | /**
133 | * Return true on success and return false on failure.
134 | */
135 | public function performUploading() {
136 | for ($i = 0; $i < $this->concurrentTaskNumber; ++$i) {
137 | if ($this->offset >= $this->fileSize) {
138 | break;
139 | }
140 |
141 | $sliceContent = file_get_contents($this->srcFpath, false, null, $this->offset, $this->sliceSize);
142 | if ($sliceContent === false) {
143 | $this->setError(COSAPI_PARAMS_ERROR, 'read file ' . $this->srcFpath . ' error');
144 | return false;
145 | }
146 |
147 | $request = new HttpRequest();
148 | $request->timeoutMs = $this->timeoutMs;
149 | $request->url = $this->url;
150 | $request->method = 'POST';
151 | $request->customHeaders = array(
152 | 'Authorization: ' . $this->signature,
153 | );
154 | $request->dataToPost = array(
155 | 'op' => 'upload_slice_data',
156 | 'session' => $this->session,
157 | 'offset' => $this->offset,
158 | 'filecontent' => $sliceContent,
159 | 'datamd5' => md5($sliceContent),
160 | );
161 | $request->userData = array(
162 | 'retryCount' => 0,
163 | );
164 |
165 | $this->libcurlWrapper->startSendingRequest($request, array($this, 'uploadCallback'));
166 |
167 | $this->offset += $this->sliceSize;
168 | }
169 |
170 | $this->libcurlWrapper->performSendingRequest();
171 |
172 | if ($this->errorCode !== COSAPI_SUCCESS) {
173 | return false;
174 | }
175 |
176 | return true;
177 | }
178 |
179 | /**
180 | * Return true on success and return false on failure.
181 | */
182 | public function finishUploading() {
183 | $request = array(
184 | 'url' => $this->url,
185 | 'method' => 'post',
186 | 'timeout' => $this->timeoutMs / 1000,
187 | 'data' => array(
188 | 'op' => 'upload_slice_finish',
189 | 'session' => $this->session,
190 | 'filesize' => $this->fileSize,
191 | ),
192 | 'header' => array(
193 | 'Authorization: ' . $this->signature,
194 | ),
195 | );
196 |
197 | $response = $this->sendRequest($request);
198 | if ($response === false) {
199 | return false;
200 | }
201 |
202 | $this->accessUrl = $response['data']['access_url'];
203 | $this->resourcePath = $response['data']['resource_path'];
204 | $this->sourceUrl = $response['data']['source_url'];
205 |
206 | return true;
207 | }
208 |
209 | private function sendRequest($request) {
210 | $response = HttpClient::sendRequest($request);
211 | if ($response === false) {
212 | $this->setError(COSAPI_NETWORK_ERROR, 'network error');
213 | return false;
214 | }
215 |
216 | $responseJson = json_decode($response, true);
217 | if ($responseJson === NULL) {
218 | $this->setError(COSAPI_NETWORK_ERROR, 'network error');
219 | return false;
220 | }
221 |
222 | $this->requestId = $responseJson['request_id'];
223 | if ($responseJson['code'] != 0) {
224 | $this->setError($responseJson['code'], $responseJson['message']);
225 | return false;
226 | }
227 |
228 | return $responseJson;
229 | }
230 |
231 | private function clearError() {
232 | $this->errorCode = COSAPI_SUCCESS;
233 | $this->errorMessage = 'success';
234 | }
235 |
236 | private function setError($errorCode, $errorMessage) {
237 | $this->errorCode = $errorCode;
238 | $this->errorMessage = $errorMessage;
239 | }
240 |
241 | public function uploadCallback($request, $response) {
242 | if ($this->errorCode !== COSAPI_SUCCESS) {
243 | return;
244 | }
245 |
246 | $requestErrorCode = COSAPI_SUCCESS;
247 | $requestErrorMessage = 'success';
248 | $retryCount = $request->userData['retryCount'];
249 |
250 | $responseJson = json_decode($response->body, true);
251 | if ($responseJson === NULL) {
252 | $requestErrorCode = COSAPI_NETWORK_ERROR;
253 | $requestErrorMessage = 'network error';
254 | }
255 |
256 | if ($response->curlErrorCode !== CURLE_OK) {
257 | $requestErrorCode = COSAPI_NETWORK_ERROR;
258 | $requestErrorMessage = 'network error: curl errno ' . $response->curlErrorCode;
259 | }
260 |
261 | $this->requestId = $responseJson['request_id'];
262 | if ($responseJson['code'] != 0) {
263 | $requestErrorCode = $responseJson['code'];
264 | $requestErrorMessage = $responseJson['message'];
265 | }
266 |
267 | if (isset($responseJson['data']['datamd5']) &&
268 | $responseJson['data']['datamd5'] !== $request->dataToPost['datamd5']) {
269 | $requestErrorCode = COSAPI_INTEGRITY_ERROR;
270 | $requestErrorMessage = 'cosapi integrity error';
271 | }
272 |
273 | if ($requestErrorCode !== COSAPI_SUCCESS) {
274 | if ($retryCount >= $this->maxRetryCount) {
275 | $this->setError($requestErrorCode, $requestErrorMessage);
276 | } else {
277 | $request->userData['retryCount'] += 1;
278 | $this->libcurlWrapper->startSendingRequest($request, array($this, 'uploadCallback'));
279 | }
280 | return;
281 | }
282 |
283 | if ($this->offset >= $this->fileSize) {
284 | return;
285 | }
286 |
287 | // Send next slice.
288 | $nextSliceContent = file_get_contents($this->srcFpath, false, null, $this->offset, $this->sliceSize);
289 | if ($nextSliceContent === false) {
290 | $this->setError(COSAPI_PARAMS_ERROR, 'read file ' . $this->srcFpath . ' error');
291 | return;
292 | }
293 |
294 | $nextSliceRequest = new HttpRequest();
295 | $nextSliceRequest->timeoutMs = $this->timeoutMs;
296 | $nextSliceRequest->url = $this->url;
297 | $nextSliceRequest->method = 'POST';
298 | $nextSliceRequest->customHeaders = array(
299 | 'Authorization: ' . $this->signature,
300 | );
301 | $nextSliceRequest->dataToPost = array(
302 | 'op' => 'upload_slice_data',
303 | 'session' => $this->session,
304 | 'offset' => $this->offset,
305 | 'filecontent' => $nextSliceContent,
306 | 'datamd5' => md5($nextSliceContent),
307 | );
308 | $nextSliceRequest->userData = array(
309 | 'retryCount' => 0,
310 | );
311 |
312 | $this->libcurlWrapper->startSendingRequest($nextSliceRequest, array($this, 'uploadCallback'));
313 |
314 | $this->offset += $this->sliceSize;
315 | }
316 | }
317 |
--------------------------------------------------------------------------------
/cloud/nos/autoload.php:
--------------------------------------------------------------------------------
1 | 1) {
24 | $ext = strtolower(end($parts));
25 | if (isset(self::$mime_types[$ext])) {
26 | return self::$mime_types[$ext];
27 | }
28 | }
29 |
30 | return null;
31 | }
32 |
33 | private static $mime_types = array(
34 | 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
35 | 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
36 | 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
37 | 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
38 | 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
39 | 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
40 | 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
41 | 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
42 | 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
43 | 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
44 | 'apk' => 'application/vnd.android.package-archive',
45 | 'hqx' => 'application/mac-binhex40',
46 | 'cpt' => 'application/mac-compactpro',
47 | 'doc' => 'application/msword',
48 | 'ogg' => 'audio/ogg',
49 | 'pdf' => 'application/pdf',
50 | 'rtf' => 'text/rtf',
51 | 'mif' => 'application/vnd.mif',
52 | 'xls' => 'application/vnd.ms-excel',
53 | 'ppt' => 'application/vnd.ms-powerpoint',
54 | 'odc' => 'application/vnd.oasis.opendocument.chart',
55 | 'odb' => 'application/vnd.oasis.opendocument.database',
56 | 'odf' => 'application/vnd.oasis.opendocument.formula',
57 | 'odg' => 'application/vnd.oasis.opendocument.graphics',
58 | 'otg' => 'application/vnd.oasis.opendocument.graphics-template',
59 | 'odi' => 'application/vnd.oasis.opendocument.image',
60 | 'odp' => 'application/vnd.oasis.opendocument.presentation',
61 | 'otp' => 'application/vnd.oasis.opendocument.presentation-template',
62 | 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
63 | 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
64 | 'odt' => 'application/vnd.oasis.opendocument.text',
65 | 'odm' => 'application/vnd.oasis.opendocument.text-master',
66 | 'ott' => 'application/vnd.oasis.opendocument.text-template',
67 | 'oth' => 'application/vnd.oasis.opendocument.text-web',
68 | 'sxw' => 'application/vnd.sun.xml.writer',
69 | 'stw' => 'application/vnd.sun.xml.writer.template',
70 | 'sxc' => 'application/vnd.sun.xml.calc',
71 | 'stc' => 'application/vnd.sun.xml.calc.template',
72 | 'sxd' => 'application/vnd.sun.xml.draw',
73 | 'std' => 'application/vnd.sun.xml.draw.template',
74 | 'sxi' => 'application/vnd.sun.xml.impress',
75 | 'sti' => 'application/vnd.sun.xml.impress.template',
76 | 'sxg' => 'application/vnd.sun.xml.writer.global',
77 | 'sxm' => 'application/vnd.sun.xml.math',
78 | 'sis' => 'application/vnd.symbian.install',
79 | 'wbxml' => 'application/vnd.wap.wbxml',
80 | 'wmlc' => 'application/vnd.wap.wmlc',
81 | 'wmlsc' => 'application/vnd.wap.wmlscriptc',
82 | 'bcpio' => 'application/x-bcpio',
83 | 'torrent' => 'application/x-bittorrent',
84 | 'bz2' => 'application/x-bzip2',
85 | 'vcd' => 'application/x-cdlink',
86 | 'pgn' => 'application/x-chess-pgn',
87 | 'cpio' => 'application/x-cpio',
88 | 'csh' => 'application/x-csh',
89 | 'dvi' => 'application/x-dvi',
90 | 'spl' => 'application/x-futuresplash',
91 | 'gtar' => 'application/x-gtar',
92 | 'hdf' => 'application/x-hdf',
93 | 'jar' => 'application/java-archive',
94 | 'jnlp' => 'application/x-java-jnlp-file',
95 | 'js' => 'application/javascript',
96 | 'json' => 'application/json',
97 | 'ksp' => 'application/x-kspread',
98 | 'chrt' => 'application/x-kchart',
99 | 'kil' => 'application/x-killustrator',
100 | 'latex' => 'application/x-latex',
101 | 'rpm' => 'application/x-rpm',
102 | 'sh' => 'application/x-sh',
103 | 'shar' => 'application/x-shar',
104 | 'swf' => 'application/x-shockwave-flash',
105 | 'sit' => 'application/x-stuffit',
106 | 'sv4cpio' => 'application/x-sv4cpio',
107 | 'sv4crc' => 'application/x-sv4crc',
108 | 'tar' => 'application/x-tar',
109 | 'tcl' => 'application/x-tcl',
110 | 'tex' => 'application/x-tex',
111 | 'man' => 'application/x-troff-man',
112 | 'me' => 'application/x-troff-me',
113 | 'ms' => 'application/x-troff-ms',
114 | 'ustar' => 'application/x-ustar',
115 | 'src' => 'application/x-wais-source',
116 | 'zip' => 'application/zip',
117 | 'm3u' => 'audio/x-mpegurl',
118 | 'ra' => 'audio/x-pn-realaudio',
119 | 'wav' => 'audio/x-wav',
120 | 'wma' => 'audio/x-ms-wma',
121 | 'wax' => 'audio/x-ms-wax',
122 | 'pdb' => 'chemical/x-pdb',
123 | 'xyz' => 'chemical/x-xyz',
124 | 'bmp' => 'image/bmp',
125 | 'gif' => 'image/gif',
126 | 'ief' => 'image/ief',
127 | 'png' => 'image/png',
128 | 'wbmp' => 'image/vnd.wap.wbmp',
129 | 'ras' => 'image/x-cmu-raster',
130 | 'pnm' => 'image/x-portable-anymap',
131 | 'pbm' => 'image/x-portable-bitmap',
132 | 'pgm' => 'image/x-portable-graymap',
133 | 'ppm' => 'image/x-portable-pixmap',
134 | 'rgb' => 'image/x-rgb',
135 | 'xbm' => 'image/x-xbitmap',
136 | 'xpm' => 'image/x-xpixmap',
137 | 'xwd' => 'image/x-xwindowdump',
138 | 'css' => 'text/css',
139 | 'rtx' => 'text/richtext',
140 | 'tsv' => 'text/tab-separated-values',
141 | 'jad' => 'text/vnd.sun.j2me.app-descriptor',
142 | 'wml' => 'text/vnd.wap.wml',
143 | 'wmls' => 'text/vnd.wap.wmlscript',
144 | 'etx' => 'text/x-setext',
145 | 'mxu' => 'video/vnd.mpegurl',
146 | 'flv' => 'video/x-flv',
147 | 'wm' => 'video/x-ms-wm',
148 | 'wmv' => 'video/x-ms-wmv',
149 | 'wmx' => 'video/x-ms-wmx',
150 | 'wvx' => 'video/x-ms-wvx',
151 | 'avi' => 'video/x-msvideo',
152 | 'movie' => 'video/x-sgi-movie',
153 | 'ice' => 'x-conference/x-cooltalk',
154 | '3gp' => 'video/3gpp',
155 | 'ai' => 'application/postscript',
156 | 'aif' => 'audio/x-aiff',
157 | 'aifc' => 'audio/x-aiff',
158 | 'aiff' => 'audio/x-aiff',
159 | 'asc' => 'text/plain',
160 | 'atom' => 'application/atom+xml',
161 | 'au' => 'audio/basic',
162 | 'bin' => 'application/octet-stream',
163 | 'cdf' => 'application/x-netcdf',
164 | 'cgm' => 'image/cgm',
165 | 'class' => 'application/octet-stream',
166 | 'dcr' => 'application/x-director',
167 | 'dif' => 'video/x-dv',
168 | 'dir' => 'application/x-director',
169 | 'djv' => 'image/vnd.djvu',
170 | 'djvu' => 'image/vnd.djvu',
171 | 'dll' => 'application/octet-stream',
172 | 'dmg' => 'application/octet-stream',
173 | 'dms' => 'application/octet-stream',
174 | 'dtd' => 'application/xml-dtd',
175 | 'dv' => 'video/x-dv',
176 | 'dxr' => 'application/x-director',
177 | 'eps' => 'application/postscript',
178 | 'exe' => 'application/octet-stream',
179 | 'ez' => 'application/andrew-inset',
180 | 'gram' => 'application/srgs',
181 | 'grxml' => 'application/srgs+xml',
182 | 'gz' => 'application/x-gzip',
183 | 'htm' => 'text/html',
184 | 'html' => 'text/html',
185 | 'ico' => 'image/x-icon',
186 | 'ics' => 'text/calendar',
187 | 'ifb' => 'text/calendar',
188 | 'iges' => 'model/iges',
189 | 'igs' => 'model/iges',
190 | 'jp2' => 'image/jp2',
191 | 'jpe' => 'image/jpeg',
192 | 'jpeg' => 'image/jpeg',
193 | 'jpg' => 'image/jpeg',
194 | 'kar' => 'audio/midi',
195 | 'lha' => 'application/octet-stream',
196 | 'lzh' => 'application/octet-stream',
197 | 'm4a' => 'audio/mp4a-latm',
198 | 'm4p' => 'audio/mp4a-latm',
199 | 'm4u' => 'video/vnd.mpegurl',
200 | 'm4v' => 'video/x-m4v',
201 | 'mac' => 'image/x-macpaint',
202 | 'mathml' => 'application/mathml+xml',
203 | 'mesh' => 'model/mesh',
204 | 'mid' => 'audio/midi',
205 | 'midi' => 'audio/midi',
206 | 'mov' => 'video/quicktime',
207 | 'mp2' => 'audio/mpeg',
208 | 'mp3' => 'audio/mpeg',
209 | 'mp4' => 'video/mp4',
210 | 'mpe' => 'video/mpeg',
211 | 'mpeg' => 'video/mpeg',
212 | 'mpg' => 'video/mpeg',
213 | 'mpga' => 'audio/mpeg',
214 | 'msh' => 'model/mesh',
215 | 'nc' => 'application/x-netcdf',
216 | 'oda' => 'application/oda',
217 | 'ogv' => 'video/ogv',
218 | 'pct' => 'image/pict',
219 | 'pic' => 'image/pict',
220 | 'pict' => 'image/pict',
221 | 'pnt' => 'image/x-macpaint',
222 | 'pntg' => 'image/x-macpaint',
223 | 'ps' => 'application/postscript',
224 | 'qt' => 'video/quicktime',
225 | 'qti' => 'image/x-quicktime',
226 | 'qtif' => 'image/x-quicktime',
227 | 'ram' => 'audio/x-pn-realaudio',
228 | 'rdf' => 'application/rdf+xml',
229 | 'rm' => 'application/vnd.rn-realmedia',
230 | 'roff' => 'application/x-troff',
231 | 'sgm' => 'text/sgml',
232 | 'sgml' => 'text/sgml',
233 | 'silo' => 'model/mesh',
234 | 'skd' => 'application/x-koan',
235 | 'skm' => 'application/x-koan',
236 | 'skp' => 'application/x-koan',
237 | 'skt' => 'application/x-koan',
238 | 'smi' => 'application/smil',
239 | 'smil' => 'application/smil',
240 | 'snd' => 'audio/basic',
241 | 'so' => 'application/octet-stream',
242 | 'svg' => 'image/svg+xml',
243 | 't' => 'application/x-troff',
244 | 'texi' => 'application/x-texinfo',
245 | 'texinfo' => 'application/x-texinfo',
246 | 'tif' => 'image/tiff',
247 | 'tiff' => 'image/tiff',
248 | 'tr' => 'application/x-troff',
249 | 'txt' => 'text/plain',
250 | 'vrml' => 'model/vrml',
251 | 'vxml' => 'application/voicexml+xml',
252 | 'webm' => 'video/webm',
253 | 'webp' => 'image/webp',
254 | 'wrl' => 'model/vrml',
255 | 'xht' => 'application/xhtml+xml',
256 | 'xhtml' => 'application/xhtml+xml',
257 | 'xml' => 'application/xml',
258 | 'xsl' => 'application/xml',
259 | 'xslt' => 'application/xslt+xml',
260 | 'xul' => 'application/vnd.mozilla.xul+xml',
261 | );
262 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Core/NosException.php:
--------------------------------------------------------------------------------
1 | details = $details;
24 | } else {
25 | $message = $details;
26 | parent::__construct($message);
27 | }
28 | }
29 |
30 | public function getHTTPStatus()
31 | {
32 | return isset($this->details['status']) ? $this->details['status'] : '';
33 | }
34 |
35 | public function getRequestId()
36 | {
37 | return isset($this->details['request-id']) ? $this->details['request-id'] : '';
38 | }
39 |
40 | public function getErrorCode()
41 | {
42 | return isset($this->details['code']) ? $this->details['code'] : '';
43 | }
44 |
45 | public function getErrorMessage()
46 | {
47 | return isset($this->details['message']) ? $this->details['message'] : '';
48 | }
49 |
50 | public function getDetails()
51 | {
52 | return isset($this->details['body']) ? $this->details['body'] : '';
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Core/NosUtil.php:
--------------------------------------------------------------------------------
1 | $value) {
37 | if (is_string($key) && ! is_array($value)) {
38 | $temp[] = rawurlencode($key) . '=' . rawurlencode($value);
39 | }
40 | }
41 | return implode('&', $temp);
42 | }
43 |
44 | /**
45 | * 转义字符替换
46 | *
47 | * @param string $subject
48 | * @return string
49 | */
50 | public static function sReplace($subject)
51 | {
52 | $search = array('&','<','>','\'','"');
53 | $replace = array('&','<','>',''','"');
54 | return str_replace($search, $replace, $subject);
55 | }
56 |
57 | /**
58 | * 检查是否是中文编码
59 | *
60 | * @param
61 | * $str
62 | * @return int
63 | */
64 | public static function chkChinese($str)
65 | {
66 | return preg_match('/[\x80-\xff]./', $str);
67 | }
68 |
69 | /**
70 | * 检测是否GB2312编码
71 | *
72 | * @param string $str
73 | * @return boolean false UTF-8编码 TRUE GB2312编码
74 | */
75 | public static function isGb2312($str)
76 | {
77 | for ($i = 0; $i < strlen($str); $i ++) {
78 | $v = ord($str[$i]);
79 | if ($v > 127) {
80 | if (($v >= 228) && ($v <= 233)) {
81 | if (($i + 2) >= (strlen($str) - 1))
82 | return true; // not enough characters
83 | $v1 = ord($str[$i + 1]);
84 | $v2 = ord($str[$i + 2]);
85 | if (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191))
86 | return false;
87 | else
88 | return true;
89 | }
90 | }
91 | }
92 | return false;
93 | }
94 |
95 | /**
96 | * 检测是否GBK编码
97 | *
98 | * @param string $str
99 | * @param boolean $gbk
100 | * @return boolean
101 | */
102 | public static function checkChar($str, $gbk = true)
103 | {
104 | for ($i = 0; $i < strlen($str); $i ++) {
105 | $v = ord($str[$i]);
106 | if ($v > 127) {
107 | if (($v >= 228) && ($v <= 233)) {
108 | if (($i + 2) >= (strlen($str) - 1))
109 | return $gbk ? true : FALSE; // not enough characters
110 | $v1 = ord($str[$i + 1]);
111 | $v2 = ord($str[$i + 2]);
112 | if ($gbk) {
113 | return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? FALSE : TRUE; // GBK
114 | } else {
115 | return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? TRUE : FALSE;
116 | }
117 | }
118 | }
119 | }
120 | return $gbk ? TRUE : FALSE;
121 | }
122 |
123 | /**
124 | * 检验bucket名称是否合法
125 | * bucket的命名规范:
126 | * 1.
127 | * 只能包括小写字母,数字,-,.
128 | * 2. 必须以小写字母或者数字开头
129 | * 3. 长度必须在3-63字节之间
130 | *
131 | * @param string $bucket Bucket名称
132 | * @return boolean
133 | */
134 | public static function validateBucket($bucket)
135 | {
136 | $pattern = '/^[a-z0-9][a-z0-9-\.]{2,62}$/';
137 | if (! preg_match($pattern, $bucket)) {
138 | return false;
139 | }
140 | return true;
141 | }
142 |
143 | /**
144 | * 检验object名称是否合法
145 | * object命名规范:
146 | * 1.
147 | * 规则长度必须在1-1000字节之间
148 | * 2. 使用UTF-8编码
149 | *
150 | * @param string $object
151 | * Object名称
152 | * @return boolean
153 | */
154 | public static function validateObject($object)
155 | {
156 | $pattern = '/^.{1,1000}$/';
157 | if (empty($object) || ! preg_match($pattern, $object) || self::startsWith($object, '/') || self::startsWith($object, '\\')) {
158 | return false;
159 | }
160 | return true;
161 | }
162 |
163 | /**
164 | * 判断字符串$str是不是以$findMe开始
165 | *
166 | * @param string $str
167 | * @param string $findMe
168 | * @return bool
169 | */
170 | public static function startsWith($str, $findMe)
171 | {
172 | if (strpos($str, $findMe) === 0) {
173 | return true;
174 | } else {
175 | return false;
176 | }
177 | }
178 |
179 | /**
180 | * 检验$options
181 | *
182 | * @param array $options
183 | * @throws NOSException
184 | * @return boolean
185 | */
186 | public static function validateOptions($options)
187 | {
188 | // $options
189 | if ($options != NULL && ! is_array($options)) {
190 | throw new NosException($options . ':' . 'option must be array');
191 | }
192 | }
193 |
194 | /**
195 | * 检查上传文件的内容是否合法
196 | *
197 | * @param $content string
198 | * @throws NOSException
199 | */
200 | public static function validateContent($content)
201 | {
202 | if (empty($content)) {
203 | throw new NosException("http body content is invalid");
204 | }
205 | }
206 |
207 | /**
208 | * 校验BUCKET/OBJECT/OBJECT GROUP是否为空
209 | *
210 | * @param string $name
211 | * @param string $errMsg
212 | * @throws NOSException
213 | * @return void
214 | */
215 | public static function throwNOSExceptionWithMessageIfEmpty($name, $errMsg)
216 | {
217 | if (empty($name)) {
218 | throw new NosException($errMsg);
219 | }
220 | }
221 |
222 | /**
223 | * 仅供测试使用的接口,请勿使用
224 | *
225 | * @param
226 | * $filename
227 | * @param
228 | * $size
229 | */
230 | public static function generateFile($filename, $size)
231 | {
232 | if (file_exists($filename) && $size == filesize($filename)) {
233 | echo $filename . " already exists, no need to create again. ";
234 | return;
235 | }
236 | $part_size = 1 * 1024 * 1024;
237 | $fp = fopen($filename, "w");
238 | $characters = << 0) {
245 | if ($size < $part_size) {
246 | $write_size = $size;
247 | } else {
248 | $write_size = $part_size;
249 | }
250 | $size -= $write_size;
251 | $a = $characters[rand(0, $charactersLength - 1)];
252 | $content = str_repeat($a, $write_size);
253 | $flag = fwrite($fp, $content);
254 | if (! $flag) {
255 | echo "write to " . $filename . " failed.
";
256 | break;
257 | }
258 | }
259 | } else {
260 | echo "open " . $filename . " failed.
";
261 | }
262 | fclose($fp);
263 | }
264 |
265 | /**
266 | * 得到文件的md5编码
267 | *
268 | * @param
269 | * $filename
270 | * @param
271 | * $from_pos
272 | * @param
273 | * $to_pos
274 | * @return string
275 | */
276 | public static function getMd5SumForFile($filename, $from_pos, $to_pos)
277 | {
278 | $content_md5 = "";
279 | if (($to_pos - $from_pos) > self::NOS_MAX_PART_SIZE) {
280 | return $content_md5;
281 | }
282 | $filesize = filesize($filename);
283 | if ($from_pos >= $filesize || $to_pos >= $filesize || $from_pos < 0 || $to_pos < 0) {
284 | return $content_md5;
285 | }
286 |
287 | $total_length = $to_pos - $from_pos + 1;
288 | $buffer = 8192;
289 | $left_length = $total_length;
290 | if (! file_exists($filename)) {
291 | return $content_md5;
292 | }
293 |
294 | if (false === $fh = fopen($filename, 'rb')) {
295 | return $content_md5;
296 | }
297 |
298 | fseek($fh, $from_pos);
299 | $data = '';
300 | while (! feof($fh)) {
301 | if ($left_length >= $buffer) {
302 | $read_length = $buffer;
303 | } else {
304 | $read_length = $left_length;
305 | }
306 | if ($read_length <= 0) {
307 | break;
308 | } else {
309 | $data .= fread($fh, $read_length);
310 | $left_length = $left_length - $read_length;
311 | }
312 | }
313 | fclose($fh);
314 | $content_md5 = md5($data);
315 | return $content_md5;
316 | }
317 |
318 | /**
319 | * 检测是否windows系统,因为windows系统默认编码为GBK
320 | *
321 | * @return bool
322 | */
323 | public static function isWin()
324 | {
325 | return strtoupper(substr(PHP_OS, 0, 3)) == "WIN";
326 | }
327 |
328 | /**
329 | * 主要是由于windows系统编码是gbk,遇到中文时候,如果不进行转换处理会出现找不到文件的问题
330 | *
331 | * @param
332 | * $file_path
333 | * @return string
334 | */
335 | public static function encodePath($file_path)
336 | {
337 | if (self::chkChinese($file_path) && self::isWin()) {
338 | $file_path = iconv('utf-8', 'gbk', $file_path);
339 | }
340 | return $file_path;
341 | }
342 |
343 | /**
344 | * 判断用户输入的endpoint是否是 xxx.xxx.xxx.xxx:port 或者 xxx.xxx.xxx.xxx的ip格式
345 | *
346 | * @param string $endpoint
347 | * 需要做判断的endpoint
348 | * @return boolean
349 | */
350 | public static function isIPFormat($endpoint)
351 | {
352 | $ip_array = explode(":", $endpoint);
353 | $hostname = $ip_array[0];
354 | $ret = filter_var($hostname, FILTER_VALIDATE_IP);
355 | if (! $ret) {
356 | return false;
357 | } else {
358 | return true;
359 | }
360 | }
361 |
362 | public static function createPutBucketDuplicationXmlBody($duplication)
363 | {
364 | $xml = new \SimpleXMLElement('');
365 | $xml->addChild('Status', $duplication);
366 | return trim($xml->asXML());
367 | }
368 |
369 | public static function createPutBucketVersingXmlBody($versing)
370 | {
371 | $xml = new \SimpleXMLElement('');
372 | $xml->addChild('Status', $versing);
373 | return trim($xml->asXML());
374 | }
375 |
376 | /**
377 | *
378 | * @param unknown $key
379 | */
380 | public static function creatPutBucketDefault404XmlBody($key)
381 | {
382 | $xml = new \SimpleXMLElement('');
383 | $xml->addChild('Key', $key);
384 | return trim($xml->asXML());
385 | }
386 |
387 | /**
388 | * 生成DeleteMultiObjects接口的xml消息
389 | *
390 | * @param string[] $objects
391 | * @param bool $quiet
392 | * @return string
393 | */
394 | public static function createDeleteObjectsXmlBody($objects,$quite)
395 | {
396 | $xml = new \SimpleXMLElement('');
397 | $xml->addChild('Quiet', $quite);
398 | foreach ($objects as $object) {
399 | $sub_object = $xml->addChild('Object');
400 | $object = NosUtil::sReplace($object);
401 | $sub_object->addChild('Key', $object);
402 | }
403 | return trim($xml->asXML());
404 | }
405 |
406 | /**
407 | * 生成CompleteMultipartUpload接口的xml消息
408 | *
409 | * @param array[] $listParts
410 | * @return string
411 | */
412 | public static function createCompleteMultipartUploadXmlBody($listParts)
413 | {
414 | $xml = new \SimpleXMLElement('');
415 | foreach ($listParts as $node) {
416 | $part = $xml->addChild('Part');
417 | $part->addChild('PartNumber', $node['PartNumber']);
418 | $part->addChild('ETag', $node['ETag']);
419 | }
420 | return trim($xml->asXML());
421 | }
422 |
423 | /**
424 | * 读取目录
425 | *
426 | * @param string $dir
427 | * @param string $exclude
428 | * @param bool $recursive
429 | * @return string[]
430 | */
431 | public static function readDir($dir, $exclude = ".|..|.svn|.git", $recursive = false)
432 | {
433 | $file_list_array = array();
434 | $base_path = $dir;
435 | $exclude_array = explode("|", $exclude);
436 | $exclude_array = array_unique(array_merge($exclude_array, array(
437 | '.',
438 | '..'
439 | )));
440 |
441 | if ($recursive) {
442 | foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)) as $new_file) {
443 | if ($new_file->isDir())
444 | continue;
445 | $object = str_replace($base_path, '', $new_file);
446 | if (! in_array(strtolower($object), $exclude_array)) {
447 | $object = ltrim($object, '/');
448 | if (is_file($new_file)) {
449 | $key = md5($new_file . $object, false);
450 | $file_list_array[$key] = array(
451 | 'path' => $new_file,
452 | 'file' => $object
453 | );
454 | }
455 | }
456 | }
457 | } else
458 | if ($handle = opendir($dir)) {
459 | while (false !== ($file = readdir($handle))) {
460 | if (! in_array(strtolower($file), $exclude_array)) {
461 | $new_file = $dir . '/' . $file;
462 | $object = $file;
463 | $object = ltrim($object, '/');
464 | if (is_file($new_file)) {
465 | $key = md5($new_file . $object, false);
466 | $file_list_array[$key] = array(
467 | 'path' => $new_file,
468 | 'file' => $object
469 | );
470 | }
471 | }
472 | }
473 | closedir($handle);
474 | }
475 | return $file_list_array;
476 | }
477 |
478 | /**
479 | *
480 | * @param unknown $object
481 | * @return mixed
482 | */
483 | public static function objectEncode($object)
484 | {
485 | return str_replace(array("+","%2A"),array("%20","*"), urlencode($object));
486 | }
487 | }
488 |
489 |
490 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Http/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2006-2010 Ryan Parman, Foleeo Inc., and contributors. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without modification, are
4 | permitted provided that the following conditions are met:
5 |
6 | * Redistributions of source code must retain the above copyright notice, this list of
7 | conditions and the following disclaimer.
8 |
9 | * Redistributions in binary form must reproduce the above copyright notice, this list
10 | of conditions and the following disclaimer in the documentation and/or other materials
11 | provided with the distribution.
12 |
13 | * Neither the name of Ryan Parman, Foleeo Inc. nor the names of its contributors may be used to
14 | endorse or promote products derived from this software without specific prior written
15 | permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
18 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
20 | AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 | POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Http/RequestCore_Exception.php:
--------------------------------------------------------------------------------
1 | ).
29 | * @param string $body (Required) XML-formatted response from AWS.
30 | * @param integer $status (Optional) HTTP response status code from the request.
31 | * @return Mixed Contains an `header` property (HTTP headers as an associative array), a or `body` property, and an `status` code.
32 | */
33 | public function __construct($header, $body, $status = null)
34 | {
35 | $this->header = $header;
36 | $this->body = $body;
37 | $this->status = $status;
38 |
39 | return $this;
40 | }
41 |
42 | /**
43 | * Did we receive the status code we expected?
44 | *
45 | * @param integer|array $codes (Optional) The status code(s) to expect. Pass an for a single acceptable value, or an of integers for multiple acceptable values.
46 | * @return boolean Whether we received the expected status code or not.
47 | */
48 | public function isOK($codes = array(200, 201, 204, 206))
49 | {
50 | if (is_array($codes)) {
51 | return in_array($this->status, $codes);
52 | }
53 |
54 | return $this->status === $codes;
55 | }
56 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/BucketInfo.php:
--------------------------------------------------------------------------------
1 | name = $name;
23 | $this->createDate = $createDate;
24 | }
25 |
26 | /**
27 | * 得到bucket的名称
28 | *
29 | * @return string
30 | */
31 | public function getName()
32 | {
33 | return $this->name;
34 | }
35 |
36 | /**
37 | * 得到bucket的创建时间
38 | *
39 | * @return string
40 | */
41 | public function getCreateDate()
42 | {
43 | return $this->createDate;
44 | }
45 |
46 | /**
47 | * bucket的名称
48 | *
49 | * @var string
50 | */
51 | private $name;
52 |
53 | /**
54 | * bucket的创建事件
55 | *
56 | * @var string
57 | */
58 | private $createDate;
59 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/BucketListInfo.php:
--------------------------------------------------------------------------------
1 | bucketList = $bucketList;
21 | }
22 |
23 | /**
24 | * 得到BucketInfo列表
25 | *
26 | * @return BucketInfo[]
27 | */
28 | public function getBucketList()
29 | {
30 | return $this->bucketList;
31 | }
32 |
33 | /**
34 | * BucketInfo信息列表
35 | *
36 | * @var array
37 | */
38 | private $bucketList = array();
39 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/DeleteFailedInfo.php:
--------------------------------------------------------------------------------
1 | key = $key;
9 | $this->code = $code;
10 | $this->message = $message;
11 | }
12 |
13 | /**
14 | * @return the $key
15 | */
16 | public function getKey()
17 | {
18 | return $this->key;
19 | }
20 |
21 | /**
22 | * @return the $code
23 | */
24 | public function getCode()
25 | {
26 | return $this->code;
27 | }
28 |
29 | /**
30 | * @return the $message
31 | */
32 | public function getMessage()
33 | {
34 | return $this->message;
35 | }
36 |
37 | /**
38 | * @param string $key
39 | */
40 | public function setKey($key)
41 | {
42 | $this->key = $key;
43 | }
44 |
45 | /**
46 | * @param string $code
47 | */
48 | public function setCode($code)
49 | {
50 | $this->code = $code;
51 | }
52 |
53 | /**
54 | * @param string $message
55 | */
56 | public function setMessage($message)
57 | {
58 | $this->message = $message;
59 | }
60 |
61 |
62 | private $key = '';
63 | private $code = '';
64 | private $message = '';
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/ListMultipartUploadInfo.php:
--------------------------------------------------------------------------------
1 | bucket = $bucket;
10 | $this->nextKeyMarker = $nextKeyMarker;
11 | $this->uploads = $uploads;
12 | $this->isTruncated = $isTruncated;
13 | }
14 |
15 | /**
16 | * @return the $bucket
17 | */
18 | public function getBucket()
19 | {
20 | return $this->bucket;
21 | }
22 |
23 | /**
24 | * @return the $isTruncted
25 | */
26 | public function getIsTruncated()
27 | {
28 | return $this->isTruncated;
29 | }
30 |
31 | /**
32 | * @return the $nextKeyMarker
33 | */
34 | public function getNextKeyMarker()
35 | {
36 | return $this->nextKeyMarker;
37 | }
38 |
39 | /**
40 | * @return the $uploads
41 | */
42 | public function getUploads()
43 | {
44 | return $this->uploads;
45 | }
46 |
47 | private $bucket = '';
48 | private $nextKeyMarker = '';
49 | private $isTruncated = '';
50 | private $uploads = array();
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/ListPartsInfo.php:
--------------------------------------------------------------------------------
1 | bucket = $bucket;
10 | $this->key = $key;
11 | $this->uploadId = $uploadId;
12 | $this->storageClass = $storageClass;
13 | $this->partNumberMarker = $partNumberMarker;
14 | $this->nextPartNumberMarker = $nextPartNumberMarker;
15 | $this->maxParts = $maxParts;
16 | $this->isTruncated = $isTruncated;
17 | $this->listPart = $listPart;
18 | }
19 |
20 | /**
21 | * @return the $bucket
22 | */
23 | public function getBucket()
24 | {
25 | return $this->bucket;
26 | }
27 |
28 | /**
29 | * @return the $key
30 | */
31 | public function getKey()
32 | {
33 | return $this->key;
34 | }
35 |
36 | /**
37 | * @return the $uploadId
38 | */
39 | public function getUploadId()
40 | {
41 | return $this->uploadId;
42 | }
43 |
44 | /**
45 | * @return the $storageClass
46 | */
47 | public function getStorageClass()
48 | {
49 | return $this->storageClass;
50 | }
51 |
52 | /**
53 | * @return the $partNumberMarker
54 | */
55 | public function getPartNumberMarker()
56 | {
57 | return $this->partNumberMarker;
58 | }
59 |
60 | /**
61 | * @return the $nextPartNumberMarker
62 | */
63 | public function getNextPartNumberMarker()
64 | {
65 | return $this->nextPartNumberMarker;
66 | }
67 |
68 | /**
69 | * @return the $maxParts
70 | */
71 | public function getMaxParts()
72 | {
73 | return $this->maxParts;
74 | }
75 |
76 | /**
77 | * @return the $isTruncated
78 | */
79 | public function getIsTruncated()
80 | {
81 | return $this->isTruncated;
82 | }
83 |
84 | /**
85 | * @return the $listPart
86 | */
87 | public function getListPart()
88 | {
89 | return $this->listPart;
90 | }
91 |
92 |
93 | private $bucket = '';
94 | private $key = '';
95 | private $uploadId = '';
96 | private $storageClass = '';
97 | private $partNumberMarker = 0;
98 | private $nextPartNumberMarker = 0;
99 | private $maxParts = 0;
100 | private $isTruncated = NULL;
101 | private $listPart =array();
102 | }
103 |
104 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/ObjectInfo.php:
--------------------------------------------------------------------------------
1 | key = $key;
32 | $this->lastModified = $lastModified;
33 | $this->eTag = $eTag;
34 | $this->size = $size;
35 | $this->storageClass = $storageClass;
36 | }
37 |
38 | /**
39 | * @return string
40 | */
41 | public function getKey()
42 | {
43 | return $this->key;
44 | }
45 |
46 | /**
47 | * @return string
48 | */
49 | public function getLastModified()
50 | {
51 | return $this->lastModified;
52 | }
53 |
54 | /**
55 | * @return string
56 | */
57 | public function getETag()
58 | {
59 | return $this->eTag;
60 | }
61 |
62 | /**
63 | * @return int
64 | */
65 | public function getSize()
66 | {
67 | return $this->size;
68 | }
69 |
70 | /**
71 | * @return string
72 | */
73 | public function getStorageClass()
74 | {
75 | return $this->storageClass;
76 | }
77 |
78 | private $key = "";
79 | private $lastModified = "";
80 | private $eTag = "";
81 | private $size = 0;
82 | private $storageClass = "";
83 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/ObjectListInfo.php:
--------------------------------------------------------------------------------
1 | bucketName = $bucketName;
30 | $this->prefix = $prefix;
31 | $this->marker = $marker;
32 | $this->nextMarker = $nextMarker;
33 | $this->maxKeys = $maxKeys;
34 | $this->isTruncated = $isTruncated;
35 | $this->objectList = $objectList;
36 | $this->commonPrefixes = $commonPrefixes;
37 | }
38 |
39 | /**
40 | * @return the $commonPrefixes
41 | */
42 | public function getCommonPrefixes()
43 | {
44 | return $this->commonPrefixes;
45 | }
46 |
47 | /**
48 | * @param Ambigous $commonPrefixes
49 | */
50 | public function setCommonPrefixes($commonPrefixes)
51 | {
52 | $this->commonPrefixes = $commonPrefixes;
53 | }
54 |
55 | /**
56 | * @return string
57 | */
58 | public function getBucketName()
59 | {
60 | return $this->bucketName;
61 | }
62 |
63 | /**
64 | * @return string
65 | */
66 | public function getPrefix()
67 | {
68 | return $this->prefix;
69 | }
70 |
71 | /**
72 | * @return string
73 | */
74 | public function getMarker()
75 | {
76 | return $this->marker;
77 | }
78 |
79 | /**
80 | * @return int
81 | */
82 | public function getMaxKeys()
83 | {
84 | return $this->maxKeys;
85 | }
86 |
87 |
88 | /**
89 | * @return mixed
90 | */
91 | public function getIsTruncated()
92 | {
93 | return $this->isTruncated;
94 | }
95 |
96 | /**
97 | * 返回ListObjects接口返回数据中的ObjectInfo列表
98 | *
99 | * @return ObjectInfo[]
100 | */
101 | public function getObjectList()
102 | {
103 | return $this->objectList;
104 | }
105 |
106 | /**
107 | * @return string
108 | */
109 | public function getNextMarker()
110 | {
111 | return $this->nextMarker;
112 | }
113 |
114 | private $bucketName = '';
115 | private $prefix = '';
116 | private $marker = '';
117 | private $nextMarker = '';
118 | private $maxKeys = 0;
119 | private $isTruncated = null;
120 | private $objectList = array();
121 | private $commonPrefixes = '';
122 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/PartInfo.php:
--------------------------------------------------------------------------------
1 | partNumber = $partNumber;
10 | $this->lastModified = $lastModified;
11 | $this->eTag = $eTag;
12 | $this->size = $size;
13 | }
14 |
15 | /**
16 | * @return the $partNumber
17 | */
18 | public function getPartNumber()
19 | {
20 | return $this->partNumber;
21 | }
22 |
23 | /**
24 | * @return the $lastModified
25 | */
26 | public function getLastModified()
27 | {
28 | return $this->lastModified;
29 | }
30 |
31 | /**
32 | * @return the $eTag
33 | */
34 | public function getETag()
35 | {
36 | return $this->eTag;
37 | }
38 |
39 | /**
40 | * @return the $size
41 | */
42 | public function getSize()
43 | {
44 | return $this->size;
45 | }
46 |
47 | private $partNumber = 0;
48 | private $lastModified ='';
49 | private $eTag = '';
50 | private $size = 0;
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/UploadInfo.php:
--------------------------------------------------------------------------------
1 | key = $key;
10 | $this->uploadId = $uploadId;
11 | $this->storageClass = $storageClass;
12 | }
13 |
14 | /**
15 | * @return the $bucket
16 | */
17 | public function getKey()
18 | {
19 | return $this->key;
20 | }
21 |
22 | /**
23 | * @return the $uploadId
24 | */
25 | public function getUploadId()
26 | {
27 | return $this->uploadId;
28 | }
29 |
30 | /**
31 | * @return the $storageClass
32 | */
33 | public function getStorageClass()
34 | {
35 | return $this->storageClass;
36 | }
37 |
38 |
39 | private $key = '';
40 | private $uploadId = '';
41 | private $storageClass ='';
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Model/XmlConfig.php:
--------------------------------------------------------------------------------
1 | rawResponse->body) ? "" : $this->rawResponse->body;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/ExistResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->status) === 200 ? true : false;
18 | }
19 |
20 | /**
21 | * 根据返回http状态码判断,[200-299]即认为是OK, 判断是否存在的接口,404也认为是一种
22 | * 有效响应
23 | *
24 | * @return bool
25 | */
26 | protected function isResponseOk()
27 | {
28 | $status = $this->rawResponse->status;
29 | if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) {
30 | return true;
31 | }
32 | return false;
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/GetLocationResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
12 | if (!isset($content) || empty($content)) {
13 | throw new NosException("invalid response,empty response body");
14 | }
15 | try {
16 | $xml = simplexml_load_string($content);
17 | } catch (\Exception $e) {
18 | throw new NosException("invalid response,response body is invalid xml");
19 | }
20 | $location = strval($xml['0']);
21 | if ($xml->count() != 0) {
22 | throw new NosException("invalid response,child found,xml format exception");
23 | }
24 | return $location;
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/GetObjectMetaResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->header;
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/InitiateMultipartUploadResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
12 | if (! isset($content) || empty($content)) {
13 | throw new NosException("invalid response,empty response body");
14 | }
15 | try {
16 | $xml = simplexml_load_string($content);
17 | } catch (\Exception $e) {
18 | throw new NosException("invalid response,response body is invalid xml");
19 | }
20 | if (isset($xml->UploadId)) {
21 | return strval($xml->UploadId);
22 | }
23 | throw new NosException("invalid response,no UploadId found,xml format exception");
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/ListBucketsResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
24 | if (! isset($content) || empty($content)) {
25 | throw new NosException("invalid response,empty response body");
26 | }
27 | try {
28 | $xml = new \SimpleXMLElement($content);
29 | } catch (\Exception $e) {
30 | throw new NosException("invalid response,response body is invalid xml");
31 | }
32 | if (isset($xml->Buckets) && isset($xml->Buckets->Bucket)) {
33 | foreach ($xml->Buckets->Bucket as $bucket) {
34 | $bucketInfo = new BucketInfo(strval($bucket->Name), strval($bucket->CreationDate));
35 | $bucketList[] = $bucketInfo;
36 | }
37 | }
38 | return new BucketListInfo($bucketList);
39 | }
40 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/ListMultipartUploadResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
14 | if (! isset($content) || empty($content)) {
15 | throw new NosException("invalid response,empty response body");
16 | }
17 | try {
18 | $xml = simplexml_load_string($content);
19 | } catch (\Exception $e) {
20 | throw new NosException("invalid response,response body is invalid xml");
21 | }
22 |
23 | $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : "";
24 | $nextKeyMarker = isset($xml->NextKeyMarker) ? strval($xml->NextKeyMarker) : "";
25 | $isTruncated = isset($xml->IsTruncated)? strval($xml->IsTruncated):'';
26 | $listUpload = array();
27 |
28 | if (isset($xml->Upload)) {
29 | foreach ($xml->Upload as $upload) {
30 | $key = isset($upload->Key) ? strval($upload->Key) : "";
31 | $uploadId = isset($upload->UploadId) ? strval($upload->UploadId) : "";
32 | $storageClass = isset($upload->StorageClass) ? strval($upload->StorageClass) : "";
33 | $listUpload[] = new UploadInfo($key, $uploadId, $storageClass);
34 | }
35 | }
36 | return new ListMultipartUploadInfo($bucket, $nextKeyMarker,$isTruncated, $listUpload);
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/ListObjectsResult.php:
--------------------------------------------------------------------------------
1 | Contents)) {
20 | foreach ($xml->Contents as $content) {
21 | $key = isset($content->Key) ? strval($content->Key) : '';
22 | $lastModified = isset($content->LastModified) ? strval($content->LastModified) : '';
23 | $eTag = isset($content->ETag) ? strval($content->ETag) : '';
24 | $size = isset($content->Size) ? intval($content->Size) : 0;
25 | $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : "";
26 | $objectList[] = new ObjectInfo($key, $lastModified, $eTag, $size, $storageClass);
27 | }
28 | }
29 | return $objectList;
30 | }
31 |
32 | /**
33 | * 解析ListObjects接口返回的xml数据
34 | *
35 | * return ObjectListInfo
36 | */
37 | protected function parseDataFromResponse()
38 | {
39 | $content = $this->rawResponse->body;
40 | if(!isset($content) || empty($content))
41 | {
42 | throw new NosException("invalid response,empty response body");
43 | }
44 | try {
45 | $xml = new \SimpleXMLElement($this->rawResponse->body);
46 | } catch (\Exception $e) {
47 | throw new NosException("invalid response,response body invalid xml");
48 | }
49 | $bucketName = isset($xml->Name) ? strval($xml->Name) : '';
50 | $prfix = isset($xml->Prefix) ? strval($xml->Prefix) : '';
51 | $maxKeys = isset($xml->MaxKeys) ? intval($xml->MaxKeys) : '';
52 | $marker = isset($xml->Marker) ? strval($xml->Marker) : '';
53 | $nextMarker = isset($xml->NextMarker) ? strval($xml->NextMarker) : '';
54 | $isTruncatedStr = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : '';
55 | $isTruncated = $isTruncatedStr === "true" ? true : false;
56 | $commonPrefixes = isset($xml->CommonPrefixes) ? strval($xml->CommonPrefixes->Prefix) : '';
57 | $objectList = $this->parseObjectList($xml);
58 | return new ObjectListInfo($bucketName, $prfix, $commonPrefixes, $marker, $nextMarker, $maxKeys, $isTruncated, $objectList);
59 | }
60 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/ListPartsResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
14 | if (! isset($content) || empty($content)) {
15 | throw new NosException("invalid response,empty response body");
16 | }
17 | try {
18 | $xml = simplexml_load_string($content);
19 | } catch (\Exception $e) {
20 | throw new NosException("invalid response,response body invalid xml");
21 | }
22 | $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : '';
23 | $key = isset($xml->Key) ? strval($xml->Key) : '';
24 | $uploadId = isset($xml->UploadId) ? strval($xml->UploadId) : '';
25 | $storageClass = isset($xml->StorageClass) ? strval($xml->StorageClass) : '';
26 | $partNumberMarker = isset($xml->PartNumberMarker) ? intval($xml->PartNumberMarker) : '';
27 | $nextPartNumberMarker = isset($xml->NextPartNumberMarker) ? intval($xml->NextPartNumberMarker) : '';
28 | $maxParts = isset($xml->MaxParts) ? intval($xml->MaxParts) : '';
29 | $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : '';
30 | $partList = array();
31 | if (isset($xml->Part)) {
32 | foreach ($xml->Part as $part) {
33 | $partNumber = isset($part->PartNumber) ? intval($part->PartNumber) : '';
34 | $lastModified = isset($part->LastModified) ? strval($part->LastModified) : '';
35 | $eTag = isset($part->ETag) ? strval($part->ETag) : '';
36 | $size = isset($part->Size) ? intval($part->Size) : '';
37 | $partList[] = new PartInfo($partNumber, $lastModified, $eTag, $size);
38 | }
39 | }
40 | return new ListPartsInfo($bucket, $key, $uploadId, $storageClass, $partNumberMarker, $nextPartNumberMarker, $maxParts, $isTruncated, $partList);
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/MultiDeleteResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
13 | if (! isset($content) || empty($content)) {
14 | throw new NosException("invalid response,empty response body");
15 | }
16 | try {
17 | $xml = simplexml_load_string($content);
18 | } catch (\Exception $e) {
19 | throw new NosException("invalid response,response body invalid xml");
20 | }
21 | if(!isset($xml->Error) && !isset($xml->Deleted)){
22 | return null;
23 | }
24 | $succ = array();
25 | foreach ($xml->Deleted as $deleted){
26 | $succ[] = strval($deleted->Key);
27 | }
28 | $fails = array();
29 | foreach ($xml->Error as $err){
30 | $failInfo = new DeleteFailedInfo(strval($err->Key),strval($err->Code),strval($err->Message));
31 | $fails[] = $failInfo;
32 | }
33 | $result = array();
34 | if(count($succ)){
35 | $result['succeed'] = $succ;
36 | }
37 | if(count($fails)){
38 | $result['failed'] = $fails;
39 | }
40 | return $result;
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/ObjDeduplicateResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
11 | if(!isset($content) || empty($content))
12 | {
13 | throw new NosException("invalid response,empty rsoponse body");
14 | }
15 | try {
16 | $xml = simplexml_load_string($content);
17 | }catch(\Exception $e)
18 | {
19 | throw new NosException("invalid response,rsoponse body is invalid xml");
20 | }
21 | if(isset($xml->ObjectContentAlreadyExist))
22 | {
23 | return strval($xml->ObjectContentAlreadyExist);
24 | }
25 | throw new NosException("invalid response,no ObjectContentAlreadyExist found,xml format exception");
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/PutSetDeleteResult.php:
--------------------------------------------------------------------------------
1 | rawResponse = $response;
28 | $this->parseResponse();
29 | }
30 |
31 | /**
32 | * 获取requestId
33 | *
34 | * @return string
35 | */
36 | public function getRequestId()
37 | {
38 | if (isset($this->rawResponse) &&
39 | isset($this->rawResponse->header) &&
40 | isset($this->rawResponse->header['x-nos-request-id'])
41 | ) {
42 | return $this->rawResponse->header['x-nos-request-id'];
43 | } else {
44 | return '';
45 | }
46 | }
47 |
48 | /**
49 | * 得到返回数据,不同的请求返回数据格式不同
50 | *
51 | * $return mixed
52 | */
53 | public function getData()
54 | {
55 | return $this->parsedData;
56 | }
57 |
58 | /**
59 | * 由子类实现,不同的请求返回数据有不同的解析逻辑,由子类实现
60 | *
61 | * @return mixed
62 | */
63 | abstract protected function parseDataFromResponse();
64 |
65 | /**
66 | * 操作是否成功
67 | *
68 | * @return mixed
69 | */
70 | public function isOK()
71 | {
72 | return $this->isOk;
73 | }
74 |
75 | /**
76 | * @throws NOSException
77 | */
78 | public function parseResponse()
79 | {
80 | $this->isOk = $this->isResponseOk();
81 | if ($this->isOk) {
82 | $this->parsedData = $this->parseDataFromResponse();
83 | } else {
84 | $httpStatus = strval($this->rawResponse->status);
85 | $requestId = strval($this->getRequestId());
86 | $code = $this->retrieveErrorCode($this->rawResponse->body);
87 | $message = $this->retrieveErrorMessage($this->rawResponse->body);
88 | $body = $this->rawResponse->body;
89 |
90 | $details = array(
91 | 'status' => $httpStatus,
92 | 'request-id' => $requestId,
93 | 'code' => $code,
94 | 'message' => $message,
95 | 'body' => $body
96 | );
97 | throw new NosException($details);
98 | }
99 | }
100 |
101 | /**
102 | * 尝试从body中获取错误Message
103 | *
104 | * @param $body
105 | * @return string
106 | */
107 | private function retrieveErrorMessage($body)
108 | {
109 | if (empty($body) || false === strpos($body, 'Message)) {
114 | return strval($xml->Message);
115 | }
116 | return '';
117 | }
118 |
119 | /**
120 | * 尝试从body中获取错误Code
121 | *
122 | * @param $body
123 | * @return string
124 | */
125 | private function retrieveErrorCode($body)
126 | {
127 | if (empty($body) || false === strpos($body, 'Code)) {
132 | return strval($xml->Code);
133 | }
134 | return '';
135 | }
136 |
137 | /**
138 | * 根据返回http状态码判断,[200-299]即认为是OK
139 | *
140 | * @return bool
141 | */
142 | protected function isResponseOk()
143 | {
144 | $status = $this->rawResponse->status;
145 | if ((int)(intval($status) / 100) == 2) {
146 | return true;
147 | }
148 | return false;
149 | }
150 |
151 | /**
152 | * 返回原始的返回数据
153 | *
154 | * @return ResponseCore
155 | */
156 | public function getRawResponse()
157 | {
158 | return $this->rawResponse;
159 | }
160 |
161 | /**
162 | * 标示请求是否成功
163 | */
164 | protected $isOk = false;
165 | /**
166 | * 由子类解析过的数据
167 | */
168 | protected $parsedData = null;
169 | /**
170 | * 存放auth函数返回的原始Response
171 | *
172 | * @var ResponseCore
173 | */
174 | protected $rawResponse;
175 | }
176 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/UploadPartResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->header;
10 | if (isset($header["etag"])) {
11 | return trim($header["etag"],"\"");
12 | }
13 | throw new NosException("cannot get ETag");
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/aclResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->header['x-nos-acl']))
16 | {
17 | $acl_type = strval($this->rawResponse->header['x-nos-acl']);
18 | return $acl_type;
19 | }
20 | else
21 | {
22 | throw new NosException("invalid response,no require head found");
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/cloud/nos/src/NOS/Result/statusResult.php:
--------------------------------------------------------------------------------
1 | rawResponse->body;
12 | if(empty($content))
13 | {
14 | throw new NosException("invalid response,,empty response body");
15 | }
16 | try {
17 | $xml = simplexml_load_string($content);
18 | }catch(\Exception $e)
19 | {
20 | throw new NosException("invalid response,,response body is invalid xml");
21 | }
22 | if(isset($xml->Status))
23 | {
24 | return strval($xml->Status);
25 | }
26 | else
27 | {
28 | throw new NosException("invalid response,no Status found,xml format exception");
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/cloud/qiniu/autoload.php:
--------------------------------------------------------------------------------
1 | accessKey = $accessKey;
14 | $this->secretKey = $secretKey;
15 | }
16 |
17 | public function getAccessKey()
18 | {
19 | return $this->accessKey;
20 | }
21 |
22 | public function sign($data)
23 | {
24 | $hmac = hash_hmac('sha1', $data, $this->secretKey, true);
25 | return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac);
26 | }
27 |
28 | public function signWithData($data)
29 | {
30 | $encodedData = \Qiniu\base64_urlSafeEncode($data);
31 | return $this->sign($encodedData) . ':' . $encodedData;
32 | }
33 |
34 | public function signRequest($urlString, $body, $contentType = null)
35 | {
36 | $url = parse_url($urlString);
37 | $data = '';
38 | if (array_key_exists('path', $url)) {
39 | $data = $url['path'];
40 | }
41 | if (array_key_exists('query', $url)) {
42 | $data .= '?' . $url['query'];
43 | }
44 | $data .= "\n";
45 |
46 | if ($body !== null && $contentType === 'application/x-www-form-urlencoded') {
47 | $data .= $body;
48 | }
49 | return $this->sign($data);
50 | }
51 |
52 | public function verifyCallback($contentType, $originAuthorization, $url, $body)
53 | {
54 | $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
55 | return $originAuthorization === $authorization;
56 | }
57 |
58 | public function privateDownloadUrl($baseUrl, $expires = 3600)
59 | {
60 | $deadline = time() + $expires;
61 |
62 | $pos = strpos($baseUrl, '?');
63 | if ($pos !== false) {
64 | $baseUrl .= '&e=';
65 | } else {
66 | $baseUrl .= '?e=';
67 | }
68 | $baseUrl .= $deadline;
69 |
70 | $token = $this->sign($baseUrl);
71 | return "$baseUrl&token=$token";
72 | }
73 |
74 | public function uploadToken($bucket, $key = null, $expires = 3600, $policy = null, $strictPolicy = true)
75 | {
76 | $deadline = time() + $expires;
77 | $scope = $bucket;
78 | if ($key !== null) {
79 | $scope .= ':' . $key;
80 | }
81 |
82 | $args = self::copyPolicy($args, $policy, $strictPolicy);
83 | $args['scope'] = $scope;
84 | $args['deadline'] = $deadline;
85 |
86 | $b = json_encode($args);
87 | return $this->signWithData($b);
88 | }
89 |
90 | /**
91 | *上传策略,参数规格详见
92 | *http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
93 | */
94 | private static $policyFields = array(
95 | 'callbackUrl',
96 | 'callbackBody',
97 | 'callbackHost',
98 | 'callbackBodyType',
99 | 'callbackFetchKey',
100 |
101 | 'returnUrl',
102 | 'returnBody',
103 |
104 | 'endUser',
105 | 'saveKey',
106 | 'insertOnly',
107 |
108 | 'detectMime',
109 | 'mimeLimit',
110 | 'fsizeMin',
111 | 'fsizeLimit',
112 |
113 | 'persistentOps',
114 | 'persistentNotifyUrl',
115 | 'persistentPipeline',
116 |
117 | 'deleteAfterDays',
118 | 'fileType',
119 | 'isPrefixalScope',
120 | );
121 |
122 | private static function copyPolicy(&$policy, $originPolicy, $strictPolicy)
123 | {
124 | if ($originPolicy === null) {
125 | return array();
126 | }
127 | foreach ($originPolicy as $key => $value) {
128 | if (!$strictPolicy || in_array((string)$key, self::$policyFields, true)) {
129 | $policy[$key] = $value;
130 | }
131 | }
132 | return $policy;
133 | }
134 |
135 | public function authorization($url, $body = null, $contentType = null)
136 | {
137 | $authorization = 'QBox ' . $this->signRequest($url, $body, $contentType);
138 | return array('Authorization' => $authorization);
139 | }
140 |
141 | public function authorizationV2($url, $method, $body = null, $contentType = null)
142 | {
143 | $urlItems = parse_url($url);
144 | $host = $urlItems['host'];
145 |
146 | if (isset($urlItems['port'])) {
147 | $port = $urlItems['port'];
148 | } else {
149 | $port = '';
150 | }
151 |
152 | $path = $urlItems['path'];
153 | if (isset($urlItems['query'])) {
154 | $query = $urlItems['query'];
155 | } else {
156 | $query = '';
157 | }
158 |
159 | //write request uri
160 | $toSignStr = $method . ' ' . $path;
161 | if (!empty($query)) {
162 | $toSignStr .= '?' . $query;
163 | }
164 |
165 | //write host and port
166 | $toSignStr .= "\nHost: " . $host;
167 | if (!empty($port)) {
168 | $toSignStr .= ":" . $port;
169 | }
170 |
171 | //write content type
172 | if (!empty($contentType)) {
173 | $toSignStr .= "\nContent-Type: " . $contentType;
174 | }
175 |
176 | $toSignStr .= "\n\n";
177 |
178 | //write body
179 | if (!empty($body)) {
180 | $toSignStr .= $body;
181 | }
182 |
183 | $sign = $this->sign($toSignStr);
184 | $auth = 'Qiniu ' . $sign;
185 | return array('Authorization' => $auth);
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Config.php:
--------------------------------------------------------------------------------
1 | zone = $z;
30 | $this->useHTTPS = false;
31 | $this->useCdnDomains = false;
32 | $this->zoneCache = array();
33 | }
34 |
35 | public function getUpHost($accessKey, $bucket)
36 | {
37 | $zone = $this->getZone($accessKey, $bucket);
38 | if ($this->useHTTPS === true) {
39 | $scheme = "https://";
40 | } else {
41 | $scheme = "http://";
42 | }
43 |
44 | $host = $zone->srcUpHosts[0];
45 | if ($this->useCdnDomains === true) {
46 | $host = $zone->cdnUpHosts[0];
47 | }
48 |
49 | return $scheme . $host;
50 | }
51 |
52 | public function getUpBackupHost($accessKey, $bucket)
53 | {
54 | $zone = $this->getZone($accessKey, $bucket);
55 | if ($this->useHTTPS === true) {
56 | $scheme = "https://";
57 | } else {
58 | $scheme = "http://";
59 | }
60 |
61 | $host = $zone->cdnUpHosts[0];
62 | if ($this->useCdnDomains === true) {
63 | $host = $zone->srcUpHosts[0];
64 | }
65 |
66 | return $scheme . $host;
67 | }
68 |
69 | public function getRsHost($accessKey, $bucket)
70 | {
71 | $zone = $this->getZone($accessKey, $bucket);
72 |
73 | if ($this->useHTTPS === true) {
74 | $scheme = "https://";
75 | } else {
76 | $scheme = "http://";
77 | }
78 |
79 | return $scheme . $zone->rsHost;
80 | }
81 |
82 | public function getRsfHost($accessKey, $bucket)
83 | {
84 | $zone = $this->getZone($accessKey, $bucket);
85 |
86 | if ($this->useHTTPS === true) {
87 | $scheme = "https://";
88 | } else {
89 | $scheme = "http://";
90 | }
91 |
92 | return $scheme . $zone->rsfHost;
93 | }
94 |
95 | public function getIovipHost($accessKey, $bucket)
96 | {
97 | $zone = $this->getZone($accessKey, $bucket);
98 |
99 | if ($this->useHTTPS === true) {
100 | $scheme = "https://";
101 | } else {
102 | $scheme = "http://";
103 | }
104 |
105 | return $scheme . $zone->iovipHost;
106 | }
107 |
108 | public function getApiHost($accessKey, $bucket)
109 | {
110 | $zone = $this->getZone($accessKey, $bucket);
111 |
112 | if ($this->useHTTPS === true) {
113 | $scheme = "https://";
114 | } else {
115 | $scheme = "http://";
116 | }
117 |
118 | return $scheme . $zone->apiHost;
119 | }
120 |
121 | private function getZone($accessKey, $bucket)
122 | {
123 | $cacheId = "$accessKey:$bucket";
124 |
125 | if (isset($this->zoneCache[$cacheId])) {
126 | $zone = $this->zoneCache[$cacheId];
127 | } elseif (isset($this->zone)) {
128 | $zone = $this->zone;
129 | $this->zoneCache[$cacheId] = $zone;
130 | } else {
131 | $zone = Zone::queryZone($accessKey, $bucket);
132 | $this->zoneCache[$cacheId] = $zone;
133 | }
134 | return $zone;
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Etag.php:
--------------------------------------------------------------------------------
1 | $val) {
41 | array_push($data, '--' . $mimeBoundary);
42 | array_push($data, "Content-Disposition: form-data; name=\"$key\"");
43 | array_push($data, '');
44 | array_push($data, $val);
45 | }
46 |
47 | array_push($data, '--' . $mimeBoundary);
48 | $finalMimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType;
49 | $finalFileName = self::escapeQuotes($fileName);
50 | array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$finalFileName\"");
51 | array_push($data, "Content-Type: $finalMimeType");
52 | array_push($data, '');
53 | array_push($data, $fileBody);
54 |
55 | array_push($data, '--' . $mimeBoundary . '--');
56 | array_push($data, '');
57 |
58 | $body = implode("\r\n", $data);
59 | $contentType = 'multipart/form-data; boundary=' . $mimeBoundary;
60 | $headers['Content-Type'] = $contentType;
61 | $request = new Request('POST', $url, $headers, $body);
62 | return self::sendRequest($request);
63 | }
64 |
65 | private static function userAgent()
66 | {
67 | $sdkInfo = "QiniuPHP/" . Config::SDK_VER;
68 |
69 | $systemInfo = php_uname("s");
70 | $machineInfo = php_uname("m");
71 |
72 | $envInfo = "($systemInfo/$machineInfo)";
73 |
74 | $phpVer = phpversion();
75 |
76 | $ua = "$sdkInfo $envInfo PHP/$phpVer";
77 | return $ua;
78 | }
79 |
80 | public static function sendRequest($request)
81 | {
82 | $t1 = microtime(true);
83 | $ch = curl_init();
84 | $options = array(
85 | CURLOPT_USERAGENT => self::userAgent(),
86 | CURLOPT_RETURNTRANSFER => true,
87 | CURLOPT_SSL_VERIFYPEER => false,
88 | CURLOPT_SSL_VERIFYHOST => false,
89 | CURLOPT_HEADER => true,
90 | CURLOPT_NOBODY => false,
91 | CURLOPT_CUSTOMREQUEST => $request->method,
92 | CURLOPT_URL => $request->url,
93 | );
94 |
95 | // Handle open_basedir & safe mode
96 | if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
97 | $options[CURLOPT_FOLLOWLOCATION] = true;
98 | }
99 |
100 | if (!empty($request->headers)) {
101 | $headers = array();
102 | foreach ($request->headers as $key => $val) {
103 | array_push($headers, "$key: $val");
104 | }
105 | $options[CURLOPT_HTTPHEADER] = $headers;
106 | }
107 | curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
108 |
109 | if (!empty($request->body)) {
110 | $options[CURLOPT_POSTFIELDS] = $request->body;
111 | }
112 | curl_setopt_array($ch, $options);
113 | $result = curl_exec($ch);
114 | $t2 = microtime(true);
115 | $duration = round($t2 - $t1, 3);
116 | $ret = curl_errno($ch);
117 | if ($ret !== 0) {
118 | $r = new Response(-1, $duration, array(), null, curl_error($ch));
119 | curl_close($ch);
120 | return $r;
121 | }
122 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
123 | $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
124 | $headers = self::parseHeaders(substr($result, 0, $header_size));
125 | $body = substr($result, $header_size);
126 | curl_close($ch);
127 | return new Response($code, $duration, $headers, $body, null);
128 | }
129 |
130 | private static function parseHeaders($raw)
131 | {
132 | $headers = array();
133 | $headerLines = explode("\r\n", $raw);
134 | foreach ($headerLines as $line) {
135 | $headerLine = trim($line);
136 | $kv = explode(':', $headerLine);
137 | if (count($kv) > 1) {
138 | $kv[0] =self::ucwordsHyphen($kv[0]);
139 | $headers[$kv[0]] = trim($kv[1]);
140 | }
141 | }
142 | return $headers;
143 | }
144 |
145 | private static function escapeQuotes($str)
146 | {
147 | $find = array("\\", "\"");
148 | $replace = array("\\\\", "\\\"");
149 | return str_replace($find, $replace, $str);
150 | }
151 |
152 | private static function ucwordsHyphen($str)
153 | {
154 | return str_replace('- ', '-', ucwords(str_replace('-', '- ', $str)));
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Http/Error.php:
--------------------------------------------------------------------------------
1 |
7 | * {"error" : "detailed error message"}
8 | *
9 | */
10 | final class Error
11 | {
12 | private $url;
13 | private $response;
14 |
15 | public function __construct($url, $response)
16 | {
17 | $this->url = $url;
18 | $this->response = $response;
19 | }
20 |
21 | public function code()
22 | {
23 | return $this->response->statusCode;
24 | }
25 |
26 | public function getResponse()
27 | {
28 | return $this->response;
29 | }
30 |
31 | public function message()
32 | {
33 | return $this->response->error;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Http/Request.php:
--------------------------------------------------------------------------------
1 | method = strtoupper($method);
14 | $this->url = $url;
15 | $this->headers = $headers;
16 | $this->body = $body;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Http/Response.php:
--------------------------------------------------------------------------------
1 | 'Continue',
20 | 101 => 'Switching Protocols',
21 | 102 => 'Processing',
22 | 200 => 'OK',
23 | 201 => 'Created',
24 | 202 => 'Accepted',
25 | 203 => 'Non-Authoritative Information',
26 | 204 => 'No Content',
27 | 205 => 'Reset Content',
28 | 206 => 'Partial Content',
29 | 207 => 'Multi-Status',
30 | 208 => 'Already Reported',
31 | 226 => 'IM Used',
32 | 300 => 'Multiple Choices',
33 | 301 => 'Moved Permanently',
34 | 302 => 'Found',
35 | 303 => 'See Other',
36 | 304 => 'Not Modified',
37 | 305 => 'Use Proxy',
38 | 307 => 'Temporary Redirect',
39 | 308 => 'Permanent Redirect',
40 | 400 => 'Bad Request',
41 | 401 => 'Unauthorized',
42 | 402 => 'Payment Required',
43 | 403 => 'Forbidden',
44 | 404 => 'Not Found',
45 | 405 => 'Method Not Allowed',
46 | 406 => 'Not Acceptable',
47 | 407 => 'Proxy Authentication Required',
48 | 408 => 'Request Timeout',
49 | 409 => 'Conflict',
50 | 410 => 'Gone',
51 | 411 => 'Length Required',
52 | 412 => 'Precondition Failed',
53 | 413 => 'Request Entity Too Large',
54 | 414 => 'Request-URI Too Long',
55 | 415 => 'Unsupported Media Type',
56 | 416 => 'Requested Range Not Satisfiable',
57 | 417 => 'Expectation Failed',
58 | 422 => 'Unprocessable Entity',
59 | 423 => 'Locked',
60 | 424 => 'Failed Dependency',
61 | 425 => 'Reserved for WebDAV advanced collections expired proposal',
62 | 426 => 'Upgrade required',
63 | 428 => 'Precondition Required',
64 | 429 => 'Too Many Requests',
65 | 431 => 'Request Header Fields Too Large',
66 | 500 => 'Internal Server Error',
67 | 501 => 'Not Implemented',
68 | 502 => 'Bad Gateway',
69 | 503 => 'Service Unavailable',
70 | 504 => 'Gateway Timeout',
71 | 505 => 'HTTP Version Not Supported',
72 | 506 => 'Variant Also Negotiates (Experimental)',
73 | 507 => 'Insufficient Storage',
74 | 508 => 'Loop Detected',
75 | 510 => 'Not Extended',
76 | 511 => 'Network Authentication Required',
77 | );
78 |
79 | /**
80 | * @param int $code 状态码
81 | * @param double $duration 请求时长
82 | * @param array $headers 响应头部
83 | * @param string $body 响应内容
84 | * @param string $error 错误描述
85 | */
86 | public function __construct($code, $duration, array $headers = array(), $body = null, $error = null)
87 | {
88 | $this->statusCode = $code;
89 | $this->duration = $duration;
90 | $this->headers = $headers;
91 | $this->body = $body;
92 | $this->error = $error;
93 | $this->jsonData = null;
94 | if ($error !== null) {
95 | return;
96 | }
97 |
98 | if ($body === null) {
99 | if ($code >= 400) {
100 | $this->error = self::$statusTexts[$code];
101 | }
102 | return;
103 | }
104 | if (self::isJson($headers)) {
105 | try {
106 | $jsonData = self::bodyJson($body);
107 | if ($code >= 400) {
108 | $this->error = $body;
109 | if ($jsonData['error'] !== null) {
110 | $this->error = $jsonData['error'];
111 | }
112 | }
113 | $this->jsonData = $jsonData;
114 | } catch (\InvalidArgumentException $e) {
115 | $this->error = $body;
116 | if ($code >= 200 && $code < 300) {
117 | $this->error = $e->getMessage();
118 | }
119 | }
120 | } elseif ($code >= 400) {
121 | $this->error = $body;
122 | }
123 | return;
124 | }
125 |
126 | public function json()
127 | {
128 | return $this->jsonData;
129 | }
130 |
131 | private static function bodyJson($body)
132 | {
133 | return \Qiniu\json_decode((string) $body, true, 512);
134 | }
135 |
136 | public function xVia()
137 | {
138 | $via = $this->headers['X-Via'];
139 | if ($via === null) {
140 | $via = $this->headers['X-Px'];
141 | }
142 | if ($via === null) {
143 | $via = $this->headers['Fw-Via'];
144 | }
145 | return $via;
146 | }
147 |
148 | public function xLog()
149 | {
150 | return $this->headers['X-Log'];
151 | }
152 |
153 | public function xReqId()
154 | {
155 | return $this->headers['X-Reqid'];
156 | }
157 |
158 | public function ok()
159 | {
160 | return $this->statusCode >= 200 && $this->statusCode < 300 && $this->error === null;
161 | }
162 |
163 | public function needRetry()
164 | {
165 | $code = $this->statusCode;
166 | if ($code < 0 || ($code / 100 === 5 and $code !== 579) || $code === 996) {
167 | return true;
168 | }
169 | }
170 |
171 | private static function isJson($headers)
172 | {
173 | return array_key_exists('Content-Type', $headers) &&
174 | strpos($headers['Content-Type'], 'application/json') === 0;
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Processing/ImageUrlBuilder.php:
--------------------------------------------------------------------------------
1 |
49 | */
50 | public function thumbnail(
51 | $url,
52 | $mode,
53 | $width,
54 | $height,
55 | $format = null,
56 | $interlace = null,
57 | $quality = null,
58 | $ignoreError = 1
59 | ) {
60 |
61 | // url合法效验
62 | if (!$this->isUrl($url)) {
63 | return $url;
64 | }
65 |
66 | // 参数合法性效验
67 | if (!in_array(intval($mode), $this->modeArr, true)) {
68 | return $url;
69 | }
70 |
71 | if (!$width || !$height) {
72 | return $url;
73 | }
74 |
75 | $thumbStr = 'imageView2/' . $mode . '/w/' . $width . '/h/' . $height . '/';
76 |
77 | // 拼接输出格式
78 | if (!is_null($format)
79 | && in_array($format, $this->formatArr)
80 | ) {
81 | $thumbStr .= 'format/' . $format . '/';
82 | }
83 |
84 | // 拼接渐进显示
85 | if (!is_null($interlace)
86 | && in_array(intval($interlace), array(0, 1), true)
87 | ) {
88 | $thumbStr .= 'interlace/' . $interlace . '/';
89 | }
90 |
91 | // 拼接图片质量
92 | if (!is_null($quality)
93 | && intval($quality) >= 0
94 | && intval($quality) <= 100
95 | ) {
96 | $thumbStr .= 'q/' . $quality . '/';
97 | }
98 |
99 | $thumbStr .= 'ignore-error/' . $ignoreError . '/';
100 |
101 | // 如果有query_string用|线分割实现多参数
102 | return $url . ($this->hasQuery($url) ? '|' : '?') . $thumbStr;
103 | }
104 |
105 | /**
106 | * 图片水印
107 | *
108 | * @param string $url 图片链接
109 | * @param string $image 水印图片链接
110 | * @param numeric $dissolve 透明度
111 | * @param string $gravity 水印位置
112 | * @param numeric $dx 横轴边距
113 | * @param numeric $dy 纵轴边距
114 | * @param numeric $watermarkScale 自适应原图的短边比例
115 | * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
116 | * @return string
117 | * @author Sherlock Ren
118 | */
119 | public function waterImg(
120 | $url,
121 | $image,
122 | $dissolve = 100,
123 | $gravity = 'SouthEast',
124 | $dx = null,
125 | $dy = null,
126 | $watermarkScale = null
127 | ) {
128 | // url合法效验
129 | if (!$this->isUrl($url)) {
130 | return $url;
131 | }
132 |
133 | $waterStr = 'watermark/1/image/' . \Qiniu\base64_urlSafeEncode($image) . '/';
134 |
135 | // 拼接水印透明度
136 | if (is_numeric($dissolve)
137 | && $dissolve <= 100
138 | ) {
139 | $waterStr .= 'dissolve/' . $dissolve . '/';
140 | }
141 |
142 | // 拼接水印位置
143 | if (in_array($gravity, $this->gravityArr, true)) {
144 | $waterStr .= 'gravity/' . $gravity . '/';
145 | }
146 |
147 | // 拼接横轴边距
148 | if (!is_null($dx)
149 | && is_numeric($dx)
150 | ) {
151 | $waterStr .= 'dx/' . $dx . '/';
152 | }
153 |
154 | // 拼接纵轴边距
155 | if (!is_null($dy)
156 | && is_numeric($dy)
157 | ) {
158 | $waterStr .= 'dy/' . $dy . '/';
159 | }
160 |
161 | // 拼接自适应原图的短边比例
162 | if (!is_null($watermarkScale)
163 | && is_numeric($watermarkScale)
164 | && $watermarkScale > 0
165 | && $watermarkScale < 1
166 | ) {
167 | $waterStr .= 'ws/' . $watermarkScale . '/';
168 | }
169 |
170 | // 如果有query_string用|线分割实现多参数
171 | return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr;
172 | }
173 |
174 | /**
175 | * 文字水印
176 | *
177 | * @param string $url 图片链接
178 | * @param string $text 文字
179 | * @param string $font 文字字体
180 | * @param string $fontSize 文字字号
181 | * @param string $fontColor 文字颜色
182 | * @param numeric $dissolve 透明度
183 | * @param string $gravity 水印位置
184 | * @param numeric $dx 横轴边距
185 | * @param numeric $dy 纵轴边距
186 | * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
187 | * @return string
188 | * @author Sherlock Ren
189 | */
190 | public function waterText(
191 | $url,
192 | $text,
193 | $font = '黑体',
194 | $fontSize = 0,
195 | $fontColor = null,
196 | $dissolve = 100,
197 | $gravity = 'SouthEast',
198 | $dx = null,
199 | $dy = null
200 | ) {
201 | // url合法效验
202 | if (!$this->isUrl($url)) {
203 | return $url;
204 | }
205 |
206 | $waterStr = 'watermark/2/text/'
207 | . \Qiniu\base64_urlSafeEncode($text) . '/font/'
208 | . \Qiniu\base64_urlSafeEncode($font) . '/';
209 |
210 | // 拼接文字大小
211 | if (is_int($fontSize)) {
212 | $waterStr .= 'fontsize/' . $fontSize . '/';
213 | }
214 |
215 | // 拼接文字颜色
216 | if (!is_null($fontColor)
217 | && $fontColor
218 | ) {
219 | $waterStr .= 'fill/' . \Qiniu\base64_urlSafeEncode($fontColor) . '/';
220 | }
221 |
222 | // 拼接水印透明度
223 | if (is_numeric($dissolve)
224 | && $dissolve <= 100
225 | ) {
226 | $waterStr .= 'dissolve/' . $dissolve . '/';
227 | }
228 |
229 | // 拼接水印位置
230 | if (in_array($gravity, $this->gravityArr, true)) {
231 | $waterStr .= 'gravity/' . $gravity . '/';
232 | }
233 |
234 | // 拼接横轴边距
235 | if (!is_null($dx)
236 | && is_numeric($dx)
237 | ) {
238 | $waterStr .= 'dx/' . $dx . '/';
239 | }
240 |
241 | // 拼接纵轴边距
242 | if (!is_null($dy)
243 | && is_numeric($dy)
244 | ) {
245 | $waterStr .= 'dy/' . $dy . '/';
246 | }
247 |
248 | // 如果有query_string用|线分割实现多参数
249 | return $url . ($this->hasQuery($url) ? '|' : '?') . $waterStr;
250 | }
251 |
252 | /**
253 | * 效验url合法性
254 | *
255 | * @param string $url url链接
256 | * @return string
257 | * @author Sherlock Ren
258 | */
259 | protected function isUrl($url)
260 | {
261 | $urlArr = parse_url($url);
262 |
263 | return $urlArr['scheme']
264 | && in_array($urlArr['scheme'], array('http', 'https'))
265 | && $urlArr['host']
266 | && $urlArr['path'];
267 | }
268 |
269 | /**
270 | * 检测是否有query
271 | *
272 | * @param string $url url链接
273 | * @return string
274 | * @author Sherlock Ren
275 | */
276 | protected function hasQuery($url)
277 | {
278 | $urlArr = parse_url($url);
279 |
280 | return !empty($urlArr['query']);
281 | }
282 | }
283 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Processing/Operation.php:
--------------------------------------------------------------------------------
1 | auth = $auth;
18 | $this->domain = $domain;
19 | $this->token_expire = $token_expire;
20 | }
21 |
22 |
23 | /**
24 | * 对资源文件进行处理
25 | *
26 | * @param $key 待处理的资源文件名
27 | * @param $fops string|array fop操作,多次fop操作以array的形式传入。
28 | * eg. imageView2/1/w/200/h/200, imageMogr2/thumbnail/!75px
29 | *
30 | * @return array 文件处理后的结果及错误。
31 | *
32 | * @link http://developer.qiniu.com/docs/v6/api/reference/fop/
33 | */
34 | public function execute($key, $fops)
35 | {
36 | $url = $this->buildUrl($key, $fops);
37 | $resp = Client::get($url);
38 | if (!$resp->ok()) {
39 | return array(null, new Error($url, $resp));
40 | }
41 | if ($resp->json() !== null) {
42 | return array($resp->json(), null);
43 | }
44 | return array($resp->body, null);
45 | }
46 |
47 | public function buildUrl($key, $fops, $protocol = 'http')
48 | {
49 | if (is_array($fops)) {
50 | $fops = implode('|', $fops);
51 | }
52 |
53 | $url = $protocol . "://$this->domain/$key?$fops";
54 | if ($this->auth !== null) {
55 | $url = $this->auth->privateDownloadUrl($url, $this->token_expire);
56 | }
57 |
58 | return $url;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Processing/PersistentFop.php:
--------------------------------------------------------------------------------
1 | auth = $auth;
30 | if ($config == null) {
31 | $this->config = new Config();
32 | } else {
33 | $this->config = $config;
34 | }
35 | }
36 |
37 | /**
38 | * 对资源文件进行异步持久化处理
39 | * @param $bucket 资源所在空间
40 | * @param $key 待处理的源文件
41 | * @param $fops string|array 待处理的pfop操作,多个pfop操作以array的形式传入。
42 | * eg. avthumb/mp3/ab/192k, vframe/jpg/offset/7/w/480/h/360
43 | * @param $pipeline 资源处理队列
44 | * @param $notify_url 处理结果通知地址
45 | * @param $force 是否强制执行一次新的指令
46 | *
47 | *
48 | * @return array 返回持久化处理的persistentId, 和返回的错误。
49 | *
50 | * @link http://developer.qiniu.com/docs/v6/api/reference/fop/
51 | */
52 | public function execute($bucket, $key, $fops, $pipeline = null, $notify_url = null, $force = false)
53 | {
54 | if (is_array($fops)) {
55 | $fops = implode(';', $fops);
56 | }
57 | $params = array('bucket' => $bucket, 'key' => $key, 'fops' => $fops);
58 | \Qiniu\setWithoutEmpty($params, 'pipeline', $pipeline);
59 | \Qiniu\setWithoutEmpty($params, 'notifyURL', $notify_url);
60 | if ($force) {
61 | $params['force'] = 1;
62 | }
63 | $data = http_build_query($params);
64 | $scheme = "http://";
65 | if ($this->config->useHTTPS === true) {
66 | $scheme = "https://";
67 | }
68 | $url = $scheme . Config::API_HOST . '/pfop/';
69 | $headers = $this->auth->authorization($url, $data, 'application/x-www-form-urlencoded');
70 | $headers['Content-Type'] = 'application/x-www-form-urlencoded';
71 | $response = Client::post($url, $data, $headers);
72 | if (!$response->ok()) {
73 | return array(null, new Error($url, $response));
74 | }
75 | $r = $response->json();
76 | $id = $r['persistentId'];
77 | return array($id, null);
78 | }
79 |
80 | public function status($id)
81 | {
82 | $scheme = "http://";
83 |
84 | if ($this->config->useHTTPS === true) {
85 | $scheme = "https://";
86 | }
87 | $url = $scheme . Config::API_HOST . "/status/get/prefop?id=$id";
88 | $response = Client::get($url);
89 | if (!$response->ok()) {
90 | return array(null, new Error($url, $response));
91 | }
92 | return array($response->json(), null);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Storage/BucketManager.php:
--------------------------------------------------------------------------------
1 | auth = $auth;
23 | if ($config == null) {
24 | $this->config = new Config();
25 | } else {
26 | $this->config = $config;
27 | }
28 | }
29 |
30 | /**
31 | * 获取指定账号下所有的空间名。
32 | *
33 | * @return string[] 包含所有空间名
34 | */
35 | public function buckets($shared = true)
36 | {
37 | $includeShared = "false";
38 | if ($shared === true) {
39 | $includeShared = "true";
40 | }
41 | return $this->rsGet('/buckets?shared=' . $includeShared);
42 | }
43 |
44 | /**
45 | * 获取指定空间绑定的所有的域名
46 | *
47 | * @return string[] 包含所有空间域名
48 | */
49 | public function domains($bucket)
50 | {
51 | return $this->apiGet('/v6/domain/list?tbl=' . $bucket);
52 | }
53 |
54 | /**
55 | * 获取空间绑定的域名列表
56 | * @return string[] 包含空间绑定的所有域名
57 | */
58 |
59 | /**
60 | * 列取空间的文件列表
61 | *
62 | * @param $bucket 空间名
63 | * @param $prefix 列举前缀
64 | * @param $marker 列举标识符
65 | * @param $limit 单次列举个数限制
66 | * @param $delimiter 指定目录分隔符
67 | *
68 | * @return array 包含文件信息的数组,类似:[
69 | * {
70 | * "hash" => "",
71 | * "key" => "",
72 | * "fsize" => "",
73 | * "putTime" => ""
74 | * },
75 | * ...
76 | * ]
77 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/list.html
78 | */
79 | public function listFiles($bucket, $prefix = null, $marker = null, $limit = 1000, $delimiter = null)
80 | {
81 | $query = array('bucket' => $bucket);
82 | \Qiniu\setWithoutEmpty($query, 'prefix', $prefix);
83 | \Qiniu\setWithoutEmpty($query, 'marker', $marker);
84 | \Qiniu\setWithoutEmpty($query, 'limit', $limit);
85 | \Qiniu\setWithoutEmpty($query, 'delimiter', $delimiter);
86 | $url = $this->getRsfHost() . '/list?' . http_build_query($query);
87 | return $this->get($url);
88 | }
89 |
90 | /**
91 | * 获取资源的元信息,但不返回文件内容
92 | *
93 | * @param $bucket 待获取信息资源所在的空间
94 | * @param $key 待获取资源的文件名
95 | *
96 | * @return array 包含文件信息的数组,类似:
97 | * [
98 | * "hash" => "",
99 | * "key" => "",
100 | * "fsize" => ,
101 | * "putTime" => ""
102 | * "fileType" =>
103 | * ]
104 | *
105 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/stat.html
106 | */
107 | public function stat($bucket, $key)
108 | {
109 | $path = '/stat/' . \Qiniu\entry($bucket, $key);
110 | return $this->rsGet($path);
111 | }
112 |
113 | /**
114 | * 删除指定资源
115 | *
116 | * @param $bucket 待删除资源所在的空间
117 | * @param $key 待删除资源的文件名
118 | *
119 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
120 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/delete.html
121 | */
122 | public function delete($bucket, $key)
123 | {
124 | $path = '/delete/' . \Qiniu\entry($bucket, $key);
125 | list(, $error) = $this->rsPost($path);
126 | return $error;
127 | }
128 |
129 |
130 | /**
131 | * 给资源进行重命名,本质为move操作。
132 | *
133 | * @param $bucket 待操作资源所在空间
134 | * @param $oldname 待操作资源文件名
135 | * @param $newname 目标资源文件名
136 | *
137 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
138 | */
139 | public function rename($bucket, $oldname, $newname)
140 | {
141 | return $this->move($bucket, $oldname, $bucket, $newname);
142 | }
143 |
144 | /**
145 | * 给资源进行重命名,本质为move操作。
146 | *
147 | * @param $from_bucket 待操作资源所在空间
148 | * @param $from_key 待操作资源文件名
149 | * @param $to_bucket 目标资源空间名
150 | * @param $to_key 目标资源文件名
151 | *
152 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
153 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/copy.html
154 | */
155 | public function copy($from_bucket, $from_key, $to_bucket, $to_key, $force = false)
156 | {
157 | $from = \Qiniu\entry($from_bucket, $from_key);
158 | $to = \Qiniu\entry($to_bucket, $to_key);
159 | $path = '/copy/' . $from . '/' . $to;
160 | if ($force === true) {
161 | $path .= '/force/true';
162 | }
163 | list(, $error) = $this->rsPost($path);
164 | return $error;
165 | }
166 |
167 | /**
168 | * 将资源从一个空间到另一个空间
169 | *
170 | * @param $from_bucket 待操作资源所在空间
171 | * @param $from_key 待操作资源文件名
172 | * @param $to_bucket 目标资源空间名
173 | * @param $to_key 目标资源文件名
174 | *
175 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
176 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/move.html
177 | */
178 | public function move($from_bucket, $from_key, $to_bucket, $to_key, $force = false)
179 | {
180 | $from = \Qiniu\entry($from_bucket, $from_key);
181 | $to = \Qiniu\entry($to_bucket, $to_key);
182 | $path = '/move/' . $from . '/' . $to;
183 | if ($force) {
184 | $path .= '/force/true';
185 | }
186 | list(, $error) = $this->rsPost($path);
187 | return $error;
188 | }
189 |
190 | /**
191 | * 主动修改指定资源的文件类型
192 | *
193 | * @param $bucket 待操作资源所在空间
194 | * @param $key 待操作资源文件名
195 | * @param $mime 待操作文件目标mimeType
196 | *
197 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
198 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/chgm.html
199 | */
200 | public function changeMime($bucket, $key, $mime)
201 | {
202 | $resource = \Qiniu\entry($bucket, $key);
203 | $encode_mime = \Qiniu\base64_urlSafeEncode($mime);
204 | $path = '/chgm/' . $resource . '/mime/' . $encode_mime;
205 | list(, $error) = $this->rsPost($path);
206 | return $error;
207 | }
208 |
209 |
210 | /**
211 | * 修改指定资源的存储类型
212 | *
213 | * @param $bucket 待操作资源所在空间
214 | * @param $key 待操作资源文件名
215 | * @param $fileType 待操作文件目标文件类型
216 | *
217 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
218 | * @link https://developer.qiniu.com/kodo/api/3710/modify-the-file-type
219 | */
220 | public function changeType($bucket, $key, $fileType)
221 | {
222 | $resource = \Qiniu\entry($bucket, $key);
223 | $path = '/chtype/' . $resource . '/type/' . $fileType;
224 | list(, $error) = $this->rsPost($path);
225 | return $error;
226 | }
227 |
228 | /**
229 | * 修改文件的存储状态,即禁用状态和启用状态间的的互相转换
230 | *
231 | * @param $bucket 待操作资源所在空间
232 | * @param $key 待操作资源文件名
233 | * @param $status 待操作文件目标文件类型
234 | *
235 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
236 | * @link https://developer.qiniu.com/kodo/api/4173/modify-the-file-status
237 | */
238 | public function changeStatus($bucket, $key, $status)
239 | {
240 | $resource = \Qiniu\entry($bucket, $key);
241 | $path = '/chstatus/' . $resource . '/status/' . $status;
242 | list(, $error) = $this->rsPost($path);
243 | return $error;
244 | }
245 |
246 | /**
247 | * 从指定URL抓取资源,并将该资源存储到指定空间中
248 | *
249 | * @param $url 指定的URL
250 | * @param $bucket 目标资源空间
251 | * @param $key 目标资源文件名
252 | *
253 | * @return array 包含已拉取的文件信息。
254 | * 成功时: [
255 | * [
256 | * "hash" => "",
257 | * "key" => ""
258 | * ],
259 | * null
260 | * ]
261 | *
262 | * 失败时: [
263 | * null,
264 | * Qiniu/Http/Error
265 | * ]
266 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/fetch.html
267 | */
268 | public function fetch($url, $bucket, $key = null)
269 | {
270 |
271 | $resource = \Qiniu\base64_urlSafeEncode($url);
272 | $to = \Qiniu\entry($bucket, $key);
273 | $path = '/fetch/' . $resource . '/to/' . $to;
274 |
275 | $ak = $this->auth->getAccessKey();
276 | $ioHost = $this->config->getIovipHost($ak, $bucket);
277 |
278 | $url = $ioHost . $path;
279 | return $this->post($url, null);
280 | }
281 |
282 | /**
283 | * 从镜像源站抓取资源到空间中,如果空间中已经存在,则覆盖该资源
284 | *
285 | * @param $bucket 待获取资源所在的空间
286 | * @param $key 代获取资源文件名
287 | *
288 | * @return mixed 成功返回NULL,失败返回对象Qiniu\Http\Error
289 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/prefetch.html
290 | */
291 | public function prefetch($bucket, $key)
292 | {
293 | $resource = \Qiniu\entry($bucket, $key);
294 | $path = '/prefetch/' . $resource;
295 |
296 | $ak = $this->auth->getAccessKey();
297 | $ioHost = $this->config->getIovipHost($ak, $bucket);
298 |
299 | $url = $ioHost . $path;
300 | list(, $error) = $this->post($url, null);
301 | return $error;
302 | }
303 |
304 | /**
305 | * 在单次请求中进行多个资源管理操作
306 | *
307 | * @param $operations 资源管理操作数组
308 | *
309 | * @return array 每个资源的处理情况,结果类似:
310 | * [
311 | * { "code" => , "data" => },
312 | * { "code" => },
313 | * { "code" => },
314 | * { "code" => },
315 | * { "code" => , "data" => { "error": "" } },
316 | * ...
317 | * ]
318 | * @link http://developer.qiniu.com/docs/v6/api/reference/rs/batch.html
319 | */
320 | public function batch($operations)
321 | {
322 | $params = 'op=' . implode('&op=', $operations);
323 | return $this->rsPost('/batch', $params);
324 | }
325 |
326 | /**
327 | * 设置文件的生命周期
328 | *
329 | * @param $bucket 设置文件生命周期文件所在的空间
330 | * @param $key 设置文件生命周期文件的文件名
331 | * @param $days 设置该文件多少天后删除,当$days设置为0时表示取消该文件的生命周期
332 | *
333 | * @return Mixed
334 | * @link https://developer.qiniu.com/kodo/api/update-file-lifecycle
335 | */
336 | public function deleteAfterDays($bucket, $key, $days)
337 | {
338 | $entry = \Qiniu\entry($bucket, $key);
339 | $path = "/deleteAfterDays/$entry/$days";
340 | list(, $error) = $this->rsPost($path);
341 | return $error;
342 | }
343 |
344 | private function getRsfHost()
345 | {
346 | $scheme = "http://";
347 | if ($this->config->useHTTPS == true) {
348 | $scheme = "https://";
349 | }
350 | return $scheme . Config::RSF_HOST;
351 | }
352 |
353 | private function getRsHost()
354 | {
355 | $scheme = "http://";
356 | if ($this->config->useHTTPS == true) {
357 | $scheme = "https://";
358 | }
359 | return $scheme . Config::RS_HOST;
360 | }
361 |
362 | private function getApiHost()
363 | {
364 | $scheme = "http://";
365 | if ($this->config->useHTTPS == true) {
366 | $scheme = "https://";
367 | }
368 | return $scheme . Config::API_HOST;
369 | }
370 |
371 | private function rsPost($path, $body = null)
372 | {
373 | $url = $this->getRsHost() . $path;
374 | return $this->post($url, $body);
375 | }
376 |
377 | private function apiGet($path)
378 | {
379 | $url = $this->getApiHost() . $path;
380 | return $this->get($url);
381 | }
382 |
383 | private function rsGet($path)
384 | {
385 | $url = $this->getRsHost() . $path;
386 | return $this->get($url);
387 | }
388 |
389 | private function get($url)
390 | {
391 | $headers = $this->auth->authorization($url);
392 | $ret = Client::get($url, $headers);
393 | if (!$ret->ok()) {
394 | return array(null, new Error($url, $ret));
395 | }
396 | return array($ret->json(), null);
397 | }
398 |
399 | private function post($url, $body)
400 | {
401 | $headers = $this->auth->authorization($url, $body, 'application/x-www-form-urlencoded');
402 | $ret = Client::post($url, $body, $headers);
403 | if (!$ret->ok()) {
404 | return array(null, new Error($url, $ret));
405 | }
406 | $r = ($ret->body === null) ? array() : $ret->json();
407 | return array($r, null);
408 | }
409 |
410 | public static function buildBatchCopy($source_bucket, $key_pairs, $target_bucket, $force)
411 | {
412 | return self::twoKeyBatch('/copy', $source_bucket, $key_pairs, $target_bucket, $force);
413 | }
414 |
415 |
416 | public static function buildBatchRename($bucket, $key_pairs, $force)
417 | {
418 | return self::buildBatchMove($bucket, $key_pairs, $bucket, $force);
419 | }
420 |
421 |
422 | public static function buildBatchMove($source_bucket, $key_pairs, $target_bucket, $force)
423 | {
424 | return self::twoKeyBatch('/move', $source_bucket, $key_pairs, $target_bucket, $force);
425 | }
426 |
427 |
428 | public static function buildBatchDelete($bucket, $keys)
429 | {
430 | return self::oneKeyBatch('/delete', $bucket, $keys);
431 | }
432 |
433 |
434 | public static function buildBatchStat($bucket, $keys)
435 | {
436 | return self::oneKeyBatch('/stat', $bucket, $keys);
437 | }
438 |
439 | public static function buildBatchDeleteAfterDays($bucket, $key_day_pairs)
440 | {
441 | $data = array();
442 | foreach ($key_day_pairs as $key => $day) {
443 | array_push($data, '/deleteAfterDays/' . \Qiniu\entry($bucket, $key) . '/' . $day);
444 | }
445 | return $data;
446 | }
447 |
448 | public static function buildBatchChangeMime($bucket, $key_mime_pairs)
449 | {
450 | $data = array();
451 | foreach ($key_mime_pairs as $key => $mime) {
452 | array_push($data, '/chgm/' . \Qiniu\entry($bucket, $key) . '/mime/' . base64_encode($mime));
453 | }
454 | return $data;
455 | }
456 |
457 | public static function buildBatchChangeType($bucket, $key_type_pairs)
458 | {
459 | $data = array();
460 | foreach ($key_type_pairs as $key => $type) {
461 | array_push($data, '/chtype/' . \Qiniu\entry($bucket, $key) . '/type/' . $type);
462 | }
463 | return $data;
464 | }
465 |
466 | private static function oneKeyBatch($operation, $bucket, $keys)
467 | {
468 | $data = array();
469 | foreach ($keys as $key) {
470 | array_push($data, $operation . '/' . \Qiniu\entry($bucket, $key));
471 | }
472 | return $data;
473 | }
474 |
475 | private static function twoKeyBatch($operation, $source_bucket, $key_pairs, $target_bucket, $force)
476 | {
477 | if ($target_bucket === null) {
478 | $target_bucket = $source_bucket;
479 | }
480 | $data = array();
481 | $forceOp = "false";
482 | if ($force) {
483 | $forceOp = "true";
484 | }
485 | foreach ($key_pairs as $from_key => $to_key) {
486 | $from = \Qiniu\entry($source_bucket, $from_key);
487 | $to = \Qiniu\entry($target_bucket, $to_key);
488 | array_push($data, $operation . '/' . $from . '/' . $to . "/force/" . $forceOp);
489 | }
490 | return $data;
491 | }
492 | }
493 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Storage/FormUploader.php:
--------------------------------------------------------------------------------
1 | "",
24 | * "key" => ""
25 | * ]
26 | */
27 | public static function put(
28 | $upToken,
29 | $key,
30 | $data,
31 | $config,
32 | $params,
33 | $mime,
34 | $fname
35 | ) {
36 |
37 | $fields = array('token' => $upToken);
38 | if ($key === null) {
39 | $fname='nullkey';
40 | } else {
41 | $fields['key'] = $key;
42 | }
43 |
44 | //enable crc32 check by default
45 | $fields['crc32'] = \Qiniu\crc32_data($data);
46 |
47 | if ($params) {
48 | foreach ($params as $k => $v) {
49 | $fields[$k] = $v;
50 | }
51 | }
52 |
53 | list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
54 | if ($err != null) {
55 | return array(null, $err);
56 | }
57 |
58 | $upHost = $config->getUpHost($accessKey, $bucket);
59 |
60 | $response = Client::multipartPost($upHost, $fields, 'file', $fname, $data, $mime);
61 | if (!$response->ok()) {
62 | return array(null, new Error($upHost, $response));
63 | }
64 | return array($response->json(), null);
65 | }
66 |
67 | /**
68 | * 上传文件到七牛,内部使用
69 | *
70 | * @param $upToken 上传凭证
71 | * @param $key 上传文件名
72 | * @param $filePath 上传文件的路径
73 | * @param $config 上传配置
74 | * @param $params 自定义变量,规格参考
75 | * http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
76 | * @param $mime 上传数据的mimeType
77 | *
78 | * @return array 包含已上传文件的信息,类似:
79 | * [
80 | * "hash" => "",
81 | * "key" => ""
82 | * ]
83 | */
84 | public static function putFile(
85 | $upToken,
86 | $key,
87 | $filePath,
88 | $config,
89 | $params,
90 | $mime
91 | ) {
92 |
93 |
94 | $fields = array('token' => $upToken, 'file' => self::createFile($filePath, $mime));
95 | if ($key !== null) {
96 | $fields['key'] = $key;
97 | }
98 |
99 | $fields['crc32'] = \Qiniu\crc32_file($filePath);
100 |
101 | if ($params) {
102 | foreach ($params as $k => $v) {
103 | $fields[$k] = $v;
104 | }
105 | }
106 | $fields['key'] = $key;
107 | $headers = array('Content-Type' => 'multipart/form-data');
108 |
109 | list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
110 | if ($err != null) {
111 | return array(null, $err);
112 | }
113 |
114 | $upHost = $config->getUpHost($accessKey, $bucket);
115 |
116 | $response = Client::post($upHost, $fields, $headers);
117 | if (!$response->ok()) {
118 | return array(null, new Error($upHost, $response));
119 | }
120 | return array($response->json(), null);
121 | }
122 |
123 | private static function createFile($filename, $mime)
124 | {
125 | // PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax
126 | // See: https://wiki.php.net/rfc/curl-file-upload
127 | if (function_exists('curl_file_create')) {
128 | return curl_file_create($filename, $mime);
129 | }
130 |
131 | // Use the old style if using an older version of PHP
132 | $value = "@{$filename}";
133 | if (!empty($mime)) {
134 | $value .= ';type=' . $mime;
135 | }
136 |
137 | return $value;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Storage/ResumeUploader.php:
--------------------------------------------------------------------------------
1 | upToken = $upToken;
51 | $this->key = $key;
52 | $this->inputStream = $inputStream;
53 | $this->size = $size;
54 | $this->params = $params;
55 | $this->mime = $mime;
56 | $this->contexts = array();
57 | $this->config = $config;
58 |
59 | list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($upToken);
60 | if ($err != null) {
61 | return array(null, $err);
62 | }
63 |
64 | $upHost = $config->getUpHost($accessKey, $bucket);
65 | if ($err != null) {
66 | throw new \Exception($err->message(), 1);
67 | }
68 | $this->host = $upHost;
69 | }
70 |
71 | /**
72 | * 上传操作
73 | */
74 | public function upload($fname)
75 | {
76 | $uploaded = 0;
77 | while ($uploaded < $this->size) {
78 | $blockSize = $this->blockSize($uploaded);
79 | $data = fread($this->inputStream, $blockSize);
80 | if ($data === false) {
81 | throw new \Exception("file read failed", 1);
82 | }
83 | $crc = \Qiniu\crc32_data($data);
84 | $response = $this->makeBlock($data, $blockSize);
85 | $ret = null;
86 | if ($response->ok() && $response->json() != null) {
87 | $ret = $response->json();
88 | }
89 | if ($response->statusCode < 0) {
90 | list($accessKey, $bucket, $err) = \Qiniu\explodeUpToken($this->upToken);
91 | if ($err != null) {
92 | return array(null, $err);
93 | }
94 |
95 | $upHostBackup = $this->config->getUpBackupHost($accessKey, $bucket);
96 | $this->host = $upHostBackup;
97 | }
98 | if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
99 | $response = $this->makeBlock($data, $blockSize);
100 | $ret = $response->json();
101 | }
102 |
103 | if (!$response->ok() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
104 | return array(null, new Error($this->currentUrl, $response));
105 | }
106 | array_push($this->contexts, $ret['ctx']);
107 | $uploaded += $blockSize;
108 | }
109 | return $this->makeFile($fname);
110 | }
111 |
112 | /**
113 | * 创建块
114 | */
115 | private function makeBlock($block, $blockSize)
116 | {
117 | $url = $this->host . '/mkblk/' . $blockSize;
118 | return $this->post($url, $block);
119 | }
120 |
121 | private function fileUrl($fname)
122 | {
123 | $url = $this->host . '/mkfile/' . $this->size;
124 | $url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime);
125 | if ($this->key != null) {
126 | $url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key);
127 | }
128 | $url .= '/fname/' . \Qiniu\base64_urlSafeEncode($fname);
129 | if (!empty($this->params)) {
130 | foreach ($this->params as $key => $value) {
131 | $val = \Qiniu\base64_urlSafeEncode($value);
132 | $url .= "/$key/$val";
133 | }
134 | }
135 | return $url;
136 | }
137 |
138 | /**
139 | * 创建文件
140 | */
141 | private function makeFile($fname)
142 | {
143 | $url = $this->fileUrl($fname);
144 | $body = implode(',', $this->contexts);
145 | $response = $this->post($url, $body);
146 | if ($response->needRetry()) {
147 | $response = $this->post($url, $body);
148 | }
149 | if (!$response->ok()) {
150 | return array(null, new Error($this->currentUrl, $response));
151 | }
152 | return array($response->json(), null);
153 | }
154 |
155 | private function post($url, $data)
156 | {
157 | $this->currentUrl = $url;
158 | $headers = array('Authorization' => 'UpToken ' . $this->upToken);
159 | return Client::post($url, $data, $headers);
160 | }
161 |
162 | private function blockSize($uploaded)
163 | {
164 | if ($this->size < $uploaded + Config::BLOCK_SIZE) {
165 | return $this->size - $uploaded;
166 | }
167 | return Config::BLOCK_SIZE;
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Storage/UploadManager.php:
--------------------------------------------------------------------------------
1 | config = $config;
24 | }
25 |
26 | /**
27 | * 上传二进制流到七牛
28 | *
29 | * @param $upToken 上传凭证
30 | * @param $key 上传文件名
31 | * @param $data 上传二进制流
32 | * @param $params 自定义变量,规格参考
33 | * http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
34 | * @param $mime 上传数据的mimeType
35 | * @param $checkCrc 是否校验crc32
36 | *
37 | * @return array 包含已上传文件的信息,类似:
38 | * [
39 | * "hash" => "",
40 | * "key" => ""
41 | * ]
42 | */
43 | public function put(
44 | $upToken,
45 | $key,
46 | $data,
47 | $params = null,
48 | $mime = 'application/octet-stream',
49 | $fname = null
50 | ) {
51 |
52 | $params = self::trimParams($params);
53 | return FormUploader::put(
54 | $upToken,
55 | $key,
56 | $data,
57 | $this->config,
58 | $params,
59 | $mime,
60 | $fname
61 | );
62 | }
63 |
64 |
65 | /**
66 | * 上传文件到七牛
67 | *
68 | * @param $upToken 上传凭证
69 | * @param $key 上传文件名
70 | * @param $filePath 上传文件的路径
71 | * @param $params 自定义变量,规格参考
72 | * http://developer.qiniu.com/docs/v6/api/overview/up/response/vars.html#xvar
73 | * @param $mime 上传数据的mimeType
74 | * @param $checkCrc 是否校验crc32
75 | *
76 | * @return array 包含已上传文件的信息,类似:
77 | * [
78 | * "hash" => "",
79 | * "key" => ""
80 | * ]
81 | */
82 | public function putFile(
83 | $upToken,
84 | $key,
85 | $filePath,
86 | $params = null,
87 | $mime = 'application/octet-stream',
88 | $checkCrc = false
89 | ) {
90 |
91 | $file = fopen($filePath, 'rb');
92 | if ($file === false) {
93 | throw new \Exception("file can not open", 1);
94 | }
95 | $params = self::trimParams($params);
96 | $stat = fstat($file);
97 | $size = $stat['size'];
98 | if ($size <= Config::BLOCK_SIZE) {
99 | $data = fread($file, $size);
100 | fclose($file);
101 | if ($data === false) {
102 | throw new \Exception("file can not read", 1);
103 | }
104 | return FormUploader::put(
105 | $upToken,
106 | $key,
107 | $data,
108 | $this->config,
109 | $params,
110 | $mime,
111 | basename($filePath)
112 | );
113 | }
114 |
115 | $up = new ResumeUploader(
116 | $upToken,
117 | $key,
118 | $file,
119 | $size,
120 | $params,
121 | $mime,
122 | $this->config
123 | );
124 | $ret = $up->upload(basename($filePath));
125 | fclose($file);
126 | return $ret;
127 | }
128 |
129 | public static function trimParams($params)
130 | {
131 | if ($params === null) {
132 | return null;
133 | }
134 | $ret = array();
135 | foreach ($params as $k => $v) {
136 | $pos = strpos($k, 'x:');
137 | if ($pos === 0 && !empty($v)) {
138 | $ret[$k] = $v;
139 | }
140 | }
141 | return $ret;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/Zone.php:
--------------------------------------------------------------------------------
1 | srcUpHosts = $srcUpHosts;
34 | $this->cdnUpHosts = $cdnUpHosts;
35 | $this->rsHost = $rsHost;
36 | $this->rsfHost = $rsfHost;
37 | $this->apiHost = $apiHost;
38 | $this->iovipHost = $iovipHost;
39 | }
40 |
41 | //华东机房
42 | public static function zone0()
43 | {
44 | $Zone_z0 = new Zone(
45 | array("up.qiniup.com", 'up-jjh.qiniup.com', 'up-xs.qiniup.com'),
46 | array('upload.qiniup.com', 'upload-jjh.qiniup.com', 'upload-xs.qiniup.com'),
47 | 'rs.qiniu.com',
48 | 'rsf.qiniu.com',
49 | 'api.qiniu.com',
50 | 'iovip.qbox.me'
51 | );
52 | return $Zone_z0;
53 | }
54 |
55 | //华北机房
56 | public static function zone1()
57 | {
58 | $Zone_z1 = new Zone(
59 | array('up-z1.qiniup.com'),
60 | array('upload-z1.qiniup.com'),
61 | "rs-z1.qiniu.com",
62 | "rsf-z1.qiniu.com",
63 | "api-z1.qiniu.com",
64 | "iovip-z1.qbox.me"
65 | );
66 |
67 | return $Zone_z1;
68 | }
69 |
70 | //华南机房
71 | public static function zone2()
72 | {
73 | $Zone_z2 = new Zone(
74 | array('up-z2.qiniup.com', 'up-dg.qiniup.com', 'up-fs.qiniup.com'),
75 | array('upload-z2.qiniup.com', 'upload-dg.qiniup.com', 'upload-fs.qiniup.com'),
76 | "rs-z2.qiniu.com",
77 | "rsf-z2.qiniu.com",
78 | "api-z2.qiniu.com",
79 | "iovip-z2.qbox.me"
80 | );
81 | return $Zone_z2;
82 | }
83 |
84 | //北美机房
85 | public static function zoneNa0()
86 | {
87 | //北美机房
88 | $Zone_na0 = new Zone(
89 | array('up-na0.qiniup.com'),
90 | array('upload-na0.qiniup.com'),
91 | "rs-na0.qiniu.com",
92 | "rsf-na0.qiniu.com",
93 | "api-na0.qiniu.com",
94 | "iovip-na0.qbox.me"
95 | );
96 | return $Zone_na0;
97 | }
98 |
99 | //新加坡机房
100 | public static function zoneAs0()
101 | {
102 | //新加坡机房
103 | $Zone_as0 = new Zone(
104 | array('up-as0.qiniup.com'),
105 | array('upload-as0.qiniup.com'),
106 | "rs-as0.qiniu.com",
107 | "rsf-as0.qiniu.com",
108 | "api-as0.qiniu.com",
109 | "iovip-as0.qbox.me"
110 | );
111 | return $Zone_as0;
112 | }
113 |
114 | /*
115 | * GET /v2/query?ak=&&bucket=
116 | **/
117 | public static function queryZone($ak, $bucket)
118 | {
119 | $zone = new Zone();
120 | $url = Config::UC_HOST . '/v2/query' . "?ak=$ak&bucket=$bucket";
121 | $ret = Client::Get($url);
122 | if (!$ret->ok()) {
123 | return array(null, new Error($url, $ret));
124 | }
125 | $r = ($ret->body === null) ? array() : $ret->json();
126 | //print_r($ret);
127 | //parse zone;
128 |
129 | $iovipHost = $r['io']['src']['main'][0];
130 | $zone->iovipHost = $iovipHost;
131 | $accMain = $r['up']['acc']['main'][0];
132 | array_push($zone->cdnUpHosts, $accMain);
133 | if (isset($r['up']['acc']['backup'])) {
134 | foreach ($r['up']['acc']['backup'] as $key => $value) {
135 | array_push($zone->cdnUpHosts, $value);
136 | }
137 | }
138 | $srcMain = $r['up']['src']['main'][0];
139 | array_push($zone->srcUpHosts, $srcMain);
140 | if (isset($r['up']['src']['backup'])) {
141 | foreach ($r['up']['src']['backup'] as $key => $value) {
142 | array_push($zone->srcUpHosts, $value);
143 | }
144 | }
145 |
146 | //set specific hosts
147 | if (strstr($zone->iovipHost, "z1") !== false) {
148 | $zone->rsHost = "rs-z1.qiniu.com";
149 | $zone->rsfHost = "rsf-z1.qiniu.com";
150 | $zone->apiHost = "api-z1.qiniu.com";
151 | } elseif (strstr($zone->iovipHost, "z2") !== false) {
152 | $zone->rsHost = "rs-z2.qiniu.com";
153 | $zone->rsfHost = "rsf-z2.qiniu.com";
154 | $zone->apiHost = "api-z2.qiniu.com";
155 | } elseif (strstr($zone->iovipHost, "na0") !== false) {
156 | $zone->rsHost = "rs-na0.qiniu.com";
157 | $zone->rsfHost = "rsf-na0.qiniu.com";
158 | $zone->apiHost = "api-na0.qiniu.com";
159 | } elseif (strstr($zone->iovipHost, "as0") !== false) {
160 | $zone->rsHost = "rs-as0.qiniu.com";
161 | $zone->rsfHost = "rsf-as0.qiniu.com";
162 | $zone->apiHost = "api-as0.qiniu.com";
163 | } else {
164 | $zone->rsHost = "rs.qiniu.com";
165 | $zone->rsfHost = "rsf.qiniu.com";
166 | $zone->apiHost = "api.qiniu.com";
167 | }
168 |
169 | return $zone;
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/cloud/qiniu/src/Qiniu/functions.php:
--------------------------------------------------------------------------------
1 | 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
84 | JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
85 | JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
86 | JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
87 | JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
88 | );
89 |
90 | if (empty($json)) {
91 | return null;
92 | }
93 | $data = \json_decode($json, $assoc, $depth);
94 |
95 | if (JSON_ERROR_NONE !== json_last_error()) {
96 | $last = json_last_error();
97 | throw new \InvalidArgumentException(
98 | 'Unable to parse JSON data: '
99 | . (isset($jsonErrors[$last])
100 | ? $jsonErrors[$last]
101 | : 'Unknown error')
102 | );
103 | }
104 |
105 | return $data;
106 | }
107 |
108 | /**
109 | * 计算七牛API中的数据格式
110 | *
111 | * @param $bucket 待操作的空间名
112 | * @param $key 待操作的文件名
113 | *
114 | * @return string 符合七牛API规格的数据格式
115 | * @link http://developer.qiniu.com/docs/v6/api/reference/data-formats.html
116 | */
117 | function entry($bucket, $key)
118 | {
119 | $en = $bucket;
120 | if (!empty($key)) {
121 | $en = $bucket . ':' . $key;
122 | }
123 | return base64_urlSafeEncode($en);
124 | }
125 |
126 | /**
127 | * array 辅助方法,无值时不set
128 | *
129 | * @param $array 待操作array
130 | * @param $key key
131 | * @param $value value 为null时 不设置
132 | *
133 | * @return array 原来的array,便于连续操作
134 | */
135 | function setWithoutEmpty(&$array, $key, $value)
136 | {
137 | if (!empty($value)) {
138 | $array[$key] = $value;
139 | }
140 | return $array;
141 | }
142 |
143 | /**
144 | * 缩略图链接拼接
145 | *
146 | * @param string $url 图片链接
147 | * @param int $mode 缩略模式
148 | * @param int $width 宽度
149 | * @param int $height 长度
150 | * @param string $format 输出类型
151 | * @param int $quality 图片质量
152 | * @param int $interlace 是否支持渐进显示
153 | * @param int $ignoreError 忽略结果
154 | * @return string
155 | * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/imageview2.html
156 | * @author Sherlock Ren
157 | */
158 | function thumbnail(
159 | $url,
160 | $mode,
161 | $width,
162 | $height,
163 | $format = null,
164 | $quality = null,
165 | $interlace = null,
166 | $ignoreError = 1
167 | ) {
168 |
169 | static $imageUrlBuilder = null;
170 | if (is_null($imageUrlBuilder)) {
171 | $imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
172 | }
173 |
174 | return call_user_func_array(array($imageUrlBuilder, 'thumbnail'), func_get_args());
175 | }
176 |
177 | /**
178 | * 图片水印
179 | *
180 | * @param string $url 图片链接
181 | * @param string $image 水印图片链接
182 | * @param numeric $dissolve 透明度
183 | * @param string $gravity 水印位置
184 | * @param numeric $dx 横轴边距
185 | * @param numeric $dy 纵轴边距
186 | * @param numeric $watermarkScale 自适应原图的短边比例
187 | * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html
188 | * @return string
189 | * @author Sherlock Ren
190 | */
191 | function waterImg(
192 | $url,
193 | $image,
194 | $dissolve = 100,
195 | $gravity = 'SouthEast',
196 | $dx = null,
197 | $dy = null,
198 | $watermarkScale = null
199 | ) {
200 |
201 | static $imageUrlBuilder = null;
202 | if (is_null($imageUrlBuilder)) {
203 | $imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
204 | }
205 |
206 | return call_user_func_array(array($imageUrlBuilder, 'waterImg'), func_get_args());
207 | }
208 |
209 | /**
210 | * 文字水印
211 | *
212 | * @param string $url 图片链接
213 | * @param string $text 文字
214 | * @param string $font 文字字体
215 | * @param string $fontSize 文字字号
216 | * @param string $fontColor 文字颜色
217 | * @param numeric $dissolve 透明度
218 | * @param string $gravity 水印位置
219 | * @param numeric $dx 横轴边距
220 | * @param numeric $dy 纵轴边距
221 | * @link http://developer.qiniu.com/code/v6/api/kodo-api/image/watermark.html#text-watermark
222 | * @return string
223 | * @author Sherlock Ren
224 | */
225 | function waterText(
226 | $url,
227 | $text,
228 | $font = '黑体',
229 | $fontSize = 0,
230 | $fontColor = null,
231 | $dissolve = 100,
232 | $gravity = 'SouthEast',
233 | $dx = null,
234 | $dy = null
235 | ) {
236 |
237 | static $imageUrlBuilder = null;
238 | if (is_null($imageUrlBuilder)) {
239 | $imageUrlBuilder = new \Qiniu\Processing\ImageUrlBuilder;
240 | }
241 |
242 | return call_user_func_array(array($imageUrlBuilder, 'waterText'), func_get_args());
243 | }
244 |
245 | /**
246 | * 从uptoken解析accessKey和bucket
247 | *
248 | * @param $upToken
249 | * @return array(ak,bucket,err=null)
250 | */
251 | function explodeUpToken($upToken)
252 | {
253 | $items = explode(':', $upToken);
254 | if (count($items) != 3) {
255 | return array(null, null, "invalid uptoken");
256 | }
257 | $accessKey = $items[0];
258 | $putPolicy = json_decode(base64_decode($items[2]));
259 | $scope = $putPolicy->scope;
260 | $scopeItems = explode(':', $scope);
261 | $bucket = $scopeItems[0];
262 | return array($accessKey, $bucket, null);
263 | }
264 | }
265 |
--------------------------------------------------------------------------------
/css/border-anim-h.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/border-anim-h.gif
--------------------------------------------------------------------------------
/css/border-anim-v.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/border-anim-v.gif
--------------------------------------------------------------------------------
/css/graphics/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/close.png
--------------------------------------------------------------------------------
/css/graphics/closeX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/closeX.png
--------------------------------------------------------------------------------
/css/graphics/controlbar-black-border.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar-black-border.gif
--------------------------------------------------------------------------------
/css/graphics/controlbar-text-buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar-text-buttons.png
--------------------------------------------------------------------------------
/css/graphics/controlbar-white-small.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar-white-small.gif
--------------------------------------------------------------------------------
/css/graphics/controlbar-white.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar-white.gif
--------------------------------------------------------------------------------
/css/graphics/controlbar2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar2.gif
--------------------------------------------------------------------------------
/css/graphics/controlbar3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar3.gif
--------------------------------------------------------------------------------
/css/graphics/controlbar4-hover.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar4-hover.gif
--------------------------------------------------------------------------------
/css/graphics/controlbar4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/controlbar4.gif
--------------------------------------------------------------------------------
/css/graphics/fullexpand.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/fullexpand.gif
--------------------------------------------------------------------------------
/css/graphics/geckodimmer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/geckodimmer.png
--------------------------------------------------------------------------------
/css/graphics/icon.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/icon.gif
--------------------------------------------------------------------------------
/css/graphics/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/loader.gif
--------------------------------------------------------------------------------
/css/graphics/loader.white.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/loader.white.gif
--------------------------------------------------------------------------------
/css/graphics/outlines/beveled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/outlines/beveled.png
--------------------------------------------------------------------------------
/css/graphics/outlines/drop-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/outlines/drop-shadow.png
--------------------------------------------------------------------------------
/css/graphics/outlines/glossy-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/outlines/glossy-dark.png
--------------------------------------------------------------------------------
/css/graphics/outlines/outer-glow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/outlines/outer-glow.png
--------------------------------------------------------------------------------
/css/graphics/outlines/rounded-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/outlines/rounded-black.png
--------------------------------------------------------------------------------
/css/graphics/outlines/rounded-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/outlines/rounded-white.png
--------------------------------------------------------------------------------
/css/graphics/resize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/resize.gif
--------------------------------------------------------------------------------
/css/graphics/scrollarrows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/scrollarrows.png
--------------------------------------------------------------------------------
/css/graphics/zoomin.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/zoomin.cur
--------------------------------------------------------------------------------
/css/graphics/zoomout.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jzwalk/HighSlide/58f101f0804b1be4fe1369a6e56175734ae89601/css/graphics/zoomout.cur
--------------------------------------------------------------------------------
/css/highslide-ie6.css:
--------------------------------------------------------------------------------
1 | .closebutton {
2 | /* NOTE! This URL is relative to the HTML page, not the CSS */
3 | filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
4 | src='../highslide/graphics/close.png', sizingMethod='scale');
5 |
6 | background: none;
7 | cursor: hand;
8 | }
9 |
10 | /* Viewport fixed hack */
11 | .highslide-viewport {
12 | position: absolute;
13 | left: expression( ( ( ignoreMe1 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
14 | top: expression( ( ignoreMe2 = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) + 'px' );
15 | width: expression( ( ( ignoreMe3 = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) ) + 'px' );
16 | height: expression( ( ( ignoreMe4 = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) ) + 'px' );
17 | }
18 |
19 | /* Thumbstrip PNG fix */
20 | .highslide-scroll-down, .highslide-scroll-up {
21 | position: relative;
22 | overflow: hidden;
23 | }
24 | .highslide-scroll-down div, .highslide-scroll-up div {
25 | /* NOTE! This URL is relative to the HTML page, not the CSS */
26 | filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
27 | src='../highslide/graphics/scrollarrows.png', sizingMethod='scale');
28 | background: none !important;
29 | position: absolute;
30 | cursor: hand;
31 | width: 75px;
32 | height: 75px !important;
33 | }
34 | .highslide-thumbstrip-horizontal .highslide-scroll-down div {
35 | left: -50px;
36 | top: -15px;
37 | }
38 | .highslide-thumbstrip-horizontal .highslide-scroll-up div {
39 | top: -15px;
40 | }
41 | .highslide-thumbstrip-vertical .highslide-scroll-down div {
42 | top: -50px;
43 | }
44 |
45 | /* Thumbstrip marker arrow trasparent background fix */
46 | .highslide-thumbstrip .highslide-marker {
47 | border-color: white; /* match the background */
48 | }
49 | .dark .highslide-thumbstrip-horizontal .highslide-marker {
50 | border-color: #111;
51 | }
52 | .highslide-viewport .highslide-marker {
53 | border-color: #333;
54 | }
55 | .highslide-thumbstrip {
56 | float: left;
57 | }
58 |
59 | /* Positioning fixes for the control bar */
60 | .text-controls .highslide-controls {
61 | width: 480px;
62 | }
63 | .text-controls a span {
64 | width: 4em;
65 | }
66 | .text-controls .highslide-full-expand a span {
67 | width: 0;
68 | }
69 | .text-controls .highslide-close a span {
70 | width: 0;
71 | }
72 |
73 | /* Special */
74 | .in-page .highslide-thumbstrip-horizontal .highslide-marker {
75 | border-bottom: gray;
76 | }
77 |
--------------------------------------------------------------------------------
/css/imgareaselect-animated.css:
--------------------------------------------------------------------------------
1 | /*
2 | * ias animated border style
3 | */
4 |
5 | .ias-border1 {
6 | background: url(border-anim-v.gif) repeat-y left top;
7 | }
8 |
9 | .ias-border2 {
10 | background: url(border-anim-h.gif) repeat-x left top;
11 | }
12 |
13 | .ias-border3 {
14 | background: url(border-anim-v.gif) repeat-y right top;
15 | }
16 |
17 | .ias-border4 {
18 | background: url(border-anim-h.gif) repeat-x left bottom;
19 | }
20 |
21 | .ias-border1, .ias-border2,
22 | .ias-border3, .ias-border4 {
23 | filter: alpha(opacity=50);
24 | opacity: 0.5;
25 | }
26 |
27 | .ias-handle {
28 | background-color: #fff;
29 | border: solid 1px #000;
30 | filter: alpha(opacity=50);
31 | opacity: 0.5;
32 | }
33 |
34 | .ias-outer {
35 | background-color: #000;
36 | filter: alpha(opacity=50);
37 | opacity: 0.5;
38 | }
39 |
40 | .ias-selection {
41 | }
--------------------------------------------------------------------------------
/js/imgareaselect.js:
--------------------------------------------------------------------------------
1 | eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(m($){18 W=2v.4T,D=2v.4S,F=2v.4R,u=2v.4Q;m V(){C $("<4P/>")};$.N=m(T,c){18 O=$(T),1F,A=V(),1k=V(),I=V().r(V()).r(V()).r(V()),B=V().r(V()).r(V()).r(V()),E=$([]),1K,G,l,17={v:0,l:0},Q,M,1l,1g={v:0,l:0},12=0,1J="1H",2k,2j,1t,1s,S,1B,1A,2o,2n,14,1Q,a,b,j,g,f={a:0,b:0,j:0,g:0,H:0,L:0},2u=R.4O,1M=4N.4M,$p,d,i,o,w,h,2p;m 1n(x){C x+17.v-1g.v};m 1m(y){C y+17.l-1g.l};m 1b(x){C x-17.v+1g.v};m 1a(y){C y-17.l+1g.l};m 1z(3J){C 3J.4L-1g.v};m 1y(3I){C 3I.4K-1g.l};m 13(32){18 1i=32||1t,1h=32||1s;C{a:u(f.a*1i),b:u(f.b*1h),j:u(f.j*1i),g:u(f.g*1h),H:u(f.j*1i)-u(f.a*1i),L:u(f.g*1h)-u(f.b*1h)}};m 23(a,b,j,g,31){18 1i=31||1t,1h=31||1s;f={a:u(a/1i||0),b:u(b/1h||0),j:u(j/1i||0),g:u(g/1h||0)};f.H=f.j-f.a;f.L=f.g-f.b};m 1f(){9(!1F||!O.H()){C}17={v:u(O.2t().v),l:u(O.2t().l)};Q=O.2Y();M=O.3H();17.l+=(O.30()-M)>>1;17.v+=(O.2q()-Q)>>1;1B=u(c.4J/1t)||0;1A=u(c.4I/1s)||0;2o=u(F(c.4H/1t||1<<24,Q));2n=u(F(c.4G/1s||1<<24,M));9($().4F=="1.3.2"&&1J=="21"&&!2u["4E"]){17.l+=D(R.1q.2r,2u.2r);17.v+=D(R.1q.2s,2u.2s)}1g=/1H|4D/.1c(1l.q("1p"))?{v:u(1l.2t().v)-1l.2s(),l:u(1l.2t().l)-1l.2r()}:1J=="21"?{v:$(R).2s(),l:$(R).2r()}:{v:0,l:0};G=1n(0);l=1m(0);9(f.j>Q||f.g>M){1U()}};m 1V(3F){9(!1Q){C}A.q({v:1n(f.a),l:1m(f.b)}).r(1k).H(w=f.H).L(h=f.L);1k.r(I).r(E).q({v:0,l:0});I.H(D(w-I.2q()+I.2Y(),0)).L(D(h-I.30()+I.3H(),0));$(B[0]).q({v:G,l:l,H:f.a,L:M});$(B[1]).q({v:G+f.a,l:l,H:w,L:f.b});$(B[2]).q({v:G+f.j,l:l,H:Q-f.j,L:M});$(B[3]).q({v:G+f.a,l:l+f.g,H:w,L:M-f.g});w-=E.2q();h-=E.30();2O(E.3f){15 8:$(E[4]).q({v:w>>1});$(E[5]).q({v:w,l:h>>1});$(E[6]).q({v:w>>1,l:h});$(E[7]).q({l:h>>1});15 4:E.3G(1,3).q({v:w});E.3G(2,4).q({l:h})}9(3F!==Y){9($.N.2Z!=2R){$(R).U($.N.2z,$.N.2Z)}9(c.1T){$(R)[$.N.2z]($.N.2Z=2R)}}9(1j&&I.2q()-I.2Y()==2){I.q("3E",0);3x(m(){I.q("3E","4C")},0)}};m 22(3D){1f();1V(3D);a=1n(f.a);b=1m(f.b);j=1n(f.j);g=1m(f.g)};m 27(2X,2w){c.1P?2X.4B(c.1P,2w):2X.1r()};m 1d(2W){18 x=1b(1z(2W))-f.a,y=1a(1y(2W))-f.b;9(!2p){1f();2p=11;A.1G("4A",m(){2p=Y})}S="";9(c.2D){9(y<=c.1W){S="n"}X{9(y>=f.L-c.1W){S="s"}}9(x<=c.1W){S+="w"}X{9(x>=f.H-c.1W){S+="e"}}}A.q("2V",S?S+"-19":c.26?"4z":"");9(1K){1K.4y()}};m 2S(4x){$("1q").q("2V","");9(c.4w||f.H*f.L==0){27(A.r(B),m(){$(J).1r()})}$(R).U("P",2l);A.P(1d);c.2f(T,13())};m 2C(1X){9(1X.3z!=1){C Y}1f();9(S){$("1q").q("2V",S+"-19");a=1n(f[/w/.1c(S)?"j":"a"]);b=1m(f[/n/.1c(S)?"g":"b"]);$(R).P(2l).1G("1x",2S);A.U("P",1d)}X{9(c.26){2k=G+f.a-1z(1X);2j=l+f.b-1y(1X);A.U("P",1d);$(R).P(2T).1G("1x",m(){c.2f(T,13());$(R).U("P",2T);A.P(1d)})}X{O.1O(1X)}}C Y};m 1w(3C){9(14){9(3C){j=D(G,F(G+Q,a+W(g-b)*14*(j>a||-1)));g=u(D(l,F(l+M,b+W(j-a)/14*(g>b||-1))));j=u(j)}X{g=D(l,F(l+M,b+W(j-a)/14*(g>b||-1)));j=u(D(G,F(G+Q,a+W(g-b)*14*(j>a||-1))));g=u(g)}}};m 1U(){a=F(a,G+Q);b=F(b,l+M);9(W(j-a)<1B){j=a-1B*(jG+Q){a=G+Q-1B}}}9(W(g-b)<1A){g=b-1A*(gl+M){b=l+M-1A}}}j=D(G,F(j,G+Q));g=D(l,F(g,l+M));1w(W(j-a)2o){j=a-2o*(j2n){g=b-2n*(g=0){E.H(5).L(5)}9(o=c.2K){E.q({2K:o,2H:"3m"})}1R(E,{3n:"2J-28",3l:"2I-28",3o:"1e"})}1t=c.4l/Q||1;1s=c.4k/M||1;9(K.a!=3q){23(K.a,K.b,K.j,K.g);K.2F=!K.1r}9(K.1T){c.1T=$.2c({2b:1,2a:"19"},K.1T)}B.29(c.1S+"-4j");1k.29(c.1S+"-4i");3p(i=0;i++<4;){$(I[i-1]).29(c.1S+"-2J"+i)}1R(1k,{4h:"2I-28",4g:"1e"});1R(I,{3o:"1e",2K:"2J-H"});1R(B,{4f:"2I-28",4e:"1e"});9(o=c.3n){$(I[0]).q({2H:"3m",3k:o})}9(o=c.3l){$(I[1]).q({2H:"4d",3k:o})}A.2G(1k.r(I).r(1K)).2G(E);9(1j){9(o=(B.q("3j")||"").3i(/1e=(\\d+)/)){B.q("1e",o[1]/1Z)}9(o=(I.q("3j")||"").3i(/1e=(\\d+)/)){I.q("1e",o[1]/1Z)}}9(K.1r){27(A.r(B))}X{9(K.2F&&1F){1Q=11;A.r(B).2E(c.1P||0);22()}}14=(d=(c.4c||"").4b(/:/))[0]/d[1];O.r(B).U("1O",2A);9(c.1E||c.1D===Y){A.U("P",1d).U("1O",2C);$(3h).U("19",2B)}X{9(c.1D||c.1E===Y){9(c.2D||c.26){A.P(1d).1O(2C)}$(3h).19(2B)}9(!c.4a){O.r(B).1O(2A)}}c.1D=c.1E=1Y};J.1o=m(){25({1E:11});A.r(B).1o()};J.49=m(){C c};J.33=25;J.48=13;J.47=23;J.46=1N;J.45=22;18 1j=(/44 ([\\w.]+)/i.43(1M)||[])[1],3c=/42/i.1c(1M),3d=/41/i.1c(1M)&&!/3Z/i.1c(1M);$p=O;3g($p.3f){12=D(12,!1L($p.q("z-3e"))?$p.q("z-3e"):12);9($p.q("1p")=="21"){1J="21"}$p=$p.20(":3Y(1q)")}12=c.1I||12;9(1j){O.3X("3W","3V")}$.N.2z=1j||3d?"3U":"3T";9(3c){1K=V().q({H:"1Z%",L:"1Z%",1p:"1H",1I:12+2||2})}A.r(B).q({3b:"3a",1p:1J,3S:"3a",1I:12||"0"});A.q({1I:12+2||2});1k.r(I).q({1p:"1H",36:0});T.35||T.3R=="35"||!O.2y("3Q")?2x():O.1G("3P",2x);9(!1F&&1j&&1j>=7){T.34=T.34}};$.2w.N=m(Z){Z=Z||{};J.3O(m(){9($(J).1C("N")){9(Z.1o){$(J).1C("N").1o();$(J).3N("N")}X{$(J).1C("N").33(Z)}}X{9(!Z.1o){9(Z.1D===1Y&&Z.1E===1Y){Z.1D=11}$(J).1C("N",3M $.N(J,Z))}}});9(Z.3L){C $(J).1C("N")}C J}})(3K);',62,304,'|||||||||if|x1|y1|_7|||_23|y2|||x2||top|function||||css|add|||_4|left|||||_a|_d|return|_2|_e|_3|_10|width|_c|this|_55|height|_13|imgAreaSelect|_8|mousemove|_12|document|_1c|_6|unbind|_5|_1|else|false|_58||true|_16|_2c|_21|case|_50|_11|var|resize|_29|_28|test|_3a|opacity|_30|_15|sy|sx|_35|_b|_14|_27|_26|remove|position|body|hide|_1b|_1a|break|_45|_42|mouseup|evY|evX|_1e|_1d|data|enable|disable|_9|one|absolute|zIndex|_17|_f|isNaN|ua|_4a|mousedown|fadeSpeed|_22|_51|classPrefix|keys|_31|_32|resizeMargin|_40|undefined|100|parent|fixed|_36|_2e||_4f|movable|_38|color|addClass|ctrl|shift|extend|_54|altKey|onSelectEnd|onSelectChange|_49|_4c|_19|_18|_3e|_48|_20|_1f|_25|outerWidth|scrollTop|scrollLeft|offset|_24|Math|fn|_4e|is|keyPress|_4b|_4d|_3f|resizable|fadeIn|show|append|borderStyle|background|border|borderWidth|handles|_53|key|switch|alt|arrows|_34|_3c|_41|_44|cursor|_3b|_39|innerWidth|onKeyPress|outerHeight|_2f|_2d|setOptions|src|complete|fontSize||||hidden|visibility|_56|_57|index|length|while|window|match|filter|borderColor|borderColor2|solid|borderColor1|borderOpacity|for|null|_52|default|originalEvent|ctrlKey|shiftKey|onInit|setTimeout|onSelectStart|which|_47|_46|_43|_37|margin|_33|slice|innerHeight|_2b|_2a|jQuery|instance|new|removeData|each|load|img|readyState|overflow|keypress|keydown|on|unselectable|attr|not|chrome||webkit|opera|exec|msie|update|cancelSelection|setSelection|getSelection|getOptions|persistent|split|aspectRatio|dashed|outerOpacity|outerColor|selectionOpacity|selectionColor|selection|outer|imageHeight|imageWidth|parseInt|handle|corners|in|keyCode|imgareaselect|animated|instanceof|visible|preventDefault|autoHide|_3d|toggle|move|mouseout|fadeOut|auto|relative|getBoundingClientRect|jquery|maxHeight|maxWidth|minHeight|minWidth|pageY|pageX|userAgent|navigator|documentElement|div|round|min|max|abs'.split('|')))
2 |
--------------------------------------------------------------------------------