diff --git a/classes/CLI/Command.php b/classes/CLI/Command.php
index 7de8e3ee..4d10a231 100755
--- a/classes/CLI/Command.php
+++ b/classes/CLI/Command.php
@@ -62,7 +62,6 @@ protected function runTask($task, $options = [], $selected = []) {
$task->dumpExisting();
$task->loadNextData();
-
Command::Out("", true);
Command::Info("Found %W{$task->totalItems}%n items.", true);
@@ -79,4 +78,4 @@ protected function runTask($task, $options = [], $selected = []) {
}
public abstract static function Register();
-}
\ No newline at end of file
+}
diff --git a/classes/Model/Model.php b/classes/Model/Model.php
index 2b2f50f6..829c08f8 100755
--- a/classes/Model/Model.php
+++ b/classes/Model/Model.php
@@ -62,6 +62,12 @@ abstract class Model {
*/
protected $jsonProperties = [];
+ /**
+ * Map of column name to property names
+ * @var array
+ */
+ protected $columnMap = [];
+
//endregion
//region Static Methods
@@ -99,20 +105,26 @@ public function __construct($data = null) {
$modelProps = array_keys($this->modelProperties);
foreach($modelProps as $prop) {
- if (property_exists($data, $prop)) {
+ $propName = $prop;
+
+ if (isset($this->columnMap[$prop])) {
+ $propName = $this->columnMap[$prop];
+ }
+
+ if (property_exists($data, $propName)) {
if (in_array($prop, $this->serializedProperties)) {
- $this->{$prop} = maybe_unserialize($data->{$prop});
+ $val = $data->{$propName};
+ $this->{$prop} = maybe_unserialize($val);
} else if (in_array($prop, $this->jsonProperties)) {
- if (!empty($data->{$prop})) {
- $this->{$prop} = json_decode($data->{$prop}, true);
+ if (!empty($data->{$propName})) {
+ $this->{$prop} = json_decode($data->{$propName}, true);
}
} else {
- $this->{$prop} = $data->{$prop};
+ $this->{$prop} = $data->{$propName};
}
}
}
}
-
}
//endregion
@@ -191,19 +203,25 @@ public function save() {
$formats = [];
foreach($this->modelProperties as $prop => $format) {
+ $colName = $prop;
+
+ if (isset($this->columnMap[$prop])) {
+ $colName = $this->columnMap[$prop];
+ }
+
if (in_array($prop, $this->serializedProperties)) {
- $data[$prop] = maybe_serialize($this->{$prop});
+ $data[$colName] = maybe_serialize($this->{$prop});
$formats[] = '%s';
} else if (in_array($prop, $this->jsonProperties)) {
if (!empty($this->{$prop})) {
- $data[$prop] = json_encode($this->{$prop}, JSON_PRETTY_PRINT);
+ $data[$colName] = json_encode($this->{$prop}, JSON_PRETTY_PRINT);
} else {
- $data[$prop] = null;
+ $data[$colName] = null;
}
$formats[] = '%s';
} else {
- $data[$prop] = $this->{$prop};
+ $data[$colName] = $this->{$prop};
$formats[] = $format;
}
}
@@ -214,12 +232,18 @@ public function save() {
$this->id = $wpdb->insert_id;
$this->modelState = self::MODEL_LIVE;
return true;
+ } else {
+ $lastError = $wpdb->last_error;
+ error_log($lastError);
}
} else {
$result = $wpdb->update(static::table(), $data, ['id' => $this->id], $formats);
if (!empty($result)) {
$this->modelState = self::MODEL_LIVE;
return true;
+ } else {
+ $error = $wpdb->last_error;
+ $dafuk = 'what';
}
}
@@ -230,7 +254,6 @@ public function save() {
* Called before the model deletes itself
*/
protected function willDelete() {
-
}
/**
@@ -263,7 +286,7 @@ public function delete() {
/**
* Returns a task with the given ID
*
- * @param $id
+ * @param int $id
*
* @return Model|null
* @throws \Exception
@@ -316,4 +339,4 @@ public static function all($orderBy = null, $limit = 0, $page = 0) {
return null;
}
//endregion
-}
\ No newline at end of file
+}
diff --git a/classes/Storage/Driver/Backblaze/BackblazeAdapter.php b/classes/Storage/Driver/Backblaze/BackblazeAdapter.php
deleted file mode 100755
index b7f8fdbf..00000000
--- a/classes/Storage/Driver/Backblaze/BackblazeAdapter.php
+++ /dev/null
@@ -1,259 +0,0 @@
-client = $client;
- $this->bucketName = $bucketName;
- }
-
- /**
- * {@inheritdoc}
- */
- public function has($path) {
- return $this->client->fileExists(['FileName' => $path, 'BucketName' => $this->bucketName]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function write($path, $contents, Config $config) {
- $file = $this->client->upload([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path,
- 'Body' => $contents
- ]);
-
- return $this->getFileInfo($file);
- }
-
- /**
- * {@inheritdoc}
- */
- public function writeStream($path, $resource, Config $config) {
- $file = $this->client->upload([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path,
- 'Body' => $resource
- ]);
-
- return $this->getFileInfo($file);
- }
-
- /**
- * {@inheritdoc}
- */
- public function update($path, $contents, Config $config)
- {
- $file = $this->client->upload([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path,
- 'Body' => $contents
- ]);
- return $this->getFileInfo($file);
- }
-
- /**
- * {@inheritdoc}
- */
- public function updateStream($path, $resource, Config $config)
- {
- $file = $this->client->upload([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path,
- 'Body' => $resource
- ]);
-
- return $this->getFileInfo($file);
- }
-
- /**
- * {@inheritdoc}
- */
- public function read($path) {
- $file = $this->client->getFile([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path
- ]);
-
- $fileContent = $this->client->download([
- 'FileId' => $file->getId()
- ]);
-
- return ['contents' => $fileContent];
- }
-
- /**
- * {@inheritdoc}
- */
- public function readStream($path) {
- $stream = stream_for();
- $download = $this->client->download([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path,
- 'SaveAs' => $stream,
- ]);
- $stream->seek(0);
- try {
- $resource = StreamWrapper::getResource($stream);
- } catch (\InvalidArgumentException $e) {
- return false;
- }
- return $download === true ? ['stream' => $resource] : false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function rename($path, $newpath) {
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function copy($path, $newPath) {
- return $this->client->upload([
- 'BucketName' => $this->bucketName,
- 'FileName' => $newPath,
- 'Body' => @file_get_contents($path)
- ]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function delete($path) {
- return $this->client->deleteFile(['FileName' => $path, 'BucketName' => $this->bucketName]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function deleteDir($path) {
- return $this->client->deleteFile(['FileName' => $path, 'BucketName' => $this->bucketName]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function createDir($path, Config $config) {
- return $this->client->upload([
- 'BucketName' => $this->bucketName,
- 'FileName' => $path,
- 'Body' => ''
- ]);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getMetadata($path) {
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getMimetype($path) {
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getSize($path) {
- $file = $this->client->getFile(['FileName' => $path, 'BucketName' => $this->bucketName]);
-
- return $this->getFileInfo($file);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getTimestamp($path) {
- $file = $this->client->getFile(['FileName' => $path, 'BucketName' => $this->bucketName]);
-
- return $this->getFileInfo($file);
- }
-
- /**
- * {@inheritdoc}
- */
- public function listContents($directory = '', $recursive = false) {
- $fileObjects = $this->client->listFiles([
- 'BucketName' => $this->bucketName,
- ]);
- if ($recursive === true && $directory === '') {
- $regex = '/^.*$/';
- } else if ($recursive === true && $directory !== '') {
- $regex = '/^' . preg_quote($directory) . '\/.*$/';
- } else if ($recursive === false && $directory === '') {
- $regex = '/^(?!.*\\/).*$/';
- } else if ($recursive === false && $directory !== '') {
- $regex = '/^' . preg_quote($directory) . '\/(?!.*\\/).*$/';
- } else {
- throw new \InvalidArgumentException();
- }
- $fileObjects = array_filter($fileObjects, function ($fileObject) use ($directory, $regex) {
- return 1 === preg_match($regex, $fileObject->getName());
- });
- $normalized = array_map(function ($fileObject) {
- return $this->getFileInfo($fileObject);
- }, $fileObjects);
- return array_values($normalized);
- }
-
- /**
- * Get file info
- *
- * @param $file File
- *
- * @return array
- */
-
- protected function getFileInfo($file) {
- $normalized = [
- 'type' => 'file',
- 'path' => $file->getName(),
- 'timestamp' => substr($file->getUploadTimestamp(), 0, -3),
- 'size' => $file->getSize()
- ];
-
- return $normalized;
- }
-}
\ No newline at end of file
diff --git a/classes/Storage/Driver/Backblaze/BackblazeStorage.php b/classes/Storage/Driver/Backblaze/BackblazeStorage.php
index e965f5d0..ba2b9816 100755
--- a/classes/Storage/Driver/Backblaze/BackblazeStorage.php
+++ b/classes/Storage/Driver/Backblaze/BackblazeStorage.php
@@ -27,7 +27,7 @@
use ILAB\MediaCloud\Storage\StorageException;
use ILAB\MediaCloud\Storage\StorageFile;
use ILAB\MediaCloud\Storage\StorageInterface;
-use ILAB\MediaCloud\Storage\StorageManager;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use function ILAB\MediaCloud\Utilities\anyNull;
use function ILAB\MediaCloud\Utilities\arrayPath;
use ILAB\MediaCloud\Utilities\Environment;
@@ -50,10 +50,10 @@ class BackblazeStorage implements StorageInterface, AuthCacheInterface, Configur
/** @var BackblazeSettings|null */
protected $settings = null;
- /*** @var string */
- protected $bucketUrl = false;
+ /** @var string|null */
+ protected $bucketUrl = null;
- /*** @var Client */
+ /** @var Client|null */
protected $client = null;
//endregion
@@ -107,6 +107,10 @@ public function supportsDirectUploads() {
return false;
}
+ public function supportsWildcardDirectUploads() {
+ return false;
+ }
+
public function supportsBrowser() {
return true;
}
@@ -191,7 +195,8 @@ public function client() {
/**
* Returns the Backblaze client
- * @return Client
+ *
+ * @return Client|null
*/
protected function getClient() {
if(!$this->enabled()) {
@@ -248,17 +253,17 @@ public function upload($key, $fileName, $acl, $cacheControl=null, $expires=null,
}
try {
- Logger::startTiming("Start Upload", ['file' => $key]);
+ Logger::startTiming("Start Upload", ['file' => $key], __METHOD__, __LINE__);
$this->client->upload([
'BucketName' => $this->settings->bucket,
'FileName' => $key,
'Body' => fopen($fileName, 'r')
]);
- Logger::endTiming("End Upload", ['file' => $key]);
+ Logger::endTiming("End Upload", ['file' => $key], __METHOD__, __LINE__);
return $this->bucketUrl.$key;
} catch (\Exception $ex) {
- Logger::error("Backblaze upload error", ['exception' => $ex->getMessage()]);
+ Logger::error("Backblaze upload error", ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
if ($tries < 4) {
return $this->upload($key, $fileName, $acl, $cacheControl, $expires, null, null, null, $tries + 1);
} else {
@@ -279,7 +284,7 @@ public function delete($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $key
- ]);
+ ], __METHOD__, __LINE__);
}
}
@@ -303,7 +308,7 @@ public function deleteDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $file->key()
- ]);
+ ], __METHOD__, __LINE__);
}
}
}
@@ -318,7 +323,7 @@ public function deleteDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $file->key()
- ]);
+ ], __METHOD__, __LINE__);
}
}
}
@@ -330,7 +335,7 @@ public function deleteDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $key
- ]);
+ ], __METHOD__, __LINE__);
}
}
@@ -433,12 +438,6 @@ public function enqueueUploaderScripts() {
}
//endregion
- //region Adapter
- public function adapter() {
- return new BackblazeAdapter($this->client, $this->settings->bucket);
- }
- //endregion
-
//region Auth Cache
public function cacheB2Auth($key, $authData) {
update_option('ilab_media_cloud_b2_auth_cache', [
@@ -502,7 +501,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.backblaze.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
@@ -539,7 +538,7 @@ public static function processWizardSettings() {
$oldKey = Environment::ReplaceOption($accessKeyName, $accessKey);
$oldSecret = Environment::ReplaceOption($secretName, $secret);
- StorageManager::resetStorageInstance();
+ StorageToolSettings::resetStorageInstance();
try {
$storage = new static();
@@ -554,7 +553,7 @@ public static function processWizardSettings() {
Environment::UpdateOption($accessKeyName, $oldKey);
Environment::UpdateOption($secretName, $oldSecret);
- StorageManager::resetStorageInstance();
+ StorageToolSettings::resetStorageInstance();
$message = "There was a problem with your settings. Please double check entries for potential mistakes.";
@@ -566,4 +565,10 @@ public static function processWizardSettings() {
//endregion
+ //region Optimization
+ public function prepareOptimizationInfo() {
+ return [
+ ];
+ }
+ //endregion
}
diff --git a/classes/Storage/Driver/GoogleCloud/GoogleStorage.php b/classes/Storage/Driver/GoogleCloud/GoogleStorage.php
index 4841244f..f481f566 100755
--- a/classes/Storage/Driver/GoogleCloud/GoogleStorage.php
+++ b/classes/Storage/Driver/GoogleCloud/GoogleStorage.php
@@ -26,20 +26,15 @@
use ILAB\MediaCloud\Storage\StorageException;
use ILAB\MediaCloud\Storage\StorageFile;
use ILAB\MediaCloud\Storage\StorageInterface;
-use ILAB\MediaCloud\Storage\StorageGlobals;
use function ILAB\MediaCloud\Utilities\anyNull;
use function ILAB\MediaCloud\Utilities\arrayPath;
use ILAB\MediaCloud\Utilities\Environment;
use ILAB\MediaCloud\Utilities\Logging\ErrorCollector;
use ILAB\MediaCloud\Utilities\Logging\Logger;
use ILAB\MediaCloud\Utilities\NoticeManager;
-use ILAB\MediaCloud\Utilities\Tracker;
-use function ILAB\MediaCloud\Utilities\vomit;
use ILAB\MediaCloud\Wizard\ConfiguresWizard;
use ILAB\MediaCloud\Wizard\StorageWizardTrait;
use ILAB\MediaCloud\Wizard\WizardBuilder;
-use League\Flysystem\AdapterInterface;
-use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;
if(!defined('ABSPATH')) {
header('Location: /');
@@ -64,9 +59,6 @@ class GoogleStorage implements StorageInterface, ConfiguresWizard {
/*** @var StorageClient */
private $client = null;
- /** @var null|AdapterInterface */
- protected $adapter = null;
-
//endregion
//region Constructor
@@ -177,6 +169,10 @@ public function supportsDirectUploads() {
return true;
}
+ public function supportsWildcardDirectUploads() {
+ return false;
+ }
+
public function supportsBrowser() {
return true;
}
@@ -204,14 +200,14 @@ public function validateSettings($errorCollector = null) {
$errorCollector->addError("Bucket {$this->settings->bucket} does not exist.");
}
- Logger::info("Bucket does not exist.");
+ Logger::info("Bucket does not exist.", [], __METHOD__, __LINE__);
}
} catch (\Exception $ex) {
if ($errorCollector) {
$errorCollector->addError("Error insuring that {$this->settings->bucket} exists. Message: ".$ex->getMessage());
}
- Logger::error("Google Storage Error", ['exception' => $ex->getMessage()]);
+ Logger::error("Google Storage Error", ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
}
}
@@ -286,7 +282,7 @@ protected function getClient($errorCollector = null) {
$errorCollector->addError("Google configuration is incorrect or missing.");
}
- Logger::info('Could not create Google storage client.');
+ Logger::info('Could not create Google storage client.', [], __METHOD__, __LINE__);
}
return $client;
@@ -377,7 +373,7 @@ public function upload($key, $fileName, $acl, $cacheControl=null, $expires=null,
}
try {
- Logger::startTiming("Start Upload", ['file' => $key]);
+ Logger::startTiming("Start Upload", ['file' => $key], __METHOD__, __LINE__);
$data = [
'name' => $key,
@@ -390,9 +386,9 @@ public function upload($key, $fileName, $acl, $cacheControl=null, $expires=null,
$object = $bucket->upload(fopen($fileName, 'r'), $data);
- Logger::endTiming("End Upload", ['file' => $key]);
+ Logger::endTiming("End Upload", ['file' => $key], __METHOD__, __LINE__);
} catch (\Exception $ex) {
- Logger::error("Error uploading $fileName ...",['exception' => $ex->getMessage()]);
+ Logger::error("Error uploading $fileName ...",['exception' => $ex->getMessage()], __METHOD__, __LINE__);
StorageException::ThrowFromOther($ex);
}
@@ -460,7 +456,7 @@ public function createDirectory($key) {
$bucket = $this->client->bucket($this->settings->bucket);
try {
- Logger::startTiming("Start Create Directory", ['file' => $key]);
+ Logger::startTiming("Start Create Directory", ['file' => $key], __METHOD__, __LINE__);
$data = [
'name' => $key
@@ -472,11 +468,11 @@ public function createDirectory($key) {
$bucket->upload(null, $data);
- Logger::endTiming("End Create Directory", ['file' => $key]);
+ Logger::endTiming("End Create Directory", ['file' => $key], __METHOD__, __LINE__);
return true;
} catch (\Exception $ex) {
- Logger::error("Error creating directory $key ...",['exception' => $ex->getMessage()]);
+ Logger::error("Error creating directory $key ...",['exception' => $ex->getMessage()], __METHOD__, __LINE__);
StorageException::ThrowFromOther($ex);
}
@@ -501,7 +497,7 @@ public function deleteDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $file->key()
- ]);
+ ], __METHOD__, __LINE__);
}
}
}
@@ -516,7 +512,7 @@ public function deleteDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $file->key()
- ]);
+ ], __METHOD__, __LINE__);
}
}
}
@@ -528,7 +524,7 @@ public function deleteDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $key
- ]);
+ ], __METHOD__, __LINE__);
}
}
@@ -652,18 +648,6 @@ public function enqueueUploaderScripts() {
}
//endregion
-
- //region Filesystem
- public function adapter() {
- if (!empty($this->adapter)) {
- return $this->adapter;
- }
-
- $this->adapter = new GoogleStorageAdapter($this->client, $this->client->bucket($this->settings->bucket));
- return $this->adapter;
- }
- //endregion
-
//region Wizard
/**
@@ -698,7 +682,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.google.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
@@ -762,4 +746,11 @@ public static function processWizardSettings() {
//endregion
+ //region Optimization
+ public function prepareOptimizationInfo() {
+ return [
+ ];
+ }
+ //endregion
+
}
diff --git a/classes/Storage/Driver/GoogleCloud/GoogleStorageSettings.php b/classes/Storage/Driver/GoogleCloud/GoogleStorageSettings.php
index e65c86c4..d1d3dc59 100755
--- a/classes/Storage/Driver/GoogleCloud/GoogleStorageSettings.php
+++ b/classes/Storage/Driver/GoogleCloud/GoogleStorageSettings.php
@@ -72,7 +72,7 @@ public function __get($name) {
if (file_exists($credFile)) {
$this->_credentials = json_decode(file_get_contents($credFile), true);
} else {
- Logger::error("Credentials file '$credFile' could not be found.");
+ Logger::error("Credentials file '$credFile' could not be found.", [], __METHOD__, __LINE__);
}
}
@@ -90,11 +90,10 @@ public function __get($name) {
}
public function __isset($name) {
- if ($name === 'credentials') {
+ if (in_array($name, ['credentials'])) {
return true;
}
return parent::__isset($name);
}
-
-}
\ No newline at end of file
+}
diff --git a/classes/Storage/Driver/S3/DigitalOceanStorage.php b/classes/Storage/Driver/S3/DigitalOceanStorage.php
index dc7c54be..8ac4790a 100755
--- a/classes/Storage/Driver/S3/DigitalOceanStorage.php
+++ b/classes/Storage/Driver/S3/DigitalOceanStorage.php
@@ -119,7 +119,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.do.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
diff --git a/classes/Storage/Driver/S3/DreamHostStorage.php b/classes/Storage/Driver/S3/DreamHostStorage.php
new file mode 100755
index 00000000..d163ca0a
--- /dev/null
+++ b/classes/Storage/Driver/S3/DreamHostStorage.php
@@ -0,0 +1,123 @@
+section('cloud-storage-dreamhost', true)
+ ->form('wizard.cloud-storage.providers.dreamhost.form', 'Cloud Storage Settings', 'Configure Media Cloud with your cloud storage settings.', [static::class, 'processWizardSettings'])
+ ->hiddenField('nonce', wp_create_nonce('update-storage-settings'))
+ ->hiddenField('mcloud-storage-provider', 'dreamhost')
+ ->textField('mcloud-storage-s3-access-key', 'Access Key', '', null)
+ ->passwordField('mcloud-storage-s3-secret', 'Secret', '', null)
+ ->textField('mcloud-storage-s3-bucket', 'Bucket', 'The name of bucket you wish to store your media in.', null)
+ ->hiddenField('mcloud-storage-s3-region', 'auto')
+ ->selectField('mcloud-storage-s3-endpoint', 'Custom Endpoint', "", null, [
+ 'objects-us-east-1.dream.io' => 'objects-us-east-1.dream.io',
+ ])
+ ->hiddenField('mcloud-storage-s3-use-path-style-endpoint', true)
+ ->endStep()
+ ->testStep('wizard.cloud-storage.providers.dreamhost.test', 'Test Settings', 'Perform tests to insure that your cloud storage provider is configured correctly.', false);
+
+ static::addTests($builder);
+
+ $builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
+ ->group('wizard.cloud-storage.providers.dreamhost.success', 'select-buttons')
+ ->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
+ ->endGroup()
+ ->endStep();
+
+ return $builder;
+ }
+
+ protected static function validateWizardInput($provider, $accessKey, $secret, $bucket, $region, $endpoint) {
+ return !anyNull($provider, $accessKey, $secret, $bucket, $endpoint);
+ }
+ //endregion
+
+}
diff --git a/classes/Storage/Driver/S3/MinioStorage.php b/classes/Storage/Driver/S3/MinioStorage.php
index b6f3534d..18fa916e 100755
--- a/classes/Storage/Driver/S3/MinioStorage.php
+++ b/classes/Storage/Driver/S3/MinioStorage.php
@@ -153,7 +153,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.minio.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
diff --git a/classes/Storage/Driver/S3/OtherS3Storage.php b/classes/Storage/Driver/S3/OtherS3Storage.php
index 54a9da64..5c73678a 100755
--- a/classes/Storage/Driver/S3/OtherS3Storage.php
+++ b/classes/Storage/Driver/S3/OtherS3Storage.php
@@ -20,13 +20,10 @@
use ILAB\MediaCloud\Storage\FileInfo;
use ILAB\MediaCloud\Storage\InvalidStorageSettingsException;
use ILAB\MediaCloud\Storage\StorageException;
-use ILAB\MediaCloud\Storage\StorageManager;
-use ILAB\MediaCloud\Storage\StorageGlobals;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use function ILAB\MediaCloud\Utilities\anyNull;
use function ILAB\MediaCloud\Utilities\arrayPath;
use ILAB\MediaCloud\Utilities\Environment;
-use ILAB\MediaCloud\Wizard\ConfiguresWizard;
-use ILAB\MediaCloud\Wizard\StorageWizardTrait;
use ILAB\MediaCloud\Wizard\WizardBuilder;
if (!defined( 'ABSPATH')) { header( 'Location: /'); die; }
@@ -184,7 +181,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.other-s3.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
@@ -232,7 +229,7 @@ public static function processWizardSettings() {
$oldEndpoint = Environment::ReplaceOption($endpointName, $endpoint);
$oldPathStyleEndpoint = Environment::ReplaceOption($pathStyleEndpointName, $pathStyleEndpoint);
- StorageManager::resetStorageInstance();
+ StorageToolSettings::resetStorageInstance();
try {
$storage = new static();
@@ -250,7 +247,7 @@ public static function processWizardSettings() {
Environment::UpdateOption($endpointName, $oldEndpoint);
Environment::UpdateOption($pathStyleEndpointName, $oldPathStyleEndpoint);
- StorageManager::resetStorageInstance();
+ StorageToolSettings::resetStorageInstance();
$message = "There was a problem with your settings. Please double check entries for potential mistakes.";
@@ -262,4 +259,11 @@ public static function processWizardSettings() {
//endregion
+
+ //region Optimization
+ public function prepareOptimizationInfo() {
+ return [
+ ];
+ }
+ //endregion
}
diff --git a/classes/Storage/Driver/S3/S3Storage.php b/classes/Storage/Driver/S3/S3Storage.php
index 3e528961..69e5af57 100755
--- a/classes/Storage/Driver/S3/S3Storage.php
+++ b/classes/Storage/Driver/S3/S3Storage.php
@@ -17,13 +17,11 @@
namespace ILAB\MediaCloud\Storage\Driver\S3;
use FasterImage\FasterImage;
-use ILAB\MediaCloud\Storage\Driver\GoogleCloud\GoogleStorageSettings;
use ILAB\MediaCloud\Storage\FileInfo;
use ILAB\MediaCloud\Storage\InvalidStorageSettingsException;
use ILAB\MediaCloud\Storage\StorageException;
use ILAB\MediaCloud\Storage\StorageFile;
-use ILAB\MediaCloud\Storage\StorageGlobals;
-use ILAB\MediaCloud\Storage\StorageManager;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use function ILAB\MediaCloud\Utilities\anyNull;
use function ILAB\MediaCloud\Utilities\arrayPath;
use ILAB\MediaCloud\Utilities\Environment;
@@ -40,8 +38,6 @@
use ILABAmazon\S3\PostObjectV4;
use ILABAmazon\S3\S3Client;
use ILABAmazon\S3\S3MultiRegionClient;
-use ILAB_League\Flysystem\AwsS3v3\AwsS3Adapter;
-use League\Flysystem\AdapterInterface;
if(!defined('ABSPATH')) {
header('Location: /');
@@ -55,9 +51,6 @@ class S3Storage implements S3StorageInterface, ConfiguresWizard {
/** @var S3StorageSettings|null */
protected $settings = null;
- /** @var null|AdapterInterface */
- protected $adapter = null;
-
/*** @var S3Client|S3MultiRegionClient|null */
protected $client = null;
@@ -149,7 +142,11 @@ public function signedURLExpirationForType($type = null) {
}
public function supportsDirectUploads() {
- return (StorageManager::driver() === 's3');
+ return (StorageToolSettings::driver() === 's3');
+ }
+
+ public function supportsWildcardDirectUploads() {
+ return in_array(StorageToolSettings::driver(), ['s3', 'do']);
}
public static function settingsErrorOptionName() {
@@ -196,12 +193,12 @@ public function validateSettings($errorCollector = null) {
}
}
- Logger::error("Error insuring bucket exists.", ['exception' => $ex->getMessage()]);
+ Logger::error("Error insuring bucket exists.", ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
}
if (empty($valid) && empty($connectError)) {
try {
- Logger::info("Bucket does not exist, trying to list buckets.");
+ Logger::info("Bucket does not exist, trying to list buckets.", [], __METHOD__, __LINE__);
$result = $client->listBuckets();
$buckets = $result->get('Buckets');
@@ -219,7 +216,7 @@ public function validateSettings($errorCollector = null) {
$errorCollector->addError("Bucket {$this->settings->bucket} does not exist.");
}
- Logger::info("Bucket does not exist.");
+ Logger::info("Bucket does not exist.", [], __METHOD__, __LINE__);
}
} catch(AwsException $ex) {
if ($errorCollector) {
@@ -235,7 +232,7 @@ public function validateSettings($errorCollector = null) {
}
}
- Logger::error("Error insuring bucket exists.", ['exception' => $ex->getMessage()]);
+ Logger::error("Error insuring bucket exists.", ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
}
}
}
@@ -321,7 +318,7 @@ protected function getBucketRegion() {
$region = $s3->determineBucketRegion($this->settings->bucket);
}
catch(AwsException $ex) {
- Logger::error("AWS Error fetching region", ['exception' => $ex->getMessage()]);
+ Logger::error("AWS Error fetching region", ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
}
return $region;
@@ -359,7 +356,7 @@ protected function getS3MultiRegionClient() {
}
}
- if($this->settings->useTransferAcceleration && (StorageManager::driver() === 's3')) {
+ if($this->settings->useTransferAcceleration && (StorageToolSettings::driver() === 's3')) {
$config['use_accelerate_endpoint'] = true;
}
@@ -388,7 +385,7 @@ protected function getS3Client($region = false, $errorCollector = null) {
$errorCollector->addError('Could not determine region.');
}
- Logger::info("Could not get region from server.");
+ Logger::info("Could not get region from server.", [], __METHOD__, __LINE__);
return null;
}
@@ -431,7 +428,7 @@ protected function getS3Client($region = false, $errorCollector = null) {
}
}
- if($this->settings->useTransferAcceleration && (StorageManager::driver() === 's3')) {
+ if($this->settings->useTransferAcceleration && (StorageToolSettings::driver() === 's3')) {
$config['use_accelerate_endpoint'] = true;
}
@@ -456,7 +453,7 @@ protected function getClient($errorCollector = null) {
$s3 = $this->getS3Client(false, $errorCollector);
if(!$s3) {
- Logger::info('Could not create regular client, creating multi-region client instead.');
+ Logger::info('Could not create regular client, creating multi-region client instead.', [], __METHOD__, __LINE__);
if ($errorCollector) {
$errorCollector->addError("Could not create regular client, creating multi-region client instead.");
@@ -496,7 +493,7 @@ public function updateACL($key, $acl) {
return $result;
} catch (\Exception $ex) {
- Logger::error("Error changing ACL for '$key' to '$acl'. Exception: ".$ex->getMessage());
+ Logger::error("Error changing ACL for '$key' to '$acl'. Exception: ".$ex->getMessage(), [], __METHOD__, __LINE__);
return false;
}
}
@@ -542,7 +539,7 @@ public function copy($sourceKey, $destKey, $acl, $mime = false, $cacheControl =
$this->client->copyObject($copyOptions);
}
catch(AwsException $ex) {
- Logger::error('S3 Error Copying Object', ['exception' => $ex->getMessage(), 'options' => $copyOptions]);
+ Logger::error('S3 Error Copying Object', ['exception' => $ex->getMessage(), 'options' => $copyOptions], __METHOD__, __LINE__);
throw new StorageException($ex->getMessage(), $ex->getCode(), $ex);
}
}
@@ -582,9 +579,9 @@ public function upload($key, $fileName, $acl, $cacheControl=null, $expires=null,
try {
$file = fopen($fileName, 'r');
- Logger::startTiming("Start Upload", ['file' => $key]);
+ Logger::startTiming("Start Upload", ['file' => $key], __METHOD__, __LINE__);
$result = $this->client->upload($this->settings->bucket, $key, $file, $acl, $options);
- Logger::endTiming("End Upload", ['file' => $key]);
+ Logger::endTiming("End Upload", ['file' => $key], __METHOD__, __LINE__);
fclose($file);
@@ -598,7 +595,7 @@ public function upload($key, $fileName, $acl, $cacheControl=null, $expires=null,
'key' => $key,
'privacy' => $acl,
'options' => $options
- ]);
+ ], __METHOD__, __LINE__);
throw new StorageException($ex->getMessage(), $ex->getCode(), $ex);
}
@@ -610,16 +607,16 @@ public function delete($key) {
}
try {
- Logger::startTiming("Deleting '$key'");
+ Logger::startTiming("Deleting '$key'", [], __METHOD__, __LINE__);
$this->client->deleteObject(['Bucket' => $this->settings->bucket, 'Key' => $key]);
- Logger::endTiming("Deleted '$key'");
+ Logger::endTiming("Deleted '$key'", [], __METHOD__, __LINE__);
}
catch(AwsException $ex) {
Logger::error('S3 Delete File Error', [
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $key
- ]);
+ ], __METHOD__, __LINE__);
}
}
@@ -629,16 +626,16 @@ public function deleteDirectory($key) {
}
try {
- Logger::startTiming("Deleting directory '$key'");
+ Logger::startTiming("Deleting directory '$key'", [], __METHOD__, __LINE__);
$this->client->deleteMatchingObjects($this->settings->bucket, $key);
- Logger::endTiming("Deleted directory '$key'");
+ Logger::endTiming("Deleted directory '$key'", [], __METHOD__, __LINE__);
}
catch(AwsException $ex) {
Logger::error('S3 Delete File Error', [
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $key
- ]);
+ ], __METHOD__, __LINE__);
}
}
@@ -651,7 +648,7 @@ public function createDirectory($key) {
try {
$key = rtrim($key, '/').'/';
- Logger::startTiming("Creating folder '$key'");
+ Logger::startTiming("Creating folder '$key'", [], __METHOD__, __LINE__);
$this->client->putObject([
'Bucket' => $this->settings->bucket,
'Key' => $key,
@@ -659,7 +656,7 @@ public function createDirectory($key) {
'ACL' => 'public-read',
'ContentLength' => 0
]);
- Logger::endTiming("Created folder '$key'");
+ Logger::endTiming("Created folder '$key'", [], __METHOD__, __LINE__);
return true;
}
@@ -668,7 +665,7 @@ public function createDirectory($key) {
'exception' => $ex->getMessage(),
'Bucket' => $this->settings->bucket,
'Key' => $key
- ]);
+ ], __METHOD__, __LINE__);
}
return false;
@@ -699,7 +696,7 @@ public function info($key) {
$result = $result[$presignedUrl];
$size = $result['size'];
} catch (\Exception $ex) {
- Logger::error("Error getting file size info for: ".$ex->getMessage());
+ Logger::error("Error getting file size info for: ".$ex->getMessage(), [], __METHOD__, __LINE__);
}
}
@@ -807,7 +804,7 @@ protected function presignedRequest($key, $expiration = 0) {
}
public function presignedUrl($key, $expiration = 0) {
- if ((StorageManager::driver() === 's3') && ($this->settings->validSignedCDNSettings())) {
+ if ((StorageToolSettings::driver() === 's3') && ($this->settings->validSignedCDNSettings())) {
if (empty($expiration)) {
$expiration = $this->settings->presignedURLExpiration;
}
@@ -865,16 +862,20 @@ public function url($key, $type = null) {
/**
* Returns the options data for generating the policy for uploads
+ *
* @param $acl
* @param $key
*
* @return array
*/
protected function getOptionsData($acl, $key) {
+ $keyparts = explode('.', $key);
+
return [
['bucket' => $this->settings->bucket],
['acl' => $acl],
- ['key' => $key],
+// ['key' => $key],
+ ['starts-with', '$key', $keyparts[0]],
['starts-with', '$Content-Type', '']
];
}
@@ -896,7 +897,7 @@ public function uploadUrl($key, $acl, $mimeType = null, $cacheControl = null, $e
return new S3UploadInfo($key, $postObject, $acl, $cacheControl, $expires);
}
catch(AwsException $ex) {
- Logger::error('S3 Generate File Upload URL Error', ['exception' => $ex->getMessage()]);
+ Logger::error('S3 Generate File Upload URL Error', ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
throw new StorageException($ex->getMessage(), $ex->getCode(), $ex);
}
}
@@ -906,17 +907,6 @@ public function enqueueUploaderScripts() {
}
//endregion
- //region Filesystem
- public function adapter() {
- if (!empty($this->adapter)) {
- return $this->adapter;
- }
-
- $this->adapter = new AwsS3Adapter($this->client, $this->settings->bucket);
- return $this->adapter;
- }
- //endregion
-
//region Wizard
/**
@@ -954,7 +944,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.s3.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
@@ -1043,7 +1033,7 @@ public static function processWizardSettings() {
$oldPathStyleEndpoint = Environment::ReplaceOption($pathStyleEndpointName, $pathStyleEndpoint);
$oldUseTransferAcceleration = Environment::ReplaceOption($useTransferAccelerationName, $useTransferAcceleration);
- StorageManager::resetStorageInstance();
+ StorageToolSettings::resetStorageInstance();
try {
$storage = new static();
@@ -1062,7 +1052,7 @@ public static function processWizardSettings() {
Environment::UpdateOption($pathStyleEndpointName, $oldPathStyleEndpoint);
Environment::UpdateOption($useTransferAccelerationName, $oldUseTransferAcceleration);
- StorageManager::resetStorageInstance();
+ StorageToolSettings::resetStorageInstance();
$message = "There was a problem with your settings. Please double check entries for potential mistakes.";
@@ -1072,8 +1062,16 @@ public static function processWizardSettings() {
}
}
+ //endregion
-
-
+ //region Optimization
+ public function prepareOptimizationInfo() {
+ return [
+ 'key' => $this->settings->key,
+ 'secret' => $this->settings->secret,
+ 'bucket' => $this->bucket(),
+ 'region' => $this->region()
+ ];
+ }
//endregion
}
diff --git a/classes/Storage/Driver/S3/S3StorageSettings.php b/classes/Storage/Driver/S3/S3StorageSettings.php
index 387f33ee..bf063adc 100755
--- a/classes/Storage/Driver/S3/S3StorageSettings.php
+++ b/classes/Storage/Driver/S3/S3StorageSettings.php
@@ -17,7 +17,7 @@
namespace ILAB\MediaCloud\Storage\Driver\S3;
use ILAB\MediaCloud\Storage\StorageInterface;
-use ILAB\MediaCloud\Storage\StorageManager;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use ILAB\MediaCloud\Tools\ToolSettings;
use ILAB\MediaCloud\Utilities\Environment;
use function ILAB\MediaCloud\Utilities\gen_uuid;
@@ -108,7 +108,7 @@ public function __construct($storage) {
public function __get($name) {
if ($name === 'endpoint') {
- if (StorageManager::driver() === 's3') {
+ if (StorageToolSettings::driver() === 's3') {
return null;
}
@@ -159,13 +159,13 @@ public function __get($name) {
if ($storageClass::defaultRegion() !== null) {
$this->region = $storageClass::defaultRegion();
- } else if ((StorageManager::driver() !== 'wasabi') && (StorageManager::driver() !== 'do')) {
+ } else if ((StorageToolSettings::driver() !== 'wasabi') && (StorageToolSettings::driver() !== 'do')) {
$region = Environment::Option('mcloud-storage-s3-region', ['ILAB_AWS_S3_REGION', 'ILAB_CLOUD_REGION'], 'auto');
if($region !== 'auto') {
$this->_region = $region;
}
- } else if (StorageManager::driver() === 'wasabi') {
+ } else if (StorageToolSettings::driver() === 'wasabi') {
$this->_region = Environment::Option('mcloud-storage-wasabi-region', null, null);
}
@@ -246,4 +246,4 @@ public function deletePrivateKey($message, $title = '', $args = array()) {
call_user_func( $this->dieHandler, $message, $title, $args );
}
-}
\ No newline at end of file
+}
diff --git a/classes/Storage/Driver/S3/WasabiStorage.php b/classes/Storage/Driver/S3/WasabiStorage.php
index 46f21255..cbfe7625 100755
--- a/classes/Storage/Driver/S3/WasabiStorage.php
+++ b/classes/Storage/Driver/S3/WasabiStorage.php
@@ -147,14 +147,16 @@ public function uploadUrl($key, $acl, $mimeType = null, $cacheControl = null, $e
$optionsData[] = ['Expires' => $expires];
}
+
+
$putCommand = $this->client->getCommand('PutObject',$optionsData);
$request = $this->client->createPresignedRequest($putCommand, '+20 minutes');
$signedUrl = (string)$request->getUri();
return new OtherS3UploadInfo($key,$signedUrl,$acl);
}
- catch(AwsException $ex) {
- Logger::error('S3 Generate File Upload URL Error', ['exception' => $ex->getMessage()]);
+ catch(\Exception $ex) {
+ Logger::error('S3 Generate File Upload URL Error', ['exception' => $ex->getMessage()], __METHOD__, __LINE__);
throw new StorageException($ex->getMessage(), $ex->getCode(), $ex);
}
}
@@ -203,7 +205,7 @@ public static function configureWizard($builder = null) {
$builder->select('Complete', 'Basic setup is now complete! Configure advanced settings or setup imgix.')
->group('wizard.cloud-storage.providers.wasabi.success', 'select-buttons')
->option('configure-imgix', 'Set Up imgix', null, null, 'imgix')
- ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings-storage')
+ ->option('advanced-settings', 'Advanced Settings', null, null, null, null, 'admin:admin.php?page=media-cloud-settings&tab=storage')
->endGroup()
->endStep();
diff --git a/classes/Storage/StorageGlobals.php b/classes/Storage/StorageGlobals.php
index 12556555..ab461d44 100755
--- a/classes/Storage/StorageGlobals.php
+++ b/classes/Storage/StorageGlobals.php
@@ -353,7 +353,7 @@ public static function deleteOnUpload() {
/** @return bool */
public static function queuedDeletes() {
$canQueue = apply_filters('media-cloud/storage/queue-deletes', true);
- Logger::info("StorageGlobals::queuedDeletes - Filter returned: '$canQueue'");
+ Logger::info("StorageGlobals::queuedDeletes - Filter returned: '$canQueue'", [], __METHOD__, __LINE__);
return (!empty($canQueue) && self::instance()->queuedDeletes);
}
diff --git a/classes/Storage/StorageInterface.php b/classes/Storage/StorageInterface.php
index 850b6d9a..326309d6 100755
--- a/classes/Storage/StorageInterface.php
+++ b/classes/Storage/StorageInterface.php
@@ -17,8 +17,6 @@
namespace ILAB\MediaCloud\Storage;
use ILAB\MediaCloud\Utilities\Logging\ErrorCollector;
-use ILAB\MediaCloud\Wizard\WizardBuilder;
-use League\Flysystem\AdapterInterface;
if (!defined('ABSPATH')) { header('Location: /'); die; }
@@ -33,6 +31,12 @@ interface StorageInterface {
*/
public function supportsDirectUploads();
+ /**
+ * Determines if the StorageInterface supports wildcard direct uploads
+ * @return bool
+ */
+ public function supportsWildcardDirectUploads();
+
/**
* The identifier for the storage interface, eg 's3', 'do', etc.
* @return string
@@ -283,14 +287,15 @@ public function dir($path = '', $delimiter = '/');
*/
public function ls($path = '', $delimiter = '/');
- /**
- * @return AdapterInterface
- */
- public function adapter();
-
/**
* Determines if the storage provider supports browsing
* @return bool
*/
public function supportsBrowser();
-}
\ No newline at end of file
+
+ /**
+ * Returns the necessary information for optimization service to deliver optimized directly to cloud storage
+ * @return array
+ */
+ public function prepareOptimizationInfo();
+}
diff --git a/classes/Storage/StorageManager.php b/classes/Storage/StorageManager.php
deleted file mode 100755
index a78bb754..00000000
--- a/classes/Storage/StorageManager.php
+++ /dev/null
@@ -1,146 +0,0 @@
- $name,
- 'class' => $class,
- 'config' => $config,
- 'help' => $help
- ];
- }
-
- /**
- * @param $identifier
- *
- * @return string
- */
- public static function driverClass($identifier) {
- if (!isset(self::$registry[$identifier])) {
- return null;
- }
-
- return self::$registry[$identifier]['class'];
- }
-
- /**
- * Current driver name
- * @return string
- */
- public static function currentDriverName() {
- $driver = static::driver();
-
- if (!isset(self::$registry[$driver])) {
- return null;
- }
-
- $class = static::driverClass($driver);
- if (empty($class)) {
- return null;
- }
-
- return $class::name();
- }
-
- /**
- * @param $identifier
- *
- * @return string
- */
- public static function driverName($identifier) {
- if (!isset(self::$registry[$identifier])) {
- return null;
- }
-
- return self::$registry[$identifier]['name'];
- }
-
- /**
- * @param $identifier
- *
- * @return array
- */
- public static function driverConfig($identifier) {
- if (!isset(self::$registry[$identifier])) {
- return null;
- }
-
- return self::$registry[$identifier]['config'];
- }
-
- /**
- * @return array
- */
- public static function drivers() {
- return self::$registry;
- }
-}
\ No newline at end of file
diff --git a/classes/Storage/StoragePostMap.php b/classes/Storage/StoragePostMap.php
index c594b662..acb17628 100755
--- a/classes/Storage/StoragePostMap.php
+++ b/classes/Storage/StoragePostMap.php
@@ -98,8 +98,6 @@ public static function uncachedAttachmentIdFromURL($url, $bucketName) {
$path = ltrim(str_replace($bucketName,'', $path),'/');
}
- $path = apply_filters('media-cloud/glide/clean-path', $path);
-
$query = $wpdb->prepare("select ID from {$wpdb->posts} where post_type='attachment' and guid like %s order by ID desc limit 1", '%'.$path);
$postId = $wpdb->get_var($query);
}
@@ -116,7 +114,7 @@ public static function attachmentIdFromURL($postId, $url, $bucketName) {
return static::$cache[$url];
}
- if (!empty(StorageGlobals::cacheLookups())) {
+ if (!empty(StorageToolSettings::instance()->cacheLookups)) {
global $wpdb;
$tableName = $wpdb->base_prefix.'mcloud_post_map';
@@ -142,7 +140,8 @@ public static function attachmentIdFromURL($postId, $url, $bucketName) {
}
$postId = static::uncachedAttachmentIdFromURL($url, $bucketName);
+
return $postId;
}
//endregion
-}
\ No newline at end of file
+}
diff --git a/classes/Storage/StorageToolMigrations.php b/classes/Storage/StorageToolMigrations.php
new file mode 100755
index 00000000..8638d58f
--- /dev/null
+++ b/classes/Storage/StorageToolMigrations.php
@@ -0,0 +1,225 @@
+displayAdminNotice('info', "Media Cloud noticed you were using {$migratedFrom} and has migrated your settings automatically. Everything should be working as before, but make sure to double check your Cloud Storage settings.", true, 'mcloud-migrated-other-plugin', 'forever');
+ update_option('mcloud-other-plugins-did-migrate', $migratedFrom);
+ }
+
+ update_option('mcloud-other-plugins-migrated', true);
+ }
+
+ //endregion
+
+ //region Stateless Migrations
+
+ private static function migrateStatelessSettings() {
+ $jsonConfigData = get_option('sm_key_json');
+ if (empty($jsonConfigData)) {
+ return false;
+ }
+
+ $bucket = get_option('sm_bucket');
+ if (empty($bucket)) {
+ return false;
+ }
+
+ $mode = get_option('sm_mode', 'cdn');
+ if ($mode === 'disabled') {
+ return false;
+ }
+
+ Environment::UpdateOption('mcloud-storage-provider', 'google');
+ Environment::UpdateOption('mcloud-storage-google-credentials', $jsonConfigData);
+ Environment::UpdateOption('mcloud-storage-google-bucket', $bucket);
+
+ $deleteUploads = ($mode === 'stateless');
+ if (!empty($deleteUploads)) {
+ Environment::UpdateOption("mcloud-storage-delete-uploads", true);
+ }
+
+ $cdn = get_option('sm_custom_domain');
+ if (!empty($cdn)) {
+ Environment::UpdateOption("mcloud-storage-cdn-base", $cdn);
+ }
+
+ $uploadDir = trim(get_option('sm_root_dir'), '/');
+ if (!empty($uploadDir)) {
+ Environment::UpdateOption("mcloud-storage-prefix", $uploadDir);
+ }
+
+ $cacheControl = get_option('sm_cache_control');
+ if (!empty($cacheControl)) {
+ Environment::UpdateOption("mcloud-storage-cache-control", $cacheControl);
+ }
+
+ return true;
+ }
+
+ //endregion
+
+ //region Offload Migrations
+
+ private static function migrateOffloadMiscSettings($offloadConfig) {
+ $deleteUploads = arrayPath($offloadConfig, 'remove-local-file', false);
+ $cdn = arrayPath($offloadConfig, 'cloudfront', null);
+ $prefix = arrayPath($offloadConfig, 'object-prefix', null);
+ $usePrefix = arrayPath($offloadConfig, 'enable-object-prefix', false);
+
+ if (!empty($deleteUploads)) {
+ Environment::UpdateOption("mcloud-storage-delete-uploads", true);
+ }
+
+ if (!empty($cdn)) {
+ Environment::UpdateOption("mcloud-storage-cdn-base", 'https://'.$cdn);
+ }
+
+ if (!empty($prefix) && !empty($usePrefix)) {
+ $prefix = rtrim($prefix, '/');
+
+ $useYearMonth = arrayPath($offloadConfig, 'use-yearmonth-folders', false);
+ if (!empty($useYearMonth)) {
+ $prefix = trailingslashit($prefix).'@{date:Y/m}';
+ }
+
+ $useVersioning = arrayPath($offloadConfig, 'object-versioning', false);
+ if ($useVersioning) {
+ $prefix = trailingslashit($prefix).'@{versioning}';
+ }
+
+ Environment::UpdateOption("mcloud-storage-prefix", $prefix);
+ }
+ }
+
+ private static function migrateOffload($provider, $key, $secret) {
+ $offloadConfig = get_option('tantan_wordpress_s3');
+ $bucket = arrayPath($offloadConfig, 'bucket', null);
+ $region = arrayPath($offloadConfig, 'region', 'auto');
+ if (empty($bucket)) {
+ return false;
+ }
+
+ Environment::UpdateOption('mcloud-storage-provider', $provider);
+ Environment::UpdateOption("mcloud-storage-s3-access-key", $key);
+ Environment::UpdateOption("mcloud-storage-s3-secret", $secret);
+ Environment::UpdateOption("mcloud-storage-s3-bucket", $bucket);
+
+ if ($provider === 'do') {
+ Environment::UpdateOption("mcloud-storage-s3-endpoint", "https://{$region}.digitaloceanspaces.com");
+ } else {
+ Environment::UpdateOption("mcloud-storage-s3-region", $region);
+ }
+
+ static::migrateOffloadMiscSettings($offloadConfig);
+
+ return true;
+ }
+
+ private static function migrateOffloadFromConfig($data) {
+ $provider = arrayPath($data, 'provider', null);
+ if (empty($provider) || !in_array($provider, ['aws', 'do', 'gcp'])) {
+ return false;
+ }
+
+ $providerMap = ['aws' => 's3', 'do' => 'do', 'gcp' => 'google'];
+ $provider = $providerMap[$provider];
+
+ if ($provider !== 'google') {
+ $key = arrayPath($data, 'access-key-id');
+ $secret = arrayPath($data, 'secret-access-key');
+
+ return static::migrateOffload($provider, $key, $secret);
+ }
+
+ $keyPath = arrayPath($data, 'key-file-path', null);
+ if (!empty($keyPath) && file_exists($keyPath)) {
+ $googleConfig = file_get_contents($keyPath);
+ } else {
+ $googleConfigData = arrayPath($data, 'key-file', null);
+ if (empty($googleConfigData) || !is_array($googleConfigData)) {
+ return false;
+ }
+
+ $googleConfig = json_encode($googleConfigData, JSON_PRETTY_PRINT);
+ }
+
+ if (empty($googleConfig)) {
+ return false;
+ }
+
+ $offloadConfig = get_option('tantan_wordpress_s3');
+ $bucket = arrayPath($offloadConfig, 'bucket', null);
+ if (empty($bucket)) {
+ return false;
+ }
+
+ Environment::UpdateOption('mcloud-storage-provider', 'google');
+ Environment::UpdateOption('mcloud-storage-google-credentials', $googleConfig);
+ Environment::UpdateOption('mcloud-storage-google-bucket', $bucket);
+
+ static::migrateOffloadMiscSettings($offloadConfig);
+
+ return true;
+ }
+
+ public static function migrateOffloadSettings() {
+ $migrated = false;
+ if (defined('AS3CF_SETTINGS')) {
+ $data = unserialize(constant('AS3CF_SETTINGS'));
+ if (!empty($data)) {
+ $migrated = static::migrateOffloadFromConfig($data);
+ }
+ } else {
+ $offloadConfig = get_option('tantan_wordpress_s3');
+ if (!empty($offloadConfig)) {
+ $migrated = static::migrateOffloadFromConfig($offloadConfig);
+ }
+ }
+
+ return $migrated;
+ }
+ //endregion
+}
diff --git a/classes/Storage/StorageToolSettings.php b/classes/Storage/StorageToolSettings.php
new file mode 100755
index 00000000..aced89e4
--- /dev/null
+++ b/classes/Storage/StorageToolSettings.php
@@ -0,0 +1,581 @@
+ ['mcloud-storage-delete-uploads', null, false],
+ "deleteFromStorage" => ['mcloud-storage-delete-from-server', null, false],
+ "prefixFormat" => ['mcloud-storage-prefix', null, ''],
+ "subsitePrefixFormat" => ['mcloud-storage-subsite-prefixes', '', []],
+ "uploadImages" => ['mcloud-storage-upload-images', null, true],
+ "uploadAudio" => ['mcloud-storage-upload-audio', null, true],
+ "uploadVideo" => ['mcloud-storage-upload-videos', null, true],
+ "uploadDocuments" => ['mcloud-storage-upload-documents', null, true],
+ "cacheControl" => ['mcloud-storage-cache-control', 'ILAB_AWS_S3_CACHE_CONTROL', null],
+ "privacyImages" => ['mcloud-storage-privacy-images', null, "inherit"],
+ "privacyAudio" => ['mcloud-storage-privacy-audio', null, "inherit"],
+ "privacyVideo" => ['mcloud-storage-privacy-video', null, "inherit"],
+ "privacyDocs" => ['mcloud-storage-privacy-docs', null, "inherit"],
+ "expireMinutes" => ['mcloud-storage-expires', 'ILAB_AWS_S3_EXPIRES', null],
+ "driver" => ['mcloud-storage-provider','ILAB_CLOUD_STORAGE_PROVIDER', 's3'],
+ "displayBadges" => ['mcloud-storage-display-badge', null, true],
+ "mediaListIntegration" => ['mcloud-storage-display-media-list', null, true],
+ "enableBigImageSize" => ['mcloud-storage-enable-big-size-threshold', null, true],
+ "uploadOriginal" => ['mcloud-storage-big-size-upload-original', null, true],
+ "overwriteExisting" => ["mcloud-storage-overwrite-existing", null, false],
+ "cacheLookups" => ["mcloud-storage-cache-lookups", null, true],
+ "skipOtherImport" => ["mcloud-storage-skip-import-other-plugin", null, false],
+ "keepSubsitePath" => ["mcloud-storage-keep-subsite-path", null, false],
+ ];
+
+
+ /** @var string|null */
+ private $_expires = null;
+
+ /** @var string */
+ private $_privacy = null;
+
+ /** @var string[] */
+ private $_ignoredMimeTypes = null;
+
+ /** @var string|null */
+ private $_docCdn = null;
+
+ /** @var string|null */
+ private $_cdn = null;
+
+ /** @var string|null */
+ private $_signedCDN = null;
+
+ /** @var bool */
+ private $_queuedDeletes = null;
+
+ /** @var null|array */
+ private $allowedMimes = null;
+
+ //endregion
+
+ //region Constructor
+ public function __construct() {
+ if (is_multisite() && is_network_admin() && empty($this->prefixFormat)) {
+ $rootSiteName = get_network()->site_name;
+ $adminUrl = network_admin_url('admin.php?page=media-cloud-settings&tab=storage#upload-handling');
+
+ NoticeManager::instance()->displayAdminNotice('warning', "You are using Multisite WordPress but have not set a custom upload directory. Your root site, '{$rootSiteName}' will be uploading to the root of your cloud storage which may not be desirable. It's recommended that you set the Upload Directory to sites/@{site-id}/@{date:Y/m}
in Cloud Storage settings.", true, 'mcloud-multisite-missing-upload-path');
+ }
+ }
+ //endregion
+
+ //region Magic Methods
+ public function __get($name) {
+ if ($name === 'expires') {
+ if (($this->_expires === null) && !empty($this->expireMinutes)) {
+ $this->_expires = gmdate('D, d M Y H:i:s \G\M\T', time() + ($this->expireMinutes * 60));
+ }
+
+ return $this->_expires;
+ }
+
+ if ($name === 'privacy') {
+ if ($this->_privacy === null) {
+ $this->_privacy = Environment::Option('mcloud-storage-privacy', null, "public-read");
+
+ }
+
+ if(!in_array($this->_privacy, ['public-read', 'authenticated-read'])) {
+ NoticeManager::instance()->displayAdminNotice('error', "Your AWS S3 settings are incorrect. The ACL '{$this->privacy}' is not valid. Defaulting to 'public-read'.");
+ $this->_privacy = 'public-read';
+ }
+
+ return $this->_privacy;
+ }
+
+ if ($name === 'ignoredMimeTypes') {
+ if ($this->_ignoredMimeTypes === null) {
+ $this->_ignoredMimeTypes = [];
+
+ $ignored = Environment::Option('mcloud-storage-ignored-mime-types', null, '');
+ $ignored_lines = explode("\n", $ignored);
+ if(count($ignored_lines) <= 1) {
+ $ignored_lines = explode(',', $ignored);
+ }
+
+ foreach($ignored_lines as $d) {
+ if(!empty($d)) {
+ $this->_ignoredMimeTypes[] = trim($d);
+ }
+ }
+
+ if (empty($this->uploadImages)) {
+ $this->_ignoredMimeTypes[] = 'image/*';
+ }
+
+ if (empty($this->uploadVideo)) {
+ $this->_ignoredMimeTypes[] = 'video/*';
+ }
+
+ if (empty($this->uploadAudio)) {
+ $this->_ignoredMimeTypes[] = 'audio/*';
+ }
+
+ if (empty($this->uploadDocuments)) {
+ $this->_ignoredMimeTypes[] = 'application/*';
+ $this->_ignoredMimeTypes[] = 'text/*';
+ }
+ }
+
+ return $this->_ignoredMimeTypes;
+ }
+
+ if ($name === 'cdn') {
+ if ($this->_cdn === null) {
+ $this->_cdn = rtrim(Environment::Option('mcloud-storage-cdn-base', 'ILAB_AWS_S3_CDN_BASE'),'/');
+ if (!empty($this->_cdn) && empty(parse_url($this->_cdn, PHP_URL_HOST))) {
+ $this->_cdn = 'https://'.$this->_cdn;
+ }
+ }
+
+ return $this->_cdn;
+ }
+
+ if ($name === 'docCdn') {
+ if ($this->_docCdn === null) {
+ $this->_docCdn = rtrim(Environment::Option('mcloud-storage-doc-cdn-base', 'ILAB_AWS_S3_DOC_CDN_BASE', $this->cdn), '/');
+ if (!empty($this->_docCdn) && empty(parse_url($this->_docCdn, PHP_URL_HOST))) {
+ $this->_docCdn = 'https://'.$this->_docCdn;
+ }
+ }
+
+ return $this->_docCdn;
+ }
+
+ if ($name === 'signedCDN') {
+ if ($this->_signedCDN === null) {
+ $this->_signedCDN = rtrim(Environment::Option('mcloud-storage-signed-cdn-base', null, null), '/');
+ if (!empty($this->_signedCDN) && empty(parse_url($this->_signedCDN, PHP_URL_HOST))) {
+ $this->_signedCDN = 'https://'.$this->_signedCDN;
+ }
+ }
+
+ return $this->_signedCDN;
+ }
+
+ if ($name === 'queuedDeletes') {
+ $canQueue = apply_filters('media-cloud/storage/queue-deletes', true);
+
+ if ($this->_queuedDeletes === null) {
+ $this->_queuedDeletes = Environment::Option('mcloud-storage-queue-deletes', null, false);
+ }
+
+ return ($canQueue && !empty($this->_queuedDeletes));
+ }
+
+
+ return parent::__get($name);
+ }
+
+
+
+ public function __isset($name) {
+ if (in_array($name, ['expires', 'privacy', 'ignoredMimeTypes', 'cdn', 'docCdn', 'signedCDN'])) {
+ return true;
+ }
+
+ return parent::__isset($name);
+ }
+
+ //endregion
+
+ //region Settings Properties
+ /** @return string|null */
+ public static function prefixFormat() {
+ if (is_multisite()) {
+ $blogId = get_current_blog_id();
+ if (isset(static::instance()->subsitePrefixFormat[$blogId])) {
+ $prefix = static::instance()->subsitePrefixFormat[$blogId];
+ if (!empty($prefix)) {
+ return $prefix;
+ }
+ }
+
+
+ }
+
+ return static::instance()->prefixFormat;
+ }
+
+ /**
+ * @param int|null $id
+ * @return string
+ */
+ public static function prefix($id = null) {
+ return Prefixer::Parse(static::prefixFormat(), $id);
+ }
+
+ /** @return string|null */
+ public static function cacheControl() {
+ return static::instance()->cacheControl;
+ }
+
+ /** @return string|null */
+ public static function expires() {
+ return static::instance()->expires;
+ }
+
+ /**
+ * @param false|null|string $type
+ *
+ * @return string
+ */
+ public static function privacy($type = null) {
+ /** @var StorageToolSettings $instance */
+ $instance = static::instance();
+
+ if (empty($type)) {
+ return $instance->privacy;
+ }
+
+ if (strpos($type, 'image') === 0) {
+ return ($instance->privacyImages === 'inherit') ? $instance->privacy : $instance->privacyImages;
+ }
+
+ if (strpos($type, 'video') === 0) {
+ return ($instance->privacyVideo === 'inherit') ? $instance->privacy : $instance->privacyVideo;
+ }
+
+ if (strpos($type, 'audio') === 0) {
+ return ($instance->privacyAudio === 'inherit') ? $instance->privacy : $instance->privacyAudio;
+ }
+
+ if ((strpos($type, 'application') === 0) || (strpos($type, 'text') === 0)) {
+ return ($instance->privacyDocs === 'inherit') ? $instance->privacy : $instance->privacyDocs;
+ }
+
+ return $instance->privacy;
+ }
+
+ /**
+ * @return array|null
+ */
+ public static function ignoredMimeTypes() {
+ return static::instance()->ignoredMimeTypes;
+ }
+
+ /**
+ * @return bool|null
+ *
+ * @param string[] $additionalTypes
+ */
+ public static function mimeTypeIsIgnored($mimeType, $additionalTypes = []) {
+ $altFormatsEnabled = apply_filters('media-cloud/imgix/alternative-formats/enabled', false);
+
+ $ignored = array_merge(static::instance()->ignoredMimeTypes, $additionalTypes);
+
+ foreach($ignored as $mimeTypeTest) {
+ if ($mimeType == $mimeTypeTest) {
+ return true;
+ }
+
+ if (strpos($mimeTypeTest, '*') !== false) {
+ $mimeTypeRegex = str_replace('*', '[aA-zZ0-9_.-]+', $mimeTypeTest);
+ $mimeTypeRegex = str_replace('/','\/', $mimeTypeRegex);
+
+ if (preg_match("/{$mimeTypeRegex}/m", $mimeType)) {
+ if (static::uploadImages() && $altFormatsEnabled && (in_array($mimeType, static::$alternativeFormatTypes))) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static function allowedMimeTypes() {
+ if (static::instance()->allowedMimes != null) {
+ return static::instance()->allowedMimes;
+ }
+
+ $altFormatsEnabled = apply_filters('media-cloud/imgix/alternative-formats/enabled', false);
+ $allowed = get_allowed_mime_types();
+
+ if (static::uploadImages() && $altFormatsEnabled) {
+ $allowed = array_merge($allowed, static::$alternativeFormatTypes);
+ }
+
+ $result = [];
+ foreach($allowed as $mime) {
+ if (static::mimeTypeIsIgnored($mime)) {
+ continue;
+ }
+
+ $result[] = $mime;
+ }
+
+ static::instance()->allowedMimes = $result;
+
+ return $result;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function uploadDocuments() {
+ return static::instance()->uploadDocuments;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function uploadImages() {
+ return static::instance()->uploadImages;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function uploadAudio() {
+ return static::instance()->uploadAudio;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function uploadVideo() {
+ return static::instance()->uploadVideo;
+ }
+
+ /** @return string|null */
+ public static function docCdn() {
+ return static::instance()->docCdn;
+ }
+
+ /** @return string|null */
+ public static function cdn() {
+ return static::instance()->cdn;
+ }
+
+ /** @return string|null */
+ public static function signedCDN() {
+ return static::instance()->signedCDN;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function deleteOnUpload() {
+ return static::instance()->deleteOnUpload;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function queuedDeletes() {
+ return static::instance()->queuedDeletes;
+ }
+
+ /**
+ * @return bool|null
+ */
+ public static function deleteFromStorage() {
+ return static::instance()->deleteFromStorage;
+ }
+
+ /**
+ * @return array|null
+ */
+ public static function alternativeFormatTypes() {
+ return static::$alternativeFormatTypes;
+ }
+ //endregion
+
+ //region Storage Manager
+ /**
+ * Gets the currently configured storage interface.
+ *
+ * @return StorageInterface
+ */
+ public static function storageInstance() {
+ if (static::$storageInterface) {
+ return static::$storageInterface;
+ }
+
+ if (!isset(static::$registry[static::driver()])) {
+ return null;
+ }
+
+ $class = static::$registry[static::driver()]['class'];
+ static::$storageInterface = new $class();
+
+ return static::$storageInterface;
+ }
+
+ public static function driver() {
+ return static::instance()->driver;
+ }
+
+ /**
+ * Resets the current storage interface
+ */
+ public static function resetStorageInstance() {
+ static::instance()->resetProperty('driver');
+ static::$storageInterface = null;
+ }
+
+ /**
+ * Registers a storage driver
+ * @param $identifier
+ * @param $name
+ * @param $class
+ * @param $config
+ */
+ public static function registerDriver($identifier, $name, $class, $config, $help) {
+ static::$registry[$identifier] = [
+ 'name' => $name,
+ 'class' => $class,
+ 'config' => $config,
+ 'help' => $help
+ ];
+ }
+
+ /**
+ * @param $identifier
+ *
+ * @return string
+ */
+ public static function driverClass($identifier) {
+ if (!isset(static::$registry[$identifier])) {
+ return null;
+ }
+
+ return static::$registry[$identifier]['class'];
+ }
+
+ /**
+ * Current driver name
+ * @return string
+ */
+ public static function currentDriverName() {
+ $driver = static::driver();
+
+ if (!isset(self::$registry[$driver])) {
+ return null;
+ }
+
+ $class = static::driverClass($driver);
+ if (empty($class)) {
+ return null;
+ }
+
+ return $class::name();
+ }
+
+ /**
+ * @param $identifier
+ *
+ * @return string
+ */
+ public static function driverName($identifier) {
+ if (!isset(static::$registry[$identifier])) {
+ return null;
+ }
+
+ return static::$registry[$identifier]['name'];
+ }
+
+ /**
+ * @param $identifier
+ *
+ * @return array
+ */
+ public static function driverConfig($identifier) {
+ if (!isset(static::$registry[$identifier])) {
+ return null;
+ }
+
+ return static::$registry[$identifier]['config'];
+ }
+
+ /**
+ * @return array
+ */
+ public static function drivers() {
+ return static::$registry;
+ }
+ //endregion
+}
\ No newline at end of file
diff --git a/classes/Tasks/AttachmentTask.php b/classes/Tasks/AttachmentTask.php
index 123614ba..79435b7f 100755
--- a/classes/Tasks/AttachmentTask.php
+++ b/classes/Tasks/AttachmentTask.php
@@ -13,7 +13,7 @@
namespace ILAB\MediaCloud\Tasks;
-use ILAB\MediaCloud\Storage\StorageGlobals;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use ILAB\MediaCloud\Utilities\Logging\Logger;
abstract class AttachmentTask extends Task {
@@ -53,6 +53,7 @@ protected function updateCurrentPost($post_id) {
* Add any additional \WP_Query post arguments to the query
*
* @param $args
+ * @param array $args
*
* @return array
*/
@@ -67,7 +68,7 @@ protected function filterPostArgs($args) {
* @return array|bool
*/
public function prepare($options = [], $selectedItems = []) {
- Logger::info("Preparing attachment task");
+ Logger::info("Preparing attachment task", [], __METHOD__, __LINE__);
if (!empty($options['selected-items'])) {
$selectedItems = explode(',', $options['selected-items']);
@@ -110,7 +111,7 @@ public function prepare($options = [], $selectedItems = []) {
$args['nopaging'] = true;
}
- $args['post_mime_type'] = StorageGlobals::allowedMimeTypes();
+ $args['post_mime_type'] = StorageToolSettings::allowedMimeTypes();
$args = $this->filterPostArgs($args);
@@ -127,8 +128,8 @@ public function prepare($options = [], $selectedItems = []) {
$this->state = Task::STATE_WAITING;
- Logger::info("Added {$this->totalItems} to the task.");
+ Logger::info("Added {$this->totalItems} to the task.", [], __METHOD__, __LINE__);
return ($this->totalItems > 0);
}
-}
\ No newline at end of file
+}
diff --git a/classes/Tasks/Task.php b/classes/Tasks/Task.php
index 2173a7b2..65fe1029 100755
--- a/classes/Tasks/Task.php
+++ b/classes/Tasks/Task.php
@@ -14,6 +14,7 @@
namespace ILAB\MediaCloud\Tasks;
use ILAB\MediaCloud\Model\Model;
+use ILAB\MediaCloud\Utilities\Environment;
use ILAB\MediaCloud\Utilities\Misc\Carbon\Carbon;
use function ILAB\MediaCloud\Utilities\gen_uuid;
use ILAB\MediaCloud\Utilities\Logging\Logger;
@@ -337,6 +338,30 @@ public static function taskOptions() {
return [];
}
+ /**
+ * The name of the option to check to display a warning confirmation message. Return null to not display a warning message.
+ * @return string|null
+ */
+ public static function warnOption() {
+ return null;
+ }
+
+ /**
+ * The answer the user must type to allow the action to start
+ * @return string|null
+ */
+ public static function warnConfirmationAnswer() {
+ return null;
+ }
+
+ /**
+ * The text of the warning confirmation
+ * @return string|null
+ */
+ public static function warnConfirmationText() {
+ return null;
+ }
+
/**
* The identifier for analytics
* @return string
@@ -422,11 +447,12 @@ public function cleanUp() {
* Runs the task.
*
* @return bool
+ *
* @throws \Exception
*/
public function run() {
if ($this->locked()) {
- Logger::info("Already running ...");
+ Logger::info("Already running ...", [], __METHOD__, __LINE__);
return self::TASK_ALREADY_RUNNING;
}
@@ -448,12 +474,12 @@ public function run() {
}
- Logger::info("Grabbing first chunk.");
+ Logger::info("Grabbing first chunk.", [], __METHOD__, __LINE__);
/** @var TaskData $chunk */
$chunk = $this->nextChunk();
if (empty($chunk)) {
- Logger::info("Chunk is empty!");
+ Logger::info("Chunk is empty!", [], __METHOD__, __LINE__);
$this->state = self::STATE_COMPLETE;
$this->updateTiming();
@@ -484,7 +510,7 @@ public function run() {
if ($this->isCancelled()) {
$this->info("Task was cancelled. Exiting.", true);
- Logger::info("Task was cancelled. Exiting.");
+ Logger::info("Task was cancelled. Exiting.", [], __METHOD__, __LINE__);
$this->state = self::STATE_CANCELLED;
$this->updateTiming();
@@ -600,7 +626,7 @@ public function run() {
}
}
- Logger::info("Unlocking ...");
+ Logger::info("Unlocking ...", [], __METHOD__, __LINE__);
$this->didFinish();
$this->unlock();
@@ -655,7 +681,7 @@ public function canWork($firstTime) {
$maxTime = apply_filters('media-cloud/batch/max-time', $maxTime);
if (time() > $this->taskStartTime + $maxTime) {
- Logger::info("Time is up!");
+ Logger::info("Time is up!", [], __METHOD__, __LINE__);
return false;
}
@@ -668,7 +694,7 @@ public function canWork($firstTime) {
$limit -= $this->memoryPer;
}
if ($memory >= $limit) {
- Logger::info("Out of memory!");
+ Logger::info("Out of memory! $memory >= $limit", [], __METHOD__, __LINE__);
return false;
}
@@ -682,7 +708,7 @@ public function canWork($firstTime) {
public function nextChunk() {
if (count($this->data) == 0) {
- Logger::info("Data is empty!");
+ Logger::info("Data is empty!", [], __METHOD__, __LINE__);
return false;
}
@@ -690,22 +716,22 @@ public function nextChunk() {
/** @var TaskData $data */
$data = $this->data[0];
if ($data->complete()) {
- Logger::info("Data is complete!");
+ Logger::info("Data is complete!", [], __METHOD__, __LINE__);
$data->delete();
array_shift($this->data);
$this->totalDataCount--;
- Logger::info("Data chunks remaining: ".$this->totalDataCount);
+ Logger::info("Data chunks remaining: ".$this->totalDataCount, [], __METHOD__, __LINE__);
if (count($this->data) === 0) {
gc_collect_cycles();
$this->data = TaskData::dataForTask($this, 10);
- Logger::info("Loaded ".count($this->data)." additional chunks.");
+ Logger::info("Loaded ".count($this->data)." additional chunks.", [], __METHOD__, __LINE__);
}
- Logger::info("Returning next chunk!");
+ Logger::info("Returning next chunk!", [], __METHOD__, __LINE__);
return $this->nextChunk();
}
@@ -803,7 +829,7 @@ public function lock() {
$maxTime = apply_filters('media-cloud/batch/lock-expiration', $maxTime);
- Logger::info("Locking for $maxTime seconds.");
+ Logger::info("Locking for $maxTime seconds.", [], __METHOD__, __LINE__);
global $wpdb;
$wpdb->update(static::table(), ['locked' => time() + $maxTime], ['id' => $this->id], ['%f']);
@@ -833,7 +859,7 @@ public function unlock() {
*/
public function locked() {
if (($this->id == null) || ($this->modelState == self::MODEL_DELETED)) {
- Logger::info("Missing ID or model is deleted.");
+ Logger::info("Missing ID or model is deleted.", [], __METHOD__, __LINE__);
return true;
}
@@ -842,12 +868,12 @@ public function locked() {
$query = $wpdb->prepare("select locked from {$table} where id = %d", [$this->id]);
$locked = $wpdb->get_var($query);
if (empty($locked)) {
- Logger::info("Lock is empty.");
+ Logger::info("Lock is empty.", [], __METHOD__, __LINE__);
return false;
}
$left = $locked - time();
- Logger::info("Lock ($locked) expires in $left seconds.");
+ Logger::info("Lock ($locked) expires in $left seconds.", [], __METHOD__, __LINE__);
return (time() < $locked);
}
@@ -926,7 +952,7 @@ public function addItem($item) {
$this->totalDataCount++;
$memory = memory_get_usage(true);
- Logger::info("Added {$this->totalDataCount} data chunks, memory: $memory.");
+ Logger::info("Added {$this->totalDataCount} data chunks, memory: $memory.", [], __METHOD__, __LINE__);
$this->currentData = new TaskData($this, null);
}
@@ -936,6 +962,24 @@ public function addItem($item) {
//endregion
+ //region Warning
+ public static function requireConfirmation() {
+ if (empty(static::warnOption())) {
+ return false;
+ }
+
+ return empty(Environment::Option(static::warnOption(), null, false));
+ }
+
+ public static function markConfirmed() {
+ if (empty(static::warnOption())) {
+ return;
+ }
+
+ Environment::UpdateOption(static::warnOption(), true);
+ }
+ //endregion
+
//region JSON
public function jsonSerialize() {
@@ -1096,6 +1140,21 @@ public static function completeTasks() {
return $results;
}
+ /**
+ * The number of running tasks
+ *
+ * @return int
+ * @throws \Exception
+ */
+ public static function canRunTask($taskId, $maxTasks) {
+ global $wpdb;
+
+ $table = static::table();
+ $state = self::STATE_RUNNING;
+ $count = $wpdb->get_var("select count(id) from {$table} where state = {$state} and id <> {$taskId}");
+ return ($count < $maxTasks);
+ }
+
//endregion
//region Scheduling
@@ -1150,4 +1209,4 @@ public static function scheduleIn($minutes, $options = [], $selection = []) {
return static::schedule(time() + ($minutes * 60), $options, $selection);
}
//endregion
-}
\ No newline at end of file
+}
diff --git a/classes/Tasks/TaskDatabase.php b/classes/Tasks/TaskDatabase.php
index a0e9d268..3ddcd97c 100755
--- a/classes/Tasks/TaskDatabase.php
+++ b/classes/Tasks/TaskDatabase.php
@@ -13,6 +13,8 @@
namespace ILAB\MediaCloud\Tasks;
+use ILAB\MediaCloud\Utilities\Logging\Logger;
+
/**
* Interface for creating the required tables
*/
@@ -31,6 +33,9 @@ public static function init() {
// TaskSchedule
static::installScheduleTable();
+
+ // TaskSchedule
+ static::installTokenTable();
}
@@ -143,5 +148,66 @@ protected static function installScheduleTable() {
}
}
+ protected static function installTokenTable() {
+ $currentVersion = get_site_option('mcloud_task_token_db_version');
+ if (!empty($currentVersion) && version_compare(self::DB_VERSION, $currentVersion, '<=')) {
+ return;
+ }
+
+ global $wpdb;
+
+ $tableName = $wpdb->base_prefix.'mcloud_task_token';
+ $charset = $wpdb->get_charset_collate();
+
+ $sql = "CREATE TABLE {$tableName} (
+ id BIGINT AUTO_INCREMENT,
+ token VARCHAR(256) NOT NULL,
+ value VARCHAR(256) NOT NULL,
+ time bigint NOT NULL,
+ PRIMARY KEY (id)
+) {$charset};";
+
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
+ dbDelta($sql);
+ $exists = ($wpdb->get_var("SHOW TABLES LIKE '$tableName'") == $tableName);
+ if ($exists) {
+ update_site_option('mcloud_task_token_db_version', self::DB_VERSION);
+ }
+ }
+
+ //endregion
+
+ //region Tokens
+
+ public static function setToken($token, $tokenVal) {
+ global $wpdb;
+ $tableName = $wpdb->base_prefix.'mcloud_task_token';
+
+ $wpdb->insert($tableName, ['token' => $token, 'value' => $tokenVal, 'time' => time()]);
+ }
+
+ public static function verifyToken($token, $tokenVal) {
+ global $wpdb;
+ $tableName = $wpdb->base_prefix.'mcloud_task_token';
+
+ $val = $wpdb->get_var($wpdb->prepare("select value from {$tableName} where token = %s", $token));
+ return ($tokenVal == $val);
+ }
+
+ public static function deleteToken($token) {
+ Logger::info("Deleting token $token", [], __METHOD__, __LINE__);
+
+ global $wpdb;
+ $tableName = $wpdb->base_prefix.'mcloud_task_token';
+ $wpdb->delete($tableName, ['token' => $token]);
+
+ static::deleteOldTokens();
+ }
+
+ public static function deleteOldTokens() {
+ global $wpdb;
+ $tableName = $wpdb->base_prefix.'mcloud_task_token';
+ $wpdb->query($wpdb->prepare("delete from {$tableName} where time <= %d", time() - (60 * 60 * 24)));
+ }
//endregion
}
\ No newline at end of file
diff --git a/classes/Tasks/TaskManager.php b/classes/Tasks/TaskManager.php
index bf69c42f..dc7cab34 100755
--- a/classes/Tasks/TaskManager.php
+++ b/classes/Tasks/TaskManager.php
@@ -20,6 +20,9 @@
* Manages background tasks
*/
final class TaskManager {
+ /** @var TaskSettings */
+ private $settings = null;
+
/**
* Task class registry
* @var string[]
@@ -44,6 +47,8 @@ final class TaskManager {
* TaskManager constructor.
*/
private function __construct() {
+ $this->settings = TaskSettings::instance();
+
TaskDatabase::init();
static::registerTask(TestTask::class);
@@ -161,14 +166,14 @@ private function closeClientConnection() {
}
public function actionRunTask() {
- Logger::info("Run Task Ajax");
+ Logger::info("Run Task Ajax", [], __METHOD__, __LINE__);
$this->closeClientConnection();
check_ajax_referer('mcloud_run_task', 'nonce');
$taskId = arrayPath($_REQUEST, 'taskId', null);
if (empty($taskId)) {
- Logger::info("Task is not defined. Dying.");
+ Logger::info("Task is not defined. Dying.", [], __METHOD__, __LINE__);
wp_die();
}
@@ -176,13 +181,13 @@ public function actionRunTask() {
if (!empty($token)) {
$tokenVal = arrayPath($_REQUEST, 'tokenVal', null);
if (!empty($tokenVal)) {
- Logger::info("Sending ACK");
+ Logger::info("Sending ACK", [], __METHOD__, __LINE__);
- update_site_option($token, $tokenVal);
+ TaskDatabase::setToken($token, $tokenVal);
}
}
- Logger::info("Running task {$taskId}");
+ Logger::info("Running task {$taskId}", [], __METHOD__, __LINE__);
$this->runTask($taskId);
}
@@ -252,9 +257,9 @@ public function handleHeartbeat() {
* Checks the status of a specific task
*/
public function actionStartTask() {
- Logger::info("Starting Task ... ");
+ Logger::info("Starting Task ... ", [], __METHOD__, __LINE__);
check_ajax_referer('mcloud_start_task', 'nonce');
- Logger::info("Nonce verified.");
+ Logger::info("Nonce verified.", [], __METHOD__, __LINE__);
$taskId = arrayPath($_REQUEST, 'taskId', null);
if (empty($taskId)) {
@@ -268,6 +273,8 @@ public function actionStartTask() {
$options = arrayPath($_REQUEST, 'options', []);
$taskClass = static::$registeredTasks[$taskId];
+ $taskClass::markConfirmed();
+
/** @var Task $task */
$task = new $taskClass();
$result = $task->prepare($options);
@@ -283,9 +290,9 @@ public function actionStartTask() {
* Checks the status of a specific task
*/
public function actionCancelTask() {
- Logger::info("Cancelling Task ... ");
+ Logger::info("Cancelling Task ... ", [], __METHOD__, __LINE__);
check_ajax_referer('mcloud_cancel_task', 'nonce');
- Logger::info("Nonce verified.");
+ Logger::info("Nonce verified.", [], __METHOD__, __LINE__);
$taskId = arrayPath($_REQUEST, 'taskId', null);
if (empty($taskId)) {
@@ -294,11 +301,11 @@ public function actionCancelTask() {
$task = Task::instance($taskId);
if (empty($task)) {
- Logger::info("No running task with task id $taskId");
+ Logger::info("No running task with task id $taskId", [], __METHOD__, __LINE__);
wp_send_json(['status' => 'error', 'message', 'Unknown task.']);
}
- Logger::info("Cancelling task {$taskId} ...");
+ Logger::info("Cancelling task {$taskId} ...", [], __METHOD__, __LINE__);
$task->cancel();
if (!empty($task->cli)) {
@@ -314,13 +321,13 @@ public function actionCancelTask() {
* Cancels all running tasks
*/
public function actionCancelAllTasks() {
- Logger::info("Cancelling All Tasks ... ");
+ Logger::info("Cancelling All Tasks ... ", [], __METHOD__, __LINE__);
check_ajax_referer('mcloud_cancel_all_tasks', 'nonce');
- Logger::info("Nonce verified.");
+ Logger::info("Nonce verified.", [], __METHOD__, __LINE__);
$tasks = static::runningTasks();
foreach($tasks as $task) {
- Logger::info("Cancelling task {$task->id()} ...");
+ Logger::info("Cancelling task {$task->id()} ...", [], __METHOD__, __LINE__);
$task->cancel();
if (!empty($task->cli)) {
@@ -335,9 +342,9 @@ public function actionCancelAllTasks() {
public function actionClearTaskHistory() {
- Logger::info("Clearing Task History ... ");
+ Logger::info("Clearing Task History ... ", [], __METHOD__, __LINE__);
check_ajax_referer('mcloud_clear_task_history', 'nonce');
- Logger::info("Nonce verified.");
+ Logger::info("Nonce verified.", [], __METHOD__, __LINE__);
global $wpdb;
$query = "delete from {$wpdb->base_prefix}mcloud_task where state >= 100";
@@ -508,7 +515,7 @@ public static function registeredTasks() {
* @throws \Exception
*/
public function queueTask($task) {
- Logger::info("Queueing task ...");
+ Logger::info("Queueing task ...", [], __METHOD__, __LINE__);
$task->wait();
TaskRunner::dispatch($task);
}
@@ -522,7 +529,7 @@ public function queueTask($task) {
*/
public function runTask($taskOrId) {
if (count($this->runningTasks) == 0) {
- Logger::info("No running tasks.");
+ Logger::info("No running tasks.", [], __METHOD__, __LINE__);
return;
}
@@ -540,38 +547,45 @@ public function runTask($taskOrId) {
}
if (empty($task)) {
- Logger::info("No task with with id '{$taskOrId}'.");
+ Logger::info("No task with with id '{$taskOrId}'.", [], __METHOD__, __LINE__);
return;
}
+ if ($this->settings->taskLimit > 0) {
+ if (!Task::canRunTask($task->id(), $this->settings->taskLimit)) {
+ Logger::info("Too many tasks running currently to run ".$task->id()." limit is ".$this->settings->taskLimit, [], __METHOD__, __LINE__);
+ return;
+ }
+ }
+
if ($task->state === Task::STATE_PREPARING) {
- Logger::info("Task is preparing, exiting.");
+ Logger::info("Task is preparing, exiting.", [], __METHOD__, __LINE__);
return;
}
if ($task->locked()) {
- Logger::info("Task already running, exiting.");
+ Logger::info("Task already running, exiting.", [], __METHOD__, __LINE__);
return;
}
if ($task->state >= Task::STATE_COMPLETE) {
- Logger::info("Task is already completed, exiting.");
+ Logger::info("Task is already completed, exiting.", [], __METHOD__, __LINE__);
return;
}
- Logger::info("Running task.");
+ Logger::info("Running task.", [], __METHOD__, __LINE__);
$result = $task->run();
- Logger::info("Result: $result");
+ Logger::info("Result: $result", [], __METHOD__, __LINE__);
$complete = false;
if (intval($result) >= Task::TASK_COMPLETE) {
- Logger::info("Result: $result >= ".Task::TASK_COMPLETE."?");
+ Logger::info("Result: $result >= ".Task::TASK_COMPLETE."?", [], __METHOD__, __LINE__);
$task->cleanup();
- Logger::info("Task complete.");
+ Logger::info("Task complete.", [], __METHOD__, __LINE__);
$complete = true;
}
if (empty($complete)) {
- Logger::info("Dispatching again.");
+ Logger::info("Dispatching again.", [], __METHOD__, __LINE__);
TaskRunner::dispatch($task);
}
}
diff --git a/classes/Tasks/TaskRunner.php b/classes/Tasks/TaskRunner.php
index 729801d3..a9d81596 100755
--- a/classes/Tasks/TaskRunner.php
+++ b/classes/Tasks/TaskRunner.php
@@ -24,30 +24,35 @@
final class TaskRunner {
//region Fields
+ /** @var TaskSettings */
+ private $settings = null;
+
/**
* Current instance
* @var TaskRunner|null
*/
private static $instance = null;
- private $verifySSL = 'default';
- private $connectTimeout = 0.01;
- private $timeout = 0.01;
- private $skipDNS = false;
- private $skipDNSHost = null;
- private $httpClientName = null;
+// private $verifySSL = 'default';
+// private $connectTimeout = 0.01;
+// private $timeout = 0.01;
+// private $skipDNS = false;
+// private $skipDNSHost = null;
+// private $httpClientName = null;
//endregion
//region Constructor
private function __construct() {
- $this->verifySSL = Environment::Option('mcloud-tasks-verify-ssl', null, 'no');
- $this->connectTimeout = Environment::Option('mcloud-tasks-connect-timeout', null, 0.01);
- $this->timeout = Environment::Option('mcloud-tasks-timeout', null, 0.01);
- $this->skipDNS = Environment::Option('mcloud-tasks-skip-dns', null, false);
- $this->skipDNSHost = Environment::Option('mcloud-tasks-skip-dns-host', null, 'ip');
- $this->httpClientName = Environment::Option('mcloud-tasks-http-client', null, 'wordpress');
+ $this->settings = TaskSettings::instance();
+
+// $this->settings->verifySSL = Environment::Option('mcloud-tasks-verify-ssl', null, 'no');
+// $this->settings->connectTimeout = Environment::Option('mcloud-tasks-connect-timeout', null, 0.01);
+// $this->settings->timeout = Environment::Option('mcloud-tasks-timeout', null, 0.01);
+// $this->settings->skipDNS = Environment::Option('mcloud-tasks-skip-dns', null, false);
+// $this->settings->skipDNSHost = Environment::Option('mcloud-tasks-skip-dns-host', null, 'ip');
+// $this->settings->httpClientName = Environment::Option('mcloud-tasks-http-client', null, 'wordpress');
if (is_admin()) {
add_action('wp_ajax_task_runner_test', [$this, 'testTaskRunner']);
@@ -83,10 +88,10 @@ public static function init() {
* @return bool|\Exception|\Psr\Http\Message\ResponseInterface
*/
protected function postRequestGuzzle($url, $args, $timeoutOverride = false) {
- if ($this->skipDNS) {
+ if ($this->settings->skipDNS) {
$ip = null;
- if ($this->skipDNSHost == 'ip') {
+ if ($this->settings->skipDNSHost == 'ip') {
$ip = getHostByName(getHostName());
if (empty($ip)) {
$ip = $_SERVER['SERVER_ADDR'];
@@ -115,10 +120,10 @@ protected function postRequestGuzzle($url, $args, $timeoutOverride = false) {
$cookies = CookieJar::fromArray($args['cookies'], $_SERVER['HTTP_HOST']);
}
- if ($this->verifySSL == 'default') {
+ if ($this->settings->verifySSL == 'default') {
$verifySSL = apply_filters( 'https_local_ssl_verify', false);
} else {
- $verifySSL = ($this->verifySSL == 'yes');
+ $verifySSL = ($this->settings->verifySSL == 'yes');
}
$rawUrl = esc_url_raw( $url );
@@ -145,29 +150,29 @@ protected function postRequestGuzzle($url, $args, $timeoutOverride = false) {
$options['timeout'] = $timeoutOverride;
$options['connect_timeout'] = $timeoutOverride;
} else {
- $options['timeout'] = max(0.01, $this->timeout);
- $options['connect_timeout'] = max(0.01, $this->connectTimeout);;
+ $options['timeout'] = max(0.01, $this->settings->timeout);
+ $options['connect_timeout'] = max(0.01, $this->settings->connectTimeout);;
}
$client = new Client();
try {
if (empty($options['synchronous'])) {
- Logger::info("Async call to $rawUrl");
+ Logger::info("Async call to $rawUrl", [], __METHOD__, __LINE__);
$options['synchronous'] = true;
$client->postSync($rawUrl, $options);
- Logger::info("Async call to $rawUrl complete.");
+ Logger::info("Async call to $rawUrl complete.", [], __METHOD__, __LINE__);
return true;
} else {
- Logger::info("Synchronous call to $rawUrl");
+ Logger::info("Synchronous call to $rawUrl", [], __METHOD__, __LINE__);
$result = $client->post($rawUrl, $options);
- Logger::info("Synchronous call to $rawUrl complete.");
+ Logger::info("Synchronous call to $rawUrl complete.", [], __METHOD__, __LINE__);
return $result;
}
} catch (\Exception $ex) {
if (!empty($args['blocking'])) {
return $ex;
} else {
- Logger::info("Async exception: ".$ex->getMessage());
+ Logger::info("Async exception: ".$ex->getMessage(), [], __METHOD__, __LINE__);
}
}
@@ -175,10 +180,10 @@ protected function postRequestGuzzle($url, $args, $timeoutOverride = false) {
}
protected function postRequestWordPress($url, $args, $timeoutOverride = false) {
- if ($this->skipDNS) {
+ if ($this->settings->skipDNS) {
$ip = null;
- if ($this->skipDNSHost == 'ip') {
+ if ($this->settings->skipDNSHost == 'ip') {
$ip = getHostByName(getHostName());
if (empty($ip)) {
$ip = $_SERVER['SERVER_ADDR'];
@@ -203,10 +208,10 @@ protected function postRequestWordPress($url, $args, $timeoutOverride = false) {
}
}
- if ($this->verifySSL == 'default') {
+ if ($this->settings->verifySSL == 'default') {
$verifySSL = apply_filters( 'https_local_ssl_verify', false);
} else {
- $verifySSL = ($this->verifySSL == 'yes');
+ $verifySSL = ($this->settings->verifySSL == 'yes');
}
$rawUrl = esc_url_raw( $url );
@@ -216,7 +221,7 @@ protected function postRequestWordPress($url, $args, $timeoutOverride = false) {
if ($timeoutOverride !== false) {
$args['timeout'] = $timeoutOverride;
} else {
- $args['timeout'] = max(0.01, $this->timeout);
+ $args['timeout'] = max(0.01, $this->settings->timeout);
}
$result = wp_remote_post($rawUrl, $args);
@@ -259,20 +264,20 @@ public static function dispatch($task) {
$url = add_query_arg($queryArgs, $url);
- Logger::info("Dispatching to {$url}.");
+ Logger::info("Dispatching to {$url}.", [], __METHOD__, __LINE__);
$loops = 0;
while(true) {
$loops++;
if ($loops > 1) {
- Logger::info("Loop #{$loops}!");
+ Logger::info("Loop #{$loops}!", [], __METHOD__, __LINE__);
}
if ($loops == 2) {
break;
}
- if (static::instance()->httpClientName == 'guzzle') {
+ if (static::instance()->settings->httpClientName == 'guzzle') {
static::instance()->postRequestGuzzle($url, [
'blocking' => false,
'cookies' => $_COOKIE
@@ -286,12 +291,18 @@ public static function dispatch($task) {
sleep(3);
- $val = Environment::WordPressOption($token);
- if ($val == $tokenVal) {
- Logger::info("ACK acknowledge!");
- delete_site_option($token);
+ if (TaskDatabase::verifyToken($token, $tokenVal)) {
+ Logger::info("ACK acknowledge!", [], __METHOD__, __LINE__);
+ TaskDatabase::deleteToken($token);
break;
}
+
+// $val = Environment::WordPressOption($token);
+// if ($val == $tokenVal) {
+// Logger::info("ACK acknowledge!", [], __METHOD__, __LINE__);
+// delete_site_option($token);
+// break;
+// }
}
}
@@ -322,16 +333,16 @@ private static function postTestRequest($which, $url) {
while ($loops < 10) {
$testVal = Environment::WordPressOption('mcloud_connection_test');
if ($testVal === 'test_value') {
- Logger::info("Connectivity test value fetched for '$which'.");
+ Logger::info("Connectivity test value fetched for '$which'.", [], __METHOD__, __LINE__);
return true;
}
- Logger::info("Connectivity test value not found for '$which'. Try #{$loops} ... trying again in 2 seconds.");
+ Logger::info("Connectivity test value not found for '$which'. Try #{$loops} ... trying again in 2 seconds.", [], __METHOD__, __LINE__);
sleep(2);
$loops++;
}
- Logger::info("Unable to get test value for '$which'.");
+ Logger::info("Unable to get test value for '$which'.", [], __METHOD__, __LINE__);
return false;
}
@@ -361,40 +372,40 @@ private static function doTestConnectivity($first, $second) {
$errors = [];
- Logger::info("Testing connectivity using first '$first'");
+ Logger::info("Testing connectivity using first '$first'", [], __METHOD__, __LINE__);
$result = static::postTestRequest($first, $url);
if ($result instanceof \Exception) {
- Logger::info("Connectivity error using first '$first' => ".$result->getMessage());
+ Logger::info("Connectivity error using first '$first' => ".$result->getMessage(), [], __METHOD__, __LINE__);
if (!in_array($result->getMessage(), $errors)) {
$errors[] = $result->getMessage();
}
} else if (empty($result)) {
- Logger::info("Connectivity error using first '$first' => Could not dispatch background task.");
+ Logger::info("Connectivity error using first '$first' => Could not dispatch background task.", [], __METHOD__, __LINE__);
$message = 'Unable to dispatch background task.';
if (!in_array($message, $errors)) {
$errors[] = $message;
}
} else {
- Logger::info("Testing connectivity first success");
+ Logger::info("Testing connectivity first success", [], __METHOD__, __LINE__);
delete_site_option('mcloud_connection_test');
return true;
}
if (!empty($errors)) {
- Logger::info("Testing Connectivity using second '$second'");
+ Logger::info("Testing Connectivity using second '$second'", [], __METHOD__, __LINE__);
$result = static::postTestRequest($second, $url);
if ($result instanceof \Exception) {
- Logger::info("Connectivity error using second '$second' => ".$result->getMessage());
+ Logger::info("Connectivity error using second '$second' => ".$result->getMessage(), [], __METHOD__, __LINE__);
if (!in_array($result->getMessage(), $errors)) {
$errors[] = $result->getMessage();
}
} else if (empty($result)) {
- Logger::info("Connectivity error using second '$second' => Could not dispatch background task.");
+ Logger::info("Connectivity error using second '$second' => Could not dispatch background task.", [], __METHOD__, __LINE__);
if (!in_array($message, $errors)) {
$errors[] = $message;
}
} else {
- Logger::info("Testing connectivity second success");
+ Logger::info("Testing connectivity second success", [], __METHOD__, __LINE__);
delete_site_option('mcloud_connection_test');
Environment::UpdateOption('mcloud-tasks-http-client', $second);
return true;
@@ -410,7 +421,7 @@ private static function doTestConnectivity($first, $second) {
* @return bool|string[]
*/
public static function testConnectivity() {
- if (static::instance()->httpClientName === 'guzzle') {
+ if (static::instance()->settings->httpClientName === 'guzzle') {
return static::doTestConnectivity('guzzle', 'wordpress');
}
@@ -421,10 +432,10 @@ public static function testConnectivity() {
* Ajax test endpoint
*/
public function testTaskRunner() {
- Logger::info("Test Task Runner");
+ Logger::info("Test Task Runner", [], __METHOD__, __LINE__);
check_ajax_referer('task_runner_test', 'nonce');
- Logger::info("Updating test option.");
+ Logger::info("Updating test option.", [], __METHOD__, __LINE__);
Environment::UpdateOption('mcloud_connection_test', 'test_value');
}
diff --git a/classes/Tasks/TaskSchedule.php b/classes/Tasks/TaskSchedule.php
index 9d7ba4c4..7186b76c 100755
--- a/classes/Tasks/TaskSchedule.php
+++ b/classes/Tasks/TaskSchedule.php
@@ -282,7 +282,9 @@ public function shouldRun() {
/**
* Runs the task if it's time to run it.
+ *
* @return bool
+ *
* @throws \Exception
*/
public function runIfNeeded() {
@@ -297,6 +299,7 @@ public function runIfNeeded() {
* Runs the task now, regardless of schedule
*
* @return bool
+ *
* @throws \Exception
*/
public function runNow() {
@@ -395,4 +398,4 @@ public function jsonSerialize() {
];
}
//endregion
-}
\ No newline at end of file
+}
diff --git a/classes/Tasks/TaskSettings.php b/classes/Tasks/TaskSettings.php
new file mode 100755
index 00000000..f7562b28
--- /dev/null
+++ b/classes/Tasks/TaskSettings.php
@@ -0,0 +1,44 @@
+ ['mcloud-tasks-verify-ssl', null, 'no'],
+ "connectTimeout" => ['mcloud-tasks-connect-timeout', null, 0.01],
+ "timeout" => ['mcloud-tasks-timeout', null, 0.01],
+ "skipDNS" => ['mcloud-tasks-skip-dns', null, false],
+ "skipDNSHost" => ['mcloud-tasks-skip-dns-host', null, 'ip'],
+ "httpClientName" => ['mcloud-tasks-http-client', null, 'wordpress'],
+ "heartbeatEnabled" => ['mcloud-tasks-heartbeat-enabled', null, true],
+ "heartbeatFrequency" => ['mcloud-tasks-heartbeat-frequency', null, 15],
+ "taskLimit" => ['mcloud-tasks-task-limit', null, 2],
+ ];
+}
\ No newline at end of file
diff --git a/classes/Tasks/TestTask.php b/classes/Tasks/TestTask.php
index 2d0f92fc..bb430c4b 100755
--- a/classes/Tasks/TestTask.php
+++ b/classes/Tasks/TestTask.php
@@ -82,28 +82,28 @@ public function prepare($options = [], $selectedItems = []) {
public function performTask($item) {
$tuid = arrayPath($this->options, 'tuid', null);
- Logger::info("Processing test item {$this->currentItem} ($tuid)");
+ Logger::info("Processing test item {$this->currentItem} ($tuid)", [], __METHOD__, __LINE__);
if (arrayPath($this->options, 'sleep', false)) {
- Logger::info("Sleeping ...");
+ Logger::info("Sleeping ...", [], __METHOD__, __LINE__);
sleep(1);
}
if (arrayPath($this->options, 'memory', false)) {
- Logger::info("Testing Memory ...");
+ Logger::info("Testing Memory ...", [], __METHOD__, __LINE__);
$this->stuff[] = str_repeat("0", 1048576 * rand(1, 2));
}
if (arrayPath($this->options, 'errors', false)) {
if (rand(1,5) == 2) {
- Logger::info("Throwing an error ...");
+ Logger::info("Throwing an error ...", [], __METHOD__, __LINE__);
return false;
}
}
if (arrayPath($this->options, 'exceptions', false)) {
if (rand(1,4) == 2) {
- Logger::info("Throwing an exception...");
+ Logger::info("Throwing an exception...", [], __METHOD__, __LINE__);
throw new \Exception('Random exception');
}
}
diff --git a/classes/Tools/BatchProcessing/BatchProcessingTool.php b/classes/Tools/BatchProcessing/BatchProcessingTool.php
index b16dfdc0..f9843aba 100755
--- a/classes/Tools/BatchProcessing/BatchProcessingTool.php
+++ b/classes/Tools/BatchProcessing/BatchProcessingTool.php
@@ -13,12 +13,14 @@
namespace ILAB\MediaCloud\Tools\BatchProcessing;
-use ILAB\MediaCloud\Storage\StorageGlobals;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
+use ILAB\MediaCloud\Tasks\TaskDatabase;
use ILAB\MediaCloud\Tools\Storage\StorageTool;
use ILAB\MediaCloud\Tools\Tool;
use ILAB\MediaCloud\Tools\ToolsManager;
use ILAB\MediaCloud\Utilities\Environment;
use ILAB\MediaCloud\Utilities\Logging\Logger;
+use function ILAB\MediaCloud\Utilities\json_response;
if (!defined( 'ABSPATH')) { header( 'Location: /'); die; }
@@ -44,4 +46,19 @@ public function alwaysEnabled() {
}
//endregion
-}
\ No newline at end of file
+
+
+
+ //region Actions
+
+ public function clearBackgroundTokens() {
+ global $wpdb;
+ $wpdb->query("delete from {$wpdb->options} where option_name like '%mcloud_token_%'");
+
+ TaskDatabase::deleteOldTokens();
+
+ json_response(['status' => 'ok', 'message' => 'Tokens cleared.']);
+ }
+
+ //endregion
+}
diff --git a/classes/Tools/Crop/CropTool.php b/classes/Tools/Crop/CropTool.php
index 69f6944e..2abc1f3e 100755
--- a/classes/Tools/Crop/CropTool.php
+++ b/classes/Tools/Crop/CropTool.php
@@ -13,7 +13,7 @@
namespace ILAB\MediaCloud\Tools\Crop;
-use ILAB\MediaCloud\Storage\StorageGlobals;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use ILAB\MediaCloud\Tools\Storage\StorageTool;
use ILAB\MediaCloud\Tools\Tool;
use ILAB\MediaCloud\Tools\ToolsManager;
@@ -30,16 +30,15 @@
*
* Crop tool
*/
-class CropTool extends Tool
-{
- protected $cropQuality = 100;
+class CropTool extends Tool {
+ /** @var CropToolSettings */
+ private $settings = null;
- public function __construct($toolName, $toolInfo, $toolManager)
- {
+ public function __construct($toolName, $toolInfo, $toolManager) {
+ $this->settings = CropToolSettings::instance();
+
parent::__construct($toolName, $toolInfo, $toolManager);
- $this->cropQuality = Environment::Option('mcloud-crop-quality', null, 100);
-
$this->testForBadPlugins();
$this->testForUselessPlugins();
}
@@ -190,6 +189,7 @@ private function hookupUI()
/**
* Generate the url for the crop UI
+ *
* @param $id
* @param string $size
* @return string
@@ -425,10 +425,22 @@ public function performCrop() {
$this->doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $crop_height, false);
}
+ private function suspendOptimizer() {
+ add_filter('media-cloud/optimizer/can-upload', '__return_false', 10);
+ add_filter('media-cloud/optimizer/no-background', '__return_true', 10);
+ }
+
+ private function resumeOptimizer() {
+ remove_filter('media-cloud/optimizer/can-upload', '__return_false', 10);
+ remove_filter('media-cloud/optimizer/no-background', '__return_true', 10);
+ }
+
/**
* Perform the actual crop
*/
private function doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $crop_height, $reset_crop) {
+ $this->suspendOptimizer();
+
$img_path = _load_image_to_edit_path( $post_id );
$meta = wp_get_attachment_metadata( $post_id );
$img_editor = wp_get_image_editor( $img_path );
@@ -449,7 +461,7 @@ private function doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $
}
$img_editor->crop($crop_x, $crop_y, $crop_width, $crop_height, $dest_width, $dest_height, false );
- $img_editor->set_quality($this->cropQuality);
+ $img_editor->set_quality($this->settings->cropQuality);
$save_path_parts = pathinfo($img_path);
$path_url=parse_url($img_path);
@@ -463,6 +475,7 @@ private function doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $
if (!file_exists($save_path)) {
if(!mkdir($save_path, 0777, true) && !is_dir($save_path)) {
+ $this->resumeOptimizer();
json_response([
'status'=>'error',
'message'=> "Path '$save_path' cannot be created."
@@ -530,7 +543,7 @@ private function doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $
if ($storageTool->enabled()) {
$canDelete = apply_filters('media-cloud/storage/delete_uploads', true);
- if(!empty($canDelete) && StorageGlobals::deleteOnUpload() && !StorageGlobals::queuedDeletes()) {
+ if(!empty($canDelete) && StorageToolSettings::deleteOnUpload() && !StorageToolSettings::queuedDeletes()) {
$toDelete = trailingslashit($save_path).$filename;
if (file_exists($toDelete)) {
@unlink($toDelete);
@@ -538,6 +551,8 @@ private function doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $
}
}
+ $this->resumeOptimizer();
+
json_response([
'status'=>'ok',
'src'=>$full_src,
@@ -545,4 +560,4 @@ private function doPerformCrop($post_id, $size, $crop_x, $crop_y, $crop_width, $
'height'=>$full_height
]);
}
-}
\ No newline at end of file
+}
diff --git a/classes/Tools/Crop/CropToolSettings.php b/classes/Tools/Crop/CropToolSettings.php
new file mode 100755
index 00000000..c3d710d6
--- /dev/null
+++ b/classes/Tools/Crop/CropToolSettings.php
@@ -0,0 +1,19 @@
+ ['mcloud-crop-quality', null, 100],
+ ];
+}
\ No newline at end of file
diff --git a/classes/Tools/Debugging/DebuggingTool.php b/classes/Tools/Debugging/DebuggingTool.php
index 1337ab6b..eed352f3 100755
--- a/classes/Tools/Debugging/DebuggingTool.php
+++ b/classes/Tools/Debugging/DebuggingTool.php
@@ -143,7 +143,7 @@ public function generateBug() {
$probeData['Globals']['DISABLE_WP_CRON'] = defined('DISABLE_WP_CRON') ? constant('DISABLE_WP_CRON') : null;
$probeData['Uploads'] = wp_get_upload_dir();
-
+
$probeData['Media Cloud Settings'] = [];
global $wpdb;
$settingsResults = $wpdb->get_results("select * from {$wpdb->options} where option_name like 'mcloud%'", ARRAY_A);
@@ -189,4 +189,4 @@ public function clearLog() {
//endregion
-}
\ No newline at end of file
+}
diff --git a/classes/Tools/Debugging/System/SystemCompatibilityTool.php b/classes/Tools/Debugging/System/SystemCompatibilityTool.php
index 49a6d22a..0de71a4a 100755
--- a/classes/Tools/Debugging/System/SystemCompatibilityTool.php
+++ b/classes/Tools/Debugging/System/SystemCompatibilityTool.php
@@ -15,7 +15,7 @@
use ILAB\MediaCloud\Utilities\Misc\Carbon\CarbonInterval;
use FasterImage\FasterImage;
-use ILAB\MediaCloud\Storage\StorageGlobals;
+use ILAB\MediaCloud\Storage\StorageToolSettings;
use ILAB\MediaCloud\Tasks\TaskRunner;
use ILAB\MediaCloud\Tools\Imgix\ImgixTool;
use ILAB\MediaCloud\Tools\Storage\StorageTool;
@@ -374,7 +374,7 @@ private function testUploadClient() {
$errors = [];
try {
- $url = $storageTool->client()->upload('_troubleshooter/sample.txt',ILAB_TOOLS_DIR.'/public/text/sample-upload.txt', StorageGlobals::privacy());
+ $url = $storageTool->client()->upload('_troubleshooter/sample.txt',ILAB_TOOLS_DIR.'/public/text/sample-upload.txt', StorageToolSettings::privacy());
Tracker::trackView("System Test - Test Uploads - Success", "/system-test/uploads/success");
} catch (\Exception $ex) {
Tracker::trackView("System Test - Test Uploads - Error", "/system-test/uploads/error");
@@ -534,7 +534,7 @@ private function testImgix() {
$errors = [];
try {
- $storageTool->client()->upload('_troubleshooter/sample.jpg',ILAB_TOOLS_DIR.'/public/img/test-image.jpg', StorageGlobals::privacy());
+ $storageTool->client()->upload('_troubleshooter/sample.jpg',ILAB_TOOLS_DIR.'/public/img/test-image.jpg', StorageToolSettings::privacy());
$imgixURL = $imgixTool->urlForKey('_troubleshooter/sample.jpg');
$faster = new FasterImage();
@@ -580,4 +580,4 @@ private function testImgix() {
//endregion
-}
\ No newline at end of file
+}
diff --git a/classes/Tools/DynamicImages/DynamicImageEditor.php b/classes/Tools/DynamicImages/DynamicImageEditor.php
index 297604f1..bd7c9fc3 100755
--- a/classes/Tools/DynamicImages/DynamicImageEditor.php
+++ b/classes/Tools/DynamicImages/DynamicImageEditor.php
@@ -212,7 +212,7 @@ public function multi_resize( $sizes ) {
}
$this->resize($size_data['width'], $size_data['height'], $size_data['crop']);
- $resized = $this->getMetadata();
+ $resized = $this->getMetadata(null);
$metadata[$size] = $resized;
$this->size = $orig_size;
@@ -229,11 +229,17 @@ public function crop( $src_x, $src_y, $src_w, $src_h, $dst_w = null, $dst_h = nu
return $this->update_size($dst_w,$dst_h);
}
- protected function getMetadata(){
+ protected function getMetadata($filename) {
$mime=($this->isGif) ? 'image/gif' : 'image/jpeg';
+ if ($filename != null) {
+ list( $filename, $extension, $mime_type ) = $this->get_output_format( $filename, $mime );
+ }
+
+
/** This filter is documented in wp-includes/class-wp-image-editor-gd.php */
$result = array(
+ 'path' => $filename,
'file' => wp_basename( $this->file ),
'width' => $this->size['width'],
'height' => $this->size['height'],
@@ -251,7 +257,7 @@ public function save( $destfilename = null, $mime_type = null ) {
} else if (wp_doing_ajax() && isset($_POST['action']) && ($_POST['action'] != 'ilab_perform_crop')) {
return $this->storageEditor->save($destfilename,$mime_type);
} else {
- return $this->getMetadata();
+ return $this->getMetadata($destfilename);
}
}
-}
\ No newline at end of file
+}
diff --git a/classes/Tools/DynamicImages/DynamicImagesTool.php b/classes/Tools/DynamicImages/DynamicImagesTool.php
index c75c0e77..21e707bf 100755
--- a/classes/Tools/DynamicImages/DynamicImagesTool.php
+++ b/classes/Tools/DynamicImages/DynamicImagesTool.php
@@ -27,11 +27,11 @@
use function ILAB\MediaCloud\Utilities\vomit;
abstract class DynamicImagesTool extends Tool {
- protected $signingKey = null;
+ /** @var DynamicImagesToolSettings */
+ protected $settings = null;
+
protected $paramPropsByType;
protected $paramProps;
- protected $keepThumbnails;
- protected $imageQuality;
protected $shouldCrop = false;
@@ -74,8 +74,8 @@ public function setup() {
You have an image optimizer plugin installed and activated. Because you are using direct upload functionality, no image you upload will be processed by these plugins as these uploads go directly to your cloud storage, bypassing WordPress completely.
You should consider deactivating these image optimizer plugins.
-You have an image optimizer plugin installed and activated. Imgix and Dynamic Images functionality will not use the images that these plugins optimize.
+You have an image optimizer plugin installed and activated. Imgix functionality will not use the images that these plugins optimize.
In the case of Imgix, Imgix will optimize images automatically for you when rendering them.
@@ -137,7 +137,7 @@ public function setup() { add_filter('clean_url', [$this, 'fixCleanedUrls'], 1000, 3); - if (!$this->keepThumbnails) { + if (empty($this->settings->keepThumbnails)) { add_filter('wp_image_editors', function($editors) { array_unshift($editors, '\ILAB\MediaCloud\Tools\DynamicImages\DynamicImageEditor'); @@ -155,7 +155,13 @@ public function setup() { return $metadata; } - $mime = $metadata['s3']['mime-type']; + if (!isset($metadata['s3']['mime-type'])) { + $mime = get_post_mime_type($attachmentId); + $metadata['s3']['mime-type'] = $mime; + } else { + $mime = $metadata['s3']['mime-type']; + } + if (strpos($mime, 'image/') !== 0) { return $metadata; } @@ -881,10 +887,8 @@ private function doDeletePreset($key) { public static function currentDynamicImagesTool() { if (ToolsManager::instance()->toolEnabled('imgix')) { return ToolsManager::instance()->tools['imgix']; - } else if (ToolsManager::instance()->toolEnabled('glide')) { - return ToolsManager::instance()->tools['glide']; } return null; } -} \ No newline at end of file +} diff --git a/classes/Tools/DynamicImages/DynamicImagesToolSettings.php b/classes/Tools/DynamicImages/DynamicImagesToolSettings.php new file mode 100755 index 00000000..c750a264 --- /dev/null +++ b/classes/Tools/DynamicImages/DynamicImagesToolSettings.php @@ -0,0 +1,19 @@ + ['mcloud-imgix-generate-thumbnails', null, true], + ]; +} \ No newline at end of file diff --git a/classes/Tools/DynamicImages/WordPressUploadsAdapter.php b/classes/Tools/DynamicImages/WordPressUploadsAdapter.php deleted file mode 100755 index f84c3731..00000000 --- a/classes/Tools/DynamicImages/WordPressUploadsAdapter.php +++ /dev/null @@ -1,263 +0,0 @@ -storageAdapter = $storageAdapter; - - parent::__construct(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.'uploads'); - } - - protected function download($path) { - if (parent::has($path)) { - return true; - } - - if ($this->storageAdapter->has($path)) { - $streamData = $this->storageAdapter->readStream($path); - if (is_array($streamData) && isset($streamData['stream'])) { - return parent::writeStream($path, $streamData['stream'], new Config()); - } - } - - return false; - } - - /** - * Update a file. - * - * @param string $path - * @param string $contents - * @param Config $config Config object - * - * @return array|false false on failure file meta data on success - */ - public function update($path, $contents, Config $config) { - if ($this->download($path)) { - return parent::update($path, $contents, $config); - } - - return false; - } - - /** - * Update a file using a stream. - * - * @param string $path - * @param resource $resource - * @param Config $config Config object - * - * @return array|false false on failure file meta data on success - */ - public function updateStream($path, $resource, Config $config) { - if ($this->download($path)) { - return parent::updateStream($path, $resource, $config); - } - - return false; - } - - /** - * Rename a file. - * - * @param string $path - * @param string $newpath - * - * @return bool - */ - public function rename($path, $newpath) { - if ($this->download($path)) { - return parent::rename($path, $newpath); - } - - return false; - } - - /** - * Copy a file. - * - * @param string $path - * @param string $newpath - * - * @return bool - */ - public function copy($path, $newpath) { - if ($this->download($path)) { - return parent::copy($path, $newpath); - } - - return false; - - } - - /** - * Delete a file. - * - * @param string $path - * - * @return bool - */ - public function delete($path) { - if ($this->download($path)) { - return parent::delete($path); - } - - return false; - } - - /** - * Set the visibility for a file. - * - * @param string $path - * @param string $visibility - * - * @return array|false file meta data - */ - public function setVisibility($path, $visibility) { - if ($this->download($path)) { - return parent::setVisibility($path, $visibility); - } - - return false; - } - - /** - * Check whether a file exists. - * - * @param string $path - * - * @return array|bool|null - */ - public function has($path) { - if (!parent::has($path)) { - return $this->storageAdapter->has($path); - } - - return true; - } - - /** - * Read a file. - * - * @param string $path - * - * @return array|false - */ - public function read($path) { - if ($this->download($path)) { - return parent::read($path); - } - - return false; - } - - /** - * Read a file as a stream. - * - * @param string $path - * - * @return array|false - */ - public function readStream($path) { - if ($this->download($path)) { - return parent::readStream($path); - } - - return false; - } - - /** - * Get all the meta data of a file or directory. - * - * @param string $path - * - * @return array|false - */ - public function getMetadata($path) { - if ($this->download($path)) { - return parent::getMetadata($path); - } - - return false; - } - - /** - * Get the size of a file. - * - * @param string $path - * - * @return array|false - */ - public function getSize($path) { - if ($this->download($path)) { - return parent::getSize($path); - } - - return false; - } - - /** - * Get the mimetype of a file. - * - * @param string $path - * - * @return array|false - */ - public function getMimetype($path) { - if ($this->download($path)) { - return parent::getMimetype($path); - } - - return false; - } - - /** - * Get the last modified time of a file as a timestamp. - * - * @param string $path - * - * @return array|false - */ - public function getTimestamp($path) { - if ($this->download($path)) { - return parent::getTimestamp($path); - } - - return false; - } - - /** - * Get the visibility of a file. - * - * @param string $path - * - * @return array|false - */ - public function getVisibility($path) { - if ($this->download($path)) { - return parent::getVisibility($path); - } - - return false; - } - -} \ No newline at end of file diff --git a/classes/Tools/Imgix/ImgixTool.php b/classes/Tools/Imgix/ImgixTool.php index fcb896c4..af8e816a 100755 --- a/classes/Tools/Imgix/ImgixTool.php +++ b/classes/Tools/Imgix/ImgixTool.php @@ -14,7 +14,7 @@ namespace ILAB\MediaCloud\Tools\Imgix; use FasterImage\FasterImage; -use ILAB\MediaCloud\Storage\StorageGlobals; +use ILAB\MediaCloud\Storage\StorageToolSettings; use ILAB\MediaCloud\Tools\DynamicImages\DynamicImagesTool; use ILAB\MediaCloud\Tools\Storage\StorageTool; use ILAB\MediaCloud\Tools\ToolsManager; @@ -38,15 +38,11 @@ * Imgix tool. */ class ImgixTool extends DynamicImagesTool implements ConfiguresWizard { - /** @var ImgixToolSettings */ - protected $settings; - - //region Constructor public function __construct($toolName, $toolInfo, $toolManager) { - parent::__construct($toolName, $toolInfo, $toolManager); + $this->settings = ImgixToolSettings::instance(); - $this->settings = new ImgixToolSettings(); + parent::__construct($toolName, $toolInfo, $toolManager); add_filter('media-cloud/imgix/enabled', function($enabled){ return $this->enabled(); @@ -313,8 +309,8 @@ public function buildSizedImage($id, $size) { } /** - * Builds an Imgix URL for an MPEG-4 video for an animated GIF source. This is called with apply_filter('imgix_build_gif_mpeg4'). - * + * Builds an Imgix URL for an MPEG-4 video for an animated GIF source. This is called with apply_filter('imgix_build_gif_mpeg4'). + * * @param mixed $value * @param int $postId * @param string $size @@ -352,8 +348,8 @@ public function buildSrcSetURL($post_id, $parentSize, $newSize) { } /** - * Builds an Imgix URL - * + * Builds an Imgix URL + * * @param int $id * @param string|array $size * @param array|null $params @@ -424,7 +420,17 @@ public function buildImage($id, $size, $params = null, $skipParams = false, $mer return null; } - $imageFile = (isset($meta['s3'])) ? $meta['s3']['key'] : $meta['file']; + if (!isset($meta['s3']['key']) && ($meta['s3']['provider'] == 'google')) { + $path = parse_url($meta['s3']['url'], PHP_URL_PATH); + $pathParts = explode('/', ltrim($path, '/')); + array_shift($pathParts); + $meta['s3']['key'] = $imageFile = ltrim(implode('/', $pathParts), '/'); + + update_post_meta($id, '_wp_attachment_metadata', $meta); + } else { + $imageFile = (isset($meta['s3']['key'])) ? $meta['s3']['key'] : $meta['file']; + } + $result = [ $imgix->createURL(str_replace('%2F', '/', urlencode($imageFile)), ($skipParams) ? [] : $params), @@ -643,7 +649,16 @@ public function buildImage($id, $size, $params = null, $skipParams = false, $mer $params = $this->buildImgixParams($params, $mimetype); $params = apply_filters('media-cloud/dynamic-images/filter-parameters', $params, $size, $id, $meta); - $imageFile = (isset($meta['s3'])) ? $meta['s3']['key'] : $meta['file']; + if (!isset($meta['s3']['key']) && ($meta['s3']['provider'] == 'google')) { + $path = parse_url($meta['s3']['url'], PHP_URL_PATH); + $pathParts = explode('/', ltrim($path, '/')); + array_shift($pathParts); + $meta['s3']['key'] = $imageFile = ltrim(implode('/', $pathParts), '/'); + + update_post_meta($id, '_wp_attachment_metadata', $meta); + } else { + $imageFile = (isset($meta['s3']['key'])) ? $meta['s3']['key'] : $meta['file']; + } $result = [ $imgix->createURL(str_replace('%2F', '/', urlencode($imageFile)), $params), @@ -695,7 +710,7 @@ public function processImageMeta($meta, $postID) { } if (!isset($meta['s3'])) { - Logger::warning( "Post $postID is missing 's3' metadata.", $meta); + Logger::warning( "Post $postID is missing 's3' metadata.", $meta, __METHOD__, __LINE__); return $meta; } @@ -1062,7 +1077,7 @@ public static function testImgix() { $errors = []; try { - $storageTool->client()->upload('_troubleshooter/sample.jpg',ILAB_TOOLS_DIR.'/public/img/test-image.jpg', StorageGlobals::privacy()); + $storageTool->client()->upload('_troubleshooter/sample.jpg',ILAB_TOOLS_DIR.'/public/img/test-image.jpg', StorageToolSettings::privacy()); $imgixURL = $imgixTool->urlForKey('_troubleshooter/sample.jpg'); $faster = new FasterImage(); diff --git a/classes/Tools/Imgix/ImgixToolSettings.php b/classes/Tools/Imgix/ImgixToolSettings.php index 142b4234..2f294481 100755 --- a/classes/Tools/Imgix/ImgixToolSettings.php +++ b/classes/Tools/Imgix/ImgixToolSettings.php @@ -13,7 +13,7 @@ namespace ILAB\MediaCloud\Tools\Imgix; -use ILAB\MediaCloud\Tools\ToolSettings; +use ILAB\MediaCloud\Tools\DynamicImages\DynamicImagesToolSettings; use ILAB\MediaCloud\Utilities\Environment; /** @@ -21,7 +21,6 @@ * @package ILAB\MediaCloud\Tools\Imgix * * @property string[] imgixDomains - * @property string signingKey * @property bool autoFormat * @property bool autoCompress * @property bool enableGifs @@ -32,13 +31,12 @@ * @property bool renderPDF * @property bool detectFaces * @property bool generateThumbnails - * @property float imageQuality */ -class ImgixToolSettings extends ToolSettings { +class ImgixToolSettings extends DynamicImagesToolSettings { private $_imgixDomains = null; private $_noGifSizes = null; - protected $settingsMap = [ + protected $imgixSettingsMap = [ 'autoFormat' => ['mcloud-imgix-auto-format', null, false], 'signingKey' => ['mcloud-imgix-signing-key', null, null], 'autoCompress' => ['mcloud-imgix-auto-compress', null, false], @@ -52,6 +50,10 @@ class ImgixToolSettings extends ToolSettings { 'imageQuality' => ['mcloud-imgix-default-quality', null, null], ]; + public function __construct() { + $this->settingsMap = array_merge($this->settingsMap, $this->imgixSettingsMap); + } + public function __get($name) { if ($name === 'imgixDomains') { if ($this->_imgixDomains === null) { @@ -71,7 +73,9 @@ public function __get($name) { } return $this->_imgixDomains; - } else if ($name === 'noGifSizes') { + } + + if ($name === 'noGifSizes') { if ($this->_noGifSizes === null) { $this->_noGifSizes = []; $noGifSizes = Environment::Option('mcloud-imgix-no-gif-sizes', null, ''); @@ -116,13 +120,11 @@ public function __set($name, $value) { } public function __isset($name) { - if ($name === 'imgixDomains') { - return true; - } else if ($name === 'noGifSizes') { + if (in_array($name, ['imgixDomains', 'noGifSizes', 'keepThumbnails'])) { return true; } - return parent::__isset($name); // TODO: Change the autogenerated stub + return parent::__isset($name); } -} \ No newline at end of file +} diff --git a/classes/Tools/MigrationsManager.php b/classes/Tools/MigrationsManager.php index 3fe5383b..2ac470ce 100755 --- a/classes/Tools/MigrationsManager.php +++ b/classes/Tools/MigrationsManager.php @@ -38,7 +38,7 @@ public function __construct() { if (file_exists($configFile)) { $this->config = include $configFile; } else { - Logger::warning("Could not find migrations config '$configFile'."); + Logger::warning("Could not find migrations config '$configFile'.", [], __METHOD__, __LINE__); } } @@ -58,7 +58,7 @@ public static function instance() { * Migrates all tools */ public function migrate($force = false) { - $lastVersion = get_option('mcloud_migration_last_version', null); + $lastVersion = Environment::Option('mcloud_migration_last_version', null, null); $processed = false; foreach($this->config as $version => $versionData) { @@ -78,15 +78,15 @@ public function migrate($force = false) { $this->processMigration($version, $versionData, false, false, false); - update_option('mcloud_migration_last_version', $version); + Environment::UpdateOption('mcloud_migration_last_version', $version); } if (!empty($this->deprecatedErrors)) { - update_option('mcloud_migration_deprecated_errors', $this->deprecatedErrors); + Environment::UpdateOption('mcloud_migration_deprecated_errors', $this->deprecatedErrors); } if (!$processed) { - $this->deprecatedErrors = get_option('mcloud_migration_deprecated_errors', []); + $this->deprecatedErrors = Environment::Option('mcloud_migration_deprecated_errors', null, []); if (!empty($this->deprecatedErrors)) { $this->deprecatedErrors = []; foreach($this->config as $version => $versionData) { @@ -94,7 +94,7 @@ public function migrate($force = false) { } if (empty($this->deprecatedErrors)) { - delete_option('mcloud_migration_deprecated_errors'); + Environment::DeleteOption('mcloud_migration_deprecated_errors'); } } } @@ -151,7 +151,7 @@ public function displayMigrationErrors() { return; } - $lastVersion = get_option('mcloud_migration_last_version', '3.0.0'); + $lastVersion = Environment::Option('mcloud_migration_last_version', null, '3.0.0'); $exist = []; foreach($this->deprecatedErrors as $oldEndVar => $newEnvVar) { diff --git a/classes/Tools/Mux/Data/MuxDatabase.php b/classes/Tools/Mux/Data/MuxDatabase.php new file mode 100755 index 00000000..6cdf397e --- /dev/null +++ b/classes/Tools/Mux/Data/MuxDatabase.php @@ -0,0 +1,138 @@ +base_prefix.'mcloud_mux_assets'; + $charset = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE {$tableName} ( + id BIGINT AUTO_INCREMENT, + muxId VARCHAR(255) NOT NULL, + status VARCHAR(32) NULL, + title VARCHAR(255) NULL, + attachmentId bigint NULL, + createdAt bigint NULL, + duration float NULL, + frameRate float NULL, + mp4Support int NOT NULL default 0, + width int NOT NULL default 0, + height int NOT NULL default 0, + aspectRatio VARCHAR(32) NULL, + jsonData text NULL, + PRIMARY KEY (id), + KEY status (status(32)), + KEY muxId (muxId(255)) +) {$charset};"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + + $exists = ($wpdb->get_var("SHOW TABLES LIKE '$tableName'") == $tableName); + if ($exists) { + update_site_option('mcloud_mux_assets_db_version', self::DB_VERSION); + } + } + + protected static function installPlaybackIDsTable() { + $currentVersion = get_site_option('mcloud_mux_playback_db_version'); + if (!empty($currentVersion) && version_compare(self::DB_VERSION, $currentVersion, '<=')) { + return; + } + + global $wpdb; + + $tableName = $wpdb->base_prefix.'mcloud_mux_playback'; + $charset = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE {$tableName} ( + id BIGINT AUTO_INCREMENT, + muxId VARCHAR(255) NOT NULL, + playbackId VARCHAR(255) NOT NULL, + policy VARCHAR(16) NOT NULL, + PRIMARY KEY (id), + KEY playbackId (playbackId(255)), + KEY policy (policy(16)), + KEY muxId (muxId(255)) +) {$charset};"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + + $exists = ($wpdb->get_var("SHOW TABLES LIKE '$tableName'") == $tableName); + if ($exists) { + update_site_option('mcloud_mux_playback_db_version', self::DB_VERSION); + } + } + + protected static function installRenditionsTable() { + $currentVersion = get_site_option('mcloud_mux_renditions_db_version'); + if (!empty($currentVersion) && version_compare(self::DB_VERSION, $currentVersion, '<=')) { + return; + } + + global $wpdb; + + $tableName = $wpdb->base_prefix.'mcloud_mux_renditions'; + $charset = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE {$tableName} ( + id BIGINT AUTO_INCREMENT, + muxId VARCHAR(255) NOT NULL, + rendition VARCHAR(16) NOT NULL, + width int null, + height int null, + bitrate int null, + filesize int null, + PRIMARY KEY (id), + KEY rendition (rendition(16)), + KEY muxId (muxId(255)) +) {$charset};"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + + $exists = ($wpdb->get_var("SHOW TABLES LIKE '$tableName'") == $tableName); + if ($exists) { + update_site_option('mcloud_mux_renditions_db_version', self::DB_VERSION); + } + } + //endregion +} \ No newline at end of file diff --git a/classes/Tools/Mux/Elementor/MuxVideoWidget.php b/classes/Tools/Mux/Elementor/MuxVideoWidget.php new file mode 100755 index 00000000..5776021c --- /dev/null +++ b/classes/Tools/Mux/Elementor/MuxVideoWidget.php @@ -0,0 +1,203 @@ +start_controls_section( 'content_section', [ + 'label' => 'Content', + 'tab' => Controls_Manager::TAB_CONTENT, + ] ); + $this->add_control( 'video', [ + 'label' => 'Video', + 'media_type' => 'video', + 'type' => Controls_Manager::MEDIA, + ] ); + $this->add_control( 'poster', [ + 'label' => 'Poster Image', + 'media_type' => 'image', + 'separator' => 'before', + 'type' => Controls_Manager::MEDIA, + ] ); + $this->add_control( 'autoplay', [ + 'label' => 'Auto Play', + 'type' => Controls_Manager::SWITCHER, + 'separator' => 'before', + ] ); + $this->add_control( 'loop', [ + 'label' => 'Loop', + 'type' => Controls_Manager::SWITCHER, + ] ); + $this->add_control( 'muted', [ + 'label' => 'Muted', + 'type' => Controls_Manager::SWITCHER, + ] ); + $this->add_control( 'playsinline', [ + 'label' => 'Play Inline', + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] ); + $this->add_control( 'controls', [ + 'label' => 'Show Controls', + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] ); + $this->add_control( 'preload', [ + 'label' => 'Preload', + 'type' => Controls_Manager::SELECT, + 'options' => [ + 'auto' => 'Auto', + 'metadata' => 'Metadata', + 'none' => 'None', + ], + 'default' => 'metadata', + ] ); + $this->end_controls_section(); + } + + private function renderEmpty( $message, $hasError = false ) + { + $classes = ( $hasError ? 'has-error' : '' ); + echo <<