├── .gitignore
├── README.md
├── filesystem
└── upyun.php
├── images
└── upyun_icon.png
├── includes
├── bootstrap_compatible.php
└── hacklogra_upyun.class.php
├── languages
├── hacklog-remote-attachment-zh_CN.mo
└── hacklog-remote-attachment-zh_CN.po
├── loader.php
├── screenshot-1.png
├── screenshot-2.png
├── upload.php
└── vendor
└── upyun.class.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .htaccess
2 | wp-config.php
3 | wp-content/uploads/
4 | wp-content/blogs.dir/
5 | wp-content/upgrade/
6 | wp-content/backup-db/
7 | wp-content/advanced-cache.php
8 | wp-content/wp-cache-config.php
9 | sitemap.xml
10 | *.log
11 | wp-content/cache/
12 | wp-content/backups/
13 | sitemap.xml.gz
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Wordpress-plugin-for-UPYUN
2 |
3 | ##WordPress插件信息
4 |
5 | ### Hacklog Remote Attachment Upyun
6 |
7 | ------------------------------------------------------------
8 |
9 | * Contributors: ihacklog
10 | * Donate link: http://ihacklog.com/donate
11 | * Tags: attachment,manager,admin,images,thumbnail,ftp,remote
12 | * Requires at least: 3.3
13 | * Tested up to: 4.6.1
14 | * Stable tag: 1.5.1
15 |
16 | ------------------------------------------------------------
17 | 此插件用于为你的WP博客添加Upyun附件上传支持。
18 | 可以与WordPress无缝结合,通过WordPress上传图片和文件到upyun, 支持大文件上传(需要开启表单 API)和防盗链功能。
19 | 有任何问题,欢迎大家提交issue:
20 |
21 | github:
22 | https://github.com/ihacklog/hacklog-remote-attachment-upyun/issues
23 |
24 | Adds remote attachments support for your WordPress blog.
25 |
26 | ------------------------------------------------------------
27 |
28 | ### Description
29 | Features: Adds remote attachments support for your WordPress blog.
30 |
31 | 此插件用于为你的WP博客添加Upyun附件上传支持。
32 |
33 | 可以与WordPress无缝结合,通过WordPress上传图片和文件到upyun, 支持大文件上传(需要开启表单 API)和防盗链功能。
34 |
35 | * 支持上传文件到upyun服务器(图片、其它附件等)
36 | * 支持同步删除(在WP后台媒体管理“删除”附件后,upyun服务器中的文件也随之删除)
37 | * @TODO 增加图片编辑功能
38 | * @TODO 优化防盗链功能
39 |
40 | * 1.1.0 增加与水印插件的兼容性,使上传到远程服务器的图片同样可以加上水印
41 | * 1.2.0 增加重复文件检测,避免同名文件被覆盖。更新和完善了帮助信息。
42 | * 1.2.1 修正在后台上传主题或插件时的bug.
43 | * 1.2.7 增加三种http数据发送方式支持远程附件(curl,fsockopen,streams),方便没有curl扩展支持的朋友.
44 | * 1.2.8 增加对xmlrpc支持(支持通过Windows Live Writer 上传图片时自动上传到Upyun服务器)
45 | * 1.2.9 修复Windows Live Writer 上传图片时url不正确的bug
46 | * 1.3.0 修复首次使用插件时,又拍云空间使用量为0时显示“测试连接失败”的bug.增加更详细的错误信息提示。
47 | * 1.4.0 增加form API上传支持,可上传100MB以内大小的文件(又拍云form API目前最大只支持100MB)
48 | * 1.4.2 增加空间TOKEN防盗链功能支持
49 | * 1.4.3 修复同一地方多处调用url时重复签名的bug
50 | * 1.4.4 修复点击Tools区的链接时,提示“没有权限”的BUG.
51 | * 1.4.5 更改url生成方式,避免因插件目录名称不同而导致404错误。增加对WP 3.9.1支持。修改对WP_http的调用方式。
52 | * 1.4.6 修复在高版本WP中打开插件表单API上传页面时报错的bug.修复默认表单API超时时间未设置时导致无法使用表单API上传的bug.
53 | * 1.5.0 编辑图片功能已经支持!
54 | * 1.5.1 fix #18 修复一个warning提示. (thanks to [GeorgeYan](https://github.com/ihacklog/hacklog-remote-attachment-upyun/issues/18))
55 | * 1.5.2 增加wp 4.6.1 支持,使用upyun 最新sdk
56 | * 1.5.3 修复使用form api时一个php警告(form api上传时不应用重复应用本插件的非form api hook).
57 | 优化代码和修复若干bug. 移除无用的crypt类.此次更新,需要重新填写一次密码.
58 |
59 | 更多信息请访问[插件主页](http://ihacklog.com/?p=5001 "plugin homepage") 获取关于插件的更多信息,使用技巧等.
60 | [安装指导](http://ihacklog.com/?p=4993 "安装指导")
61 |
62 | ======================================================================================
63 |
64 | For MORE information,please visit the [plugin homepage](http://ihacklog.com/?p=5204 "plugin homepage") for any questions about the plugin.
65 |
66 | [installation guide](http://ihacklog.com/?p=4993 "installation guide")
67 |
68 | * version 1.1.0 added compatibility with watermark plugins
69 | * version 1.2.0 added duplicated file checking,so that the existed remote files will not be overwrote.
70 | * version 1.2.1 fixed the bug when uploading new theme or plugin this plugin may cause it to fail.
71 |
72 | ### Installation
73 |
74 | 1. Upload the whole fold `hacklog-remote-attachment` to the `/wp-content/plugins/` directory
75 | 2. Activate the plugin through the 'Plugins' menu in WordPress
76 | 3. Configure the plugin via `Settings` -> `Hacklog Remote Attachment` menu and it's OK now,you can upload attachments(iamges,videos,audio,etc.) to the remote FTP server.
77 | 4. If your have moved all your local server files to remote server,then you can `UPDATE THE DATABASE` so that all your attachments URLs will be OK.
78 | You can visit [plugin homepage](http://ihacklog.com/?p=5001 "plugin homepage") for detailed installation guide.
79 |
80 | ### Screenshots
81 |
82 |
83 | 
84 |
85 |
86 |
87 | 
88 |
89 |
90 |
91 | ### Frequently Asked Questions
92 | see
93 | [Hacklog Remote Attachment FAQ](http://ihacklog.com/?p=5001 "Hacklog Remote Attachment FAQ")
94 |
95 |
96 | ### Upgrade Notice
97 | #### 1.4.x upgrade to 1.4.2
98 | 增加空间TOKEN防盗链功能支持
99 |
100 | #### 1.3.0 upgrade to 1.4.0
101 | 如果要使用**表单 API 功能**,注意在又拍云空间管理里面开启表单 API功能,并在插件后台选项中更新表单 API密匙.
102 |
103 |
104 | ### Changelog
105 |
106 | ### 1.4.3
107 | * fixed: the bug that say "you have no permission to do this" when click the
108 | link in Tools area.
109 |
110 | ### 1.4.3
111 | * fixed: the bug that duplicated sign the same url.
112 |
113 | ### 1.4.2
114 | * added: TOKEN based anti-leeching feature support.
115 |
116 | #### 1.4.1
117 | * added: HTML5 file info detect.
118 |
119 | #### 1.4.0
120 | * added: form API uploading support.
121 |
122 | #### 1.3.0
123 | * fixed: the bug that say "Connection failed" when the bucket is empty in the first time use this plugin.
124 | * improved: get verbose error message displayed.
125 |
126 | #### 1.2.9
127 | * fixed: Windows Live Writer file uploading bug(url incorrect).
128 |
129 | #### 1.2.8
130 | * added: xmlrpc support (when use Windows Live Writer or other client via xmlrpc upload attahcment,the attachment will auto uploaded to remote FTP server )
131 |
132 | #### 1.2.7
133 | * added: curl,fsockopen,streams support for http communication.
134 |
135 | #### 1.2.6
136 | * added: duplicated thumbnail filename (this things may happen when crop is TRUE)
137 |
138 | #### 1.2.5
139 | * changed: use simple xor cypher instead of using blow_fish
140 |
141 | #### 1.2.4
142 | * fixe: curl connection timeout will return '',change the message to more detailed one[class UpYun].
143 |
144 | #### 1.2.3
145 | * changed: load_textdomain param 3 uses basename(dirname()) instead of plugin_basename
146 | * fixed: trim spaces on options
147 | * improved: Prevent direct access to files
148 | * changed: uses upyun HTTP REST API to create and delete directory,files
149 | * improved: protect your API password with the strong blowfish cypher.
150 | * improved: the plugin settings page can show you the space useage of your remote bucket.
151 |
152 | #### 1.2.2
153 | * ported from Hacklog Remote Attachment
154 |
--------------------------------------------------------------------------------
/filesystem/upyun.php:
--------------------------------------------------------------------------------
1 | errors = new WP_Error();
42 | $this->check_param ($bucketname, $username, $password, $endpoint, $timeout);
43 | parent::__construct($bucketname, $username, $password, $endpoint, $timeout);
44 |
45 | }
46 |
47 | /**
48 | * @param $form_api_params
49 | */
50 | public function set_form_api_params($form_api_params) {
51 | if (!empty($form_api_params['form_api_secret'])) {
52 | $this->form_api_secret = $form_api_params['form_api_secret'];
53 | }
54 | if (!empty($form_api_params['anti_leech_token'])) {
55 | $this->anti_leech_token = $form_api_params['anti_leech_token'];
56 | }
57 | if (!empty($form_api_params['form_api_allowed_ext'])) {
58 | $this->form_api_allowed_ext = $form_api_params['form_api_allowed_ext'];
59 | }
60 | //form_api_content_max_length
61 | if (!empty($form_api_params['form_api_content_max_length'])) {
62 | $this->form_api_content_max_length = 1024 * 1024 * $form_api_params['form_api_content_max_length'];
63 | }
64 | if (!empty($form_api_params['form_api_timeout'])) {
65 | $this->form_api_timeout = $form_api_params['form_api_timeout'];
66 | }
67 | if (!empty($form_api_params['anti_leech_timeout'])) {
68 | $this->anti_leech_timeout = $form_api_params['anti_leech_timeout'];
69 | }
70 | }
71 |
72 |
73 | /**
74 | * check the needed param
75 | * @param $bucketname
76 | * @param $username
77 | * @param $password
78 | * @param $endpoint
79 | * @param $timeout
80 | */
81 | public function check_param($bucketname, $username, $password, $endpoint, $timeout) {
82 | if (empty($endpoint))
83 | {
84 | $this->errors->add ( 'empty_api_domain', __ ( 'api_domain is required' ) );
85 | }
86 |
87 | if (empty ($bucketname))
88 | {
89 | $this->errors->add ( 'empty_bucketname', __ ( 'bucketname is required' ) );
90 | }
91 |
92 | if (empty ($username))
93 | {
94 | $this->errors->add ( 'empty_username', __ ( 'username is required' ) );
95 | }
96 | if (empty ($password))
97 | {
98 | $this->errors->add ( 'empty_password', __ ( 'password is required' ) );
99 | }
100 | }
101 |
102 | // -------------------------START form api -------------------------------- //
103 |
104 | private function get_form_api_secret() {
105 | return $this->form_api_secret;
106 | }
107 |
108 | public function check_form_api_internal_error() {
109 | if (!isset($_GET['non-sign'])) {
110 | return false;
111 | }
112 | if( md5("{$_GET['code']}&{$_GET['message']}&{$_GET['url']}&{$_GET['time']}&") == $_GET['non-sign'] )
113 | {
114 | return true;
115 | }
116 | else
117 | {
118 | return false;
119 | }
120 | }
121 |
122 | public function check_form_api_return_param() {
123 | if (!isset($_GET['sign'])) {
124 | return false;
125 | }
126 | if( md5("{$_GET['code']}&{$_GET['message']}&{$_GET['url']}&{$_GET['time']}&". $this->get_form_api_secret() ) == $_GET['sign'] )
127 | {
128 | return true;
129 | }
130 | else
131 | {
132 | return false;
133 | }
134 | }
135 |
136 | /**
137 | * md5(policy+'&'+表单API验证密匙)
138 | */
139 | public function get_form_api_signature($policy) {
140 | return md5($policy . '&' . $this->get_form_api_secret() );
141 | }
142 |
143 | public function build_policy($args) {
144 | $default = array(
145 | 'expire' => $this->form_api_timeout, // 300 s
146 | 'path' => '/{year}/{mon}/{random}{.suffix}', // full relative path
147 | 'allow_file_ext' => $this->form_api_allowed_ext,
148 | 'content_length_range' =>'0,' . $this->form_api_content_max_length, // 10MB( 10485760) 20MB ( 20971520 ),最大为100MB ( 104857600 )
149 | 'return_url' => plugins_url('upload.php', HACKLOG_RA_UPYUN_LOADER),
150 | 'notify_url' => '',
151 | );
152 | $args = array_merge($default,$args);
153 | $policydoc = array(
154 | "bucket" => $args['bucket'], /// 空间名
155 | "expiration" => time() + $args['expire'], /// 该次授权过期时间
156 | "save-key" => $args['path'], /// 命名规则,/2011/12/随机.扩展名
157 | "allow-file-type" => $args['allow_file_ext'], /// 仅允许上传图片
158 | "content-length-range" => $args['content_length_range'] , /// 文件在 100K 以下
159 | "return-url" => $args['return_url'] , /// 回调地址
160 | "notify-url" =>$args['notify_url'] /// 异步回调地址
161 | );
162 | //var_dump($policydoc);
163 | $policy = base64_encode(json_encode($policydoc)); /// 注意 base64 编码后的 policy字符串中不包含换行符!
164 | return $policy;
165 | }
166 |
167 | /**
168 | * ge_anti_leech_token_sign
169 | *签名格式:MD5(密匙&过期时间&URI){中间8位}+(过期时间)
170 | * 发送cookie或通过get传递
171 | *过期时间格式: UNIX TIME
172 | * @param string $uri 文件路径,必须以/开头
173 | * @return void
174 | */
175 | public function get_anti_leech_token_sign($uri = '/') {
176 | $uri = '/' . ltrim($uri,'/');
177 | $end_time = time() + $this->anti_leech_timeout;
178 | $token_sign =md5($this->anti_leech_token . '&' .$end_time.'&' . $uri );
179 | $sign = substr($token_sign, 12,8).$end_time;
180 | return $sign;
181 | }
182 |
183 | /**
184 | * @param string $uri
185 | * @return string
186 | */
187 | public function set_anti_leech_token_sign_uri($uri = '/') {
188 | $uri = ltrim($uri,'/');
189 | return $uri . '?' . self::TOKEN_NAME .'='. $this->get_anti_leech_token_sign($uri);
190 | }
191 |
192 | public function is_url_token_signed($url = '') {
193 | if(strpos($url, self::TOKEN_NAME) > 0 )
194 | {
195 | return true;
196 | }
197 | else
198 | {
199 | return false;
200 | }
201 | }
202 |
203 | /**
204 | * @param string $uri
205 | * @param string $cookie_path
206 | * @param string $cookie_domain
207 | */
208 | public function set_anti_leech_token_sign_cookie($uri='/',$cookie_path='/',$cookie_domain='') {
209 | $uri = ltrim($uri,'/');
210 | setcookie( self::TOKEN_NAME ,$this->get_anti_leech_token_sign($uri),time() + $this->anti_leech_timeout ,$cookie_path,$cookie_domain);
211 | }
212 | // -------------------------END form api -------------------------------- //
213 |
214 | public function safe_sdk_call($func, $args) {
215 | try {
216 | $ret = call_user_func_array([$this, $func], $args);
217 | } catch (UpYunException $e) {
218 | $this->errors->add($e->getCode(), $e->getMessage());
219 | $ret = false;
220 | if ($this->debug) {
221 | throw $e;
222 | }
223 | }
224 | return $ret;
225 | }
226 |
227 | /**
228 | * @access public
229 | *
230 | * @return bool
231 | */
232 | public function connect() {
233 | //test for authentication
234 | $finfo = $this->is_file('/');
235 | if ( !$finfo ) {
236 | return false; //There was an erorr connecting to the server.
237 | }
238 | return true;
239 | }
240 |
241 | /**
242 | * download the file or save to file handler
243 | * @param $file
244 | * @param resource $file_handle
245 | * @return mixed
246 | */
247 | public function get_contents($file, $file_handle = NULL) {
248 | return $this->safe_sdk_call('readFile', [$file, $file_handle]);
249 | }
250 |
251 | /**
252 | * @param $path target path
253 | * @param $file file content or file handler
254 | * @param bool $auto_mkdir
255 | * @param null $opts
256 | * @return mixed
257 | */
258 | public function put_contents($path, $file, $auto_mkdir = true, $opts = NULL) {
259 | return $this->safe_sdk_call('writeFile', [$path, $file, $auto_mkdir, $opts]);
260 | }
261 |
262 | /**
263 | * @access public
264 | *
265 | * @param string $source
266 | * @param string $destination
267 | * @param bool $overwrite
268 | * @return bool
269 | */
270 | public function copy($source, $destination, $overwrite = false) {
271 | $ret = false;
272 | $target_exists = $this->is_file($destination);
273 | if (!$overwrite && $target_exists) {
274 | return true;
275 | }
276 | $tmpf = tmpfile();
277 | if ($tmpf) {
278 | $this->get_contents($source, $tmpf);
279 | if ($target_exists) {
280 | $this->rm($destination);
281 | }
282 | $ret = $this->put_contents($destination, $tmpf);
283 | @unlink($tmpf);
284 | return $ret;
285 | }
286 | }
287 |
288 | /**
289 | * @access public
290 | *
291 | * @param string $source
292 | * @param string $destination
293 | * @param bool $overwrite
294 | * @return bool
295 | */
296 | public function move($source, $destination, $overwrite = false) {
297 | if ($this->copy($source, $destination, $overwrite)) {
298 | return $this->rm($source);
299 | }
300 | return false;
301 | }
302 |
303 | /**
304 | * @access public
305 | *
306 | * @param string $file
307 | * @return bool
308 | */
309 | public function rm($file) {
310 | return $this->safe_sdk_call('delete', [$file]);
311 | }
312 |
313 | /**
314 | * @access public
315 | *
316 | * @param string $file
317 | * @return bool
318 | */
319 | public function exists($file) {
320 | return $this->safe_sdk_call('getFileInfo', [$file]);
321 | }
322 |
323 | /**
324 | * @access public
325 | *
326 | * @param string $file
327 | * @return bool
328 | */
329 | public function is_file($file) {
330 | return $this->exists($file);
331 | }
332 |
333 | /**
334 | * @access public
335 | *
336 | * @param string $path
337 | * @return bool
338 | */
339 | public function is_dir($path) {
340 | return $this->exists($path);
341 | }
342 |
343 | /**
344 | * @access public
345 | *
346 | * @param string $file
347 | * @return bool
348 | */
349 | public function is_readable($file) {
350 | return $this->exists($file);
351 | }
352 |
353 | /**
354 | * @access public
355 | *
356 | * @param string $file
357 | * @return bool
358 | */
359 | public function is_writable($file) {
360 | return $this->exists($file);
361 | }
362 |
363 | /**
364 | * @access public
365 | *
366 | * @param string $file
367 | * @return bool
368 | */
369 | public function atime($file) {
370 | return false;
371 | }
372 |
373 | /**
374 | * @access public
375 | *
376 | * @param string $file
377 | * @return int
378 | */
379 | public function mtime($file) {
380 | return false;
381 | }
382 |
383 | /**
384 | * @access public
385 | *
386 | * @param string $file
387 | * @return int
388 | */
389 | public function size($file) {
390 | return false;
391 | }
392 |
393 | /**
394 | * @access public
395 | *
396 | * @param string $file
397 | * @return bool
398 | */
399 | public function touch($file) {
400 | return false;
401 | }
402 |
403 | /**
404 | * @param $path
405 | * @param bool $auto_mkdir
406 | * @return bool|mixed
407 | */
408 | public function mkdir($path, $auto_mkdir = true) {
409 | return $this->safe_sdk_call('makeDir', [$path, $auto_mkdir]);
410 | }
411 |
412 | /**
413 | * @access public
414 | *
415 | * @param string $path
416 | * @param bool $recursive
417 | * @return bool
418 | */
419 | public function rmdir($path, $recursive = false) {
420 | return $this->delete($path, $recursive);
421 | }
422 |
423 | public function get_dir_list($path = '/') {
424 | return $this->safe_sdk_call('getList', [$path]);
425 | }
426 |
427 | public function get_fileinfo($path) {
428 | return $this->safe_sdk_call('getFileInfo', [$path]);
429 | }
430 |
431 | public function get_fold_usage($bucket = '/') {
432 | return $this->safe_sdk_call('getFolderUsage', [$bucket]);
433 | }
434 |
435 | public function get_bucket_usage() {
436 | return $this->safe_sdk_call('getBucketUsage', []);
437 | }
438 |
439 | public function get_api_domain() {
440 | return $this->endpoint;
441 | }
442 | }
--------------------------------------------------------------------------------
/images/upyun_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monkey-wenjun/hacklog-remote-attachment-upyun/4c414acd25d6e566afcdf2b4d3976166847c5709/images/upyun_icon.png
--------------------------------------------------------------------------------
/includes/bootstrap_compatible.php:
--------------------------------------------------------------------------------
1 | 50 && mt_rand( 0, (int)( $c / 50 ) ) == 1 ) ) {
67 | require_once( ABSPATH . WPINC . '/http.php' );
68 | $response = wp_remote_get( admin_url( 'upgrade.php?step=1' ), array( 'timeout' => 120, 'httpversion' => '1.1' ) );
69 | /** This action is documented in wp-admin/network/upgrade.php */
70 | do_action( 'after_mu_upgrade', $response );
71 | unset($response);
72 | }
73 | unset($c);
74 | }
75 | }
76 |
77 | require_once(ABSPATH . 'wp-admin/includes/admin.php');
78 |
79 | auth_redirect();
80 |
81 | // Schedule trash collection
82 | if ( !wp_next_scheduled('wp_scheduled_delete') && !defined('WP_INSTALLING') )
83 | wp_schedule_event(time(), 'daily', 'wp_scheduled_delete');
84 |
85 | set_screen_options();
86 |
87 | $date_format = get_option('date_format');
88 | $time_format = get_option('time_format');
89 |
90 | wp_enqueue_script( 'common' );
91 |
92 | $editing = false;
93 |
94 | if ( isset($_GET['page']) ) {
95 | $plugin_page = wp_unslash( $_GET['page'] );
96 | $plugin_page = plugin_basename($plugin_page);
97 | }
98 |
99 | if ( isset( $_REQUEST['post_type'] ) && post_type_exists( $_REQUEST['post_type'] ) )
100 | $typenow = $_REQUEST['post_type'];
101 | else
102 | $typenow = '';
103 |
104 | if ( isset( $_REQUEST['taxonomy'] ) && taxonomy_exists( $_REQUEST['taxonomy'] ) )
105 | $taxnow = $_REQUEST['taxonomy'];
106 | else
107 | $taxnow = '';
108 |
109 | if ( WP_NETWORK_ADMIN )
110 | require(ABSPATH . 'wp-admin/network/menu.php');
111 | elseif ( WP_USER_ADMIN )
112 | require(ABSPATH . 'wp-admin/user/menu.php');
113 | else
114 | require(ABSPATH . 'wp-admin/menu.php');
115 |
116 | if ( current_user_can( 'manage_options' ) ) {
117 | /**
118 | * Filter the maximum memory limit available for administration screens.
119 | *
120 | * This only applies to administrators, who may require more memory for tasks like updates.
121 | * Memory limits when processing images (uploaded or edited by users of any role) are
122 | * handled separately.
123 | *
124 | * The WP_MAX_MEMORY_LIMIT constant specifically defines the maximum memory limit available
125 | * when in the administration back-end. The default is 256M, or 256 megabytes of memory.
126 | *
127 | * @since 3.0.0
128 | *
129 | * @param string 'WP_MAX_MEMORY_LIMIT' The maximum WordPress memory limit. Default 256M.
130 | */
131 | @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
132 | }
133 |
134 | /**
135 | * Fires as an admin screen or script is being initialized.
136 | *
137 | * Note, this does not just run on user-facing admin screens.
138 | * It runs on admin-ajax.php and admin-post.php as well.
139 | *
140 | * This is roughly analgous to the more general 'init' hook, which fires earlier.
141 | *
142 | * @since 2.5.0
143 | */
144 | do_action( 'admin_init' );
145 |
146 | if ( isset($plugin_page) ) {
147 | if ( !empty($typenow) )
148 | $the_parent = $pagenow . '?post_type=' . $typenow;
149 | else
150 | $the_parent = $pagenow;
151 | if ( ! $page_hook = get_plugin_page_hook($plugin_page, $the_parent) ) {
152 | $page_hook = get_plugin_page_hook($plugin_page, $plugin_page);
153 | // backwards compatibility for plugins using add_management_page
154 | if ( empty( $page_hook ) && 'edit.php' == $pagenow && '' != get_plugin_page_hook($plugin_page, 'tools.php') ) {
155 | // There could be plugin specific params on the URL, so we need the whole query string
156 | if ( !empty($_SERVER[ 'QUERY_STRING' ]) )
157 | $query_string = $_SERVER[ 'QUERY_STRING' ];
158 | else
159 | $query_string = 'page=' . $plugin_page;
160 | wp_redirect( admin_url('tools.php?' . $query_string) );
161 | exit;
162 | }
163 | }
164 | unset($the_parent);
165 | }
166 |
167 | $hook_suffix = '';
168 | if ( isset($page_hook) )
169 | $hook_suffix = $page_hook;
170 | else if ( isset($plugin_page) )
171 | $hook_suffix = $plugin_page;
172 | else if ( isset($pagenow) )
173 | $hook_suffix = $pagenow;
174 |
175 | set_current_screen();
176 |
177 | // Handle plugin admin pages.
178 | if ( isset($plugin_page) ) {
179 | if ( $page_hook ) {
180 | /**
181 | * Fires before a particular screen is loaded.
182 | *
183 | * The load-* hook fires in a number of contexts. This hook is for plugin screens
184 | * where a callback is provided when the screen is registered.
185 | *
186 | * The dynamic portion of the hook name, $page_hook, refers to a mixture of plugin
187 | * page information including:
188 | * 1. The page type. If the plugin page is registered as a submenu page, such as for
189 | * Settings, the page type would be 'settings'. Otherwise the type is 'toplevel'.
190 | * 2. A separator of '_page_'.
191 | * 3. The plugin basename minus the file extension.
192 | *
193 | * Together, the three parts form the $page_hook. Citing the example above,
194 | * the hook name used would be 'load-settings_page_pluginbasename'.
195 | *
196 | * @see get_plugin_page_hook()
197 | *
198 | * @since 2.1.0
199 | */
200 | do_action( 'load-' . $page_hook );
201 | if (! isset($_GET['noheader']))
202 | require_once(ABSPATH . 'wp-admin/admin-header.php');
203 |
204 | /**
205 | * Used to call the registered callback for a plugin screen.
206 | *
207 | * @access private
208 | *
209 | * @since 1.5.0
210 | */
211 | do_action( $page_hook );
212 | } else {
213 | if ( validate_file($plugin_page) )
214 | wp_die(__('Invalid plugin page'));
215 |
216 | if ( !( file_exists(WP_PLUGIN_DIR . "/$plugin_page") && is_file(WP_PLUGIN_DIR . "/$plugin_page") ) && !( file_exists(WPMU_PLUGIN_DIR . "/$plugin_page") && is_file(WPMU_PLUGIN_DIR . "/$plugin_page") ) )
217 | wp_die(sprintf(__('Cannot load %s.'), htmlentities($plugin_page)));
218 |
219 | /**
220 | * Fires before a particular screen is loaded.
221 | *
222 | * The load-* hook fires in a number of contexts. This hook is for plugin screens
223 | * where the file to load is directly included, rather than the use of a function.
224 | *
225 | * The dynamic portion of the hook name, $plugin_page, refers to the plugin basename.
226 | *
227 | * @see plugin_basename()
228 | *
229 | * @since 1.5.0
230 | */
231 | do_action( 'load-' . $plugin_page );
232 |
233 | if ( !isset($_GET['noheader']))
234 | require_once(ABSPATH . 'wp-admin/admin-header.php');
235 |
236 | if ( file_exists(WPMU_PLUGIN_DIR . "/$plugin_page") )
237 | include(WPMU_PLUGIN_DIR . "/$plugin_page");
238 | else
239 | include(WP_PLUGIN_DIR . "/$plugin_page");
240 | }
241 |
242 | include(ABSPATH . 'wp-admin/admin-footer.php');
243 |
244 | exit();
245 | } else if (isset($_GET['import'])) {
246 |
247 | $importer = $_GET['import'];
248 |
249 | if ( ! current_user_can('import') )
250 | wp_die(__('You are not allowed to import.'));
251 |
252 | if ( validate_file($importer) ) {
253 | wp_redirect( admin_url( 'import.php?invalid=' . $importer ) );
254 | exit;
255 | }
256 |
257 | if ( ! isset($wp_importers[$importer]) || ! is_callable($wp_importers[$importer][2]) ) {
258 | wp_redirect( admin_url( 'import.php?invalid=' . $importer ) );
259 | exit;
260 | }
261 |
262 | /**
263 | * Fires before an importer screen is loaded.
264 | *
265 | * The dynamic portion of the hook name, $importer, refers to the importer slug.
266 | *
267 | * @since 3.5.0
268 | */
269 | do_action( 'load-importer-' . $importer );
270 |
271 | $parent_file = 'tools.php';
272 | $submenu_file = 'import.php';
273 | $title = __('Import');
274 |
275 | if (! isset($_GET['noheader']))
276 | require_once(ABSPATH . 'wp-admin/admin-header.php');
277 |
278 | require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
279 |
280 | define('WP_IMPORTING', true);
281 |
282 | /**
283 | * Whether to filter imported data through kses on import.
284 | *
285 | * Multisite uses this hook to filter all data through kses by default,
286 | * as a super administrator may be assisting an untrusted user.
287 | *
288 | * @since 3.1.0
289 | *
290 | * @param bool false Whether to force data to be filtered through kses. Default false.
291 | */
292 | if ( apply_filters( 'force_filtered_html_on_import', false ) )
293 | kses_init_filters(); // Always filter imported data with kses on multisite.
294 |
295 | call_user_func($wp_importers[$importer][2]);
296 |
297 | include(ABSPATH . 'wp-admin/admin-footer.php');
298 |
299 | // Make sure rules are flushed
300 | flush_rewrite_rules(false);
301 |
302 | exit();
303 | } else {
304 | /**
305 | * Fires before a particular screen is loaded.
306 | *
307 | * The load-* hook fires in a number of contexts. This hook is for core screens.
308 | *
309 | * The dynamic portion of the hook name, $pagenow, is a global variable
310 | * referring to the filename of the current page, such as 'admin.php',
311 | * 'post-new.php' etc. A complete hook for the latter would be 'load-post-new.php'.
312 | *
313 | * @since 2.1.0
314 | */
315 | do_action( 'load-' . $pagenow );
316 | // Backwards compatibility with old load-page-new.php, load-page.php,
317 | // and load-categories.php actions.
318 | if ( $typenow == 'page' ) {
319 | if ( $pagenow == 'post-new.php' )
320 | do_action( 'load-page-new.php' );
321 | elseif ( $pagenow == 'post.php' )
322 | do_action( 'load-page.php' );
323 | } elseif ( $pagenow == 'edit-tags.php' ) {
324 | if ( $taxnow == 'category' )
325 | do_action( 'load-categories.php' );
326 | elseif ( $taxnow == 'link_category' )
327 | do_action( 'load-edit-link-categories.php' );
328 | }
329 | }
330 |
331 | if ( ! empty( $_REQUEST['action'] ) ) {
332 | /**
333 | * Fires when an 'action' request variable is sent.
334 | *
335 | * The dynamic portion of the hook name, $_REQUEST['action'],
336 | * refers to the action derived from the GET or POST request.
337 | *
338 | * @since 2.6.0
339 | */
340 | do_action( 'admin_action_' . $_REQUEST['action'] );
341 | }
342 |
--------------------------------------------------------------------------------
/includes/hacklogra_upyun.class.php:
--------------------------------------------------------------------------------
1 |
6 | * @link http://ihacklog.com
7 | * @copyright Copyright (C) 2012 荒野无灯
8 | * @license http://www.gnu.org/licenses/
9 | */
10 | if (!defined('ABSPATH')) {
11 | die('What are you doing?');
12 | }
13 |
14 | require __DIR__ . '/../filesystem/upyun.php';
15 |
16 | class hacklogra_upyun
17 | {
18 | const textdomain = 'hacklog-remote-attachment';
19 | const plugin_name = 'Hacklog Remote Attachment Upyun';
20 | //the same
21 | const opt_space = 'hacklogra_remote_filesize';
22 | //new option name
23 | const opt_primary = 'hacklogra_upyun_options';
24 | const version = '1.4.4-upyun-ported-from-1.2.6-origin';
25 | private static $img_ext = array('jpg', 'jpeg', 'png', 'gif', 'bmp');
26 | private static $rest_user = 'admin';
27 | private static $rest_pwd = '4d4173594c77453d';
28 | private static $rest_server = 'v0.api.upyun.com';
29 | private static $bucketname = '';
30 | private static $form_api_secret = '';
31 | private static $form_api_content_max_length = 100;
32 | private static $form_api_allowed_ext = 'jpg,jpeg,gif,png,doc,pdf,zip,rar,tar.gz,tar.bz2,7z';
33 | private static $form_api_timeout = 300;
34 | private static $anti_leech_token = '';
35 | private static $anti_leech_timeout = 600;
36 | private static $rest_port = 80;
37 | private static $rest_timeout = 30;
38 | private static $subdir = '';
39 | private static $rest_remote_path = 'wp-files';
40 | private static $http_remote_path = 'wp-files';
41 | private static $remote_url = '';
42 | private static $remote_baseurl = '';
43 | private static $local_basepath = '';
44 | private static $local_path = '';
45 | private static $local_url = '';
46 | private static $local_baseurl = '';
47 | /**
48 | * @var Filesystem_Upyun
49 | */
50 | private static $fs = null;
51 | private static $is_form_api_upload = false;
52 |
53 | public function __construct()
54 | {
55 | self::init();
56 | //this should always check
57 | add_action('admin_notices', array(__CLASS__, 'check_rest_connection'));
58 | //should load before 'admin_menu' hook ... so,use init hook
59 | add_action('init', array(__CLASS__, 'load_textdomain'));
60 | //menu
61 | add_action('admin_menu', array(__CLASS__, 'plugin_menu'));
62 | //HOOK the upload, use init to support xmlrpc upload
63 | add_action('init', array(__CLASS__, 'admin_init'));
64 | //frontend filter,filter on image only
65 | add_filter('wp_get_attachment_url', array(__CLASS__, 'replace_baseurl'), -999);
66 | add_action('wp_ajax_hacklogra_upyun_signature', array(__CLASS__, 'return_signature'));
67 | add_action('media_buttons', array(__CLASS__, 'add_media_button'), 11);
68 | add_action('plugin_action_links_' . plugin_basename(HACKLOG_RA_UPYUN_LOADER), array(__CLASS__, 'add_plugin_actions'));
69 | empty(self::$anti_leech_token) || add_filter('the_content', array(__CLASS__, 'sign_post_url'));
70 | self::setup_rest();
71 | // self::$fs->debug = true;
72 | }
73 |
74 | ############################## PRIVATE FUNCTIONS ##############################################
75 |
76 | private static function update_options()
77 | {
78 | $value = self::get_default_opts();
79 | $keys = array_keys($value);
80 | foreach ($keys as $key) {
81 | if (!empty($_POST[$key])) {
82 | $value[$key] = addslashes(trim($_POST[$key]));
83 | }
84 | }
85 | $value['remote_baseurl'] = rtrim($value['remote_baseurl'], '/');
86 | $value['rest_remote_path'] = rtrim($value['rest_remote_path'], '/');
87 | $value['http_remote_path'] = rtrim($value['http_remote_path'], '/');
88 | if (update_option(self::opt_primary, $value))
89 | return TRUE;
90 | else
91 | return FALSE;
92 | }
93 |
94 | /**
95 | * get file extension
96 | * @static
97 | * @param $path
98 | * @return mixed
99 | */
100 | private static function get_ext($path)
101 | {
102 | return pathinfo($path, PATHINFO_EXTENSION);
103 | }
104 |
105 | /**
106 | * to see if a file is an image file.
107 | * @static
108 | * @param $path
109 | * @return bool
110 | */
111 | private static function is_image_file($path)
112 | {
113 | return in_array(self::get_ext($path), self::$img_ext);
114 | }
115 |
116 | /**
117 | * get the default options
118 | * @static
119 | * @return array
120 | */
121 | private static function get_default_opts()
122 | {
123 | return array(
124 | 'rest_user' => self::$rest_user,
125 | 'rest_pwd' => self::$rest_pwd,
126 | 'form_api_secret' => self::$form_api_secret,
127 | 'form_api_content_max_length' => self::$form_api_content_max_length,
128 | 'form_api_allowed_ext' => self::$form_api_allowed_ext,
129 | 'form_api_timeout' => self::$form_api_timeout,
130 | 'anti_leech_token' => self::$anti_leech_token,
131 | 'anti_leech_timeout' => self::$anti_leech_timeout,
132 | 'rest_server' => self::$rest_server,
133 | 'bucketname' => self::$bucketname,
134 | 'rest_port' => self::$rest_port,
135 | 'rest_timeout' => self::$rest_timeout,
136 | 'rest_remote_path' => self::$rest_remote_path,
137 | 'http_remote_path' => self::$http_remote_path,
138 | 'remote_baseurl' => self::$remote_baseurl,
139 | );
140 | }
141 |
142 | /**
143 | * increase the filesize,keep the filesize tracked.
144 | * @static
145 | * @param $file
146 | * @return void
147 | */
148 | private static function update_filesize_used($file)
149 | {
150 | if (file_exists($file)) {
151 | $filesize = filesize($file);
152 | $previous_value = get_option(self::opt_space);
153 | $to_save = $previous_value + $filesize;
154 | update_option(self::opt_space, $to_save);
155 | }
156 | }
157 |
158 | /**
159 | * decrease the filesize when a remote file is deleted.
160 | * @static
161 | * @param $fs
162 | * @param $file
163 | * @return void
164 | */
165 | private static function decrease_filesize_used($fs, $file)
166 | {
167 | if ($fs->exists($file)) {
168 | $filesize = $fs->size($file);
169 | $previous_value = get_option(self::opt_space);
170 | $to_save = $previous_value - $filesize;
171 | update_option(self::opt_space, $to_save);
172 | }
173 | }
174 |
175 | /**
176 | * like wp_handle_upload_error in file.php under wp-admin/includes
177 | * @param $message
178 | * @return array
179 | */
180 | public static function handle_upload_error($message)
181 | {
182 | return array('error' => $message);
183 | }
184 |
185 | public static function xmlrpc_error($errorString = '')
186 | {
187 | return new IXR_Error(500, $errorString);
188 | }
189 |
190 | /**
191 | * report upload error
192 | * @return type
193 | */
194 | private static function raise_upload_error()
195 | {
196 | $error_str = sprintf('%s:' . __('upload file to remote server failed!', self::textdomain), self::plugin_name);
197 | if (defined('XMLRPC_REQUEST')) {
198 | return self::xmlrpc_error($error_str);
199 | } else {
200 | return call_user_func(array(__CLASS__, 'handle_upload_error'), $error_str);
201 | }
202 | }
203 |
204 | /**
205 | * report rest connection error
206 | * @return type
207 | */
208 | private static function raise_connection_error()
209 | {
210 | $error_message = 'Unknown Error!';
211 | $all_errors = self::$fs->errors->get_error_messages();
212 | if (count($all_errors) > 0) {
213 | $error_message = implode('|', $all_errors);
214 | }
215 | $error_message = '' . $error_message . '';
216 | $error_str = sprintf('%s:' . $error_message, self::plugin_name);
217 | if (defined('XMLRPC_REQUEST')) {
218 | return self::xmlrpc_error($error_str);
219 | } else {
220 | return call_user_func(array(__CLASS__, 'handle_upload_error'), $error_str);
221 | }
222 | }
223 |
224 | ############################## PUBLIC FUNCTIONS ##############################################
225 | /**
226 | * init
227 | * @static
228 | * @return void
229 | */
230 |
231 | public static function init()
232 | {
233 | register_activation_hook(HACKLOG_RA_UPYUN_LOADER, array(__CLASS__, 'my_activation'));
234 | register_deactivation_hook(HACKLOG_RA_UPYUN_LOADER, array(__CLASS__, 'my_deactivation'));
235 | $opts = get_option(self::opt_primary);
236 | self::$rest_user = $opts['rest_user'];
237 | self::$rest_pwd = $opts['rest_pwd'];
238 | self::$form_api_secret = $opts['form_api_secret'];
239 | self::$form_api_allowed_ext = $opts['form_api_allowed_ext'];
240 | self::$form_api_content_max_length = $opts['form_api_content_max_length'];
241 | self::$form_api_timeout = $opts['form_api_timeout'];
242 | self::$anti_leech_token = $opts['anti_leech_token'];
243 | self::$anti_leech_timeout = $opts['anti_leech_timeout'];
244 | self::$rest_server = $opts['rest_server'];
245 | self::$bucketname = $opts['bucketname'];
246 | self::$rest_port = $opts['rest_port'];
247 | self::$rest_timeout = $opts['rest_timeout'] > 0 ? $opts['rest_timeout'] : 30;
248 |
249 | $opts['rest_remote_path'] = rtrim($opts['rest_remote_path'], '/');
250 | $opts['http_remote_path'] = rtrim($opts['http_remote_path'], '/');
251 | $opts['remote_baseurl'] = rtrim($opts['remote_baseurl'], '/');
252 | $upload_dir = wp_upload_dir();
253 | //be aware of / in the end
254 | self::$local_basepath = $upload_dir['basedir'];
255 | self::$local_path = $upload_dir['path'];
256 | self::$local_baseurl = $upload_dir['baseurl'];
257 | self::$local_url = $upload_dir['url'];
258 | self::$subdir = $upload_dir['subdir'];
259 | //if the post publish date was different from the media upload date,the time should take from the database.
260 | if (get_option('uploads_use_yearmonth_folders') && isset($_REQUEST['post_id'])) {
261 | $post_id = (int)$_REQUEST['post_id'];
262 | if ($post = get_post($post_id)) {
263 | if (substr($post->post_date, 0, 4) > 0) {
264 | $time = $post->post_date;
265 | $y = substr($time, 0, 4);
266 | $m = substr($time, 5, 2);
267 | $subdir = "/$y/$m";
268 | self::$subdir = $subdir;
269 | }
270 | }
271 | }
272 | //后面不带 /
273 | self::$rest_remote_path = $opts['rest_remote_path'] == '.' ? '' : $opts['rest_remote_path'];
274 | self::$http_remote_path = $opts['http_remote_path'] == '.' ? '' : $opts['http_remote_path'];
275 | //此baseurl与options里面的不同!
276 | self::$remote_baseurl = '.' == self::$http_remote_path ? $opts['remote_baseurl'] :
277 | $opts['remote_baseurl'] . '/' . self::$http_remote_path;
278 | self::$remote_url = self::$remote_baseurl . self::$subdir;
279 | }
280 |
281 | public static function handle_form_api_upload($post_id, $post_data = array())
282 | {
283 | if (!self::setup_rest()) {
284 | return new WP_Error('hacklogra_internal_error', 'failed to contruct Upyun class');
285 | }
286 | self::$is_form_api_upload = true;
287 | //check_admin_referer('media-form');
288 | // Upload File button was clicked
289 | if (self::$fs->check_form_api_internal_error()) {
290 | $id = new WP_Error('upyun_internal_error', __('Upyun internal Error!'));
291 | } else
292 | if ($_GET['code'] == '200') {
293 | if (self::$fs->check_form_api_return_param()) {
294 | $url = self::$remote_baseurl . ltrim($_GET['url'], '/');
295 | //error_log(var_export(array(self::$remote_baseurl ,$_GET['url']),true));
296 | $filename = basename($_GET['url']);
297 | $ft = wp_check_filetype($filename, null);
298 | $type = $ft['type'];
299 | $file = str_replace('/' . self::$http_remote_path . '/', '', $_GET['url']);
300 | $name_parts = pathinfo($filename);
301 | $name = trim(substr($filename, 0, -(1 + strlen($name_parts['extension']))));
302 | $title = $name;
303 | $content = '';
304 | // Construct the attachment array
305 | $attachment = array_merge(array(
306 | 'post_mime_type' => $type,
307 | 'guid' => $url,
308 | 'post_parent' => $post_id,
309 | 'post_title' => $title,
310 | 'post_content' => $content,
311 | ), $post_data);
312 |
313 | // This should never be set as it would then overwrite an existing attachment.
314 | if (isset($attachment['ID']))
315 | unset($attachment['ID']);
316 |
317 | // Save the data
318 | $id = wp_insert_attachment($attachment, $file, $post_id);
319 | if (!is_wp_error($id)) {
320 | wp_update_attachment_metadata($id, wp_generate_attachment_metadata($id, $file));
321 | }
322 |
323 | }
324 | } else {
325 | $id = new WP_Error('upyun_upload_error', $_GET['message']);
326 | }
327 | return $id;
328 | }
329 |
330 |
331 | public static function return_signature()
332 | {
333 | if (!self::setup_rest()) {
334 | die(json_encode(array('error' => 'yes', 'message' => 'failed to contruct Upyun class')));
335 | }
336 | $post_id = $_POST['post_id'];
337 | $filename = basename($_POST['file']);
338 | $unique_filename = self::unique_filename(self::$rest_remote_path . self::$subdir, $filename);
339 | $policy = self::$fs->build_policy(
340 | array('path' => '/' . self::$rest_remote_path . self::$subdir . '/' . $unique_filename,
341 | 'return_url' => plugins_url('upload.php?post_id=' . $post_id, HACKLOG_RA_UPYUN_LOADER),
342 | 'bucket' => self::$bucketname,
343 | ));
344 | $signature = self::$fs->get_form_api_signature($policy);
345 | header("Content-Type: text/json;Charset=UTF-8");
346 | die(json_encode(array('policy' => $policy, 'signature' => $signature, 'error' => 'none')));
347 | }
348 |
349 | public static function add_media_button($editor_id = 'content')
350 | {
351 | global $post_ID;
352 | $url = plugins_url("upload.php?post_id={$post_ID}&TB_iframe=1&width=640&height=451&tab=upyun", HACKLOG_RA_UPYUN_LOADER);
353 | $admin_icon = plugins_url('images/upyun_icon.png', HACKLOG_RA_UPYUN_LOADER);
354 | if (is_ssl()) {
355 | $url = str_replace('http://', 'https://', $url);
356 | }
357 | $alt = __('Upload local file to Upyun server', self::textdomain);
358 | $img = '';
359 |
360 | echo '' . $img . '';
361 | }
362 |
363 | public static function media_upload_type_form_upyun($type = 'file', $errors = null, $id = null)
364 | {
365 |
366 | $post_id = isset($_REQUEST['post_id']) ? intval($_REQUEST['post_id']) : 0;
367 | if (!self::connect_remote_server()) {
368 | return self::raise_connection_error();
369 | }
370 |
371 | media_upload_header();
372 |
373 | $upyun_form_action_url = 'http://' . self::$fs->get_api_domain() . '/' . self::$bucketname . '/';
374 | if (isset($_GET['code']) && isset($_GET['message']) && isset($_GET['url']) && isset($_GET['time']) && isset($_GET['sign'])) {
375 | $form_action_url = plugins_url('upload.php?post_id=' . $post_id . '&TB_iframe=1&width=640&height=451', HACKLOG_RA_UPYUN_LOADER);
376 | } else {
377 | $form_action_url = $upyun_form_action_url;
378 | }
379 |
380 | $form_class = 'media-upload-form type-form validate';
381 |
382 | //if ( get_user_setting('uploader') )
383 | $form_class .= ' html-uploader';
384 | ?>
385 |
386 |
' . $error['error'] . '
' . $redirect_msg . '
' . __('Remote base URL is the URL to your bucket root path.', self::textdomain) . '
' . 973 | '' . __('rest Remote path is the relative path to your bucket main directory.Use "/" for bucket main(root) directory.You can use sub-directory Like wp-files', self::textdomain) . '
' . 974 | '' . __('HTTP Remote path is the relative path to your HTTP main directory.Use "/" for HTTP main(root) directory.You can use sub-directory Like wp-files', self::textdomain) . '
' . 975 | '' . __('For more information:', self::textdomain) . ' ' . __('Please visit the Plugin Home Page and Hacklog Remote Attachment home page.', self::textdomain) . '
'; 976 | $args = array( 977 | 'title' => sprintf(__("%s Help", self::textdomain), self::plugin_name), 978 | 'id' => $current_screen_id, 979 | 'content' => $text, 980 | 'callback' => false, 981 | ); 982 | $current_screen = get_current_screen(); 983 | $current_screen->add_help_tab($args); 984 | } 985 | 986 | /** 987 | * add menu page 988 | * @see http://codex.wordpress.org/Function_Reference/add_options_page 989 | * @static 990 | * @return void 991 | */ 992 | public static function plugin_menu() 993 | { 994 | $identifier = md5(HACKLOG_RA_UPYUN_LOADER); 995 | $option_page = add_options_page(__('Hacklog Remote Attachment Upyun Options', self::textdomain), __('Remote Attachment Upyun', self::textdomain), 'manage_options', $identifier, array(__CLASS__, 'plugin_options') 996 | ); 997 | // Adds my help tab when my admin page loads 998 | add_action('load-' . $option_page, array(__CLASS__, 'add_my_contextual_help')); 999 | } 1000 | 1001 | public static function show_message($message, $type = 'e') 1002 | { 1003 | if (empty($message)) 1004 | return; 1005 | $font_color = 'e' == $type ? '#FF0000' : '#4e9a06'; 1006 | $html = ''; 1007 | $html .= "" . $message . ''; 1008 | $html .= '
%2$s
', __('The following SQL statement was executeed:', self::textdomain), $sql);
1064 | } else {
1065 | $error = __('no posts been updated.', self::textdomain);
1066 | }
1067 | }
1068 | ?>
1069 | 1268 | 1269 | get_bucket_usage(); 1272 | if (get_option(self::opt_space) != $total_size) { 1273 | update_option(self::opt_space, $total_size); 1274 | } 1275 | echo '' . self::human_size($total_size) . ''; 1276 | } else { 1277 | echo ''; 1278 | _e('Authentication failed OR Failed to connect to remote server!', self::textdomain); 1279 | echo ''; 1280 | } 1281 | ?> 1282 |
1283 |1292 | DO NOT click the link below!", self::textdomain); ?> 1293 |
1294 | 1295 | 1296 | 1297 | 1302 | 1303 | 1304 | 1305 | 1310 |Error: you have already activated Hacklog Remote Attachment,Please deactivate it and then activate this plugin(Hacklog Remote Attachment Upyun).
Failed to load bootstrap.
'; 25 | exit; 26 | } 27 | 28 | 29 | if (!current_user_can('upload_files')) 30 | wp_die(__('You do not have permission to upload files.')); 31 | 32 | wp_enqueue_script('plupload-handlers'); 33 | wp_enqueue_script('image-edit'); 34 | wp_enqueue_script('set-post-thumbnail' ); 35 | wp_enqueue_style('imgareaselect'); 36 | 37 | @header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset')); 38 | 39 | // IDs should be integers 40 | $ID = isset($ID) ? (int) $ID : 0; 41 | $post_id = isset($_REQUEST['post_id'])? (int) $_REQUEST['post_id'] : 0; 42 | 43 | // Require an ID for the edit screen 44 | if ( isset($action) && $action == 'edit' && !$ID ) 45 | wp_die(__("You are not allowed to be here")); 46 | 47 | if($post_id <= 0) 48 | { 49 | wp_die(__("You are not allowed to be here")); 50 | } 51 | else 52 | { 53 | 54 | add_filter('media_upload_tabs', 'hacklogra_upyun_upload_tags'); 55 | // upload type: image, video, file, ..? 56 | if ( isset($_GET['type']) ) 57 | $type = strval($_GET['type']); 58 | else 59 | $type = apply_filters('media_upload_default_type', 'file'); 60 | 61 | // tab: gallery, library, or type-specific 62 | if ( isset($_GET['tab']) ) 63 | $tab = strval($_GET['tab']); 64 | else 65 | $tab = apply_filters('media_upload_default_tab', 'type'); 66 | 67 | $body_id = 'media-upload'; 68 | 69 | if( $tab == 'type') 70 | { 71 | hacklogra_upyun_media_upload_handler(); 72 | } 73 | else 74 | { 75 | // let the action code decide how to handle the request 76 | if ( $tab == 'type_url' || !array_key_exists( $tab , media_upload_tabs() ) ) 77 | { 78 | do_action("media_upload_$type"); 79 | } 80 | else 81 | { 82 | do_action("media_upload_$tab"); 83 | } 84 | } 85 | 86 | } 87 | 88 | 89 | /** 90 | * {@internal Missing Short Description}} 91 | * 92 | * @since 1.4.0 93 | * 94 | * @return unknown 95 | */ 96 | function hacklogra_upyun_media_upload_handler() 97 | { 98 | global $is_iphone; 99 | 100 | $errors = array(); 101 | $id = 0; 102 | 103 | if ( isset($_GET['code']) && isset($_GET['message']) && isset($_GET['url']) && isset($_GET['time']) ) 104 | { 105 | $id = hacklogra_upyun::handle_form_api_upload($_REQUEST['post_id'], $post_data = array() ); 106 | unset($_FILES); 107 | if ( is_wp_error($id) ) 108 | { 109 | $errors['upload_error'] = $id; 110 | $id = false; 111 | } 112 | } 113 | 114 | if ( !empty($_POST['insertonlybutton']) ) 115 | { 116 | $src = $_POST['src']; 117 | if ( !empty($src) && !strpos($src, '://') ) 118 | $src = "http://$src"; 119 | 120 | if ( isset( $_POST['media_type'] ) && 'image' != $_POST['media_type'] ) { 121 | $title = esc_html( stripslashes( $_POST['title'] ) ); 122 | if ( empty( $title ) ) 123 | $title = esc_html( basename( $src ) ); 124 | 125 | if ( $title && $src ) 126 | $html = "$title"; 127 | 128 | $type = 'file'; 129 | if ( ( $ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $src ) ) && ( $ext_type = wp_ext2type( $ext ) ) 130 | && ( 'audio' == $ext_type || 'video' == $ext_type ) ) 131 | $type = $ext_type; 132 | 133 | $html = apply_filters( $type . '_send_to_editor_url', $html, esc_url_raw( $src ), $title ); 134 | } else { 135 | $align = ''; 136 | $alt = esc_attr( stripslashes( $_POST['alt'] ) ); 137 | if ( isset($_POST['align']) ) { 138 | $align = esc_attr( stripslashes( $_POST['align'] ) ); 139 | $class = " class='align$align'"; 140 | } 141 | if ( !empty($src) ) 142 | $html = "