first commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FTP/SFTP ADDON
|
||||
*
|
||||
* Name: Duplicator PRO base
|
||||
* Version: 1
|
||||
* Author: Duplicator
|
||||
* Author URI: https://duplicator.com/
|
||||
*
|
||||
* PHP version 5.3
|
||||
*
|
||||
* @category Duplicator
|
||||
* @package Plugin
|
||||
* @author Duplicator
|
||||
* @copyright 2011-2021 Snapcreek LLC
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
|
||||
* @version GIT: $Id$
|
||||
* @link https://duplicator.com/
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon;
|
||||
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\AmazonS3Storage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\AmazonS3CompatibleStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\BackblazeStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\CloudflareStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\DigitalOceanStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\DreamStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\GoogleCloudStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\VultrStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\WasabiStorage;
|
||||
use Duplicator\Addons\AmazonS3Addon\Utils\Autoloader;
|
||||
use Duplicator\Core\Addons\AbstractAddonCore;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
|
||||
/**
|
||||
* Storage ftp/sftp addon class
|
||||
*/
|
||||
class AmazonS3Addon extends AbstractAddonCore
|
||||
{
|
||||
const ADDON_PATH = __DIR__;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
Autoloader::register();
|
||||
|
||||
add_action('duplicator_pro_daily_actions', [__CLASS__, 'purgeOldS3MultipartUploads']);
|
||||
add_action('duplicator_pro_register_storage_types', [$this, 'registerStorages']);
|
||||
add_filter('duplicator_template_file', [__CLASS__, 'getTemplateFile'], 10, 2);
|
||||
add_filter('duplicator_usage_stats_storages_infos', [__CLASS__, 'getStorageUsageStats'], 10, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register storages
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function registerStorages()
|
||||
{
|
||||
AmazonS3Storage::registerType();
|
||||
AmazonS3CompatibleStorage::registerType();
|
||||
GoogleCloudStorage::registerType();
|
||||
BackblazeStorage::registerType();
|
||||
DreamStorage::registerType();
|
||||
DigitalOceanStorage::registerType();
|
||||
VultrStorage::registerType();
|
||||
CloudflareStorage::registerType();
|
||||
WasabiStorage::registerType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return template file path
|
||||
*
|
||||
* @param string $path path to the template file
|
||||
* @param string $slugTpl slug of the template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTemplateFile($path, $slugTpl)
|
||||
{
|
||||
if (strpos($slugTpl, 'amazons3addon/') === 0) {
|
||||
return self::getAddonPath() . '/template/' . $slugTpl . '.php';
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage usage stats
|
||||
*
|
||||
* @param array<string,int> $storageNums Storages num
|
||||
*
|
||||
* @return array<string,int>
|
||||
*/
|
||||
public static function getStorageUsageStats($storageNums)
|
||||
{
|
||||
if (($storages = AbstractStorageEntity::getAll()) === false) {
|
||||
$storages = [];
|
||||
}
|
||||
|
||||
$storageNums['storages_s3_count'] = 0;
|
||||
$storageNums['storages_s3_compatible_count'] = 0;
|
||||
|
||||
foreach ($storages as $index => $storage) {
|
||||
switch ($storage->getStype()) {
|
||||
case AmazonS3Storage::getSType():
|
||||
$storageNums['storages_s3_count']++;
|
||||
break;
|
||||
case AmazonS3CompatibleStorage::getSType():
|
||||
case GoogleCloudStorage::getSType():
|
||||
case BackblazeStorage::getSType():
|
||||
case DreamStorage::getSType():
|
||||
case DigitalOceanStorage::getSType():
|
||||
case VultrStorage::getSType():
|
||||
case CloudflareStorage::getSType():
|
||||
case WasabiStorage::getSType():
|
||||
$storageNums['storages_s3_compatible_count']++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $storageNums;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Purge old S3 multipart uploads
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function purgeOldS3MultipartUploads()
|
||||
{
|
||||
if (($storages = AbstractStorageEntity::getAll()) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($storages as $storage) {
|
||||
if (!$storage instanceof \Duplicator\Addons\AmazonS3Addon\Models\AmazonS3Storage) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$storage->purgeMultipartUpload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getAddonPath()
|
||||
{
|
||||
return __DIR__;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getAddonFile()
|
||||
{
|
||||
return __FILE__;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
use Duplicator\Libs\Snap\SnapUtil;
|
||||
|
||||
class AmazonS3CompatibleStorage extends AmazonS3Storage
|
||||
{
|
||||
/**
|
||||
* Get default config
|
||||
*
|
||||
* @return array<string,scalar>
|
||||
*/
|
||||
protected static function getDefaultConfig()
|
||||
{
|
||||
$config = parent::getDefaultConfig();
|
||||
$config = array_merge($config, ['ACL_full_control' => false]);
|
||||
return $config;
|
||||
}
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Amazon S3 Compatible', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an html anchor tag of location or a string
|
||||
*
|
||||
* @return string Returns an html anchor tag with the storage location as a hyperlink or just a plain string
|
||||
*/
|
||||
public function getHtmlLocationLink()
|
||||
{
|
||||
if (preg_match('/^http(s)?:\\/\\//i', $this->getLocationString())) {
|
||||
return '<a href="' . esc_url($this->getLocationString()) . '" target="_blank" >' . esc_html($this->getLocationLabel()) . '</a>';
|
||||
} else {
|
||||
return '<span>' . esc_html($this->getLocationString()) . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return '/' . $this->config['bucket'] . $this->getStorageFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return '/' . $this->config['bucket'] . $this->getStorageFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of S3 compatible providers
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getCompatibleProviders()
|
||||
{
|
||||
return array(
|
||||
'Aruba',
|
||||
'Cloudian',
|
||||
'Cloudn',
|
||||
'Connectria',
|
||||
'Constant',
|
||||
'Exoscal',
|
||||
'Eucalyptus',
|
||||
'Nifty',
|
||||
'Nimbula',
|
||||
'Minio',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get priority, used to sort storages.
|
||||
* 100 is neutral value, 0 is the highest priority
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getPriority()
|
||||
{
|
||||
return 160;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render form config fields
|
||||
*
|
||||
* @param bool $echo Echo or return
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderConfigFields($echo = true)
|
||||
{
|
||||
return TplMng::getInstance()->render(
|
||||
'amazons3addon/configs/all_s3_compatible',
|
||||
[
|
||||
'storage' => $this,
|
||||
'maxPackages' => $this->config['max_packages'],
|
||||
'storageFolder' => $this->config['storage_folder'],
|
||||
'accessKey' => $this->config['access_key'],
|
||||
'bucket' => $this->config['bucket'],
|
||||
'region' => $this->config['region'],
|
||||
'endpoint' => $this->config['endpoint'],
|
||||
'secretKey' => $this->config['secret_key'],
|
||||
'storageClass' => $this->config['storage_class'],
|
||||
'aclFullControl' => $this->config['ACL_full_control'],
|
||||
'isAutofillEndpoint' => $this->isAutofillEndpoint(),
|
||||
'isAutofillRegion' => $this->isAutofillRegion(),
|
||||
'isAclSupported' => $this->isACLSupported(),
|
||||
'aclDescription' => $this->getACLDescription(),
|
||||
'documentationLinks' => $this->getDocumentationLinks(),
|
||||
],
|
||||
$echo
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('S3 Compatibility API', 'duplicator-pro'),
|
||||
'url' => 'https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the endpoint is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAutofillEndpoint()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the region is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isAutofillRegion()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the ACL is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isACLSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACL description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getACLDescription()
|
||||
{
|
||||
return __(
|
||||
"This option only works if the storage provider supports the 'bucket-owner-full-control' object-level canned ACL.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data from http request, this method don't save data, just update object properties
|
||||
*
|
||||
* @param string $message Message
|
||||
*
|
||||
* @return bool True if success and all data is valid, false otherwise
|
||||
*/
|
||||
public function updateFromHttpRequest(&$message = '')
|
||||
{
|
||||
if ((parent::updateFromHttpRequest($message) === false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->config['endpoint'] = SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 's3_endpoint');
|
||||
$this->config['ACL_full_control'] = $this->isACLSupported() ?
|
||||
SnapUtil::sanitizeBoolInput(SnapUtil::INPUT_REQUEST, 's3_ACL_full_control') : false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register storage type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function registerType()
|
||||
{
|
||||
parent::registerType();
|
||||
|
||||
if (self::class === static::class) {
|
||||
// only add filter for current storage and not inherited
|
||||
add_filter('duplicator_pro_storage_type_class', function ($class, $type, $data) {
|
||||
if ($type == AmazonS3Storage::getSType()) {
|
||||
$isLegacy = (!isset($data['legacyEntity']) || $data['legacyEntity'] === true);
|
||||
$provider = (isset($data['s3_provider']) ? $data['s3_provider'] : '');
|
||||
if ($isLegacy && $provider == 'other') {
|
||||
$class = __CLASS__;
|
||||
}
|
||||
}
|
||||
return $class;
|
||||
}, 10, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,538 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
use DUP_PRO_Global_Entity;
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
use Duplicator\Libs\Snap\SnapUtil;
|
||||
use Duplicator\Models\DynamicGlobalEntity;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Exception;
|
||||
|
||||
class AmazonS3Storage extends AbstractStorageEntity
|
||||
{
|
||||
/** @var int */
|
||||
const DEFAULT_UPLOAD_CHUNK_SIZE_IN_KB = 6000;
|
||||
/** @var int */
|
||||
const UPLOAD_CHUNK_MIN_SIZE_IN_KB = 5 * 1024;
|
||||
|
||||
/**
|
||||
* Get default config
|
||||
*
|
||||
* @return array<string,scalar>
|
||||
*/
|
||||
protected static function getDefaultConfig()
|
||||
{
|
||||
$config = parent::getDefaultConfig();
|
||||
$config = array_merge(
|
||||
$config,
|
||||
[
|
||||
'access_key' => '',
|
||||
'bucket' => '',
|
||||
'region' => '',
|
||||
'endpoint' => '',
|
||||
'secret_key' => '',
|
||||
'storage_class' => 'STANDARD',
|
||||
'ACL_full_control' => true,
|
||||
]
|
||||
);
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field label
|
||||
*
|
||||
* @param string $field Field name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFieldLabel($field)
|
||||
{
|
||||
switch ($field) {
|
||||
case 'accessKey':
|
||||
return __('Access Key', 'duplicator-pro');
|
||||
case 'secretKey':
|
||||
return __('Secret Key', 'duplicator-pro');
|
||||
case 'region':
|
||||
return __('Region', 'duplicator-pro');
|
||||
case 'endpoint':
|
||||
return __('Endpoint', 'duplicator-pro');
|
||||
case 'bucket':
|
||||
return __('Bucket', 'duplicator-pro');
|
||||
case 'aclFullControl':
|
||||
return __('Additional Settings', 'duplicator-pro');
|
||||
default:
|
||||
throw new Exception("Unknown field: $field");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize
|
||||
*
|
||||
* Wakeup method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
parent::__wakeup();
|
||||
|
||||
if ($this->legacyEntity) {
|
||||
// Old storage entity
|
||||
$this->legacyEntity = false;
|
||||
// Make sure the storage type is right from the old entity
|
||||
$this->storage_type = $this->getSType();
|
||||
$this->config = [
|
||||
'storage_folder' => $this->s3_storage_folder,
|
||||
'max_packages' => $this->s3_max_files,
|
||||
'access_key' => $this->s3_access_key,
|
||||
'bucket' => $this->s3_bucket,
|
||||
'region' => $this->s3_region,
|
||||
'endpoint' => $this->s3_endpoint,
|
||||
'secret_key' => $this->s3_secret_key,
|
||||
'storage_class' => $this->s3_storage_class,
|
||||
'ACL_full_control' => $this->s3_ACL_full_control,
|
||||
];
|
||||
// reset old values
|
||||
$this->s3_storage_folder = '';
|
||||
$this->s3_max_files = 10;
|
||||
$this->s3_access_key = '';
|
||||
$this->s3_bucket = '';
|
||||
$this->s3_provider = 'amazon';
|
||||
$this->s3_region = '';
|
||||
$this->s3_endpoint = '';
|
||||
$this->s3_secret_key = '';
|
||||
$this->s3_storage_class = 'STANDARD';
|
||||
$this->s3_ACL_full_control = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon.
|
||||
*
|
||||
* @return string Returns the icon
|
||||
*/
|
||||
public static function getStypeIcon()
|
||||
{
|
||||
return '<img src="' . esc_url(static::getIconUrl()) . '" class="dup-storage-icon" alt="' . esc_attr(static::getStypeName()) . '" />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/aws.svg';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Amazon S3', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get priority, used to sort storages.
|
||||
* 100 is neutral value, 0 is the highest priority
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getPriority()
|
||||
{
|
||||
return 150;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
$params = [
|
||||
'region' => $this->config['region'],
|
||||
'bucket' => $this->config['bucket'],
|
||||
'prefix' => $this->getStorageFolder(),
|
||||
];
|
||||
|
||||
return 'https://console.aws.amazon.com/s3/home' . '?' . http_build_query($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an html anchor tag of location
|
||||
*
|
||||
* @return string Returns an html anchor tag with the storage location as a hyperlink.
|
||||
*
|
||||
* @example
|
||||
* OneDrive Example return
|
||||
* <a target="_blank" href="https://1drv.ms/f/sAFrQtasdrewasyghg">https://1drv.ms/f/sAFrQtasdrewasyghg</a>
|
||||
*/
|
||||
public function getHtmlLocationLink()
|
||||
{
|
||||
return '<a href="' . esc_url($this->getLocationString()) . '" target="_blank" >' . esc_html($this->getLocationLabel()) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return 's3://' . $this->config['bucket'] . $this->getStorageFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if storage is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return SnapUtil::isCurlEnabled(true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get supported notice, displayed if storage isn't supported
|
||||
*
|
||||
* @return string html string or empty if storage is supported
|
||||
*/
|
||||
public static function getNotSupportedNotice()
|
||||
{
|
||||
if (static::isSupported()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!SnapUtil::isCurlEnabled()) {
|
||||
$result = sprintf(
|
||||
__(
|
||||
"The Storage %s requires the PHP cURL extension and related functions to be enabled.",
|
||||
'duplicator-pro'
|
||||
),
|
||||
static::getStypeName()
|
||||
);
|
||||
} elseif (!SnapUtil::isCurlEnabled(true, true)) {
|
||||
$result = sprintf(
|
||||
__(
|
||||
"The Storage %s requires 'curl_multi_' type functions to be enabled. One or more are disabled on your server.",
|
||||
'duplicator-pro'
|
||||
),
|
||||
static::getStypeName()
|
||||
);
|
||||
} else {
|
||||
$result = sprintf(
|
||||
__(
|
||||
'The Storage %s is not supported on this server.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
static::getStypeName()
|
||||
);
|
||||
}
|
||||
|
||||
return esc_html($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if storage is valid
|
||||
*
|
||||
* @return bool Return true if storage is valid and ready to use, false otherwise
|
||||
*/
|
||||
public function isValid()
|
||||
{
|
||||
return $this->getAdapter()->isValid();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get action key text
|
||||
*
|
||||
* @param string $key Key name (action, pending, failed, cancelled, success)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getActionKeyText($key)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'action':
|
||||
return sprintf(
|
||||
__('Transferring to %1$s folder:<br/> <i>%2$s</i>', "duplicator-pro"),
|
||||
$this->getStypeName(),
|
||||
$this->getStorageFolder()
|
||||
);
|
||||
case 'pending':
|
||||
return sprintf(
|
||||
__('Transfer to %1$s folder %2$s is pending', "duplicator-pro"),
|
||||
$this->getStypeName(),
|
||||
$this->getStorageFolder()
|
||||
);
|
||||
case 'failed':
|
||||
return sprintf(
|
||||
__('Failed to transfer to %1$s folder %2$s', "duplicator-pro"),
|
||||
$this->getStypeName(),
|
||||
$this->getStorageFolder()
|
||||
);
|
||||
case 'cancelled':
|
||||
return sprintf(
|
||||
__('Cancelled before could transfer to %1$s folder %2$s', "duplicator-pro"),
|
||||
$this->getStypeName(),
|
||||
$this->getStorageFolder()
|
||||
);
|
||||
case 'success':
|
||||
return sprintf(
|
||||
__('Transferred package to %1$s folder %2$s', "duplicator-pro"),
|
||||
$this->getStypeName(),
|
||||
$this->getStorageFolder()
|
||||
);
|
||||
default:
|
||||
throw new Exception('Invalid key');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render form config fields
|
||||
*
|
||||
* @param bool $echo Echo or return
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderConfigFields($echo = true)
|
||||
{
|
||||
return TplMng::getInstance()->render(
|
||||
'amazons3addon/configs/amazon_s3',
|
||||
[
|
||||
'storage' => $this,
|
||||
'maxPackages' => $this->config['max_packages'],
|
||||
'storageFolder' => $this->config['storage_folder'],
|
||||
'accessKey' => $this->config['access_key'],
|
||||
'bucket' => $this->config['bucket'],
|
||||
'region' => $this->config['region'],
|
||||
'endpoint' => $this->config['endpoint'],
|
||||
'secretKey' => $this->config['secret_key'],
|
||||
'storageClass' => $this->config['storage_class'],
|
||||
'aclFullControl' => $this->config['ACL_full_control'],
|
||||
'regionOptions' => self::regionOptions(),
|
||||
],
|
||||
$echo
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update data from http request, this method don't save data, just update object properties
|
||||
*
|
||||
* @param string $message Message
|
||||
*
|
||||
* @return bool True if success and all data is valid, false otherwise
|
||||
*/
|
||||
public function updateFromHttpRequest(&$message = '')
|
||||
{
|
||||
if ((parent::updateFromHttpRequest($message) === false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->config['max_packages'] = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 's3_max_files', 10);
|
||||
$this->config['storage_folder'] = self::getSanitizedInputFolder('_s3_storage_folder');
|
||||
|
||||
$this->config['access_key'] = SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 's3_access_key');
|
||||
$secretKey = SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 's3_secret_key');
|
||||
if (strlen($secretKey) > 0) {
|
||||
$this->config['secret_key'] = $secretKey;
|
||||
}
|
||||
$this->config['region'] = SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 's3_region');
|
||||
$this->config['storage_class'] = SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 's3_storage_class');
|
||||
$this->config['bucket'] = SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 's3_bucket');
|
||||
|
||||
|
||||
$message = sprintf(
|
||||
__('Storage Updated.', 'duplicator-pro'),
|
||||
$this->config['server'],
|
||||
$this->getStorageFolder()
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full s3 client
|
||||
*
|
||||
* @return S3StorageAdapter
|
||||
*/
|
||||
protected function getAdapter()
|
||||
{
|
||||
$global = DUP_PRO_Global_Entity::getInstance();
|
||||
return new S3StorageAdapter(
|
||||
$this->config['access_key'],
|
||||
$this->config['secret_key'],
|
||||
$this->config['region'],
|
||||
$this->config['bucket'],
|
||||
$this->config['storage_folder'],
|
||||
$this->config['endpoint'],
|
||||
$this->config['storage_class'],
|
||||
$global->ipv4_only,
|
||||
!$global->ssl_disableverify,
|
||||
($global->ssl_useservercerts ? '' : DUPLICATOR_PRO_CERT_PATH),
|
||||
$this->config['ACL_full_control']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value => label pairs for region drop-down options for S3 Amazon Direct storage type
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected static function regionOptions()
|
||||
{
|
||||
return array(
|
||||
"us-east-1" => __("US East (N. Virginia)", 'duplicator-pro'),
|
||||
"us-east-2" => __("US East (Ohio)", 'duplicator-pro'),
|
||||
"us-west-1" => __("US West (N. California)", 'duplicator-pro'),
|
||||
"us-west-2" => __("US West (Oregon)", 'duplicator-pro'),
|
||||
"af-south-1" => __("Africa (Cape Town)", 'duplicator-pro'),
|
||||
"ap-east-1" => __("Asia Pacific (Hong Kong)", 'duplicator-pro'),
|
||||
"ap-south-1" => __("Asia Pacific (Mumbai)", 'duplicator-pro'),
|
||||
"ap-northeast-1" => __("Asia Pacific (Tokyo)", 'duplicator-pro'),
|
||||
"ap-northeast-2" => __("Asia Pacific (Seoul)", 'duplicator-pro'),
|
||||
"ap-northeast-3" => __("Asia Pacific (Osaka-Local)", 'duplicator-pro'),
|
||||
"ap-southeast-1" => __("Asia Pacific (Singapore)", 'duplicator-pro'),
|
||||
"ap-southeast-2" => __("Asia Pacific (Sydney)", 'duplicator-pro'),
|
||||
"ap-southeast-3" => __("Asia Pacific (Jakarta)", 'duplicator-pro'),
|
||||
"ca-central-1" => __("Canada (Central)", 'duplicator-pro'),
|
||||
"cn-north-1" => __("China (Beijing)", 'duplicator-pro'),
|
||||
"cn-northwest-1" => __("China (Ningxia)", 'duplicator-pro'),
|
||||
"eu-central-1" => __("EU (Frankfurt)", 'duplicator-pro'),
|
||||
"eu-west-1" => __("EU (Ireland)", 'duplicator-pro'),
|
||||
"eu-west-2" => __("EU (London)", 'duplicator-pro'),
|
||||
"eu-west-3" => __("EU (Paris)", 'duplicator-pro'),
|
||||
"eu-south-1" => __("Europe (Milan)", 'duplicator-pro'),
|
||||
"eu-north-1" => __("Europe (Stockholm)", 'duplicator-pro'),
|
||||
"me-south-1" => __("Middle East (Bahrain)", 'duplicator-pro'),
|
||||
"sa-east-1" => __("South America (Sao Paulo)", 'duplicator-pro'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register storage type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function registerType()
|
||||
{
|
||||
parent::registerType();
|
||||
|
||||
add_action('duplicator_update_global_storage_settings', function () {
|
||||
$dGlobal = DynamicGlobalEntity::getInstance();
|
||||
|
||||
foreach (static::getDefaultSettings() as $key => $default) {
|
||||
$value = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, $key, $default);
|
||||
$dGlobal->setVal($key, $value);
|
||||
}
|
||||
$dGlobal->save();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upload chunk size in bytes
|
||||
*
|
||||
* @return int bytes
|
||||
*/
|
||||
public function getUploadChunkSize()
|
||||
{
|
||||
$dGlobal = DynamicGlobalEntity::getInstance();
|
||||
return $dGlobal->getVal('s3_upload_part_size_in_kb', self::DEFAULT_UPLOAD_CHUNK_SIZE_IN_KB) * 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upload chunk timeout in seconds
|
||||
*
|
||||
* @return int timeout in microseconds, 0 unlimited
|
||||
*/
|
||||
public function getUploadChunkTimeout()
|
||||
{
|
||||
$global = DUP_PRO_Global_Entity::getInstance();
|
||||
return (int) ($global->php_max_worker_time_in_sec <= 0 ? 0 : $global->php_max_worker_time_in_sec * SECONDS_IN_MICROSECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default settings
|
||||
*
|
||||
* @return array<string, scalar>
|
||||
*/
|
||||
protected static function getDefaultSettings()
|
||||
{
|
||||
return ['s3_upload_part_size_in_kb' => 6000];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function renderGlobalOptions()
|
||||
{
|
||||
if (self::class !== static::class) {
|
||||
return;
|
||||
}
|
||||
$values = static::getDefaultSettings();
|
||||
$dGlobal = DynamicGlobalEntity::getInstance();
|
||||
foreach ($values as $key => $default) {
|
||||
$values[$key] = $dGlobal->getVal($key, $default);
|
||||
}
|
||||
?>
|
||||
<h3 class="title"><?php esc_html_e("Amazon S3", 'duplicator-pro') ?></h3>
|
||||
<hr size="1" />
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><label><?php esc_html_e("Upload Chunk Size", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<input
|
||||
class="dup-narrow-input text-right"
|
||||
name="s3_upload_part_size_in_kb"
|
||||
id="s3_upload_part_size_in_kb"
|
||||
type="number"
|
||||
min="<?php echo self::UPLOAD_CHUNK_MIN_SIZE_IN_KB; ?>"
|
||||
max="5243000"
|
||||
data-parsley-required
|
||||
data-parsley-type="number"
|
||||
data-parsley-errors-container="#s3_upload_chunksize_in_kb_error_container"
|
||||
value="<?php echo $values['s3_upload_part_size_in_kb']; ?>"
|
||||
> <b>KB</b>
|
||||
<div id="s3_upload_chunksize_in_kb_error_container" class="duplicator-error-container"></div>
|
||||
<p class="description">
|
||||
<?php esc_html_e('How much should be uploaded to Amazon S3 per attempt. Higher=faster but less reliable.', 'duplicator-pro'); ?>
|
||||
<?php echo esc_html(sprintf(__('Min size %skb.', 'duplicator-pro'), self::UPLOAD_CHUNK_MIN_SIZE_IN_KB)); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge old multipart uploads
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function purgeMultipartUpload()
|
||||
{
|
||||
$this->getAdapter()->abortMultipartUploads(2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class BackblazeStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Get default config
|
||||
*
|
||||
* @return array<string,scalar>
|
||||
*/
|
||||
protected static function getDefaultConfig()
|
||||
{
|
||||
$config = parent::getDefaultConfig();
|
||||
$config['ACL_full_control'] = false;
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return 'https://secure.backblaze.com/b2_buckets.htm';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return __('Bucket List', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Backblaze B2', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get priority, used to sort storages.
|
||||
* 100 is neutral value, 0 is the highest priority
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getPriority()
|
||||
{
|
||||
return 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/backblaze.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Overview', 'duplicator-pro'),
|
||||
'url' => 'https://www.backblaze.com/b2/docs/',
|
||||
],
|
||||
[
|
||||
'label' => __('S3 Compatible API', 'duplicator-pro'),
|
||||
'url' => 'https://www.backblze.com/b2/docs/s3_compatible_api.html',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field label
|
||||
*
|
||||
* @param string $field Field name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFieldLabel($field)
|
||||
{
|
||||
switch ($field) {
|
||||
case 'accessKey':
|
||||
return __('Key ID', 'duplicator-pro');
|
||||
case 'secretKey':
|
||||
return __('Application Key', 'duplicator-pro');
|
||||
}
|
||||
return parent::getFieldLabel($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if ACL is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isACLSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the region is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutofillRegion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register storage type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function registerType()
|
||||
{
|
||||
parent::registerType();
|
||||
add_filter('duplicator_pro_storage_type_class', function ($class, $type, $data) {
|
||||
if ($type == AmazonS3Storage::getSType()) {
|
||||
$isLegacy = (!isset($data['legacyEntity']) || $data['legacyEntity'] === true);
|
||||
$provider = (isset($data['s3_provider']) ? $data['s3_provider'] : '');
|
||||
if ($isLegacy && $provider == 'backblaze') {
|
||||
$class = __CLASS__;
|
||||
}
|
||||
}
|
||||
return $class;
|
||||
}, 10, 3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class CloudflareStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Cloudflare R2', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return 'https://dash.cloudflare.com/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return __('Dashboard', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/cloudflare.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the ACL is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isACLSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Overview', 'duplicator-pro'),
|
||||
'url' => 'https://developers.cloudflare.com/r2/',
|
||||
],
|
||||
[
|
||||
'label' => __('S3 Compatible API', 'duplicator-pro'),
|
||||
'url' => 'https://developers.cloudflare.com/r2/api/s3/api/',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class DigitalOceanStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 14;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Digital Ocean Spaces', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the region is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutofillRegion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the ACL is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isACLSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/digital-ocean.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return 'https://cloud.digitalocean.com/spaces/' . $this->config['bucket'] . $this->config['storage_folder'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Spaces Object Storage', 'duplicator-pro'),
|
||||
'url' => 'https://docs.digitalocean.com/products/spaces/',
|
||||
],
|
||||
[
|
||||
'label' => __('Spaces API', 'duplicator-pro'),
|
||||
'url' => 'https://docs.digitalocean.com/reference/api/spaces-api/',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class DreamStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Dream Objects', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/dreamhost.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the region is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutofillRegion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the ACL is supported
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isACLSupported()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return 'https://panel.dreamhost.com/index.cgi?tree=cloud.objects';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return __('Bucket List', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Overview', 'duplicator-pro'),
|
||||
'url' => 'https://help.dreamhost.com/hc/en-us/articles/214823108-DreamObjects-overview',
|
||||
],
|
||||
[
|
||||
'label' => __('S3 Compatible API', 'duplicator-pro'),
|
||||
'url' => 'https://help.dreamhost.com/hc/en-us/articles/217590537-How-To-Use-DreamObjects-S3-compatible-API',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class GoogleCloudStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Google Cloud Storage', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return 'https://console.cloud.google.com/storage/browser/' . $this->config['bucket'] . $this->config['storage_folder'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/google-cloud.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACL description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getACLDescription()
|
||||
{
|
||||
return __(
|
||||
"Make sure to change the 'Access Control' to 'Fine Grained' for this setting to work.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Interoperability with S3 API', 'duplicator-pro'),
|
||||
'url' => 'https://cloud.google.com/storage/docs/interoperability',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class VultrStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Vultr', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/vultr.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the region is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutofillRegion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationString()
|
||||
{
|
||||
return 'https://my.vultr.com/objectstorage/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return __('Bucket List', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Vultr Object Storage', 'duplicator-pro'),
|
||||
'url' => 'https://www.vultr.com/docs/vultr-object-storage/',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Models;
|
||||
|
||||
class WasabiStorage extends AmazonS3CompatibleStorage
|
||||
{
|
||||
/**
|
||||
* Return the storage type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getSType()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getStypeName()
|
||||
{
|
||||
return __('Wasabi', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage type icon url.
|
||||
*
|
||||
* @return string The icon url
|
||||
*/
|
||||
protected static function getIconUrl()
|
||||
{
|
||||
return DUPLICATOR_PRO_IMG_URL . '/wasabi.svg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the endpoint is generated automatically
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutofillEndpoint()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get storage location string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocationURL()
|
||||
{
|
||||
return 'https://console.wasabisys.com/file_manager/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the storage location label.
|
||||
*
|
||||
* @return string The storage location label
|
||||
*/
|
||||
protected function getLocationLabel()
|
||||
{
|
||||
return __('Bucket List', 'duplicator-pro');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation links
|
||||
*
|
||||
* @return array<int,array<string,string>>
|
||||
*/
|
||||
protected static function getDocumentationLinks()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'label' => __('Wasabi Academy', 'duplicator-pro'),
|
||||
'url' => 'https://docs.wasabi.com/',
|
||||
],
|
||||
[
|
||||
'label' => __('S3 Compatible API', 'duplicator-pro'),
|
||||
'url' => 'https://docs.wasabi.com/docs/wasabi-api',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Auloader calsses
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
namespace Duplicator\Addons\AmazonS3Addon\Utils;
|
||||
|
||||
use Duplicator\Addons\AmazonS3Addon\AmazonS3Addon;
|
||||
use Duplicator\Utils\AbstractAutoloader;
|
||||
|
||||
/**
|
||||
* Autoloader calss, dont user Duplicator library here
|
||||
*/
|
||||
final class Autoloader extends AbstractAutoloader
|
||||
{
|
||||
const VENDOR_PATH = AmazonS3Addon::ADDON_PATH . '/vendor-prefixed/';
|
||||
|
||||
/**
|
||||
* Register autoloader function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register()
|
||||
{
|
||||
spl_autoload_register([__CLASS__, 'load']);
|
||||
|
||||
self::loadFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load class
|
||||
*
|
||||
* @param string $className class name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function load($className)
|
||||
{
|
||||
foreach (self::getNamespacesVendorMapping() as $namespace => $mappedPath) {
|
||||
if (strpos($className, $namespace) !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filepath = self::getFilenameFromClass($className, $namespace, $mappedPath);
|
||||
if (file_exists($filepath)) {
|
||||
include $filepath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load necessary files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function loadFiles()
|
||||
{
|
||||
$files = [
|
||||
'/paragonie/random_compat/lib/random.php',
|
||||
'/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'/guzzlehttp/promises/src/functions_include.php',
|
||||
'/guzzlehttp/psr7/src/functions_include.php',
|
||||
'/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'/symfony/polyfill-php70/bootstrap.php',
|
||||
'/symfony/polyfill-php72/bootstrap.php',
|
||||
'/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'/mtdowling/jmespath.php/src/JmesPath.php',
|
||||
'/aws/aws-sdk-php/src/functions.php',
|
||||
];
|
||||
|
||||
foreach ($files as $file) {
|
||||
require_once self::VENDOR_PATH . $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return namespace mapping
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected static function getNamespacesVendorMapping()
|
||||
{
|
||||
return [
|
||||
self::ROOT_VENDOR . 'Symfony\\Polyfill\\Intl\\Idn' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/symfony/polyfill-intl-idn',
|
||||
self::ROOT_VENDOR . 'Symfony\\Polyfill\\Intl\\Normalizer' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/symfony/polyfill-intl-normalizer',
|
||||
self::ROOT_VENDOR . 'Symfony\\Polyfill\\Mbstring' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/symfony/polyfill-mbstring',
|
||||
self::ROOT_VENDOR . 'Symfony\\Polyfill\\Php70' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/symfony/polyfill-php70',
|
||||
self::ROOT_VENDOR . 'Symfony\\Polyfill\\Php72' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/symfony/polyfill-php72',
|
||||
self::ROOT_VENDOR . 'JmesPath' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/mtdowling/jmespath.php/src',
|
||||
self::ROOT_VENDOR . 'Psr\\Http\\Message' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/psr/http-message/src',
|
||||
self::ROOT_VENDOR . 'GuzzleHttp\\Promise' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/guzzlehttp/promises/src',
|
||||
self::ROOT_VENDOR . 'GuzzleHttp\\Psr7' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/guzzlehttp/psr7/src',
|
||||
self::ROOT_VENDOR . 'GuzzleHttp' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/guzzlehttp/guzzle/src',
|
||||
self::ROOT_VENDOR . 'Aws' => AmazonS3Addon::getAddonPath() . '/vendor-prefixed/aws/aws-sdk-php/src',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\AmazonS3CompatibleStorage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AmazonS3CompatibleStorage $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var int */
|
||||
$maxPackages = $tplData["maxPackages"];
|
||||
/** @var string */
|
||||
$storageFolder = $tplData["storageFolder"];
|
||||
/** @var string */
|
||||
$accessKey = $tplData["accessKey"];
|
||||
/** @var string */
|
||||
$bucket = $tplData["bucket"];
|
||||
/** @var string */
|
||||
$region = $tplData["region"];
|
||||
/** @var string */
|
||||
$secretKey = $tplData["secretKey"];
|
||||
/** @var string */
|
||||
$storageClass = $tplData["storageClass"];
|
||||
/** @var string */
|
||||
$endpoint = $tplData["endpoint"];
|
||||
/** @var string */
|
||||
$aclFullControl = $tplData["aclFullControl"];
|
||||
/** @var bool */
|
||||
$isAutofillEndpoint = $tplData["isAutofillEndpoint"];
|
||||
/** @var bool */
|
||||
$isAutofillRegion = $tplData["isAutofillRegion"];
|
||||
/** @var bool */
|
||||
$isAclSupported = $tplData["isAclSupported"];
|
||||
/** @var string */
|
||||
$aclDescription = $tplData["aclDescription"];
|
||||
/** @var array<int,array<string,string>> */
|
||||
$documentationLinks = $tplData["documentationLinks"];
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/provider_head');
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="2" style="padding-left:0">
|
||||
<i><?php printf(
|
||||
esc_html_x(
|
||||
'S3 Setup Guide: %1$sStep-by-Step%2$s and %3$sUser Bucket Policy%4$s.',
|
||||
'1%$s and %3$s are opening and %2$s and %4$s are closing <a> tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'amazon-s3-step-by-step') . '">',
|
||||
'</a>',
|
||||
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'amazon-s3-policy-setup') . '" target="_blank">',
|
||||
'</a>'
|
||||
); ?>
|
||||
</i>
|
||||
<i>
|
||||
<?php if (count($documentationLinks) > 0) {
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Documentation for %s: ',
|
||||
'%s is the provider name',
|
||||
'duplicator-pro'
|
||||
),
|
||||
esc_html($storage->getStypeName())
|
||||
);
|
||||
|
||||
echo implode(', ', array_map(function ($link) {
|
||||
return '<a target="_blank" href="' . $link['url'] . '">' . $link['label'] . '</a>';
|
||||
}, $documentationLinks));
|
||||
} ?>
|
||||
</i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for=""><?php esc_html_e("Authorization", 'duplicator-pro'); ?></label></th>
|
||||
<td class="dup-s3-auth-account">
|
||||
<h3>
|
||||
<?php
|
||||
if ($storage->getId() < 0) {
|
||||
echo $storage->getStypeIcon();
|
||||
}
|
||||
?>
|
||||
<?php echo esc_html($storage->getStypeName()) . ' ' . esc_html__('Account', 'duplicator-pro'); ?>
|
||||
</h3>
|
||||
<?php if ($storage->getSType() === AmazonS3CompatibleStorage::getSType()) {
|
||||
$tplMng->render('amazons3addon/parts/s3_compatible_msg');
|
||||
} ?>
|
||||
<table class="dup-form-sub-area margin-top-1">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="s3_access_key_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php echo esc_html($storage->getFieldLabel('accessKey')); ?>:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
id="s3_access_key_<?php echo (int) $storage->getSType(); ?>"
|
||||
name="s3_access_key"
|
||||
data-parsley-errors-container="#s3_access_key_<?php echo (int) $storage->getSType(); ?>_error_container"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
value="<?php echo esc_attr($accessKey); ?>"
|
||||
data-parsley-required="true"
|
||||
>
|
||||
<div id="s3_access_key_<?php echo (int) $storage->getSType(); ?>_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="s3_secret_key_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php echo esc_html($storage->getFieldLabel('secretKey')); ?>:
|
||||
</label>
|
||||
</th>
|
||||
|
||||
<td>
|
||||
<input
|
||||
id="s3_secret_key_<?php echo (int) $storage->getSType(); ?>"
|
||||
name="s3_secret_key"
|
||||
type="password"
|
||||
placeholder="<?php echo esc_attr(str_repeat("*", strlen($secretKey))); ?>"
|
||||
data-parsley-errors-container="#s3_secret_key_<?php echo (int) $storage->getSType(); ?>_error_container"
|
||||
autocomplete="off"
|
||||
value=""
|
||||
>
|
||||
<div id="s3_secret_key_<?php echo (int) $storage->getSType(); ?>_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"></th>
|
||||
<td>
|
||||
<table class="dup-form-sub-area dup-s3-auth-provider">
|
||||
<tr>
|
||||
<th>
|
||||
<label for="s3_endpoint_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php echo esc_html($storage->getFieldLabel('endpoint')); ?>:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
id="s3_endpoint_<?php echo (int) $storage->getSType(); ?>"
|
||||
name="s3_endpoint"
|
||||
value="<?php echo esc_attr($endpoint); ?>"
|
||||
<?php echo ($isAutofillEndpoint ? 'readonly="true"' : ''); ?>
|
||||
data-parsley-required="true"
|
||||
>
|
||||
<?php if ($isAutofillEndpoint) : ?>
|
||||
<p class="description">
|
||||
<i><?php esc_html_e('The endpoint URL will be autofilled based on the region.', 'duplicator-pro'); ?></i>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<label for="s3_region_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php echo esc_html($storage->getFieldLabel('region')); ?>:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
id="s3_region_<?php echo (int) $storage->getSType(); ?>"
|
||||
name="s3_region"
|
||||
<?php echo ($isAutofillRegion ? 'readonly="true"' : ''); ?>
|
||||
value="<?php echo esc_attr($region); ?>"
|
||||
data-parsley-required="true"
|
||||
data-parsley-pattern="[0-9a-zA-Z-_]+"
|
||||
>
|
||||
<?php if ($isAutofillRegion) : ?>
|
||||
<p class="description">
|
||||
<i><?php esc_html_e('The region will be autodetected from the endpoint URL.', 'duplicator-pro'); ?></i>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="invisible_out_of_screen">
|
||||
<th>
|
||||
<label for="s3_storage_class_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php esc_html_e("Storage Class", 'duplicator-pro'); ?>:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<select id="s3_storage_class_<?php echo (int) $storage->getSType(); ?>" name="s3_storage_class">
|
||||
<option <?php selected(true); ?> value="STANDARD"><?php esc_html_e("Standard", 'duplicator-pro'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="s3_bucket_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php echo esc_html($storage->getFieldLabel('bucket')); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
id="s3_bucket_<?php echo (int) $storage->getSType(); ?>"
|
||||
name="s3_bucket"
|
||||
type="text"
|
||||
value="<?php echo esc_attr($bucket); ?>"
|
||||
data-parsley-required="true"
|
||||
>
|
||||
<p class="description">
|
||||
<i><?php esc_html_e("S3 Bucket where you want to save the backups.", 'duplicator-pro'); ?></i>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="_s3_storage_folder_<?php echo (int) $storage->getSType(); ?>"><?php esc_html_e("Storage Folder", 'duplicator-pro'); ?>:</label></th>
|
||||
<td>
|
||||
<input
|
||||
id="_s3_storage_folder_<?php echo (int) $storage->getSType(); ?>"
|
||||
name="_s3_storage_folder"
|
||||
type="text"
|
||||
value="<?php echo esc_attr($storageFolder); ?>"
|
||||
>
|
||||
<p class="description">
|
||||
<i>
|
||||
<?php
|
||||
esc_html_e(
|
||||
"Folder where packages will be stored. This should be unique for each web-site using Duplicator.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</i>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="s3_max_files_<?php echo (int) $storage->getSType(); ?>"><?php esc_html_e("Max Packages", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<label for="s3_max_files_<?php echo (int) $storage->getSType(); ?>">
|
||||
<input
|
||||
id="s3_max_files_<?php echo (int) $storage->getSType(); ?>"
|
||||
class="s3_max_files"
|
||||
name="s3_max_files"
|
||||
type="number"
|
||||
value="<?php echo (int) $maxPackages; ?>"
|
||||
min="0"
|
||||
maxlength="4"
|
||||
data-parsley-errors-container="#s3_max_files_<?php echo (int) $storage->getSType(); ?>_error_container"
|
||||
data-parsley-required="true"
|
||||
data-parsley-type="number"
|
||||
data-parsley-min="0"
|
||||
>
|
||||
<?php esc_html_e("Number of packages to keep in folder.", 'duplicator-pro'); ?>
|
||||
<p class="description">
|
||||
<i><?php esc_html_e("When this limit is exceeded, the oldest package will be deleted. Set to 0 for no limit.", 'duplicator-pro'); ?></i>
|
||||
</p>
|
||||
</label>
|
||||
<div id="s3_max_files_<?php echo (int) $storage->getSType(); ?>_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ($isAclSupported) : ?>
|
||||
<tr class="s3-acl-row" valign="top">
|
||||
<th scope="row"><label><?php echo esc_html($storage->getFieldLabel('aclFullControl')); ?></label></th>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="s3_ACL_full_control"
|
||||
id="s3_ACL_full_control_<?php echo (int) $storage->getSType(); ?>"
|
||||
value="1"
|
||||
<?php checked($aclFullControl, true); ?>
|
||||
>
|
||||
<label for="s3_ACL_full_control_<?php echo (int) $storage->getSType(); ?>">
|
||||
<?php esc_html_e("Give bucket owner full control (ACL) to all files uploaded by Duplicator Pro.", 'duplicator-pro'); ?>
|
||||
</label><br />
|
||||
<p class="description">
|
||||
<i>
|
||||
<?php echo esc_html($aclDescription); ?>
|
||||
</i>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/provider_foot');
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\AmazonS3Storage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AmazonS3Storage $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var int */
|
||||
$maxPackages = $tplData["maxPackages"];
|
||||
/** @var string */
|
||||
$storageFolder = $tplData["storageFolder"];
|
||||
/** @var string */
|
||||
$accessKey = $tplData["accessKey"];
|
||||
/** @var string */
|
||||
$bucket = $tplData["bucket"];
|
||||
/** @var string */
|
||||
$region = $tplData["region"];
|
||||
/** @var string */
|
||||
$secretKey = $tplData["secretKey"];
|
||||
/** @var string */
|
||||
$storageClass = $tplData["storageClass"];
|
||||
/** @var string */
|
||||
$endpoint = $tplData["endpoint"];
|
||||
/** @var string */
|
||||
$aclFullControl = $tplData["aclFullControl"];
|
||||
/** @var array<string,string> */
|
||||
$regionOptions = $tplData["regionOptions"];
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/provider_head');
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="2" style="padding-left:0">
|
||||
<i>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Amazon S3 Setup Guide: %1$sStep-by-Step%2$s and %3$sUser Bucket Policy%4$s.',
|
||||
'1,3 represents <a> tag, 2,4 represents </a> tag',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a target="_blank" href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'amazon-s3-step-by-step') . '">',
|
||||
'</a>',
|
||||
'<a href="' . esc_url(DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'amazon-s3-policy-setup') . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for=""><?php esc_html_e("Authorization", 'duplicator-pro'); ?></label></th>
|
||||
<td class="dup-s3-auth-account">
|
||||
<h3>
|
||||
<?php esc_html_e('Amazon Account', 'duplicator-pro'); ?><br/>
|
||||
</h3>
|
||||
<table class="dup-form-sub-area">
|
||||
<tr>
|
||||
<th scope="row"><label for="s3_access_key_amazon"><?php esc_html_e("Access Key", 'duplicator-pro'); ?>:</label></th>
|
||||
<td>
|
||||
<input
|
||||
id="s3_access_key_amazon"
|
||||
name="s3_access_key"
|
||||
data-parsley-errors-container="#s3_access_key_amazon_error_container"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
value="<?php echo esc_attr($accessKey); ?>"
|
||||
>
|
||||
<div id="s3_access_key_amazon_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="s3_secret_key_amazon"><?php esc_html_e("Secret Key", 'duplicator-pro'); ?>:</label>
|
||||
</th>
|
||||
|
||||
<td>
|
||||
<input
|
||||
id="s3_secret_key_amazon"
|
||||
name="s3_secret_key"
|
||||
type="password"
|
||||
placeholder="<?php echo esc_attr(str_repeat("*", strlen($secretKey))); ?>"
|
||||
data-parsley-errors-container="#s3_secret_key_amazon_error_container"
|
||||
autocomplete="off"
|
||||
value=""
|
||||
>
|
||||
<div id="s3_secret_key_amazon_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"></th>
|
||||
<td>
|
||||
<table class="dup-form-sub-area dup-s3-auth-provider">
|
||||
<tr>
|
||||
<th><label for="s3_region_amazon"><?php esc_html_e("Region", 'duplicator-pro'); ?>:</label></th>
|
||||
<td>
|
||||
<select id="s3_region_amazon" name="s3_region">
|
||||
<?php
|
||||
foreach ($regionOptions as $value => $label) {
|
||||
?>
|
||||
<option
|
||||
<?php selected($region, $value); ?>
|
||||
value="<?php echo esc_attr($value); ?>"
|
||||
>
|
||||
<?php echo esc_html($label . " - '" . $value . "'"); ?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="s3_storage_class_amazon"><?php esc_html_e("Storage Class", 'duplicator-pro'); ?>:</label></th>
|
||||
<td>
|
||||
<select id="s3_storage_class_amazon" name="s3_storage_class">
|
||||
<option <?php selected($storageClass == 'REDUCED_REDUNDANCY'); ?> value="REDUCED_REDUNDANCY">
|
||||
<?php esc_html_e("Reduced Redundancy", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option <?php selected($storageClass == 'STANDARD'); ?> value="STANDARD">
|
||||
<?php esc_html_e("Standard", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option <?php selected($storageClass == 'STANDARD_IA'); ?> value="STANDARD_IA">
|
||||
<?php esc_html_e("Standard IA", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="_s3_storage_folder_amazon"><?php esc_html_e("Storage Folder", 'duplicator-pro'); ?>:</label></th>
|
||||
<td>
|
||||
<input
|
||||
id="_s3_storage_folder_amazon"
|
||||
name="_s3_storage_folder"
|
||||
type="text"
|
||||
value="<?php echo esc_attr($storageFolder); ?>"
|
||||
>
|
||||
<p>
|
||||
<i>
|
||||
<?php esc_html_e(
|
||||
"Folder where packages will be stored. This should be unique for each web-site using Duplicator.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</i>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="s3_bucket_amazon"><?php esc_html_e("Bucket", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<input id="s3_bucket_amazon" name="s3_bucket" type="text" value="<?php echo esc_attr($bucket); ?>">
|
||||
<p><i><?php esc_html_e("S3 Bucket where you want to save the backups.", 'duplicator-pro'); ?></i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="s3_max_files_amazon"><?php esc_html_e("Max Packages", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<label for="s3_max_files_amazon">
|
||||
<input
|
||||
id="s3_max_files_amazon"
|
||||
class="s3_max_files"
|
||||
name="s3_max_files"
|
||||
type="number"
|
||||
value="<?php echo (int) $maxPackages; ?>"
|
||||
min="0"
|
||||
maxlength="4"
|
||||
data-parsley-errors-container="#s3_max_files_amazon_error_container"
|
||||
data-parsley-required="true"
|
||||
data-parsley-type="number"
|
||||
data-parsley-min="0"
|
||||
>
|
||||
<?php esc_html_e("Number of packages to keep in folder.", 'duplicator-pro'); ?><br/>
|
||||
<i><?php esc_html_e("When this limit is exceeded, the oldest package will be deleted. Set to 0 for no limit.", 'duplicator-pro'); ?></i>
|
||||
</label>
|
||||
<div id="s3_max_files_amazon_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/provider_foot'); ?>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Addons\AmazonS3Addon\Models\AmazonS3CompatibleStorage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
?>
|
||||
|
||||
<p>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The Amazon S3 compatible storage option allows you to connect to any object storage that is compatible with the S3 API.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
esc_attr_x(
|
||||
'Examples of compatible providers are %s.',
|
||||
'%s is a comma seperated list of providers',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b>' . esc_html(implode(', ', AmazonS3CompatibleStorage::getCompatibleProviders())) . '</b>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
Reference in New Issue
Block a user