Version Description
- 2013-01-29 =
- Forked Amazon S3 for WordPress with CloudFront
- Cleaned up the UI to fit with today's WP UI
- Fixed issues causing error messages when WP_DEBUG is on
- Delete files on S3 when deleting WP attachment
- Added filter to the get_attachment_url function
- Added function to get a temporary, secure download URL for private files
Download this release
Release Info
Developer | bradt |
Plugin | WP Offload S3 Lite |
Version | 0.5 |
Comparing to | |
See all releases |
Version 0.5
- lib/curl.php +211 -0
- readme.txt +44 -0
- screenshot-1.gif +0 -0
- screenshot-2.jpg +0 -0
- wordpress-s3.php +48 -0
- wordpress-s3/admin-options.html +218 -0
- wordpress-s3/admin-tab-head.html +32 -0
- wordpress-s3/admin-tab.html +98 -0
- wordpress-s3/admin-tab.js +59 -0
- wordpress-s3/admin-version-error.html +58 -0
- wordpress-s3/class-plugin-public.php +94 -0
- wordpress-s3/class-plugin.php +496 -0
- wordpress-s3/config-sample.php +15 -0
- wordpress-s3/database.png +0 -0
- wordpress-s3/index.php +1 -0
- wordpress-s3/lib.s3.php +397 -0
- wordpress-s3/styles/add.png +0 -0
- wordpress-s3/styles/arrow_left.png +0 -0
- wordpress-s3/styles/arrow_refresh.png +0 -0
- wordpress-s3/styles/arrow_right.png +0 -0
- wordpress-s3/styles/cancel.png +0 -0
- wordpress-s3/styles/compress.png +0 -0
- wordpress-s3/styles/film.png +0 -0
- wordpress-s3/styles/folder.gif +0 -0
- wordpress-s3/styles/folder_add.png +0 -0
- wordpress-s3/styles/page.png +0 -0
- wordpress-s3/styles/page_code.png +0 -0
- wordpress-s3/styles/page_excel.png +0 -0
- wordpress-s3/styles/page_white.png +0 -0
- wordpress-s3/styles/page_white_acrobat.png +0 -0
- wordpress-s3/styles/page_white_excel.png +0 -0
- wordpress-s3/styles/page_white_php.png +0 -0
- wordpress-s3/styles/page_white_powerpoint.png +0 -0
- wordpress-s3/styles/page_white_text.png +0 -0
- wordpress-s3/styles/page_white_word.png +0 -0
- wordpress-s3/styles/page_white_zip.png +0 -0
- wordpress-s3/styles/page_word.png +0 -0
- wordpress-s3/styles/photo.png +0 -0
- wordpress-s3/styles/picture.png +0 -0
- wordpress-s3/styles/sound.png +0 -0
- wordpress-s3/styles/styles.css +189 -0
lib/curl.php
ADDED
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
This is a clone of the PEAR HTTP/Request class object. It uses libcurl to do the networking stuff.
|
4 |
+
Should also work with the HTTPS protocol
|
5 |
+
|
6 |
+
Important: Not every method has been ported, just the ones that were needed.
|
7 |
+
|
8 |
+
$Revision: 66280 $
|
9 |
+
$Date: 2008-09-25 15:28:23 +0000 (Thu, 25 Sep 2008) $
|
10 |
+
$URL: https://photo-album.googlecode.com/svn/trunk/tantan-flickr/lib/curl.php $
|
11 |
+
*/
|
12 |
+
|
13 |
+
class TanTanHTTPRequestCurl {
|
14 |
+
var $curl;
|
15 |
+
var $postData;
|
16 |
+
var $cookies;
|
17 |
+
var $raw;
|
18 |
+
var $response;
|
19 |
+
var $headers;
|
20 |
+
var $url;
|
21 |
+
|
22 |
+
function TanTanHTTPRequestCurl($url = '', $params = array()) {
|
23 |
+
$this->curl = curl_init();
|
24 |
+
$this->postData = array();
|
25 |
+
$this->cookies = array();
|
26 |
+
$this->headers = array();
|
27 |
+
if (!empty($url)) {
|
28 |
+
$this->setURL($url);
|
29 |
+
} else {
|
30 |
+
$this->setURL(false);
|
31 |
+
}
|
32 |
+
foreach ($params as $key => $value) {
|
33 |
+
$this->{'_' . $key} = $value;
|
34 |
+
}
|
35 |
+
|
36 |
+
$this->addHeader('Connection', 'close');
|
37 |
+
|
38 |
+
// We don't do keep-alives by default
|
39 |
+
$this->addHeader('Connection', 'close');
|
40 |
+
|
41 |
+
// Basic authentication
|
42 |
+
if (!empty($this->_user)) {
|
43 |
+
$this->addHeader('Authorization', 'Basic ' . base64_encode($this->_user . ':' . $this->_pass));
|
44 |
+
}
|
45 |
+
|
46 |
+
// Proxy authentication (see bug #5913)
|
47 |
+
if (!empty($this->_proxy_user)) {
|
48 |
+
$this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($this->_proxy_user . ':' . $this->_proxy_pass));
|
49 |
+
}
|
50 |
+
|
51 |
+
}
|
52 |
+
|
53 |
+
function addHeader($header, $value) {
|
54 |
+
$this->headers[$header] = $value;
|
55 |
+
}
|
56 |
+
|
57 |
+
function setMethod($method) {
|
58 |
+
|
59 |
+
// setting default values for constants if they're not present
|
60 |
+
if ( !defined('HTTP_REQUEST_METHOD_PUT') ) define('HTTP_REQUEST_METHOD_PUT', null);
|
61 |
+
if ( !defined('HTTP_REQUEST_METHOD_POST') ) define('HTTP_REQUEST_METHOD_POST', null);
|
62 |
+
|
63 |
+
switch ($method) {
|
64 |
+
case 'DELETE':
|
65 |
+
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
66 |
+
break;
|
67 |
+
case HTTP_REQUEST_METHOD_PUT:
|
68 |
+
case 'PUT':
|
69 |
+
curl_setopt($this->curl, CURLOPT_PUT, true);
|
70 |
+
//CURLOPT_INFILE CURLOPT_INFILESIZE
|
71 |
+
break;
|
72 |
+
case HTTP_REQUEST_METHOD_POST:
|
73 |
+
case 'POST':
|
74 |
+
curl_setopt($this->curl, CURLOPT_POST, true);
|
75 |
+
break;
|
76 |
+
default:
|
77 |
+
case 'GET':
|
78 |
+
curl_setopt($this->curl, CURLOPT_HTTPGET, true);
|
79 |
+
break;
|
80 |
+
case 'HEAD':
|
81 |
+
curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
82 |
+
break;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
function setURL($url) {
|
86 |
+
$this->url = $url;
|
87 |
+
}
|
88 |
+
function addPostData($name, $value) {
|
89 |
+
$this->postData[$name] = $value;
|
90 |
+
}
|
91 |
+
function addCookie($name, $value) {
|
92 |
+
$this->cookies[$name] = array('name' => $name, 'value' => $value);
|
93 |
+
}
|
94 |
+
function sendRequest() {
|
95 |
+
$headers = array(
|
96 |
+
"Accept: *.*",
|
97 |
+
);
|
98 |
+
|
99 |
+
foreach ($this->headers as $k=>$h) {
|
100 |
+
$headers[] = "$k: $h";
|
101 |
+
}
|
102 |
+
|
103 |
+
if (count($this->cookies) > 0) {
|
104 |
+
$cookieVars = '';
|
105 |
+
foreach ($this->cookies as $cookie) {
|
106 |
+
//$headers[] = "Cookie: ".$cookie['name'].'='.$cookie['value'];
|
107 |
+
$cookieVars .= ''.$cookie['name'].'='.$cookie['value'].'; ';
|
108 |
+
}
|
109 |
+
curl_setopt($this->curl, CURLOPT_COOKIE, $cookieVars);
|
110 |
+
//print_r($cookieVars);
|
111 |
+
}
|
112 |
+
|
113 |
+
if (count($this->postData) > 0) { // if a POST
|
114 |
+
$postVars = '';
|
115 |
+
foreach ($this->postData as $key=>$value) {
|
116 |
+
$postVars .= $key.'='.urlencode($value).'&';
|
117 |
+
}
|
118 |
+
// *** TODO ***
|
119 |
+
// weird, libcurl doesnt seem to POST correctly
|
120 |
+
curl_setopt($this->curl, CURLOPT_POST, true);
|
121 |
+
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postVars);
|
122 |
+
|
123 |
+
//curl_setopt($this->curl, CURLOPT_HTTPGET, true);
|
124 |
+
//$this->url .= '?'.$postVars;
|
125 |
+
|
126 |
+
|
127 |
+
} else {
|
128 |
+
curl_setopt($this->curl, CURLOPT_HTTPGET, true);
|
129 |
+
}
|
130 |
+
curl_setopt($this->curl, CURLOPT_URL, $this->url);
|
131 |
+
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, false);
|
132 |
+
curl_setopt($this->curl, CURLOPT_HEADER, true);
|
133 |
+
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
|
134 |
+
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
|
135 |
+
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
|
136 |
+
$this->raw = curl_exec($this->curl);
|
137 |
+
$this->response = $this->_parseResponse($this->raw);
|
138 |
+
return true; // hmm no error checking for now
|
139 |
+
}
|
140 |
+
|
141 |
+
function getResponseHeader($header=false) {
|
142 |
+
if ($header) {
|
143 |
+
return $this->response['header'][$header];
|
144 |
+
} else {
|
145 |
+
return $this->response['header'];
|
146 |
+
}
|
147 |
+
}
|
148 |
+
function getResponseCookies() {
|
149 |
+
$hdrCookies = array();
|
150 |
+
foreach ($this->response['header'] as $key => $value) {
|
151 |
+
if (strtolower($key) == 'set-cookie') {
|
152 |
+
$hdrCookies = array_merge($hdrCookies, explode("\n", $value));
|
153 |
+
}
|
154 |
+
}
|
155 |
+
//$hdrCookies = explode("\n", $this->response['header']['Set-Cookie']);
|
156 |
+
$cookies = array();
|
157 |
+
|
158 |
+
foreach ($hdrCookies as $cookie) {
|
159 |
+
if ($cookie) {
|
160 |
+
list($name, $value) = explode('=', $cookie, 2);
|
161 |
+
list($value, $domain, $path, $expires) = explode(';', $value);
|
162 |
+
$cookies[$name] = array('name' => $name, 'value' => $value);
|
163 |
+
}
|
164 |
+
}
|
165 |
+
return $cookies;
|
166 |
+
}
|
167 |
+
function getResponseBody() {
|
168 |
+
return $this->response['body'];
|
169 |
+
}
|
170 |
+
function getResponseCode() {
|
171 |
+
return $this->response['code'];
|
172 |
+
}
|
173 |
+
function getResponseRaw() {
|
174 |
+
return $this->raw;
|
175 |
+
}
|
176 |
+
function clearPostData($var=false) {
|
177 |
+
if (!$var) {
|
178 |
+
$this->postData = array();
|
179 |
+
} else {
|
180 |
+
unset($this->postData[$var]);
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
function _parseResponse($this_response) {
|
185 |
+
if (substr_count($this_response, 'HTTP/1.') > 1) { // yet another weird bug. CURL seems to be appending response bodies together
|
186 |
+
$chunks = preg_split('@(HTTP/[0-9]\.[0-9] [0-9]{3}.*\n)@', $this_response, -1, PREG_SPLIT_DELIM_CAPTURE);
|
187 |
+
$this_response = array_pop($chunks);
|
188 |
+
$this_response = array_pop($chunks) . $this_response;
|
189 |
+
|
190 |
+
}
|
191 |
+
|
192 |
+
list($response_headers, $response_body) = explode("\r\n\r\n", $this_response, 2);
|
193 |
+
$response_header_lines = explode("\r\n", $response_headers);
|
194 |
+
|
195 |
+
$http_response_line = array_shift($response_header_lines);
|
196 |
+
if (preg_match('@^HTTP/[0-9]\.[0-9] 100@',$http_response_line, $matches)) {
|
197 |
+
return $this->_parseResponse($response_body);
|
198 |
+
} else if(preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@',$http_response_line, $matches)) {
|
199 |
+
$response_code = $matches[1];
|
200 |
+
}
|
201 |
+
$response_header_array = array();
|
202 |
+
foreach($response_header_lines as $header_line) {
|
203 |
+
list($header,$value) = explode(': ', $header_line, 2);
|
204 |
+
if ( isset( $response_header_array[$header] ) ) {
|
205 |
+
$response_header_array[$header] .= $value."\n";
|
206 |
+
}
|
207 |
+
}
|
208 |
+
return array("code" => $response_code, "header" => $response_header_array, "body" => $response_body);
|
209 |
+
}
|
210 |
+
}
|
211 |
+
?>
|
readme.txt
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Amazon S3 and Cloudfront ===
|
2 |
+
Contributors: bradt
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC
|
4 |
+
Tags: uploads, amazon, s3, mirror, admin, media, cdn, cloudfront
|
5 |
+
Requires at least: 2.3
|
6 |
+
Tested up to: 3.5.1
|
7 |
+
Stable tag: 0.5
|
8 |
+
License: GPLv3
|
9 |
+
|
10 |
+
Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery.
|
11 |
+
|
12 |
+
== Description ==
|
13 |
+
|
14 |
+
This plugin automatically copies images, videos, documents, and any other media added through WordPress' media uploader to [Amazon Simple Storage Service](http://aws.amazon.com/s3/) (S3). It then automatically replaces the URL to each media file with their respective S3 URL or, if you have configured [Amazon CloudFront](http://aws.amazon.com/cloudfront/), the respective CloudFront URL. Image thumbnails are also copied to S3 and delivered through S3/CloudFront.
|
15 |
+
|
16 |
+
Uploading files *directly* to your S3 account is not currently supported by this plugin. Also, if you're adding this plugin to a site that's been around for a while, your existing media files will not be copied or served from S3. Only newly uploaded files will be copied and served from S3.
|
17 |
+
|
18 |
+
You'll also find a new icon next to the "Add Media" button when editing a post. This allows you to easily browse and manage files in S3.
|
19 |
+
|
20 |
+
**Request features, report bugs, and submit pull requests on [Github](https://github.com/bradt/wp-tantan-s3/)**
|
21 |
+
|
22 |
+
*This plugin is a fork of
|
23 |
+
[Amazon S3 for WordPress with CloudFront](http://wordpress.org/extend/plugins/tantan-s3-cloudfront/)
|
24 |
+
which is a fork of [Amazon S3 for WordPress](http://wordpress.org/extend/plugins/tantan-s3/), also known as tantan-s3. See the Change Log to see what has been done so far.*
|
25 |
+
|
26 |
+
== Installation ==
|
27 |
+
|
28 |
+
1. Use WordPress' built-in installer
|
29 |
+
2. Access the Amazon S3 option under Settings and configure your Amazon details
|
30 |
+
|
31 |
+
== Screenshots ==
|
32 |
+
|
33 |
+
1. The settings screen for the plugin
|
34 |
+
2. Browse files in a Amazon S3 bucket
|
35 |
+
|
36 |
+
== Changelog ==
|
37 |
+
|
38 |
+
= 0.5 - 2013-01-29 =
|
39 |
+
* Forked [Amazon S3 for WordPress with CloudFront](http://wordpress.org/extend/plugins/tantan-s3-cloudfront/)
|
40 |
+
* Cleaned up the UI to fit with today's WP UI
|
41 |
+
* Fixed issues causing error messages when WP_DEBUG is on
|
42 |
+
* [Delete files on S3 when deleting WP attachment](https://github.com/bradt/wp-tantan-s3/commit/e777cd49a4b6999f999bd969241fb24cbbcece60)
|
43 |
+
* [Added filter to the get_attachment_url function](https://github.com/bradt/wp-tantan-s3/commit/bbe1aed5c2ae900e9ba1b16ba6806c28ab8e2f1c)
|
44 |
+
* [Added function to get a temporary, secure download URL for private files](https://github.com/bradt/wp-tantan-s3/commit/11f46ec2714d34907009e37ad3b97f4421aefed3)
|
screenshot-1.gif
ADDED
Binary file
|
screenshot-2.jpg
ADDED
Binary file
|
wordpress-s3.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Amazon S3 and CloudFront
|
4 |
+
Plugin URI: https://github.com/bradt/wp-tantan-s3
|
5 |
+
Description: Automatically copies media uploads to Amazon S3 for storage and delivery. Optionally configure Amazon CloudFront for even faster delivery.
|
6 |
+
Author: Brad Touesnard
|
7 |
+
Version: 0.5
|
8 |
+
Author URI: http://bradt.ca
|
9 |
+
|
10 |
+
// Copyright (c) 2013 Brad Touesnard. All rights reserved.
|
11 |
+
//
|
12 |
+
// Released under the GPL license
|
13 |
+
// http://www.opensource.org/licenses/gpl-license.php
|
14 |
+
//
|
15 |
+
// **********************************************************************
|
16 |
+
// This program is distributed in the hope that it will be useful, but
|
17 |
+
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
19 |
+
// **********************************************************************
|
20 |
+
//
|
21 |
+
// Forked Amazon S3 for WordPress with CloudFront (http://wordpress.org/extend/plugins/tantan-s3-cloudfront/)
|
22 |
+
// which is a fork of Amazon S3 for WordPress (http://wordpress.org/extend/plugins/tantan-s3/).
|
23 |
+
|
24 |
+
*/
|
25 |
+
if (class_exists('TanTanWordPressS3Plugin')) return;
|
26 |
+
|
27 |
+
// s3 lib requires php5
|
28 |
+
if (strpos($_SERVER['REQUEST_URI'], '/wp-admin/') >= 0) { // just load in admin
|
29 |
+
$ver = get_bloginfo('version');
|
30 |
+
if (version_compare(phpversion(), '5.0', '>=') && version_compare($ver, '2.1', '>=')) {
|
31 |
+
require_once(dirname(__FILE__).'/wordpress-s3/class-plugin.php');
|
32 |
+
$TanTanWordPressS3Plugin = new TanTanWordPressS3Plugin();
|
33 |
+
} elseif (ereg('wordpress-mu-', $ver)) {
|
34 |
+
require_once(dirname(__FILE__).'/wordpress-s3/class-plugin.php');
|
35 |
+
$TanTanWordPressS3Plugin = new TanTanWordPressS3Plugin();
|
36 |
+
} else {
|
37 |
+
class TanTanWordPressS3Error {
|
38 |
+
function TanTanWordPressS3Error() {add_action('admin_menu', array(&$this, 'addhooks'));}
|
39 |
+
function addhooks() {add_options_page('Amazon S3', 'Amazon S3', 10, __FILE__, array(&$this, 'admin'));}
|
40 |
+
function admin(){include(dirname(__FILE__).'/wordpress-s3/admin-version-error.html');}
|
41 |
+
}
|
42 |
+
$error = new TanTanWordPressS3Error();
|
43 |
+
}
|
44 |
+
} else {
|
45 |
+
require_once(dirname(__FILE__).'/wordpress-s3/class-plugin-public.php');
|
46 |
+
$TanTanWordPressS3Plugin = new TanTanWordPressS3PluginPublic();
|
47 |
+
}
|
48 |
+
?>
|
wordpress-s3/admin-options.html
ADDED
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ( isset($error) && $error ):?>
|
2 |
+
<div id="message" class="error fade"><p><strong><?php echo $error?></strong></p></div>
|
3 |
+
<?php elseif ( isset($message) && $message ):?>
|
4 |
+
<div id="message" class="updated fade"><p><strong><?php echo $message?></strong></p></div>
|
5 |
+
<?php endif;?>
|
6 |
+
<script type="text/javascript">
|
7 |
+
function s3_selectBucket(obj) {
|
8 |
+
if (obj.options[obj.selectedIndex].value == 'new') {
|
9 |
+
var bucket = prompt("Bucket name: ");
|
10 |
+
if (bucket) {
|
11 |
+
var len = obj.options.length
|
12 |
+
obj.options[len] = new Option("New bucket: " + bucket, bucket);
|
13 |
+
obj.options[len].selected = true;
|
14 |
+
}
|
15 |
+
}
|
16 |
+
}
|
17 |
+
</script>
|
18 |
+
<style type="text/css">
|
19 |
+
div.album {
|
20 |
+
float:left;
|
21 |
+
width:200px;
|
22 |
+
height:150px;
|
23 |
+
margin-right:15px;
|
24 |
+
}
|
25 |
+
div.album td {
|
26 |
+
font-size:0.9em;
|
27 |
+
}
|
28 |
+
div.album-hidden img {
|
29 |
+
opacity:0.5;
|
30 |
+
}
|
31 |
+
.form-table {
|
32 |
+
max-width: 850px;
|
33 |
+
float: left;
|
34 |
+
clear: none;
|
35 |
+
margin: 0 40px 20px 0;
|
36 |
+
}
|
37 |
+
.form-table th h3 {
|
38 |
+
margin: 0;
|
39 |
+
}
|
40 |
+
.wps3-author {
|
41 |
+
width: 250px;
|
42 |
+
float: left;
|
43 |
+
padding: 20px;
|
44 |
+
border: 1px solid #ccc;
|
45 |
+
overflow: hidden;
|
46 |
+
margin: 0 0 40px 0;
|
47 |
+
}
|
48 |
+
.wps3-author img {
|
49 |
+
float: left;
|
50 |
+
margin-right: 20px;
|
51 |
+
border-radius: 32px;
|
52 |
+
}
|
53 |
+
.wps3-author .desc {
|
54 |
+
float: left;
|
55 |
+
}
|
56 |
+
.wps3-author h3 {
|
57 |
+
font-size: 12px;
|
58 |
+
margin: 0;
|
59 |
+
}
|
60 |
+
.wps3-author h2 {
|
61 |
+
font-size: 18px;
|
62 |
+
margin: 0;
|
63 |
+
padding: 0;
|
64 |
+
}
|
65 |
+
.wps3-author h2 a {
|
66 |
+
color: #464646;
|
67 |
+
text-decoration: none;
|
68 |
+
}
|
69 |
+
.wps3-author h2 a:hover {
|
70 |
+
color: #000;
|
71 |
+
}
|
72 |
+
.wps3-author p {
|
73 |
+
margin: 0;
|
74 |
+
}
|
75 |
+
.wps3-author .github {
|
76 |
+
padding-top: 5px;
|
77 |
+
}
|
78 |
+
</style>
|
79 |
+
|
80 |
+
|
81 |
+
<div class="wrap">
|
82 |
+
<div id="icon-options-general" class="icon32"><br></div>
|
83 |
+
<h2 id="write-post">Amazon S3 and CloudFront</h2>
|
84 |
+
<?php
|
85 |
+
global $TanTanVersionCheck;
|
86 |
+
if (is_object($TanTanVersionCheck)):?>
|
87 |
+
<div style="width:200px; border:1px solid #ccc;padding:10px; float:right; margin:0 0 10px 10px;">
|
88 |
+
<strong>Plugin Updates:</strong><br />
|
89 |
+
<a href="plugins.php?page=tantan/version-check.php">Check for updates to this plugin ></a>
|
90 |
+
</div>
|
91 |
+
<?php endif;?>
|
92 |
+
|
93 |
+
<table class="form-table">
|
94 |
+
<form method="post">
|
95 |
+
<input type="hidden" name="action" value="save" />
|
96 |
+
<tr valign="top">
|
97 |
+
<td colspan="2">
|
98 |
+
<h3>AWS Access Credentials</h3>
|
99 |
+
<p>
|
100 |
+
If you don't have an Amazon S3 account yet, you need to
|
101 |
+
<a href="http://aws.amazon.com/s3/">sign up</a>.<br />
|
102 |
+
|
103 |
+
Once you've signed up, you can retrieve your access credentials from the
|
104 |
+
<a href="https://portal.aws.amazon.com/gp/aws/securityCredentials">Security Credentials</a>
|
105 |
+
page of your Amazon Web Services account.
|
106 |
+
</p>
|
107 |
+
</td>
|
108 |
+
</tr>
|
109 |
+
<tr valign="top">
|
110 |
+
<th width="33%" scope="row">Access Key ID:</th>
|
111 |
+
<td><input type="text" name="options[key]" value="<?php echo $options['key'];?>" size="50" /></td>
|
112 |
+
</tr>
|
113 |
+
<tr valign="top">
|
114 |
+
<th width="33%" scope="row">Secret Access Key:</th>
|
115 |
+
<td><input type="text" name="options[secret]" value="<?php echo ($options['secret'] ? '-- not shown --' : '');?>" size="50" /></td>
|
116 |
+
</tr>
|
117 |
+
<?php if (!isset($buckets) || !$buckets):?>
|
118 |
+
<tr valign="top">
|
119 |
+
<td colspan="2">
|
120 |
+
<p class="submit">
|
121 |
+
<input type="submit" class="button button-primary" value="Next Step" />
|
122 |
+
</p>
|
123 |
+
</td>
|
124 |
+
</tr>
|
125 |
+
<?php else:?>
|
126 |
+
<tr valign="top">
|
127 |
+
<td colspan="2">
|
128 |
+
<h3>S3 Settings</h3>
|
129 |
+
</td>
|
130 |
+
</tr>
|
131 |
+
<tr valign="top">
|
132 |
+
<th width="33%" scope="row"> </th>
|
133 |
+
<td>
|
134 |
+
<select name="options[bucket]" size="1" onchange="return s3_selectBucket(this)" style="margin-bottom: 5px; width: 380px;">
|
135 |
+
<option value="">-- Select an S3 Bucket --</option>
|
136 |
+
<?php if (is_array($buckets)) foreach ($buckets as $bucket):?>
|
137 |
+
<option value="<?php echo $bucket?>" <?php echo ( isset( $options['bucket'] ) && $bucket == $options['bucket'] ) ? 'selected="selected"' : ''; ?>><?php echo $bucket?></option>
|
138 |
+
<?php endforeach;?>
|
139 |
+
<option value="new">Create a new bucket...</option>
|
140 |
+
</select><br />
|
141 |
+
|
142 |
+
<input type="checkbox" name="options[virtual-host]" value="1" id="virtual-host" <?php echo ( isset( $options['virtual-host'] ) && $options['virtual-host'] ) ? 'checked="checked" ' : '';?> />
|
143 |
+
<label for="virtual-host"> Bucket is setup for virtual hosting</label> (<a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/VirtualHosting.html">more info</a>)
|
144 |
+
<br />
|
145 |
+
|
146 |
+
<input type="checkbox" name="options[expires]" value="315360000" id="expires" <?php echo ( isset( $options['expires'] ) && $options['expires'] ) ? 'checked="checked" ' : ''; ?> />
|
147 |
+
<label for="expires"> Set a <a href="http://developer.yahoo.com/performance/rules.html#expires" target="_blank">far future HTTP expiration header</a> for uploaded files <em>(recommended)</em></label>
|
148 |
+
<br />
|
149 |
+
|
150 |
+
<input type="checkbox" name="options[permissions]" value="public" id="permissions" <?php echo ( isset( $options['permissions'] ) && $options['permissions'] == 'public' ) ? 'checked="checked" ' : ''; ?> />
|
151 |
+
<label for="permissions"> Force set the permissions on all files in the bucket to public</label>
|
152 |
+
|
153 |
+
</td>
|
154 |
+
</tr>
|
155 |
+
|
156 |
+
<tr valign="top">
|
157 |
+
<td colspan="2">
|
158 |
+
<h3>CloudFront Settings</h3>
|
159 |
+
</td>
|
160 |
+
</tr>
|
161 |
+
<tr valign="top">
|
162 |
+
<th width="33%" scope="row">Domain Name</th>
|
163 |
+
<td>
|
164 |
+
<input type="text" name="options[cloudfront]" value="<?php echo isset( $options['cloudfront'] ) ? $options['cloudfront'] : ''; ?>" size="50" />
|
165 |
+
<p class="description">Leave blank if you aren't using CloudFront.</p>
|
166 |
+
</td>
|
167 |
+
</tr>
|
168 |
+
|
169 |
+
<tr valign="top">
|
170 |
+
<td colspan="2">
|
171 |
+
<h3>Plugin Settings</h3>
|
172 |
+
</td>
|
173 |
+
</tr>
|
174 |
+
|
175 |
+
<tr valign="top">
|
176 |
+
<th width="33%" scope="row"> </th>
|
177 |
+
<td>
|
178 |
+
<input type="checkbox" name="options[wp-uploads]" value="1" id="wp-uploads" <?php echo ( isset( $options['wp-uploads'] ) && $options['wp-uploads'] ) ? 'checked="checked" ' : ''; ?> />
|
179 |
+
<label for="wp-uploads"> Enable copying of media files to S3 and serving media files from S3/CloudFront</label>
|
180 |
+
<p class="description">Uncheck this to revert back to using your own web host for storage and delivery at anytime.</p>
|
181 |
+
</td>
|
182 |
+
</tr>
|
183 |
+
|
184 |
+
<tr>
|
185 |
+
<td colspan="2">
|
186 |
+
<p class="submit">
|
187 |
+
<input type="submit" class="button button-primary" value="Save Changes" />
|
188 |
+
</p>
|
189 |
+
</td>
|
190 |
+
</tr>
|
191 |
+
<?php endif;?>
|
192 |
+
|
193 |
+
|
194 |
+
</form>
|
195 |
+
|
196 |
+
</table>
|
197 |
+
|
198 |
+
|
199 |
+
|
200 |
+
<div class="wps3-author">
|
201 |
+
<img src="http://www.gravatar.com/avatar/e538ca4cb34839d4e5e3ccf20c37c67b?s=128&d" width="64" height="64" />
|
202 |
+
<div class="desc">
|
203 |
+
<h3>Maintained by</h3>
|
204 |
+
<h2>Brad Touesnard</h2>
|
205 |
+
<p>
|
206 |
+
<a href="http://profiles.wordpress.org/bradt/">Profile</a>
|
207 |
+
|
208 |
+
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5VPMGLLK94XJC">Donate</a>
|
209 |
+
</p>
|
210 |
+
<p class="github">
|
211 |
+
<a href="https://github.com/bradt/wp-tantan-s3/">Contribute on GitHub</a>
|
212 |
+
</p>
|
213 |
+
</div>
|
214 |
+
</div>
|
215 |
+
|
216 |
+
|
217 |
+
|
218 |
+
</div>
|
wordpress-s3/admin-tab-head.html
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$dir = dirname(__FILE__);
|
3 |
+
$pluginRootURL = plugins_url( '', __FILE__ );
|
4 |
+
if (!ereg('media-upload.php', $_SERVER['REQUEST_URI'])): // WP < 2.5
|
5 |
+
?>
|
6 |
+
|
7 |
+
<script type="text/javascript">
|
8 |
+
addLoadEvent(function () {
|
9 |
+
var div = document.getElementById('upload-menu');
|
10 |
+
var as = div.getElementsByTagName('a')
|
11 |
+
for (var i=0;i<as.length;i++) {
|
12 |
+
var pos = as[i].innerHTML.indexOf('S3');
|
13 |
+
if (pos >= 0) {
|
14 |
+
as[i].innerHTML = '<span style="padding:0 20px 0 0;background:url(<?php echo $pluginRootURL;?>/database.png) no-repeat right;">' + as[i].innerHTML + '</span>';
|
15 |
+
}
|
16 |
+
}
|
17 |
+
<?php if ($this->options['wp-uploads'] && $this->options['bucket']):?>
|
18 |
+
var upload = document.getElementById('upload');
|
19 |
+
if (upload && upload.name == 'image') {
|
20 |
+
var span = document.createElement('span');
|
21 |
+
span.id = 'disable_amazonS3_span';
|
22 |
+
span.innerHTML = '<label for="disable_amazonS3"> don\'t upload to amazon s3 </label><input type="checkbox" name="disable_amazonS3" id="disable_amazonS3" value="1" />';
|
23 |
+
var btns = document.getElementById('buttons')
|
24 |
+
var tds = btns.getElementsByTagName('td')
|
25 |
+
tds[0].appendChild(span);
|
26 |
+
}
|
27 |
+
<?php endif;?>
|
28 |
+
});
|
29 |
+
</script>
|
30 |
+
<?php endif;?>
|
31 |
+
<script type="text/javascript" src="<?php echo $pluginRootURL;?>/admin-tab.js"></script>
|
32 |
+
<link rel='stylesheet' href='<?php echo $pluginRootURL;?>/styles/styles.css' type='text/css' />
|
wordpress-s3/admin-tab.html
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
function print_file_type($contentType, $file) {
|
3 |
+
if (ereg('octet-stream', $contentType)) {
|
4 |
+
return ereg_replace('(.*)\.([a-zA-Z0-9]*)$', '\\2', $file);
|
5 |
+
} else {
|
6 |
+
return ereg_replace('vnd.', '', ereg_replace('/', ' ', $contentType));
|
7 |
+
}
|
8 |
+
}
|
9 |
+
?>
|
10 |
+
|
11 |
+
<div id="amazon-s3-wrap">
|
12 |
+
|
13 |
+
<div class="infobar">
|
14 |
+
|
15 |
+
<span class="nav-controls">
|
16 |
+
<?php if (true || $_SERVER['HTTP_REFERER']):?>
|
17 |
+
<a href="javascript:history.back()" onclick="" id="btn-back" title="back">back</a>
|
18 |
+
<a href="javascript:history.forward()" onclick="" id="btn-forward" title="forward">forward</a>
|
19 |
+
<?php endif; ?>
|
20 |
+
<a href="javascript:window.location.reload()" onclick="" id="btn-refresh" title="refresh view">refresh</a>
|
21 |
+
<a href="#" onclick="return s3_toggleUpload();" id="btn-upload" title="upload">upload</a>
|
22 |
+
<a href="#" onclick="return s3_toggleCreateFolder();" id="btn-folder" title="create new folder">new folder</a>
|
23 |
+
</span>
|
24 |
+
<span class="path">
|
25 |
+
<?php
|
26 |
+
$tree = $keys;
|
27 |
+
echo '<a href="'.add_query_arg('prefix', urlencode(''), $_SERVER['REQUEST_URI']).'" class="home">home</a> / ';
|
28 |
+
$path = '';
|
29 |
+
$paths = preg_split('/\//', $prefix, 100, PREG_SPLIT_NO_EMPTY);
|
30 |
+
$numPaths = count($paths);
|
31 |
+
$i=0;
|
32 |
+
foreach ($paths as $name) if ($name) {
|
33 |
+
$path .= $name .'/';
|
34 |
+
$isLast = (++$i) >= $numPaths;
|
35 |
+
echo '<a class="'.( $isLast ? 'last' : '').'" href="'.add_query_arg('prefix', urlencode($path), $_SERVER['REQUEST_URI']).'">'.$name.'</a> '.(!$isLast ? ' / ' : ' ');
|
36 |
+
}
|
37 |
+
?>
|
38 |
+
</span>
|
39 |
+
<span class="options">
|
40 |
+
<input type="checkbox" name="useBittorrent" id="useBittorrent" value="1" /><label for="useBittorrent"> create links as torrents</label>
|
41 |
+
</span>
|
42 |
+
<div id="create-form">
|
43 |
+
<form method="post">
|
44 |
+
<input type="hidden" name="prefix" value="<?php echo htmlentities($_GET['prefix']);?>">
|
45 |
+
<input type="text" name="newfolder" id="newfolder" />
|
46 |
+
<input type="submit" value="create" />
|
47 |
+
</form>
|
48 |
+
</div>
|
49 |
+
<div id="upload-form">
|
50 |
+
<form method="post" enctype="multipart/form-data">
|
51 |
+
<input type="file" name="newfile" />
|
52 |
+
<input type="submit" value="upload" />
|
53 |
+
</form>
|
54 |
+
</div>
|
55 |
+
|
56 |
+
</div>
|
57 |
+
<div class="folders">
|
58 |
+
<form method="post">
|
59 |
+
<ul id="prefixes">
|
60 |
+
<?php
|
61 |
+
if (is_array($prefixes)) foreach ($prefixes as $prefix):
|
62 |
+
$label = substr($prefix, strrpos(trim($prefix, '/'), '/')+1);
|
63 |
+
$label = ($path ? ereg_replace($path, "", '/'.$prefix) : $prefix);
|
64 |
+
$label = trim($prefix, '/');
|
65 |
+
if (ereg('/', $label)) $label = substr($label, strrpos($label, '/')+1);
|
66 |
+
?>
|
67 |
+
<li><a href="<?php echo add_query_arg('prefix', urlencode($prefix), $_SERVER['REQUEST_URI']);?>" title="<?php echo $label;?>"><?php echo $label;?></a></li>
|
68 |
+
<?php
|
69 |
+
endforeach;
|
70 |
+
?>
|
71 |
+
</ul>
|
72 |
+
</form>
|
73 |
+
</div>
|
74 |
+
<div class="files">
|
75 |
+
<ul id="keys">
|
76 |
+
<?php if (count($keys)): foreach ($keys as $i => $file):
|
77 |
+
$file = '/'.$file;
|
78 |
+
$url = 'http://'.$accessDomain.$file;
|
79 |
+
$label = substr($file, strrpos($file, '/')+1);
|
80 |
+
?>
|
81 |
+
<li class="<?php echo print_file_type($meta[$i]['content-type'], $file);?>"><a
|
82 |
+
<?php if (ereg("^image/.*", $meta[$i]['content-type'])):?>
|
83 |
+
onclick="return s3_insertImage('<?php echo $url;?>', '<?php echo basename($url);?>')"
|
84 |
+
<?php else:?>
|
85 |
+
onclick="return s3_insertLink('<?php echo addslashes($label);?>', '<?php echo $url;?>')"
|
86 |
+
<?php endif;?>
|
87 |
+
href="<?php echo $url;?>"
|
88 |
+
class="file <?php echo ereg_replace('/', ' ', $meta[$i]['content-type']);?>"
|
89 |
+
title="<?php echo $meta[$i]['date'];?> - <?php echo $meta[$i]['content-length'];?> bytes"><?php echo $label;?></a>
|
90 |
+
</li>
|
91 |
+
<?php endforeach;?>
|
92 |
+
<?php else:?>
|
93 |
+
<li class="empty">no files in this folder</li>
|
94 |
+
<?php endif;?>
|
95 |
+
</ul>
|
96 |
+
</div>
|
97 |
+
</div>
|
98 |
+
<br clear="both" />
|
wordpress-s3/admin-tab.js
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
function s3_insertImage(imgURL, title) {
|
3 |
+
if (!title) title = '';
|
4 |
+
return s3_insert('<img src="'+imgURL+'" class="s3-img" border="0" alt="'+title+'" /> ');
|
5 |
+
}
|
6 |
+
|
7 |
+
function s3_insertLink(label, url) {
|
8 |
+
var useBittorrent = document.getElementById('useBittorrent').checked
|
9 |
+
return s3_insert('<a href="'+url+(useBittorrent ? '?torrent' : '')+'" class="s3-link'+(useBittorrent ? ' torrent' : '')+'">' + label + '</a> ');
|
10 |
+
}
|
11 |
+
function s3_insert(h) {
|
12 |
+
var win = window.dialogArguments || opener || parent || top;
|
13 |
+
|
14 |
+
if (typeof win.send_to_editor == 'function') {
|
15 |
+
win.send_to_editor(h);
|
16 |
+
if (typeof win.tb_remove == 'function')
|
17 |
+
win.tb_remove();
|
18 |
+
return false;
|
19 |
+
}
|
20 |
+
tinyMCE = win.tinyMCE;
|
21 |
+
if ( typeof tinyMCE != 'undefined' && tinyMCE.getInstanceById('content') ) {
|
22 |
+
tinyMCE.selectedInstance.getWin().focus();
|
23 |
+
tinyMCE.execCommand('mceInsertContent', false, h);
|
24 |
+
} else win.edInsertContent(win.edCanvas, h);
|
25 |
+
|
26 |
+
return false;
|
27 |
+
}
|
28 |
+
function s3_toggleUpload() {
|
29 |
+
document.getElementById('create-form').style.display='none';
|
30 |
+
|
31 |
+
var div = document.getElementById('upload-form');
|
32 |
+
if (div.style.display == 'block') {
|
33 |
+
div.style.display = 'none';
|
34 |
+
} else {
|
35 |
+
div.style.display = 'block';
|
36 |
+
}
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
function s3_toggleCreateFolder() {
|
40 |
+
document.getElementById('upload-form').style.display='none';
|
41 |
+
|
42 |
+
var div = document.getElementById('create-form');
|
43 |
+
if (div.style.display == 'block') {
|
44 |
+
div.style.display = 'none';
|
45 |
+
} else {
|
46 |
+
div.style.display = 'block';
|
47 |
+
document.getElementById('newfolder').focus();
|
48 |
+
}
|
49 |
+
return false;
|
50 |
+
|
51 |
+
|
52 |
+
var div = document.getElementById('createFolder');
|
53 |
+
if (div.className != 'create') {
|
54 |
+
div.className = 'create';
|
55 |
+
document.getElementById('newfolder').focus();
|
56 |
+
} else {
|
57 |
+
div.className = '';
|
58 |
+
}
|
59 |
+
}
|
wordpress-s3/admin-version-error.html
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ($error):?>
|
2 |
+
<div id="message" class="error fade"><p><strong><?php echo $error?></strong></p></div>
|
3 |
+
<?php elseif ($message):?>
|
4 |
+
<div id="message" class="updated fade"><p><strong><?php echo $message?></strong></p></div>
|
5 |
+
<?php endif;?>
|
6 |
+
|
7 |
+
<style>
|
8 |
+
fieldset.options {
|
9 |
+
clear:both;
|
10 |
+
border:1px solid #ccc;
|
11 |
+
}
|
12 |
+
fieldset.options legend {
|
13 |
+
font-family: Georgia,"Times New Roman",Times,serif;
|
14 |
+
font-size: 22px;
|
15 |
+
}
|
16 |
+
|
17 |
+
div.album {
|
18 |
+
float:left;
|
19 |
+
width:200px;
|
20 |
+
height:150px;
|
21 |
+
margin-right:15px;
|
22 |
+
}
|
23 |
+
div.album td {
|
24 |
+
font-size:0.9em;
|
25 |
+
}
|
26 |
+
div.album-hidden img {
|
27 |
+
opacity:0.5;
|
28 |
+
}
|
29 |
+
</style>
|
30 |
+
|
31 |
+
|
32 |
+
<div class="wrap">
|
33 |
+
<h2 id="write-post">Amazon S3 Plugin for WordPress</h2>
|
34 |
+
<div style="width:250px;border:1px solid #ccc;float:right;padding:10px;margin:0 0 10px 10px;">
|
35 |
+
<strong><a href="http://www.dreamhost.com/r.cgi?156998" target="_blank">Switch to a better web host!</a></strong><br />
|
36 |
+
Use the coupon code
|
37 |
+
<b>TANTAN50COUPON</b>
|
38 |
+
when you signup to get a $50 discount, and you'll
|
39 |
+
help support this plugin in the process.
|
40 |
+
That works out to be less than $6.00 per month for the first year.
|
41 |
+
|
42 |
+
</div>
|
43 |
+
<h3>Error</h3>
|
44 |
+
<p>
|
45 |
+
Sorry, this plugin requires at least PHP <strong>5.0</strong> and WordPress <strong>2.1</strong> in order to work correctly.
|
46 |
+
Please contact your systems administrator about getting your version of PHP and/or WordPress upgraded.
|
47 |
+
</p>
|
48 |
+
<p>
|
49 |
+
Your PHP version: <strong style="<?php echo (version_compare(phpversion(), '5.0.0', '<') ? 'color:red;' : '');?>"><?php echo phpversion();?></strong><br />
|
50 |
+
Your WordPress version: <strong style="<?php echo (version_compare(get_bloginfo('version'), '2.1', '<') ? 'color:red;' : '');?>"><?php bloginfo('version'); ?></strong>
|
51 |
+
<br />
|
52 |
+
</p>
|
53 |
+
|
54 |
+
<p>
|
55 |
+
<a href="http://www.php.net/downloads.php">Download PHP</a><br />
|
56 |
+
<a href="http://wordpress.org/download/">Download WordPress</a><br />
|
57 |
+
</p>
|
58 |
+
</div>
|
wordpress-s3/class-plugin-public.php
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class TanTanWordPressS3PluginPublic {
|
3 |
+
var $options;
|
4 |
+
var $s3;
|
5 |
+
var $meta;
|
6 |
+
|
7 |
+
function TanTanWordPressS3PluginPublic() {
|
8 |
+
$this->options = array();
|
9 |
+
if (file_exists(dirname(__FILE__).'/config.php')) {
|
10 |
+
require_once(dirname(__FILE__).'/config.php');
|
11 |
+
if ($TanTanWordPressS3Config) $this->options = $TanTanWordPressS3Config;
|
12 |
+
}
|
13 |
+
add_action('plugins_loaded', array(&$this, 'addhooks'));
|
14 |
+
}
|
15 |
+
function addhooks() {
|
16 |
+
add_filter('wp_get_attachment_url', array(&$this, 'wp_get_attachment_url'), 9, 2);
|
17 |
+
}
|
18 |
+
function wp_get_attachment_url($url, $postID) {
|
19 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
20 |
+
|
21 |
+
if ($this->options['wp-uploads'] && ($amazon = get_post_meta($postID, 'amazonS3_info', true))) {
|
22 |
+
if ( isset($this->options['cloudfront']) && $this->options['cloudfront'] ) {
|
23 |
+
$accessDomain = $this->options['cloudfront'];
|
24 |
+
}
|
25 |
+
elseif ( isset($this->options['virtual-host']) && $this->options['virtual-host'] ) {
|
26 |
+
$accessDomain = $this->options['bucket'];
|
27 |
+
}
|
28 |
+
else {
|
29 |
+
$accessDomain = $amazon['bucket'] . '.s3.amazonaws.com';
|
30 |
+
}
|
31 |
+
|
32 |
+
$url = 'http://'.$accessDomain.'/'.$amazon['key'];
|
33 |
+
|
34 |
+
$url = apply_filters( 'wps3_get_attachment_url', $url, $postID, $this );
|
35 |
+
}
|
36 |
+
|
37 |
+
return $url;
|
38 |
+
}
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Generate a link to download a file from Amazon S3 using query string
|
43 |
+
* authentication. This link is only valid for a limited amount of time.
|
44 |
+
*
|
45 |
+
* @param $bucket The name of the bucket in which the file is stored.
|
46 |
+
* @param $filekey The key of the file, excluding the leading slash.
|
47 |
+
* @param $expires The amount of time the link is valid (in seconds).
|
48 |
+
* @param $operation The type of HTTP operation. Either GET or HEAD.
|
49 |
+
*/
|
50 |
+
function get_secure_attachment_url($postID, $expires = 900, $operation = 'GET') {
|
51 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
52 |
+
|
53 |
+
if (
|
54 |
+
!$this->options['wp-uploads'] || !$this->options['key'] || !$this->options['secret']
|
55 |
+
|| !$this->options['bucket'] || !($amazon = get_post_meta($postID, 'amazonS3_info', true))
|
56 |
+
) {
|
57 |
+
return false;
|
58 |
+
}
|
59 |
+
|
60 |
+
$accessDomain = $this->options['virtual-host'] ? $amazon['bucket'] : $amazon['bucket'].'.s3.amazonaws.com';
|
61 |
+
|
62 |
+
$expire_time = time() + $expires;
|
63 |
+
$filekey = rawurlencode($amazon['key']);
|
64 |
+
$filekey = str_replace('%2F', '/', $filekey);
|
65 |
+
$path = $amazon['bucket'] .'/'. $filekey;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* StringToSign = HTTP-VERB + "\n" +
|
69 |
+
* Content-MD5 + "\n" +
|
70 |
+
* Content-Type + "\n" +
|
71 |
+
* Expires + "\n" +
|
72 |
+
* CanonicalizedAmzHeaders +
|
73 |
+
* CanonicalizedResource;
|
74 |
+
*/
|
75 |
+
|
76 |
+
$stringtosign =
|
77 |
+
$operation ."\n". // type of HTTP request (GET/HEAD)
|
78 |
+
"\n". // Content-MD5 is meaningless for GET
|
79 |
+
"\n". // Content-Type is meaningless for GET
|
80 |
+
$expire_time ."\n". // set the expire date of this link
|
81 |
+
"/$path"; // full path (incl bucket), starting with a /
|
82 |
+
|
83 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
84 |
+
$s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
85 |
+
$signature = urlencode($s3->constructSig($stringtosign));
|
86 |
+
|
87 |
+
return sprintf('http://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s', $accessDomain, $filekey, $this->options['key'], $expire_time, $signature);
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
function wps3_get_secure_attachment_url($postID, $expires = 900, $operation = 'GET') {
|
92 |
+
global $TanTanWordPressS3Plugin;
|
93 |
+
return $TanTanWordPressS3Plugin->get_secure_attachment_url($postID, $expires, $operation);
|
94 |
+
}
|
wordpress-s3/class-plugin.php
ADDED
@@ -0,0 +1,496 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once(dirname(__FILE__).'/class-plugin-public.php');
|
3 |
+
class TanTanWordPressS3Plugin extends TanTanWordPressS3PluginPublic {
|
4 |
+
|
5 |
+
function TanTanWordPressS3Plugin() {
|
6 |
+
parent::TanTanWordPressS3PluginPublic();
|
7 |
+
if (!file_exists(dirname(__FILE__).'/config.php')) {
|
8 |
+
add_action('admin_menu', array(&$this, 'settings'));
|
9 |
+
}
|
10 |
+
if (!isset($this->options['hideAmazonS3UploadTab']) || !$this->options['hideAmazonS3UploadTab']) {
|
11 |
+
add_action('load-upload.php', array(&$this, 'addPhotosTab')); // WP < 2.5
|
12 |
+
|
13 |
+
// WP >= 2.5
|
14 |
+
add_action('media_buttons_context', array(&$this, 'media_buttons'));
|
15 |
+
add_action('media_upload_tabs', array(&$this, 'media_upload_tabs'));
|
16 |
+
add_action('media_upload_tantan-wordpress-s3', array(&$this, 'media_upload_content'));
|
17 |
+
}
|
18 |
+
add_action('activate_tantan/wordpress-s3.php', array(&$this, 'activate'));
|
19 |
+
if (isset($_GET['tantanActivate']) && $_GET['tantanActivate'] == 'wordpress-s3') {
|
20 |
+
$this->showConfigNotice();
|
21 |
+
}
|
22 |
+
$this->photos = array();
|
23 |
+
$this->albums = array();
|
24 |
+
$this->perPage = 1000;
|
25 |
+
|
26 |
+
|
27 |
+
}
|
28 |
+
|
29 |
+
// this should install the javascripts onto the user's s3.amazonaws.com account
|
30 |
+
|
31 |
+
function installAjax() {
|
32 |
+
$js = array('S3Ajax.js');
|
33 |
+
}
|
34 |
+
|
35 |
+
function activate() {
|
36 |
+
wp_redirect('plugins.php?tantanActivate=wordpress-s3');
|
37 |
+
exit;
|
38 |
+
}
|
39 |
+
function deactivate() {}
|
40 |
+
|
41 |
+
function showConfigNotice() {
|
42 |
+
add_action('admin_notices', create_function('', 'echo \'<div id="message" class="updated fade"><p>Amazon S3 Plugin for WordPress <strong>activated</strong>. <a href="options-general.php?page=tantan/wordpress-s3/class-plugin.php">Configure the plugin ></a></p></div>\';'));
|
43 |
+
}
|
44 |
+
|
45 |
+
function settings() {
|
46 |
+
add_options_page('Amazon S3', 'Amazon S3', 10, __FILE__, array(&$this, 'admin'));
|
47 |
+
$this->version_check();
|
48 |
+
}
|
49 |
+
function addhooks() {
|
50 |
+
parent::addhooks();
|
51 |
+
if (!isset($_POST['disable_amazonS3']) || !$_POST['disable_amazonS3']) {
|
52 |
+
add_filter('wp_update_attachment_metadata', array(&$this, 'wp_update_attachment_metadata'), 9, 2);
|
53 |
+
//can't delete mirrored files just yet
|
54 |
+
//add_filter('wp_get_attachment_metadata', array(&$this, 'wp_get_attachment_metadata'));
|
55 |
+
add_filter('delete_attachment', array(&$this, 'delete_attachment'));
|
56 |
+
}
|
57 |
+
}
|
58 |
+
function version_check() {
|
59 |
+
global $TanTanVersionCheck;
|
60 |
+
if (is_object($TanTanVersionCheck)) {
|
61 |
+
$data = get_plugin_data(dirname(__FILE__).'/../wordpress-s3.php');
|
62 |
+
$TanTanVersionCheck->versionCheck(668, $data['Version']);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
function admin() {
|
66 |
+
if ( isset( $_POST['action'] ) && $_POST['action'] == 'save' ) {
|
67 |
+
if (!is_array($_POST['options'])) $_POST['options'] = array();
|
68 |
+
$options = get_option('tantan_wordpress_s3');
|
69 |
+
|
70 |
+
$_POST['options']['key'] = trim($_POST['options']['key']);
|
71 |
+
$_POST['options']['secret'] = trim($_POST['options']['secret']);
|
72 |
+
|
73 |
+
if (!$_POST['options']['secret'] || ereg('not shown', $_POST['options']['secret'])) {
|
74 |
+
$_POST['options']['secret'] = $options['secret'];
|
75 |
+
}
|
76 |
+
|
77 |
+
update_option('tantan_wordpress_s3', $_POST['options']);
|
78 |
+
|
79 |
+
if (isset($_POST['options']['bucket']) && $_POST['options']['bucket']) {
|
80 |
+
$options = get_option('tantan_wordpress_s3');
|
81 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
82 |
+
$s3 = new TanTanS3($options['key'], $options['secret']);
|
83 |
+
|
84 |
+
if (!in_array($_POST['options']['bucket'], $s3->listBuckets())) {
|
85 |
+
if ($s3->createBucket($_POST['options']['bucket'],'public-read')) {
|
86 |
+
$message = "Saved settings and created a new bucket: ".$_POST['options']['bucket'];
|
87 |
+
} else {
|
88 |
+
$error = "There was an error creating the bucket: ".$_POST['options']['bucket'];
|
89 |
+
}
|
90 |
+
} else {
|
91 |
+
$message = "Saved settings.";
|
92 |
+
}
|
93 |
+
} else {
|
94 |
+
$message = "Saved Amazon S3 authentication information. ";
|
95 |
+
}
|
96 |
+
if (function_exists('dns_get_record') && isset( $_POST['options']['virtual-host'] ) && $_POST['options']['virtual-host'] ) {
|
97 |
+
$record = dns_get_record($_POST['options']['bucket']);
|
98 |
+
if (($record[0]['type'] != 'CNAME') || ($record[0]['target'] != $_POST['options']['bucket'].'s3.amazonaws.com')) {
|
99 |
+
$error = "Warning: Your DNS doesn't seem to be setup correctly to virtually host the domain <em>".$_POST['options']['bucket']."</em>. ".
|
100 |
+
"Double check and make sure the following entry is added to your DNS. ".
|
101 |
+
"<a href='http://docs.amazonwebservices.com/AmazonS3/2006-03-01/VirtualHosting.html'>More info ></a>".
|
102 |
+
"<br /><br />".
|
103 |
+
"<code>".$_POST['options']['bucket']." CNAME ".$_POST['options']['bucket'].".s3.amazonaws.com.</code>".
|
104 |
+
"<br /><br />".
|
105 |
+
"<small>You can ignore this message if you're sure everything is setup correctly.</small>";
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
$options = get_option('tantan_wordpress_s3');
|
110 |
+
if ($options['key'] && $options['secret']) {
|
111 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
112 |
+
$s3 = new TanTanS3($options['key'], $options['secret']);
|
113 |
+
if (!($buckets = $s3->listBuckets())) {
|
114 |
+
$error = $this->getErrorMessage($s3->parsed_xml, $s3->responseCode);
|
115 |
+
}
|
116 |
+
|
117 |
+
$s3->initCacheTables();
|
118 |
+
|
119 |
+
} elseif ($options['key']) {
|
120 |
+
$error = "Please enter your Secret Access Key.";
|
121 |
+
} elseif ($options['secret']) {
|
122 |
+
$error = "Please enter your Access Key ID.";
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
include(dirname(__FILE__).'/admin-options.html');
|
127 |
+
}
|
128 |
+
|
129 |
+
|
130 |
+
/*
|
131 |
+
Delete corresponding files from Amazon S3
|
132 |
+
*/
|
133 |
+
function delete_attachment( $post_id ) {
|
134 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
135 |
+
|
136 |
+
if (!$this->options['wp-uploads'] || !$this->options['bucket'] || !$this->options['secret']) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
+
$backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
|
141 |
+
|
142 |
+
$intermediate_sizes = array();
|
143 |
+
foreach ( get_intermediate_image_sizes() as $size ) {
|
144 |
+
if ( $intermediate = image_get_intermediate_size( $post_id, $size ) )
|
145 |
+
$intermediate_sizes[] = $intermediate;
|
146 |
+
}
|
147 |
+
|
148 |
+
if ( !( $amazon = get_post_meta( $post_id, 'amazonS3_info', true ) ) ) {
|
149 |
+
return;
|
150 |
+
}
|
151 |
+
|
152 |
+
$amazon_path = dirname( $amazon['key'] );
|
153 |
+
|
154 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
155 |
+
$this->s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
156 |
+
$this->s3->setOptions($this->options);
|
157 |
+
|
158 |
+
// remove intermediate and backup images if there are any
|
159 |
+
foreach ( $intermediate_sizes as $intermediate ) {
|
160 |
+
$this->s3->deleteObject( $amazon['bucket'], path_join( $amazon_path, $intermediate['file'] ) );
|
161 |
+
}
|
162 |
+
|
163 |
+
if ( is_array($backup_sizes) ) {
|
164 |
+
foreach ( $backup_sizes as $size ) {
|
165 |
+
$this->s3->deleteObject( $amazon['bucket'], path_join( $amazon_path, $del_file ) );
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
$this->s3->deleteObject( $amazon['bucket'], $amazon['key'] );
|
170 |
+
}
|
171 |
+
|
172 |
+
function wp_get_attachment_metadata($data=false, $postID=false) {
|
173 |
+
if (is_numeric($postID)) $this->meta = get_post_meta($postID, 'amazonS3_info', true);
|
174 |
+
return $data;
|
175 |
+
}
|
176 |
+
/*
|
177 |
+
Handle uploads through default WordPress upload handler
|
178 |
+
*/
|
179 |
+
function wp_update_attachment_metadata($data, $postID) {
|
180 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
181 |
+
|
182 |
+
if (!$this->options['wp-uploads'] || !$this->options['bucket'] || !$this->options['secret']) {
|
183 |
+
return $data;
|
184 |
+
}
|
185 |
+
|
186 |
+
add_filter('option_siteurl', array(&$this, 'upload_path'));
|
187 |
+
$uploadDir = wp_upload_dir();
|
188 |
+
remove_filter('option_siteurl', array(&$this, 'upload_path'));
|
189 |
+
$parts = parse_url($uploadDir['url']);
|
190 |
+
|
191 |
+
$prefix = substr($parts['path'], 1) .'/';
|
192 |
+
$type = get_post_mime_type($postID);
|
193 |
+
|
194 |
+
$data['file'] = get_attached_file($postID, true);
|
195 |
+
|
196 |
+
$acl = apply_filters( 'wps3_upload_acl', 'public-read', $type, $data, $postID, $this );
|
197 |
+
|
198 |
+
if (file_exists($data['file'])) {
|
199 |
+
$file = array(
|
200 |
+
'name' => basename($data['file']),
|
201 |
+
'type' => $type,
|
202 |
+
'tmp_name' => $data['file'],
|
203 |
+
'error' => 0,
|
204 |
+
'size' => filesize($data['file']),
|
205 |
+
);
|
206 |
+
|
207 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
208 |
+
$this->s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
209 |
+
$this->s3->setOptions($this->options);
|
210 |
+
|
211 |
+
if ($this->s3->putObjectStream($this->options['bucket'], $prefix.$file['name'], $file, $acl)) {
|
212 |
+
|
213 |
+
if ($data['thumb']) {
|
214 |
+
$thumbpath = str_replace( basename( $data['file'] ), $data['thumb'], $data['file'] );
|
215 |
+
$filethumb = array(
|
216 |
+
'name' => $data['thumb'],
|
217 |
+
'type' => $type,
|
218 |
+
'tmp_name' => $thumbpath,
|
219 |
+
'size' => filesize($thumbpath),
|
220 |
+
);
|
221 |
+
|
222 |
+
$this->s3->putObjectStream($this->options['bucket'], $prefix.$filethumb['name'], $filethumb);
|
223 |
+
} elseif (count($data['sizes'])) foreach ($data['sizes'] as $altName => $altSize) {
|
224 |
+
$altPath = str_replace( basename( $data['file'] ), $altSize['file'], $data['file'] );
|
225 |
+
$altMeta = array(
|
226 |
+
'name' => $altSize['file'],
|
227 |
+
'type' => $type,
|
228 |
+
'tmp_name' => $altPath,
|
229 |
+
'size' => filesize($altPath),
|
230 |
+
);
|
231 |
+
$this->s3->putObjectStream($this->options['bucket'], $prefix.$altMeta['name'], $altMeta);
|
232 |
+
|
233 |
+
}
|
234 |
+
|
235 |
+
|
236 |
+
delete_post_meta($postID, 'amazonS3_info');
|
237 |
+
add_post_meta($postID, 'amazonS3_info', array(
|
238 |
+
'bucket' => $this->options['bucket'],
|
239 |
+
'key' => $prefix.$file['name']
|
240 |
+
));
|
241 |
+
} else {
|
242 |
+
|
243 |
+
}
|
244 |
+
}
|
245 |
+
return $data;
|
246 |
+
}
|
247 |
+
function wp_handle_upload($info) {
|
248 |
+
return $info;
|
249 |
+
}
|
250 |
+
|
251 |
+
// figure out the correct path to upload to, for wordpress mu installs
|
252 |
+
function upload_path($path='') {
|
253 |
+
global $current_blog;
|
254 |
+
if (!$current_blog) return $path;
|
255 |
+
if ($current_blog->path == '/' && ($current_blog->blog_id != 1)) {
|
256 |
+
$dir = substr($current_blog->domain, 0, strpos($current_blog->domain, '.'));
|
257 |
+
} else {
|
258 |
+
// prepend a directory onto the path for vhosted blogs
|
259 |
+
if (constant("VHOST") != 'yes') {
|
260 |
+
$dir = '';
|
261 |
+
} else {
|
262 |
+
$dir = $current_blog->path;
|
263 |
+
}
|
264 |
+
}
|
265 |
+
//echo trim($path.'/'.$dir, '/');
|
266 |
+
if ($path == '') {
|
267 |
+
$path = $current_blog->path;
|
268 |
+
}
|
269 |
+
return trim($path.'/'.$dir, '/');
|
270 |
+
}
|
271 |
+
function media_buttons($context) {
|
272 |
+
global $post_ID, $temp_ID;
|
273 |
+
$pluginRootURL = plugins_url( '', __FILE__ );
|
274 |
+
$image_btn = $pluginRootURL.'/database.png';
|
275 |
+
$image_title = 'Amazon S3';
|
276 |
+
|
277 |
+
$uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
|
278 |
+
|
279 |
+
$media_upload_iframe_src = "media-upload.php?post_id=$uploading_iframe_ID";
|
280 |
+
$out = ' <a href="'.$media_upload_iframe_src.'&tab=tantan-wordpress-s3&TB_iframe=true&height=500&width=640" class="thickbox" title="'.$image_title.'"><img src="'.$image_btn.'" alt="'.$image_title.'" /></a>';
|
281 |
+
return $context.$out;
|
282 |
+
}
|
283 |
+
function media_upload_tabs( $tabs ) {
|
284 |
+
$tabs['tantan-wordpress-s3'] = 'Amazon S3';
|
285 |
+
return $tabs;
|
286 |
+
}
|
287 |
+
function media_upload_content() {
|
288 |
+
$this->upload_files_tantan_amazons3(); // process any uploaded files or new folders
|
289 |
+
|
290 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
291 |
+
//if (!is_object($this->s3)) {
|
292 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
293 |
+
$this->s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
294 |
+
$this->s3->setOptions($this->options);
|
295 |
+
//}
|
296 |
+
|
297 |
+
add_action('admin_print_scripts', array(&$this, 'upload_tabs_scripts'));
|
298 |
+
wp_iframe(array(&$this, 'tab'));
|
299 |
+
}
|
300 |
+
/*
|
301 |
+
Display tabs
|
302 |
+
*/
|
303 |
+
function addPhotosTab() {
|
304 |
+
add_filter('wp_upload_tabs', array(&$this, 'wp_upload_tabs'));
|
305 |
+
add_action('upload_files_tantan_amazons3', array(&$this, 'upload_files_tantan_amazons3'));
|
306 |
+
add_action('upload_files_upload', array(&$this, 'upload_files_upload'));
|
307 |
+
add_action('admin_print_scripts', array(&$this, 'upload_tabs_scripts'));
|
308 |
+
}
|
309 |
+
function wp_upload_tabs ($array) {
|
310 |
+
/*
|
311 |
+
0 => tab display name,
|
312 |
+
1 => required cap,
|
313 |
+
2 => function that produces tab content,
|
314 |
+
3 => total number objects OR array(total, objects per page),
|
315 |
+
4 => add_query_args
|
316 |
+
*/
|
317 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
318 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
319 |
+
$this->s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
320 |
+
|
321 |
+
|
322 |
+
if ($this->options['key'] && $this->options['secret'] && $this->options['bucket']) {
|
323 |
+
$paged = array();
|
324 |
+
$args = array('prefix' => ''); // this doesn't do anything in WP 2.1.2
|
325 |
+
$tab = array(
|
326 |
+
'tantan_amazons3' => array('Amazon S3', 'upload_files', array(&$this, 'tab'), $paged, $args),
|
327 |
+
//'tantan_amazons3_upload' => array('Upload S3', 'upload_files', array(&$this, 'upload'), $paged, $args),
|
328 |
+
);
|
329 |
+
|
330 |
+
return array_merge($array, $tab);
|
331 |
+
} else {
|
332 |
+
return $array;
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
function get_access_domain() {
|
337 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
338 |
+
|
339 |
+
if ( isset($this->options['cloudfront']) && $this->options['cloudfront'] ) {
|
340 |
+
return $this->options['cloudfront'];
|
341 |
+
}
|
342 |
+
elseif ( isset($this->options['virtual-host']) && $this->options['virtual-host'] ) {
|
343 |
+
return $this->options['bucket'];
|
344 |
+
}
|
345 |
+
else {
|
346 |
+
return $this->options['bucket'].'.s3.amazonaws.com';
|
347 |
+
}
|
348 |
+
}
|
349 |
+
|
350 |
+
function upload_tabs_scripts() {
|
351 |
+
//wp_enqueue_script('prototype');
|
352 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
353 |
+
|
354 |
+
$accessDomain = $this->get_access_domain();
|
355 |
+
|
356 |
+
include(dirname(__FILE__).'/admin-tab-head.html');
|
357 |
+
}
|
358 |
+
function upload_files_upload() {
|
359 |
+
// javascript here to inject javascript and allow the upload from to post to amazon s3 instead
|
360 |
+
}
|
361 |
+
function upload_files_tantan_amazons3() {
|
362 |
+
global $current_blog;
|
363 |
+
$restrictPrefix = ''; // restrict to a selected prefix in current bucket
|
364 |
+
if ($current_blog) { // if wordpress mu
|
365 |
+
$restrictPrefix = ltrim($this->upload_path().'/files/', '/');
|
366 |
+
}
|
367 |
+
|
368 |
+
if (is_array($_FILES['newfile'])) {
|
369 |
+
$file = $_FILES['newfile'];
|
370 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
371 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
372 |
+
$this->s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
373 |
+
$this->s3->setOptions($this->options);
|
374 |
+
$this->s3->putObjectStream($this->options['bucket'], $restrictPrefix.$_GET['prefix'].$file['name'], $file);
|
375 |
+
}
|
376 |
+
if ($_POST['newfolder']) {
|
377 |
+
if (!$this->options) $this->options = get_option('tantan_wordpress_s3');
|
378 |
+
require_once(dirname(__FILE__).'/lib.s3.php');
|
379 |
+
$this->s3 = new TanTanS3($this->options['key'], $this->options['secret']);
|
380 |
+
|
381 |
+
$this->s3->putPrefix($this->options['bucket'], $restrictPrefix.$_POST['prefix'].$_POST['newfolder']);
|
382 |
+
}
|
383 |
+
}
|
384 |
+
function tab() {
|
385 |
+
global $current_blog;
|
386 |
+
$restrictPrefix = ''; // restrict to a selected prefix in current bucket
|
387 |
+
if ($current_blog) { // if wordpress mu
|
388 |
+
$restrictPrefix = ltrim($this->upload_path().'/files/', '/');
|
389 |
+
}
|
390 |
+
|
391 |
+
$offsetpage = (int) $_GET['paged'];
|
392 |
+
if (!$offsetpage) $offsetpage = 1;
|
393 |
+
|
394 |
+
if (!$this->options['key'] || !$this->options['secret']) {
|
395 |
+
return;
|
396 |
+
}
|
397 |
+
$bucket = $this->options['bucket'];
|
398 |
+
$accessDomain = $this->get_access_domain();
|
399 |
+
|
400 |
+
$prefix = $_GET['prefix'] ? $_GET['prefix'] : '';
|
401 |
+
list($prefixes, $keys, $meta, $privateKeys) = $this->getKeys($restrictPrefix.$prefix);
|
402 |
+
if ($restrictPrefix) {
|
403 |
+
foreach ($prefixes as $k=>$v) {
|
404 |
+
$prefixes[$k] = str_replace($restrictPrefix, '', $v);
|
405 |
+
}
|
406 |
+
}
|
407 |
+
include(dirname(__FILE__).'/admin-tab.html');
|
408 |
+
}
|
409 |
+
|
410 |
+
function getErrorMessage($parsed_xml, $responseCode){
|
411 |
+
$message = 'Error '.$responseCode.': ' . $parsed_xml->Message;
|
412 |
+
if(isset($parsed_xml->StringToSignBytes)) $message .= "<br>Hex-endcoded string to sign: " . $parsed_xml->StringToSignBytes;
|
413 |
+
return $message;
|
414 |
+
}
|
415 |
+
|
416 |
+
// turns array('a', 'b', 'c') into $array['a']['b']['c']
|
417 |
+
function mapKey($keys, $path) {
|
418 |
+
$k =& $keys;
|
419 |
+
$size = count($path) - 1;
|
420 |
+
$workingPath = '/';
|
421 |
+
foreach ($path as $i => $p) {
|
422 |
+
if ($i === $size) {
|
423 |
+
$k['_size'] = isset($k['_size']) ? $k['_size'] + 1 : 1;
|
424 |
+
$k['_path'] = $workingPath;
|
425 |
+
$k['_objects'][$k['_size']] = $p;
|
426 |
+
} else {
|
427 |
+
$k =& $k[$p]; // traverse the tree
|
428 |
+
$workingPath .= $p . '/';
|
429 |
+
}
|
430 |
+
}
|
431 |
+
return $keys;
|
432 |
+
}
|
433 |
+
|
434 |
+
// should probably figgure out a way to cache these results to make things more speedy
|
435 |
+
function getKeys($prefix) {
|
436 |
+
$ret = $this->s3->listKeys($this->options['bucket'], false, urlencode($prefix), '/');//, false, 's3/', '/');
|
437 |
+
|
438 |
+
if ($this->s3->responseCode >= 400) {
|
439 |
+
return array();
|
440 |
+
}
|
441 |
+
$keys = array();
|
442 |
+
$privateKeys = array();
|
443 |
+
$prefixes = array();
|
444 |
+
$meta = array();
|
445 |
+
if ($this->s3->parsed_xml->CommonPrefixes) foreach ($this->s3->parsed_xml->CommonPrefixes as $content) {
|
446 |
+
$prefixes[] = (string) $content->Prefix;
|
447 |
+
}
|
448 |
+
|
449 |
+
if ($this->s3->parsed_xml->Contents) foreach ($this->s3->parsed_xml->Contents as $content) {
|
450 |
+
$key = (string) $content->Key;
|
451 |
+
if ($this->isPublic($key)) $keys[] = $key;
|
452 |
+
else {
|
453 |
+
if (!($p1 = ereg('^\.', $key)) &&
|
454 |
+
!($p2 = ereg('_\$folder\$$', $key)) &&
|
455 |
+
!($p3 = ereg('placeholder.ns3', $key))) {
|
456 |
+
$privateKeys[] = $key;
|
457 |
+
} elseif ($p2) {
|
458 |
+
$prefix = ereg_replace('(_\$folder\$$)', '/', $key);
|
459 |
+
if (!in_array($prefix, $prefixes)) $prefixes[] = $prefix;
|
460 |
+
} else {
|
461 |
+
|
462 |
+
}
|
463 |
+
}
|
464 |
+
}
|
465 |
+
if ($this->options['permissions'] == 'public') {
|
466 |
+
foreach ($privateKeys as $key) {
|
467 |
+
$this->s3->setObjectACL($this->options['bucket'], $key, 'public-read');
|
468 |
+
$keys[] = $key;
|
469 |
+
}
|
470 |
+
}
|
471 |
+
|
472 |
+
foreach ($keys as $i => $key) {
|
473 |
+
$meta[$i] = $this->s3->getMetadata($this->options['bucket'], $key);
|
474 |
+
}
|
475 |
+
natcasesort($keys);
|
476 |
+
natcasesort($prefixes);
|
477 |
+
|
478 |
+
return array($prefixes, $keys, $meta, $privateKeys);
|
479 |
+
}
|
480 |
+
|
481 |
+
function isPublic($key) {
|
482 |
+
$everyone = 'http://acs.amazonaws.com/groups/global/AllUsers';
|
483 |
+
$this->s3->getObjectACL($this->options['bucket'], $key);
|
484 |
+
$acl = (array) $this->s3->parsed_xml->AccessControlList;
|
485 |
+
if (is_array($acl['Grant'])) foreach ($acl['Grant'] as $grant) {
|
486 |
+
$grant = (array) $grant;
|
487 |
+
if ($grant['Grantee'] && (ereg('AllUsers', (string) $grant['Grantee']->URI))) {
|
488 |
+
$perm = (string) $grant['Permission'];
|
489 |
+
if ($perm == 'READ' || $perm == 'FULL_CONTROL') return true;
|
490 |
+
}
|
491 |
+
}
|
492 |
+
|
493 |
+
|
494 |
+
}
|
495 |
+
}
|
496 |
+
?>
|
wordpress-s3/config-sample.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// rename this file to "config.php" to use the settings below, instead of settings saved in the database through the dashboard admin
|
3 |
+
// this can be used to automatically configure the plugin in a WordPress MU environment, or if you have automated scripts to deploy WordPress installs
|
4 |
+
$TanTanWordPressS3Config = array(
|
5 |
+
'key' => '', // AWS Access Key ID
|
6 |
+
'secret' => '', // AWS Secret Key
|
7 |
+
'bucket' => '', // S3 Bucket
|
8 |
+
'virtual-host' => false, // Bucket is configured for virtual hosting
|
9 |
+
'wp-uploads' => true, // mirror all WordPress uploads into Amazon S3 bucket
|
10 |
+
'permissions' => '', // set to "public" to have the plugin force all files in the specified bucket to "public" (sometimes third party upload utilities don't do this)
|
11 |
+
'hideAmazonS3UploadTab' => false, // hide the Amazon S3 tab in the WordPress upload widget
|
12 |
+
'expires' => 315360000, // set http expires header 10 years into the future
|
13 |
+
'cloudfront' => '', //this can be your cloudfront DNS name (*.cloudfront.net) or a CNAME alias
|
14 |
+
);
|
15 |
+
?>
|
wordpress-s3/database.png
ADDED
Binary file
|
wordpress-s3/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php /* empty */ ?>
|
wordpress-s3/lib.s3.php
ADDED
@@ -0,0 +1,397 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Calculates RFC 2104 compliant HMACs.
|
4 |
+
Based on code from http://pear.php.net/package/Crypt_HMAC
|
5 |
+
*/
|
6 |
+
class TanTanCrypt_HMAC {
|
7 |
+
var $_func;var $_ipad;var $_opad;var $_pack;
|
8 |
+
function TanTanCrypt_HMAC($key, $func = 'md5'){$this->setFunction($func);$this->setKey($key);}
|
9 |
+
function setFunction($func){if (!$this->_pack = $this->_getPackFormat($func)) { die('Unsupported hash function'); }$this->_func = $func;}
|
10 |
+
function setKey($key){$func = $this->_func;if (strlen($key) > 64) {$key = pack($this->_pack, $func($key));}if (strlen($key) < 64) {$key = str_pad($key, 64, chr(0));}$this->_ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));$this->_opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));}
|
11 |
+
function _getPackFormat($func){$packs = array('md5' => 'H32', 'sha1' => 'H40');return isset($packs[$func]) ? $packs[$func] : false;}
|
12 |
+
function hash($data){$func = $this->_func;return $func($this->_opad . pack($this->_pack, $func($this->_ipad . $data)));}
|
13 |
+
}
|
14 |
+
/*
|
15 |
+
class Stream{
|
16 |
+
var $data;
|
17 |
+
function stream_function($handle, $fd, $length){return fread($this->data, $length);}
|
18 |
+
}
|
19 |
+
*/
|
20 |
+
if (!class_exists('TanTanHTTPRequestCurl')) require_once (dirname(__FILE__).'/../lib/curl.php');
|
21 |
+
|
22 |
+
/*
|
23 |
+
based on code provided by Amazon
|
24 |
+
*/
|
25 |
+
// This software code is made available "AS IS" without warranties of any
|
26 |
+
// kind. You may copy, display, modify and redistribute the software
|
27 |
+
// code either by itself or as incorporated into your code; provided that
|
28 |
+
// you do not remove any proprietary notices. Your use of this software
|
29 |
+
// code is at your own risk and you waive any claim against Amazon
|
30 |
+
// Digital Services, Inc. or its affiliates with respect to your use of
|
31 |
+
// this software code. (c) 2006 Amazon Digital Services, Inc. or its
|
32 |
+
// affiliates.
|
33 |
+
|
34 |
+
class TanTanS3 {
|
35 |
+
|
36 |
+
var $serviceUrl;
|
37 |
+
var $accessKeyId;
|
38 |
+
var $secretKey;
|
39 |
+
var $responseString;
|
40 |
+
var $responseCode;
|
41 |
+
var $parsed_xml;
|
42 |
+
var $req;
|
43 |
+
var $fp;
|
44 |
+
var $options;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Constructor
|
48 |
+
*
|
49 |
+
* Takes ($accessKeyId, $secretKey, $serviceUrl)
|
50 |
+
*
|
51 |
+
* - [str] $accessKeyId: Your AWS Access Key Id
|
52 |
+
* - [str] $secretKey: Your AWS Secret Access Key
|
53 |
+
* - [str] $serviceUrl: OPTIONAL: defaults: http://s3.amazonaws.com/
|
54 |
+
*
|
55 |
+
*/
|
56 |
+
function TanTanS3($accessKeyId, $secretKey, $serviceUrl="http://s3.amazonaws.com/") {
|
57 |
+
global $wpdb;
|
58 |
+
$this->serviceUrl=$serviceUrl;
|
59 |
+
$this->accessKeyId=$accessKeyId;
|
60 |
+
$this->secretKey=$secretKey;
|
61 |
+
$this->req =& new TanTanHTTPRequestCurl($this->serviceUrl);
|
62 |
+
$this->options = array();
|
63 |
+
$this->options['cache_table'] = $wpdb->prefix . 'tantan_wordpress_s3_cache';
|
64 |
+
//$this->req = new HTTP_Request($this->serviceUrl);
|
65 |
+
}
|
66 |
+
|
67 |
+
function setOptions($options) {
|
68 |
+
if (is_array($options)) {
|
69 |
+
$this->options = array_merge($this->options, $options);
|
70 |
+
}
|
71 |
+
}
|
72 |
+
/**
|
73 |
+
* listBuckets -- Lists all buckets.
|
74 |
+
*/
|
75 |
+
function listBuckets() {
|
76 |
+
$ret = $this->send('', '');
|
77 |
+
if($ret == 200){
|
78 |
+
$return = array();
|
79 |
+
if(count($this->parsed_xml->Buckets->Bucket) > 0){
|
80 |
+
foreach ($this->parsed_xml->Buckets->Bucket as $bucket) {
|
81 |
+
$return[] = (string) $bucket->Name;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
return $return;
|
85 |
+
|
86 |
+
}
|
87 |
+
else{
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
/**
|
92 |
+
* listKeys -- Lists keys in a bucket.
|
93 |
+
*
|
94 |
+
* Takes ($bucket [,$marker][,$prefix][,$delimiter][,$maxKeys]) -- $marker, $prefix, $delimeter, $maxKeys are independently optional
|
95 |
+
*
|
96 |
+
* - [str] $bucket: the bucket whose keys are to be listed
|
97 |
+
* - [str] $marker: keys returned will occur lexicographically after $marker (OPTIONAL: defaults to false)
|
98 |
+
* - [str] $prefix: keys returned will start with $prefix (OPTIONAL: defaults to false)
|
99 |
+
* - [str] $delimiter: keys returned will be of the form "$prefix[some string]$delimeter" (OPTIONAL: defaults to false)
|
100 |
+
* - [str] $maxKeys: number of keys to be returned (OPTIONAL: defaults to 1000 - maximum allowed by service)
|
101 |
+
*/
|
102 |
+
function listKeys($bucket, $marker=FALSE, $prefix=FALSE, $delimiter=FALSE, $maxKeys='1000') {
|
103 |
+
$ret = $this->send($bucket, '/', "max-keys={$maxKeys}&marker={$marker}&prefix={$prefix}&delimiter={$delimiter}");
|
104 |
+
if($ret == 200){
|
105 |
+
return true;
|
106 |
+
} else {
|
107 |
+
return false;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
function createBucket($bucket, $acl = 'private') {
|
111 |
+
$httpDate = gmdate("D, d M Y G:i:s T");
|
112 |
+
$stringToSign = "PUT\n\n\n$httpDate\nx-amz-acl:$acl\n/$bucket";
|
113 |
+
$signature = $this->constructSig($stringToSign);
|
114 |
+
//$req =& new HTTP_Request($this->serviceUrl . $bucket);
|
115 |
+
$this->req->setURL($this->serviceUrl . $bucket);
|
116 |
+
$this->req->setMethod("PUT");
|
117 |
+
$this->req->addHeader("Date", $httpDate);
|
118 |
+
$this->req->addHeader("Authorization", "AWS " . $this->accessKeyId . ":" . $signature);
|
119 |
+
$this->req->addHeader("x-amz-acl", $acl);
|
120 |
+
$this->req->sendRequest();
|
121 |
+
$this->responseCode=$this->req->getResponseCode();
|
122 |
+
$this->responseString = $this->req->getResponseBody();
|
123 |
+
$this->parsed_xml = simplexml_load_string($this->responseString);
|
124 |
+
if ($this->responseCode == 200) {
|
125 |
+
return true;
|
126 |
+
} else {
|
127 |
+
return false;
|
128 |
+
}
|
129 |
+
}
|
130 |
+
/**
|
131 |
+
* getBucketACL -- Gets bucket access control policy.
|
132 |
+
*
|
133 |
+
* Takes ($bucket)
|
134 |
+
*
|
135 |
+
* - [str] $bucket: the bucket whose acl you want
|
136 |
+
*/
|
137 |
+
function getBucketACL($bucket){
|
138 |
+
$ret = $this->send($bucket, '/?acl');
|
139 |
+
if ($ret == 200) {
|
140 |
+
return true;
|
141 |
+
} else {
|
142 |
+
return false;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* getObjectACL -- gets an objects access control policy.
|
148 |
+
*
|
149 |
+
* Takes ($bucket, $key)
|
150 |
+
*
|
151 |
+
* - [str] $bucket
|
152 |
+
* - [str] $key
|
153 |
+
*/
|
154 |
+
function getObjectACL($bucket, $key){
|
155 |
+
$ret = $this->send($bucket, "/".urlencode($key).'?acl');
|
156 |
+
if ($ret == 200) {
|
157 |
+
return true;
|
158 |
+
} else {
|
159 |
+
return false;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
/**
|
163 |
+
* setObjectACL -- sets objects access control policy to one of Amazon S3 canned policies.
|
164 |
+
*
|
165 |
+
* Takes ($bucket, $key, $acl)
|
166 |
+
*
|
167 |
+
* - [str] $bucket
|
168 |
+
* - [str] $key
|
169 |
+
* - [str] $acl -- One of canned access control policies.
|
170 |
+
*/
|
171 |
+
function setObjectACL($bucket, $key, $acl){
|
172 |
+
$serviceUrl = 'http://'.$bucket.'.s3.amazonaws.com/';
|
173 |
+
|
174 |
+
$httpDate = gmdate("D, d M Y G:i:s T");
|
175 |
+
$resource = urlencode($key);
|
176 |
+
$stringToSign = "PUT\n\n\n$httpDate\nx-amz-acl:$acl\n/$bucket/$resource?acl";
|
177 |
+
$signature = $this->constructSig($stringToSign);
|
178 |
+
//$req =& new HTTP_Request($this->serviceUrl.$resource.'?acl');
|
179 |
+
$this->req->setURL($serviceUrl.$resource.'?acl');
|
180 |
+
$this->req->setMethod("PUT");
|
181 |
+
$this->req->addHeader("Date", $httpDate);
|
182 |
+
$this->req->addHeader("Authorization", "AWS " . $this->accessKeyId . ":" . $signature);
|
183 |
+
$this->req->addHeader("x-amz-acl", $acl);
|
184 |
+
$this->req->sendRequest();
|
185 |
+
if ($this->req->getResponseCode() == 200) {
|
186 |
+
return true;
|
187 |
+
} else {
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* getMetadata -- Gets the metadata associated with an object.
|
194 |
+
*
|
195 |
+
* Takes ($bucket, $key)
|
196 |
+
*
|
197 |
+
* - [str] $bucket
|
198 |
+
* - [str] $key
|
199 |
+
*/
|
200 |
+
function getMetadata($bucket, $key){
|
201 |
+
if ($data = $this->getCache($bucket."/".$key)) {
|
202 |
+
return $data;
|
203 |
+
}
|
204 |
+
$ret = $this->send($bucket, "/".urlencode($key), '', 'HEAD');
|
205 |
+
if ($ret == 200) {
|
206 |
+
$data = $this->req->getResponseHeader();
|
207 |
+
foreach ($data as $k => $d) $data[strtolower($k)] = trim($d);
|
208 |
+
$this->setCache($bucket."/".$key, $data);
|
209 |
+
return $data;
|
210 |
+
} else {
|
211 |
+
return array();
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
|
216 |
+
/**
|
217 |
+
* putObjectStream -- Streams data to a bucket.
|
218 |
+
*
|
219 |
+
* Takes ($bucket, $key, $streamFunction, $contentType, $contentLength [,$acl, $metadataArray, $md5])
|
220 |
+
* http://www.missiondata.com/blog/linux/49/s3-streaming-with-php/
|
221 |
+
*
|
222 |
+
* - [str] $bucket: the bucket into which file will be written
|
223 |
+
* - [str] $key: key of written file
|
224 |
+
* - [str] $fileName: path to file
|
225 |
+
* - [str] $contentType: file content type
|
226 |
+
* - [str] $contentLength: file content length
|
227 |
+
* - [str] $acl: access control policy of file (OPTIONAL: defaults to 'private')
|
228 |
+
* - [str] $metadataArray: associative array containing user-defined metadata (name=>value) (OPTIONAL)
|
229 |
+
* - [bool] $md5: the MD5 hash of the object (OPTIONAL)
|
230 |
+
*/
|
231 |
+
function putObjectStream($bucket, $key, $fileInfo, $acl='public-read', $metadataArray=array(), $md5=false){
|
232 |
+
$serviceUrl = 'http://'.$bucket.'.s3.amazonaws.com/';
|
233 |
+
|
234 |
+
sort($metadataArray);
|
235 |
+
$fileName = $fileInfo['tmp_name'];
|
236 |
+
$contentLength = $fileInfo['size'];
|
237 |
+
$contentType = $fileInfo['type'];
|
238 |
+
if (!file_exists($fileName)) {
|
239 |
+
return false;
|
240 |
+
}
|
241 |
+
$this->fp = fopen($fileName, 'r');
|
242 |
+
$resource = urlencode($key);
|
243 |
+
$httpDate = gmdate("D, d M Y G:i:s T");
|
244 |
+
|
245 |
+
$curl_inst = curl_init();
|
246 |
+
|
247 |
+
curl_setopt ($curl_inst, CURLOPT_CONNECTTIMEOUT, 30);
|
248 |
+
curl_setopt ($curl_inst, CURLOPT_LOW_SPEED_LIMIT, 1);
|
249 |
+
curl_setopt ($curl_inst, CURLOPT_LOW_SPEED_TIME, 180);
|
250 |
+
curl_setopt ($curl_inst, CURLOPT_NOSIGNAL, 1);
|
251 |
+
curl_setopt ($curl_inst, CURLOPT_READFUNCTION, array(&$this, 'stream_function'));
|
252 |
+
curl_setopt ($curl_inst, CURLOPT_URL, $serviceUrl . $resource);
|
253 |
+
curl_setopt ($curl_inst, CURLOPT_UPLOAD, true);
|
254 |
+
curl_setopt ($curl_inst, CURLINFO_CONTENT_LENGTH_UPLOAD, $contentLength);
|
255 |
+
|
256 |
+
$header[] = "Date: $httpDate";
|
257 |
+
$header[] = "Content-Type: $contentType";
|
258 |
+
$header[] = "Content-Length: $contentLength";
|
259 |
+
$header[] = "Expect: ";
|
260 |
+
if (is_numeric($this->options['expires'])) {
|
261 |
+
$header[] = "Expires: ".date('D, d M Y H:i:s O', time()+$this->options['expires']);
|
262 |
+
}
|
263 |
+
$header[] = "Transfer-Encoding: ";
|
264 |
+
$header[] = "x-amz-acl: $acl";
|
265 |
+
|
266 |
+
$MD5 = "";
|
267 |
+
if($md5){
|
268 |
+
$MD5 = $this->hex2b64(md5_file($filePath));
|
269 |
+
$header[] = "Content-MD5: $MD5";
|
270 |
+
}
|
271 |
+
|
272 |
+
$stringToSign="PUT\n$MD5\n$contentType\n$httpDate\nx-amz-acl:$acl\n";
|
273 |
+
foreach($metadataArray as $current){
|
274 |
+
if($current!=""){
|
275 |
+
$stringToSign.="x-amz-meta-$currentn";
|
276 |
+
$header = substr($current,0,strpos($current,':'));
|
277 |
+
$meta = substr($current,strpos($current,':')+1,strlen($current));
|
278 |
+
$header[] = "x-amz-meta-$header: $meta";
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
$stringToSign.="/$bucket/$resource";
|
283 |
+
|
284 |
+
$signature = $this->constructSig($stringToSign);
|
285 |
+
|
286 |
+
$header[] = "Authorization: AWS $this->accessKeyId:$signature";
|
287 |
+
|
288 |
+
curl_setopt($curl_inst, CURLOPT_HTTPHEADER, $header);
|
289 |
+
curl_setopt($curl_inst, CURLOPT_RETURNTRANSFER, 1);
|
290 |
+
|
291 |
+
$result = curl_exec ($curl_inst);
|
292 |
+
|
293 |
+
$this->responseString = $result;
|
294 |
+
$this->responseCode = curl_getinfo($curl_inst, CURLINFO_HTTP_CODE);
|
295 |
+
|
296 |
+
fclose($this->fp);
|
297 |
+
curl_close($curl_inst);
|
298 |
+
return true;
|
299 |
+
}
|
300 |
+
function stream_function($handle, $fd, $length){return fread($this->fp, $length);}
|
301 |
+
|
302 |
+
function putPrefix($bucket, $prefix){
|
303 |
+
$ret = $this->send($bucket, "/".urlencode($prefix.'_$folder$'), '', 'PUT', array('Content-Type' => '', 'Content-Length' => 0));
|
304 |
+
if ($ret == 200) {
|
305 |
+
return true;
|
306 |
+
} else {
|
307 |
+
return false;
|
308 |
+
}
|
309 |
+
}
|
310 |
+
|
311 |
+
function deleteObject($bucket, $key) {
|
312 |
+
$ret = $this->send($bucket, "/".urlencode($key), '', 'DELETE');
|
313 |
+
if ($ret == 204) {
|
314 |
+
return true;
|
315 |
+
} else {
|
316 |
+
return false;
|
317 |
+
}
|
318 |
+
}
|
319 |
+
|
320 |
+
function send($bucket, $resource, $args='', $method='GET', $headers=false) {
|
321 |
+
if ($bucket != '') {
|
322 |
+
$serviceUrl = 'http://'.$bucket.'.s3.amazonaws.com';
|
323 |
+
} else {
|
324 |
+
$serviceUrl = 'http://s3.amazonaws.com/';
|
325 |
+
}
|
326 |
+
|
327 |
+
$method=strtoupper($method);
|
328 |
+
$httpDate = gmdate("D, d M Y G:i:s T");
|
329 |
+
$signature = $this->constructSig("$method\n\n\n$httpDate\n/".($bucket ? ($bucket.$resource) : $resource));
|
330 |
+
|
331 |
+
$this->req->setURL($serviceUrl.$resource.($args ? '?'.$args : ''));
|
332 |
+
$this->req->setMethod($method);
|
333 |
+
$this->req->addHeader("Date", $httpDate);
|
334 |
+
$this->req->addHeader("Authorization", "AWS " . $this->accessKeyId . ":" . $signature);
|
335 |
+
if (is_array($headers)) foreach ($headers as $key => $header) $this->req->addHeader($key, $header);
|
336 |
+
$this->req->sendRequest();
|
337 |
+
if ($method=='GET') {
|
338 |
+
$this->parsed_xml = simplexml_load_string($this->req->getResponseBody());
|
339 |
+
}
|
340 |
+
|
341 |
+
return $this->req->getResponseCode();
|
342 |
+
}
|
343 |
+
function hex2b64($str) {
|
344 |
+
$raw = '';
|
345 |
+
for ($i=0; $i < strlen($str); $i+=2) {
|
346 |
+
$raw .= chr(hexdec(substr($str, $i, 2)));
|
347 |
+
}
|
348 |
+
return base64_encode($raw);
|
349 |
+
}
|
350 |
+
|
351 |
+
function constructSig($str) {
|
352 |
+
$hasher =& new TanTanCrypt_HMAC($this->secretKey, "sha1");
|
353 |
+
$signature = $this->hex2b64($hasher->hash($str));
|
354 |
+
return($signature);
|
355 |
+
}
|
356 |
+
|
357 |
+
function initCacheTables() {
|
358 |
+
global $wpdb;
|
359 |
+
if (!is_object($wpdb)) return;
|
360 |
+
|
361 |
+
$wpdb->query("CREATE TABLE IF NOT EXISTS `".$this->options['cache_table']."` (
|
362 |
+
`request` VARCHAR( 255 ) NOT NULL ,
|
363 |
+
`response` TEXT NOT NULL ,
|
364 |
+
`timestamp` DATETIME NOT NULL ,
|
365 |
+
PRIMARY KEY ( `request` )
|
366 |
+
)");
|
367 |
+
}
|
368 |
+
function setCache($key, $data) {
|
369 |
+
global $wpdb;
|
370 |
+
if (!is_object($wpdb)) return false;
|
371 |
+
$key = addslashes(trim($key));
|
372 |
+
if ($wpdb->query("DELETE FROM ".$this->options['cache_table']." WHERE request = '".$key."'") !== false) {
|
373 |
+
$sql = "INSERT INTO ".$this->options['cache_table']." (request, response, timestamp) VALUES ('".$key."', '" . addslashes(serialize($data)) . "', '" . strftime("%Y-%m-%d %H:%M:%S") . "')";
|
374 |
+
$wpdb->query($sql);
|
375 |
+
} else { // tables might not be setup, so just try to do that
|
376 |
+
$this->initCacheTables();
|
377 |
+
}
|
378 |
+
return $data;
|
379 |
+
}
|
380 |
+
function getCache($key) {
|
381 |
+
global $wpdb;
|
382 |
+
if (!is_object($wpdb)) return false;
|
383 |
+
$key = trim($key);
|
384 |
+
$result = @$wpdb->get_var("SELECT response FROM ".$this->options['cache_table']." WHERE request = '" . $key . "' LIMIT 1");
|
385 |
+
|
386 |
+
if (!empty($result)) {
|
387 |
+
return unserialize($result);
|
388 |
+
}
|
389 |
+
return false;
|
390 |
+
}
|
391 |
+
function clearCache() {
|
392 |
+
global $wpdb;
|
393 |
+
if (!is_object($wpdb)) return false;
|
394 |
+
$result = @$wpdb->query("DELETE FROM ".$this->options['cache_table'].";");
|
395 |
+
}
|
396 |
+
}
|
397 |
+
?>
|
wordpress-s3/styles/add.png
ADDED
Binary file
|
wordpress-s3/styles/arrow_left.png
ADDED
Binary file
|
wordpress-s3/styles/arrow_refresh.png
ADDED
Binary file
|
wordpress-s3/styles/arrow_right.png
ADDED
Binary file
|
wordpress-s3/styles/cancel.png
ADDED
Binary file
|
wordpress-s3/styles/compress.png
ADDED
Binary file
|
wordpress-s3/styles/film.png
ADDED
Binary file
|
wordpress-s3/styles/folder.gif
ADDED
Binary file
|
wordpress-s3/styles/folder_add.png
ADDED
Binary file
|
wordpress-s3/styles/page.png
ADDED
Binary file
|
wordpress-s3/styles/page_code.png
ADDED
Binary file
|
wordpress-s3/styles/page_excel.png
ADDED
Binary file
|
wordpress-s3/styles/page_white.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_acrobat.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_excel.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_php.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_powerpoint.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_text.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_word.png
ADDED
Binary file
|
wordpress-s3/styles/page_white_zip.png
ADDED
Binary file
|
wordpress-s3/styles/page_word.png
ADDED
Binary file
|
wordpress-s3/styles/photo.png
ADDED
Binary file
|
wordpress-s3/styles/picture.png
ADDED
Binary file
|
wordpress-s3/styles/sound.png
ADDED
Binary file
|
wordpress-s3/styles/styles.css
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#disable_amazonS3_span {
|
2 |
+
|
3 |
+
}
|
4 |
+
form#upload-file #disable_amazonS3_span input {
|
5 |
+
width:auto !important;
|
6 |
+
}
|
7 |
+
#amazon-s3-wrap {
|
8 |
+
padding:10px;
|
9 |
+
}
|
10 |
+
.infobar {
|
11 |
+
position:relative;
|
12 |
+
padding:0 0 6px 0;
|
13 |
+
margin:0 0 5px 0;
|
14 |
+
font-size:0.9em;
|
15 |
+
border-bottom:1px solid #ddd;
|
16 |
+
}
|
17 |
+
.infobar a {
|
18 |
+
border:0;
|
19 |
+
color:black;
|
20 |
+
text-decoration:none;
|
21 |
+
}
|
22 |
+
.infobar a:hover {
|
23 |
+
text-decoration:underline;
|
24 |
+
}
|
25 |
+
|
26 |
+
.infobar .nav-controls {
|
27 |
+
position:absolute;
|
28 |
+
top:0px;
|
29 |
+
left:0px;
|
30 |
+
}
|
31 |
+
.infobar .nav-controls a {
|
32 |
+
display:block;
|
33 |
+
float:left;
|
34 |
+
margin-right:10px;
|
35 |
+
height:18px;
|
36 |
+
line-height:18px;
|
37 |
+
padding-left:20px;
|
38 |
+
background:url(arrow_left.png) no-repeat left;
|
39 |
+
border:0;
|
40 |
+
color:#888;
|
41 |
+
}
|
42 |
+
.infobar .nav-controls a#btn-upload,
|
43 |
+
.infobar .nav-controls a#btn-folder,
|
44 |
+
.infobar .nav-controls a#btn-forward,
|
45 |
+
.infobar .nav-controls a#btn-refresh {
|
46 |
+
padding-left:0px;
|
47 |
+
padding-right:20px;
|
48 |
+
text-indent:-10000px;
|
49 |
+
background:url(arrow_right.png) no-repeat left;
|
50 |
+
}
|
51 |
+
.infobar .nav-controls a#btn-refresh {
|
52 |
+
background-image:url(arrow_refresh.png);
|
53 |
+
}
|
54 |
+
.infobar .nav-controls a#btn-upload {
|
55 |
+
background-image:url(add.png);
|
56 |
+
}
|
57 |
+
.infobar .nav-controls a#btn-folder {
|
58 |
+
background-image:url(folder_add.png);
|
59 |
+
}
|
60 |
+
.infobar .path {
|
61 |
+
margin-left:195px;
|
62 |
+
line-height:18px;
|
63 |
+
}
|
64 |
+
.infobar .path,
|
65 |
+
.infobar .path a{
|
66 |
+
color:#888;
|
67 |
+
}
|
68 |
+
.infobar .path a.last {
|
69 |
+
font-weight:bold;
|
70 |
+
color:#000;
|
71 |
+
}
|
72 |
+
.infobar .options {
|
73 |
+
position:absolute;
|
74 |
+
top:0px;
|
75 |
+
right:10px;
|
76 |
+
}
|
77 |
+
.infobar #upload-form, .infobar #create-form {
|
78 |
+
display:none;
|
79 |
+
padding:5px;
|
80 |
+
}
|
81 |
+
.folders {
|
82 |
+
position:relative;
|
83 |
+
margin:10px 0 0 0;
|
84 |
+
}
|
85 |
+
.folders form {
|
86 |
+
padding:0;
|
87 |
+
}
|
88 |
+
.folders ul {
|
89 |
+
list-style:none;
|
90 |
+
margin:0;
|
91 |
+
padding:0 0 0 0px;
|
92 |
+
}
|
93 |
+
.folders li {
|
94 |
+
display:block;
|
95 |
+
float:left;
|
96 |
+
width:100px;
|
97 |
+
height:18px;
|
98 |
+
overflow:hidden;
|
99 |
+
margin:0 10px 5px 0;
|
100 |
+
font-size:11px;
|
101 |
+
line-height:16px;
|
102 |
+
}
|
103 |
+
.folders li a {
|
104 |
+
border:0;
|
105 |
+
color:#555;
|
106 |
+
text-decoration:none;
|
107 |
+
background:white url(folder.gif) no-repeat 0px -3px;
|
108 |
+
padding:0 0 0 20px;
|
109 |
+
}
|
110 |
+
.folders li a:hover {
|
111 |
+
text-decoration:underline;
|
112 |
+
}
|
113 |
+
.folders li a.add {
|
114 |
+
background-image:url(folder_add.png);
|
115 |
+
}
|
116 |
+
.folders li#createFolder div.form {
|
117 |
+
display:none;
|
118 |
+
}
|
119 |
+
.folders li#createFolder.create div.form {
|
120 |
+
display:inline;
|
121 |
+
}
|
122 |
+
.folders li#createFolder.create a.add {
|
123 |
+
display:none;
|
124 |
+
}
|
125 |
+
.folders li#createFolder input {
|
126 |
+
font-size:9px;
|
127 |
+
padding:0;
|
128 |
+
}
|
129 |
+
.files {
|
130 |
+
clear:both;
|
131 |
+
}
|
132 |
+
.files ul {
|
133 |
+
list-style:none;
|
134 |
+
margin:0;
|
135 |
+
padding:0;
|
136 |
+
}
|
137 |
+
.files ul li {
|
138 |
+
display:block;
|
139 |
+
float:left;
|
140 |
+
width:175px;
|
141 |
+
height:18px;
|
142 |
+
overflow:hidden;
|
143 |
+
margin:0 10px 5px 0;
|
144 |
+
font-size:11px;
|
145 |
+
line-height:16px;
|
146 |
+
|
147 |
+
padding-left:20px;
|
148 |
+
background:url(page_white.png) no-repeat left;
|
149 |
+
}
|
150 |
+
.files ul li a {
|
151 |
+
border:0;
|
152 |
+
color:#555;
|
153 |
+
text-decoration:none;
|
154 |
+
}
|
155 |
+
.files ul li a:hover {
|
156 |
+
text-decoration:underline;
|
157 |
+
}
|
158 |
+
.files ul li.empty {
|
159 |
+
color:#888;
|
160 |
+
letter-spacing:1px;
|
161 |
+
font-style:italic;
|
162 |
+
background-image:none;
|
163 |
+
padding-left:0;
|
164 |
+
}
|
165 |
+
.files ul li.image { background-image:url(photo.png);}
|
166 |
+
|
167 |
+
.files ul li.text { background-image:url(page_white_text.png);}
|
168 |
+
|
169 |
+
.files ul li.video { background-image:url(film.png);}
|
170 |
+
.files ul li.audio,
|
171 |
+
.files ul li.ogg { background-image:url(sound.png);}
|
172 |
+
|
173 |
+
.files ul li.pdf { background-image:url(page_white_acrobat.png);}
|
174 |
+
.files ul li.msword,
|
175 |
+
.files ul li.doc { background-image:url(page_white_word.png);}
|
176 |
+
.files ul li.ms-excel,
|
177 |
+
.files ul li.xls { background-image:url(page_white_excel.png);}
|
178 |
+
.files ul li.ms-powerpoint,
|
179 |
+
.files ul li.ppt { background-image:url(page_white_powerpoint.png);}
|
180 |
+
|
181 |
+
|
182 |
+
.files ul li.javascript,
|
183 |
+
.files ul li.js,
|
184 |
+
.files ul li.html,
|
185 |
+
.files ul li.php,
|
186 |
+
.files ul li.css { background-image:url(page_code.png);}
|
187 |
+
|
188 |
+
.files ul li.zip { background-image:url(page_white_zip.png);}
|
189 |
+
|