Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 32 additions & 35 deletions readme.txt → README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
=== WP Read-Only ===
# WP S3

* Contributors: alfreddatakillen
* Contributors: parleer, frc, alfreddatakillen
* Tags: wordpress, amazon, s3, readonly
* Requires at least: 3.3
* Tested up to: 3.3.1
* Stable tag: 1.0
* Tested up to: 4.2
* Stable tag: 1.2
* License: GPLv2


This plugin was modified from work frc's modified wpro plugin, which was
forked from alfreddatakillen. I've renamed the plugin to WP S3 because
I have no intention of supporting other distributed file systems, and
because alfreddatakillen has now rewritten his wpro plugin to be much
more generic.


Plugin for running your Wordpress site without Write Access to the
web directory. Amazon S3 is used for uploads/binary storage.
This plugin was made with cluster/load balancing server setups in
mind - where you do not want your WordPress to write anything to
the local web directory.

== Description ==
## Description

This plugin will put your media uploads on Amazon S3. Unlike other
S3 plugins, this plugin does not require your uploads to first be
Expand All @@ -32,20 +40,20 @@ Note: You still need write access to the system /tmp directory for
this plugin to work. It will use the system /tmp directory for
temporary storage during uploads, image editing/scaling, etc.

= Wordpress MU/Multisite =
## Wordpress MU/Multisite

This plugin works out-of-the box with Wordpress Multisite/MU.

You will find the settings for this plugin in the Network Admin, when
in a MU/Multisite environment.

== Installation ==
## Installation

1. Put the plugin in the Wordpress `/wp-content/plugins/` directory.
2. Activate the plugin through the 'Plugins' menu in WordPress.
3. Enter your Amazon S3 settings in `Settings` > `WPRO Settings`.

= Alternative: Configure by constants in wp-config.php =
### Alternative: Configure by constants in wp-config.php

Instead of configuring the plugin in `Settings` > `WPRO Settings`,
you may use constants in your `wp-config.php`. This might be an
Expand Down Expand Up @@ -81,42 +89,42 @@ Those are the AWS endpoints:
* `s3-ap-northeast-1.amazonaws.com` - Asia Pacific (Tokyo) Region
* `s3-sa-east-1.amazonaws.com` - South America (Sao Paulo) Region

== Frequently Asked Questions ==
## Frequently Asked Questions

= Will this plugin work in Wordpress MU/Multisite environments? =
### Will this plugin work in Wordpress MU/Multisite environments?

Yes.

= Where do I report bugs? =
### Where do I report bugs?

Report any issues at the github issue tracker:
https://github.com/alfreddatakillen/wpro/issues
https://github.com/parleer/wp-s3/issues

= Where do I contribute with code, bug fixes, etc.? =
### Where do I contribute with code, bug fixes, etc.?

At github:
https://github.com/alfreddatakillen/wpro

And, plz, use tabs for indenting! :)
https://github.com/parleer/wp-s3

= What should I think of when digging the code? =
### What should I think of when digging the code?

If you define the constant WPRO_DEBUG in your wp-config.php, then
some debug data will be written to /tmp/wpro-debug

= What about the license? =
### What about the license?

Read more about GPLv2 here:
http://www.gnu.org/licenses/gpl-2.0.html

= Do you like beer? =

If we meet some day, and you think this stuff is worth it, you may buy
me a beer in return. (GPLv2 still applies.)
## Changelog

== Changelog ==
### 1.2

= 1.1 =
* Fixed bugs for WordPress MU deployment
* Added support for older WP, I think down to 2.9


### 1.1

* Added support for configuring by constants in `wp-config.php`.
* Plugin now works in open_basedir and safe_mode environments.
Expand All @@ -131,18 +139,7 @@ for contributing with code! Also, thanks to
[mavesell](https://github.com/maveseli "mavesell")
and [nmagee](https://github.com/nmagee "nmagee") for feedback and comments!

= 1.0 =
### 1.0

* The first public release.

== Roadmap ==

Todo list:

* Add support for FTP:ing uploads to somewhere, as an alternative to
Amazon S3.
* For WPMU: Store media in a single bucket, but separate them by site, in
sub-folders.
* Only handle `new` medias when activating this plugin on an existing
site. Today it's an all-or-nothing approach, and you will have to
migrate your media to S3.
92 changes: 79 additions & 13 deletions wpro.php → wp-s3.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php
/**
Plugin Name: WP Read-Only
Plugin URI: http://wordpress.org/extend/plugins/wpro/
Plugin Name: WP S3
Plugin URI: https://github.com/parleer/wp-s3
Description: Plugin for running your Wordpress site without Write Access to the web directory. Amazon S3 is used for uploads/binary storage. This plugin was made with cluster/load balancing server setups in mind - where you do not want your WordPress to write anything to the local web directory.
Version: 1.0
Author: alfreddatakillen
Author URI: http://nurd.nu/
Version: 1.2
Author: parleer
Author URI: https://github.com/parleer
License: GPLv2
*/

Expand All @@ -26,6 +26,21 @@ function sys_get_temp_dir() {
}
}

// WP < 3.5 compatibility
if ( !function_exists('is_main_network')) {
function is_main_network() {
return true;
}
}

// WP < 3.2 compatibility
if ( !function_exists('ms_is_switched')) {
define('USEBLOGSDIR', true);
function ms_is_switched() {
return true;
}
}

// open_basedir / safe_mode disallows CURLOPT_FOLLOWLOCATION
function curl_exec_follow($ch, &$maxredirect = null) {
$mr = $maxredirect === null ? 5 : intval($maxredirect);
Expand Down Expand Up @@ -184,6 +199,10 @@ function upload($file, $fullurl, $mime) {
if (!preg_match('/^\/\/([^\/]+)\/(.*)$/', $fullurl, $regs)) return false;
$url = $regs[2];

if (preg_match('/^' . str_replace('.', '\\.', str_replace('/', '\/', trim(str_replace('//', '/', wpro_get_option('wpro-aws-bucket')), '/'))) . '\/(.*)$/', $url, $regs)) {
$url = $regs[1];
}

if (!file_exists($file)) return false;
$this->removeTemporaryLocalData($file);

Expand All @@ -206,6 +225,7 @@ function upload($file, $fullurl, $mime) {
$query = "PUT /" . $this->bucket . "/" . $url . " HTTP/1.1\n";
$query .= "Host: " . $this->endpoint . "\n";
$query .= "x-amz-acl: public-read\n";
$query .= "Cache-Control: max-age=86400\n";
$query .= "Connection: keep-alive\n";
$query .= "Content-Type: " . $mime . "\n";
$query .= "Content-Length: " . filesize($file) . "\n";
Expand Down Expand Up @@ -284,9 +304,10 @@ function __construct() {
add_filter('shutdown', array($this, 'shutdown'));

// Support for Gravity Forms if Gravity Forms is enabled
if(class_exists("GFCommon")) {
//RYAN:commented out class_exists check because when running as mu-plugin the GFCommon class does not yet exist.
//if(class_exists("GFCommon")) {
add_action("gform_after_submission", array($this, 'gravityforms_after_submission'), 10, 2);
}
//}

switch (wpro_get_option('wpro-service')) {
case 'ftp':
Expand Down Expand Up @@ -509,17 +530,45 @@ function upload_dir($data) {
while (is_dir($this->upload_basedir)) $this->upload_basedir = $this->tempdir . 'wpro' . time() . rand(0, 999999);
}
$data['basedir'] = $this->upload_basedir;

// Begin building baseurl
switch (wpro_get_option('wpro-service')) {
case 'ftp':
$data['baseurl'] = '//' . trim(str_replace('//', '/', trim(wpro_get_option('wpro-ftp-webroot'), '/') . '/' . trim(wpro_get_option('wpro-folder'))), '/');
$data['baseurl'] = '//' . trim(str_replace('//', '/', trim(wpro_get_option('wpro-ftp-webroot'))), '/');
break;
default:
if (wpro_get_option('wpro-aws-virthost')) {
$data['baseurl'] = '//' . trim(str_replace('//', '/', wpro_get_option('wpro-aws-bucket') . '/' . trim(wpro_get_option('wpro-folder'))), '/');
// Use Virtual Hosted-Style with CNAME
$data['baseurl'] = '//' . trim(str_replace('//', '/', wpro_get_option('wpro-aws-virthost')), '/');
} else if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] !== 'off')) {
// Force Path-Style when using SSL, otherwise user will get a certificate error if the
// bucket contains periods. (i.e. S3's certificate won't match www.mydomain.com.s3.amazonaws.com)
$data['baseurl'] = '//s3.amazonaws.com/' . trim(str_replace('//', '/', wpro_get_option('wpro-aws-bucket')), '/');
} else {
$data['baseurl'] = '//' . trim(str_replace('//', '/', wpro_get_option('wpro-aws-bucket') . '.s3.amazonaws.com/' . trim(wpro_get_option('wpro-folder'))), '/');
// Use Virtual Hosted-Style without CNAME
//RYAN: Use the same Path-Style to be compatible with the broken dynamic-featured-image plugin.
//$data['baseurl'] = '//' . trim(str_replace('//', '/', wpro_get_option('wpro-aws-bucket') . '.s3.amazonaws.com'), '/');
$data['baseurl'] = '//s3.amazonaws.com/' . trim(str_replace('//', '/', wpro_get_option('wpro-aws-bucket')), '/');
}
}
// Append the appropriate wpro-folder to baseurl
//see wp-includes/functions.php [
if ( is_multisite() && ! ( is_main_network() && is_main_site() && defined( 'MULTISITE' ) ) ) {
if ( ! defined('USEBLOGSDIR') && ! get_site_option( 'ms_files_rewriting' ) ) {
$data['baseurl'] .= '/' . trim(str_replace('//', '/', trim(wpro_get_option('wpro-folder'))), '/');
if ( defined( 'MULTISITE' ) )
$ms_dir = '/sites/' . get_current_blog_id();
else
$ms_dir = '/' . get_current_blog_id();
} elseif ( defined( 'UPLOADS' ) && ! ms_is_switched() ) {
// Handle the old-form ms-files.php rewriting if the network still has that enabled.
$data['baseurl'] .= '/' . trim(str_replace('//', '/', trim(wpro_get_option('wpro-blogsfolder', 'wp-content/blogs.dir'))), '/');
$ms_dir = '/' . get_current_blog_id() . '/files';
}
$data['baseurl'] .= $ms_dir;
} else {
$data['baseurl'] .= '/' . trim(str_replace('//', '/', trim(wpro_get_option('wpro-folder'))), '/');
}
$data['path'] = $this->upload_basedir . $data['subdir'];
$data['url'] = $data['baseurl'] . $data['subdir'];
$this->removeTemporaryLocalData($data['path']);
Expand Down Expand Up @@ -686,14 +735,22 @@ function handle_upload_prefilter($file) {
$upload = wp_upload_dir();

$name = $file['name'];

// If a filename extension exists, lower it.
if (preg_match('/\.([^\.\/]+)$/', $file['name'], $regs)) {
$ending = '.' . $regs[1];
$preending = substr($file['name'], 0, 0 - strlen($ending));
$name = $preending . strtolower($ending);
}

$path = trim($upload['url'], '/') . '/' . $name;

$counter = 0;
while ($this->backend->file_exists($path)) {
if (preg_match('/\.([^\.\/]+)$/', $file['name'], $regs)) {
$ending = '.' . $regs[1];
$preending = substr($file['name'], 0, 0 - strlen($ending));
$name = $preending . '_' . $counter . $ending;
$name = $preending . '_' . $counter . strtolower($ending);
} else {
$name = $file['name'] . '_' . $counter;
}
Expand All @@ -707,18 +764,27 @@ function handle_upload_prefilter($file) {
}

function gravityforms_after_submission($entry, $form) {

// Upload any file attachments
$this->debug('WordpressReadOnly::gravityforms_after_submission($entry, $form);');

$upload_dir = wp_upload_dir();
foreach($form['fields'] as $field) {
if ($field['type'] == 'fileupload') {
if ($field['type'] == 'fileupload' || $field['type'] == 'post_image') {
$id = (int) $field['id'];
$file_to_upload = $entry[$id];
if($file_to_upload) {
$url = $entry[$id];
if ($field['type'] == 'post_image') {
if (strpos($file_to_upload, '|')) {
$file_to_upload = strstr($file_to_upload, '|', true);
}
if (strpos($url, '|')) {
$url = strstr($url, '|', true);
}
}
$file_to_upload = str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $file_to_upload);
$mime = wp_check_filetype($file_to_upload);

$response = $this->backend->upload($file_to_upload, $url, $mime['type']);
if (!$response) return false;
}
Expand Down