Skip to content

Commit

Permalink
3.2.3
Browse files Browse the repository at this point in the history
* Fix for asset push when the CSS rule contains a url with a query string
* Fix to insure the task heartbeat only runs once within the given interval, regardless of the number of admins logged into the admin
* Added @{type} variable for upload paths to include the upload type.  For example, if the upload path setting is set to `upload/@{type}` then when uploading an image the upload directory will be `/upload/image/`, or when uploading a video the upload path would be `/upload/video/`, etc.
* The Cloud Storage settings will show you a preview of your upload path when editing it.
* Fix for invalid presign expiration time which was causing direct uploads to fail on multisite.
* For multisite, the ability to specify different upload directories for each subsite.
  • Loading branch information
jawngee committed Oct 16, 2019
1 parent c810298 commit 206d20b
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 19 deletions.
7 changes: 5 additions & 2 deletions classes/Storage/Driver/GoogleCloud/GoogleStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class GoogleStorage implements StorageInterface {
protected $usePresignedURLs = false;

/** @var int */
protected $presignedURLExpiration = 10;
protected $presignedURLExpiration = 300;

/** @var bool */
protected $useBucketPolicyOnly = false;
Expand Down Expand Up @@ -97,7 +97,10 @@ public function __construct() {
$this->settingsError = Environment::Option('mcloud-google-settings-error', null, false);

$this->usePresignedURLs = Environment::Option('mcloud-storage-use-presigned-urls', null, false);
$this->presignedURLExpiration = Environment::Option('mcloud-storage-presigned-expiration', null, 10);
$this->presignedURLExpiration = Environment::Option('mcloud-storage-presigned-expiration', null, 300);
if (empty($this->presignedURLExpiration)) {
$this->presignedURLExpiration = 300;
}

$this->useBucketPolicyOnly = Environment::Option('mcloud-storage-bucket-policy-only', null, false);

Expand Down
7 changes: 5 additions & 2 deletions classes/Storage/Driver/S3/S3Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class S3Storage implements StorageInterface {
protected $usePresignedURLs = false;

/** @var int */
protected $presignedURLExpiration = 10;
protected $presignedURLExpiration = 300;

/** @var null|AdapterInterface */
protected $adapter = null;
Expand Down Expand Up @@ -109,7 +109,10 @@ public function __construct() {
$thisClass = get_class($this);

$this->usePresignedURLs = Environment::Option('mcloud-storage-use-presigned-urls', null, false);
$this->presignedURLExpiration = Environment::Option('mcloud-storage-presigned-expiration', null, 10);
$this->presignedURLExpiration = Environment::Option('mcloud-storage-presigned-expiration', null, 300);
if (empty($this->presignedURLExpiration)) {
$this->presignedURLExpiration = 300;
}

if(StorageManager::driver() == 's3') {
$this->useTransferAcceleration = Environment::Option('mcloud-storage-s3-use-transfer-acceleration', 'ILAB_AWS_S3_TRANSFER_ACCELERATION', false);
Expand Down
11 changes: 11 additions & 0 deletions classes/Storage/StorageSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ final class StorageSettings {
/** @var string|null */
private $prefixFormat = '';

/** @var string[] */
private $subsitePrefixFormat = [];

/** @var string|null */
private $cacheControl = null;

Expand Down Expand Up @@ -84,6 +87,7 @@ private function __construct() {
$this->deleteFromStorage = Environment::Option('mcloud-storage-delete-from-server', null, false);
$this->queuedDeletes = Environment::Option('mcloud-storage-queue-deletes', null, true);
$this->prefixFormat = Environment::Option('mcloud-storage-prefix', '');
$this->subsitePrefixFormat = Environment::Option('mcloud-storage-subsite-prefixes', '', []);

$this->uploadImages = Environment::Option('mcloud-storage-upload-images', null, true);
$this->uploadAudio = Environment::Option('mcloud-storage-upload-audio', null, true);
Expand Down Expand Up @@ -162,6 +166,13 @@ private static function instance() {
//region Settings Properties
/** @return string|null */
public static function prefixFormat() {
if (is_multisite()) {
$blogId = get_current_blog_id();
if (isset(self::instance()->subsitePrefixFormat[$blogId])) {
return self::instance()->subsitePrefixFormat[$blogId];
}
}

return self::instance()->prefixFormat;
}

Expand Down
9 changes: 9 additions & 0 deletions classes/Tasks/TaskManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ public function handleCron() {
* @throws \Exception
*/
public function handleHeartbeat() {
$freq = get_site_option('mcloud-tasks-heartbeat-frequency', 15);
$lastHeartbeat = get_site_option('mcloud_last_heartbeat', 0);
$delta = microtime(true) - $lastHeartbeat;
if (($lastHeartbeat > 0) && ($delta < $freq)) {
wp_die();
}

update_site_option('mcloud_last_heartbeat', microtime(true));

$this->closeClientConnection();

foreach($this->runningTasks as $task) {
Expand Down
68 changes: 68 additions & 0 deletions classes/Tools/SettingsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,74 @@ public function renderTextFieldSetting($args) {
]);
}

/**
* Registers an option with a text input UI
* @param $option_name
* @param $title
* @param $settings_slug
* @param null $description
* @param null $placeholder
* @param null $conditions
*/
protected function registerUploadPathFieldSetting($option_name, $title, $settings_slug, $description=null, $placeholder=null, $conditions=null) {
add_settings_field($option_name,
$title,
[$this,'renderUploadPathFieldSetting'],
$this->options_page,
$settings_slug,
['option'=>$option_name, 'description'=>$description, 'placeholder' => $placeholder, 'conditions' => $conditions]);
}

/**
* Renders a text field
* @param $args
*/
public function renderUploadPathFieldSetting($args) {
echo View::render_view('base/fields/upload-path.php',[
'value' => Environment::Option($args['option']),
'name' => $args['option'],
'placeholder' => $args['placeholder'],
'conditions' => $args['conditions'],
'description' => (isset($args['description'])) ? $args['description'] : false
]);
}

/**
* Registers an option with a text input UI
* @param $option_name
* @param $title
* @param $settings_slug
* @param null $description
* @param null $placeholder
* @param null $conditions
*/
protected function registerSubsiteUploadPathsFieldSetting($option_name, $title, $settings_slug, $description=null, $placeholder=null, $conditions=null) {
add_settings_field($option_name,
$title,
[$this,'renderSubsiteUploadPathsFieldSetting'],
$this->options_page,
$settings_slug,
['option'=>$option_name, 'description'=>$description, 'placeholder' => $placeholder, 'conditions' => $conditions]);
}

/**
* Renders a text field
* @param $args
*/
public function renderSubsiteUploadPathsFieldSetting($args) {
if (!is_multisite() || !is_network_admin()) {
echo '';
} else {
echo View::render_view('base/fields/subsite-upload-paths.php',[
'value' => Environment::Option($args['option']),
'name' => $args['option'],
'placeholder' => $args['placeholder'],
'conditions' => $args['conditions'],
'description' => (isset($args['description'])) ? $args['description'] : false
]);
}
}

/**
* Registers an option with a password input
* @param $option_name
Expand Down
5 changes: 5 additions & 0 deletions classes/Tools/Storage/StorageTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ public function updateAttachmentMetadata(
if ( $mime && $ignoreMimeTypes && StorageSettings::mimeTypeIsIgnored( $mime ) ) {
return $originalData;
}
Prefixer::setType( $mime );

if ( $this->client && $this->client->enabled() ) {
$ignoreExistingS3 = apply_filters( 'media-cloud/storage/ignore-existing-s3-data', false, $id );
Expand Down Expand Up @@ -618,6 +619,7 @@ public function updateAttachmentMetadata(

unset( $data['prefix'] );
$data['file'] = $old_file;
Prefixer::setType( null );
Prefixer::nextVersion();
return $data;
}
Expand Down Expand Up @@ -838,6 +840,7 @@ public function handleUpload( $upload, $context = 'upload' )
restore_error_handler();
}

Prefixer::setType( $upload['type'] );
$upload = $this->processFile( $upload_path, $file, $upload );
if ( isset( $upload['s3'] ) ) {

Expand All @@ -851,6 +854,8 @@ public function handleUpload( $upload, $context = 'upload' )

}
$this->uploadedDocs[$file] = $upload;
Prefixer::setType( null );
Prefixer::nextVersion();
}

return $upload;
Expand Down
38 changes: 35 additions & 3 deletions classes/Tools/Tool.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

namespace ILAB\MediaCloud\Tools;

use ILAB\MediaCloud\Storage\StorageSettings;
use ILAB\MediaCloud\Utilities\Environment;
use ILAB\MediaCloud\Utilities\NoticeManager;
use function ILAB\MediaCloud\Utilities\arrayPath;
use ILAB\MediaCloud\Utilities\Prefixer;
use ILAB\MediaCloud\Utilities\Tracker;
use function ILAB\MediaCloud\Utilities\vomit;

Expand Down Expand Up @@ -116,6 +118,10 @@ public function __construct($toolName, $toolInfo, $toolManager) {
require_once(ILAB_HELPERS_DIR.'/'.$helper);
}
}

if (is_admin()) {
add_action('wp_ajax_mcloud_preview_upload_path', [$this, 'doPreviewUploadPath']);
}
}

//endregion
Expand Down Expand Up @@ -427,9 +433,15 @@ public function registerSettings() {
$max = arrayPath($optionInfo,'max',1000);

switch($optionInfo['type']) {
case 'text-field':
$this->registerTextFieldSetting($option,$optionInfo['title'],$group,$description,$placeholder,$conditions);
break;
case 'text-field':
$this->registerTextFieldSetting($option,$optionInfo['title'],$group,$description,$placeholder,$conditions);
break;
case 'upload-path':
$this->registerUploadPathFieldSetting($option,$optionInfo['title'],$group,$description,$placeholder,$conditions);
break;
case 'subsite-upload-paths':
$this->registerSubsiteUploadPathsFieldSetting($option,$optionInfo['title'],$group,$description,$placeholder,$conditions);
break;
case 'text-area':
$this->registerTextAreaFieldSetting($option,$optionInfo['title'],$group,$description, $placeholder, $conditions);
break;
Expand Down Expand Up @@ -538,4 +550,24 @@ public function haveSettingsChanged() {
}

//endregion

//region Upload Path Preview
public function doPreviewUploadPath() {
check_ajax_referer('mcloud-preview-upload-path', 'nonce');

$prefix = sanitize_text_field($_REQUEST['prefix']);
if (empty($prefix)) {
wp_die();
}

Prefixer::nextVersion();
Prefixer::setType('image/jpeg');

wp_send_json([
'path' => Prefixer::Parse($prefix),
'prefix' => $prefix
]);

}
//endregion
}
15 changes: 15 additions & 0 deletions classes/Utilities/Prefixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ final class Prefixer {
private $versionedIds = [];

private $currentVersion = null;

private $currentType = null;
//endregion

//region Constructor/Static Instance
Expand Down Expand Up @@ -123,6 +125,7 @@ private function parsePrefix($prefix, $id = null) {
$prefix = str_replace("@{user-name}", $userName, $prefix);
$prefix = str_replace("@{unique-id}", $this->genUUID(), $prefix);
$prefix = str_replace("@{unique-path}", $this->genUUIDPath(), $prefix);
$prefix = str_replace('@{type}', $this->currentType, $prefix);
$prefix = str_replace("//", "/", $prefix);

$matches = [];
Expand Down Expand Up @@ -156,5 +159,17 @@ public static function Parse($prefixFormat, $id = null) {
public static function nextVersion() {
self::instance()->updateVersion();
}

public static function setType($type) {
if ($type != null) {
$typeParts = explode('/', $type);
$type = $typeParts[0];
if ($type == 'application') {
$type = 'doc';
}
}

self::instance()->currentType = $type;
}
//endregion
}
18 changes: 12 additions & 6 deletions config/storage.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,18 @@
"doc_beacon" => '39',
"description" => "The following options control how the storage tool handles uploads.",
"options" => [
"mcloud-storage-prefix" => [
"title" => "Upload Path",
"display-order" => 10,
"description" => "This will set the upload path to store uploads both locally and on cloud storage. Leave blank to use the WordPress default of <code>Month/Day</code>. For dynamically created paths, you can use the following variables: <code>@{date:format}</code>, <code>@{site-name}</code>, <code>@{site-host}</code>, <code>@{site-id}</code>, <code>@{versioning}</code>, <code>@{user-name}</code>, <code>@{unique-id}</code>, <code>@{unique-path}</code>. For the date token, format is any format string that you can use with php's <a href='http://php.net/manual/en/function.date.php' target='_blank'>date()</a> function. WordPress's default upload path would look like: <code>@{date:Y/m}</code>.",
"type" => "text-field"
],
"mcloud-storage-prefix" => [
"title" => "Upload Path",
"display-order" => 10,
"description" => "This will set the upload path to store uploads both locally and on cloud storage. Leave blank to use the WordPress default of <code>Month/Day</code>. For dynamically created paths, you can use the following variables: <code>@{date:format}</code>, <code>@{site-name}</code>, <code>@{site-host}</code>, <code>@{site-id}</code>, <code>@{versioning}</code>, <code>@{user-name}</code>, <code>@{unique-id}</code>, <code>@{unique-path}</code>, <code>@{type}</code>. For the date token, format is any format string that you can use with php's <a href='http://php.net/manual/en/function.date.php' target='_blank'>date()</a> function. WordPress's default upload path would look like: <code>@{date:Y/m}</code>.",
"type" => "upload-path"
],
"mcloud-storage-subsite-prefixes" => [
"title" => "Subsite Upload Paths",
"display-order" => 10,
"description" => "This allows you to override the default upload path for individual subsites in your multisite network. If left blank, that subsite will use your default upload path. As with the <strong>Upload Path</strong> setting, you can use the following variables: <code>@{date:format}</code>, <code>@{site-name}</code>, <code>@{site-host}</code>, <code>@{site-id}</code>, <code>@{versioning}</code>, <code>@{user-name}</code>, <code>@{unique-id}</code>, <code>@{unique-path}</code>, <code>@{type}</code>.",
"type" => "subsite-upload-paths"
],
"mcloud-storage-upload-images" => [
"title" => "Upload Images",
"description" => "Upload image files to cloud storage.",
Expand Down
4 changes: 2 additions & 2 deletions ilab-media-tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Plugin URI: https://github.com/interfacelab/ilab-media-tools
Description: Automatically upload media to Amazon S3 and integrate with Imgix, a real-time image processing CDN. Boosts site performance and simplifies workflows.
Author: interfacelab
Version: 3.2.2
Version: 3.2.3
Author URI: http://interfacelab.io
*/
// Copyright (c) 2016 Interfacelab LLC. All rights reserved.
Expand Down Expand Up @@ -93,7 +93,7 @@
}

// Version Defines
define( 'MEDIA_CLOUD_VERSION', '3.2.2' );
define( 'MEDIA_CLOUD_VERSION', '3.2.3' );
define( 'MEDIA_CLOUD_INFO_VERSION', '1.0.0' );
// Directory defines
define( 'ILAB_TOOLS_DIR', dirname( __FILE__ ) );
Expand Down
2 changes: 1 addition & 1 deletion public/css/ilab-media-cloud.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/mcloud-admin.js

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
Contributors: mediacloud, interfacelab
Tags: offload, amazon, s3, imgix, uploads, google cloud storage, digital ocean spaces, wasabi, minio, media, cdn, rekognition, cloudfront, images, crop, image editing, image editor, media library, offload, offload s3, filepicker, smush, ewww, imagify, shortpixel
Requires at least: 4.4
Tested up to: 5.2.2
Tested up to: 5.2.4
License: GPLv3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
Stable tag: 3.2.2
Stable tag: 3.2.3
Requires PHP: 5.6.4

Automatically store media on Amazon S3, Google Cloud Storage, DigitalOcean Spaces + others. Serve CSS/JS assets through CDNs. Integrate with Imgix.
Expand Down Expand Up @@ -109,6 +109,15 @@ No, I'm just one very enthusiastic customer.

== Changelog ==

= 3.2.3 =

* Fix for asset push when the CSS rule contains a url with a query string
* Fix to insure the task heartbeat only runs once within the given interval, regardless of the number of admins logged into the admin
* Added @{type} variable for upload paths to include the upload type. For example, if the upload path setting is set to `upload/@{type}` then when uploading an image the upload directory will be `/upload/image/`, or when uploading a video the upload path would be `/upload/video/`, etc.
* The Cloud Storage settings will show you a preview of your upload path when editing it.
* Fix for invalid presign expiration time which was causing direct uploads to fail on multisite.
* For multisite, the ability to specify different upload directories for each subsite.

= 3.2.2 =

* Fix for not activating when installed via Composer
Expand Down
Loading

0 comments on commit 206d20b

Please sign in to comment.