Atualizar src/Plugin.php
This commit is contained in:
parent
a7fb529c92
commit
eb56df4c65
476
src/Plugin.php
476
src/Plugin.php
|
|
@ -1,238 +1,238 @@
|
|||
<?php
|
||||
namespace FlysystemOffload;
|
||||
|
||||
use FlysystemOffload\Admin\SettingsPage;
|
||||
use FlysystemOffload\Filesystem\FilesystemFactory;
|
||||
use FlysystemOffload\Helpers\PathHelper;
|
||||
use FlysystemOffload\StreamWrapper\FlysystemStreamWrapper;
|
||||
use League\Flysystem\FilesystemOperator;
|
||||
use WP_Error;
|
||||
|
||||
class Plugin
|
||||
{
|
||||
private static $instance;
|
||||
private static string $pluginFile;
|
||||
private ?FilesystemOperator $filesystem = null;
|
||||
private bool $streamRegistered = false;
|
||||
private array $settings = [];
|
||||
|
||||
public static function bootstrap(string $pluginFile): void
|
||||
{
|
||||
self::$pluginFile = $pluginFile;
|
||||
|
||||
register_activation_hook($pluginFile, [self::class, 'activate']);
|
||||
register_deactivation_hook($pluginFile, [self::class, 'deactivate']);
|
||||
|
||||
add_action('plugins_loaded', static function () {
|
||||
self::instance()->init();
|
||||
});
|
||||
}
|
||||
|
||||
public static function instance(): self
|
||||
{
|
||||
return self::$instance ??= new self();
|
||||
}
|
||||
|
||||
public static function activate(): void
|
||||
{
|
||||
$defaults = [
|
||||
'adapter' => 'local',
|
||||
'base_prefix' => '',
|
||||
'adapters' => [
|
||||
's3' => [
|
||||
'access_key' => '',
|
||||
'secret_key' => '',
|
||||
'region' => '',
|
||||
'bucket' => '',
|
||||
'endpoint' => '',
|
||||
'cdn_url' => ''
|
||||
],
|
||||
'sftp' => [
|
||||
'host' => '',
|
||||
'port' => 22,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'root' => '/uploads'
|
||||
],
|
||||
'gcs' => [
|
||||
'project_id' => '',
|
||||
'bucket' => '',
|
||||
'key_file_path' => ''
|
||||
],
|
||||
'azure' => [
|
||||
'account_name' => '',
|
||||
'account_key' => '',
|
||||
'container' => '',
|
||||
'prefix' => ''
|
||||
],
|
||||
'webdav' => [
|
||||
'base_uri' => '',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'path_prefix' => ''
|
||||
],
|
||||
'googledrive' => [],
|
||||
'onedrive' => [],
|
||||
'dropbox' => []
|
||||
]
|
||||
];
|
||||
|
||||
add_option('flysystem_offload_settings', $defaults);
|
||||
}
|
||||
|
||||
public static function deactivate(): void
|
||||
{
|
||||
if (in_array('fly', stream_get_wrappers(), true)) {
|
||||
stream_wrapper_unregister('fly');
|
||||
}
|
||||
}
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
$this->settings = get_option('flysystem_offload_settings', []);
|
||||
|
||||
add_action(
|
||||
'update_option_flysystem_offload_settings',
|
||||
function ($oldValue, $newValue) {
|
||||
$this->settings = $newValue;
|
||||
$this->filesystem = null;
|
||||
$this->streamRegistered = false;
|
||||
$this->registerStreamWrapper();
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
|
||||
$this->registerStreamWrapper();
|
||||
|
||||
add_filter('upload_dir', [$this, 'filterUploadDir'], 20);
|
||||
add_filter('wp_get_attachment_url', [$this, 'filterAttachmentUrl'], 20, 2);
|
||||
add_filter('wp_get_attachment_metadata', [$this, 'filterAttachmentMetadata'], 20);
|
||||
add_filter('wp_get_original_image_path', [$this, 'filterOriginalImagePath'], 20);
|
||||
add_filter('wp_delete_file', [$this, 'handleDeleteFile'], 20);
|
||||
add_action('delete_attachment', [$this, 'handleDeleteAttachment'], 20);
|
||||
|
||||
add_action('switch_blog', function () {
|
||||
$this->filesystem = null;
|
||||
$this->streamRegistered = false;
|
||||
$this->settings = get_option('flysystem_offload_settings', []);
|
||||
$this->registerStreamWrapper();
|
||||
});
|
||||
|
||||
if (is_admin()) {
|
||||
(new SettingsPage(self::$pluginFile))->boot();
|
||||
}
|
||||
|
||||
if (defined('WP_CLI') && WP_CLI) {
|
||||
\WP_CLI::add_command('flysystem-offload health-check', [Admin\HealthCheck::class, 'run']);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFilesystem(): FilesystemOperator
|
||||
{
|
||||
if (!$this->filesystem) {
|
||||
$factory = new FilesystemFactory($this->settings);
|
||||
$result = $factory->make();
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
throw new \RuntimeException($result->get_error_message());
|
||||
}
|
||||
|
||||
$this->filesystem = $result;
|
||||
}
|
||||
|
||||
return $this->filesystem;
|
||||
}
|
||||
|
||||
private function registerStreamWrapper(): void
|
||||
{
|
||||
if ($this->streamRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
FlysystemStreamWrapper::register($this->getFilesystem(), 'fly', PathHelper::normalizePrefix($this->settings['base_prefix'] ?? ''));
|
||||
$this->streamRegistered = true;
|
||||
} catch (\Throwable $e) {
|
||||
error_log('[Flysystem Offload] No se pudo registrar el stream wrapper: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function filterUploadDir(array $dirs): array
|
||||
{
|
||||
$remoteBase = $this->getRemoteUrlBase();
|
||||
$prefix = PathHelper::normalizePrefix($this->settings['base_prefix'] ?? '');
|
||||
$subdir = $dirs['subdir'] ?? '';
|
||||
|
||||
$dirs['path'] = "fly://{$prefix}{$subdir}";
|
||||
$dirs['basedir'] = "fly://{$prefix}";
|
||||
$dirs['url'] = trailingslashit($remoteBase) . ltrim($subdir, '/');
|
||||
$dirs['baseurl'] = $remoteBase;
|
||||
|
||||
return $dirs;
|
||||
}
|
||||
|
||||
public function filterAttachmentUrl(string $url, int $postId): string
|
||||
{
|
||||
$localBase = trailingslashit(wp_get_upload_dir()['baseurl']);
|
||||
$remoteBase = trailingslashit($this->getRemoteUrlBase());
|
||||
|
||||
return str_replace($localBase, $remoteBase, $url);
|
||||
}
|
||||
|
||||
public function filterAttachmentMetadata(array $metadata): array
|
||||
{
|
||||
if (!empty($metadata['file'])) {
|
||||
$metadata['file'] = PathHelper::stripProtocol($metadata['file']);
|
||||
}
|
||||
|
||||
if (!empty($metadata['sizes'])) {
|
||||
foreach ($metadata['sizes'] as &$size) {
|
||||
if (!empty($size['file'])) {
|
||||
$size['file'] = ltrim($size['file'], '/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
public function filterOriginalImagePath(string $path): string
|
||||
{
|
||||
return PathHelper::ensureFlyProtocol($path);
|
||||
}
|
||||
|
||||
public function handleDeleteFile(string $file): string|false
|
||||
{
|
||||
$flyPath = PathHelper::stripProtocol($file);
|
||||
|
||||
try {
|
||||
$this->getFilesystem()->delete($flyPath);
|
||||
} catch (\Throwable $e) {
|
||||
error_log('[Flysystem Offload] Error al borrar archivo: ' . $flyPath . ' - ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleDeleteAttachment(int $postId): void
|
||||
{
|
||||
$files = PathHelper::collectFilesFromAttachment($postId);
|
||||
|
||||
foreach ($files as $relativePath) {
|
||||
try {
|
||||
$this->getFilesystem()->delete($relativePath);
|
||||
} catch (\Throwable $e) {
|
||||
error_log('[Flysystem Offload] Error al borrar attachment: ' . $relativePath . ' - ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getRemoteUrlBase(): string
|
||||
{
|
||||
$adapterKey = $this->settings['adapter'] ?? 'local';
|
||||
$config = $this->settings['adapters'][$adapterKey] ?? [];
|
||||
|
||||
return (new FilesystemFactory($this->settings))->resolvePublicBaseUrl($adapterKey, $config);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
namespace FlysystemOffload;
|
||||
|
||||
use FlysystemOffload\Admin\SettingsPage;
|
||||
use FlysystemOffload\Filesystem\FilesystemFactory;
|
||||
use FlysystemOffload\Helpers\PathHelper;
|
||||
use FlysystemOffload\StreamWrapper\FlysystemStreamWrapper;
|
||||
use League\Flysystem\FilesystemOperator;
|
||||
use WP_Error;
|
||||
|
||||
class Plugin
|
||||
{
|
||||
private static $instance;
|
||||
private static string $pluginFile;
|
||||
private ?FilesystemOperator $filesystem = null;
|
||||
private bool $streamRegistered = false;
|
||||
private array $settings = [];
|
||||
|
||||
public static function bootstrap(string $pluginFile): void
|
||||
{
|
||||
self::$pluginFile = $pluginFile;
|
||||
|
||||
register_activation_hook($pluginFile, [self::class, 'activate']);
|
||||
register_deactivation_hook($pluginFile, [self::class, 'deactivate']);
|
||||
|
||||
add_action('plugins_loaded', static function () {
|
||||
self::instance()->init();
|
||||
});
|
||||
}
|
||||
|
||||
public static function instance(): self
|
||||
{
|
||||
return self::$instance ??= new self();
|
||||
}
|
||||
|
||||
public static function activate(): void
|
||||
{
|
||||
$defaults = [
|
||||
'adapter' => 'local',
|
||||
'base_prefix' => '',
|
||||
'adapters' => [
|
||||
's3' => [
|
||||
'access_key' => '',
|
||||
'secret_key' => '',
|
||||
'region' => '',
|
||||
'bucket' => '',
|
||||
'endpoint' => '',
|
||||
'cdn_url' => ''
|
||||
],
|
||||
'sftp' => [
|
||||
'host' => '',
|
||||
'port' => 22,
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'root' => '/uploads'
|
||||
],
|
||||
'gcs' => [
|
||||
'project_id' => '',
|
||||
'bucket' => '',
|
||||
'key_file_path' => ''
|
||||
],
|
||||
'azure' => [
|
||||
'account_name' => '',
|
||||
'account_key' => '',
|
||||
'container' => '',
|
||||
'prefix' => ''
|
||||
],
|
||||
'webdav' => [
|
||||
'base_uri' => '',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'path_prefix' => ''
|
||||
],
|
||||
'googledrive' => [],
|
||||
'onedrive' => [],
|
||||
'dropbox' => []
|
||||
]
|
||||
];
|
||||
|
||||
add_option('flysystem_offload_settings', $defaults);
|
||||
}
|
||||
|
||||
public static function deactivate(): void
|
||||
{
|
||||
if (in_array('fly', stream_get_wrappers(), true)) {
|
||||
stream_wrapper_unregister('fly');
|
||||
}
|
||||
}
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
$this->settings = get_option('flysystem_offload_settings', []);
|
||||
|
||||
add_action(
|
||||
'update_option_flysystem_offload_settings',
|
||||
function ($oldValue, $newValue) {
|
||||
$this->settings = $newValue;
|
||||
$this->filesystem = null;
|
||||
$this->streamRegistered = false;
|
||||
$this->registerStreamWrapper();
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
|
||||
$this->registerStreamWrapper();
|
||||
|
||||
add_filter('upload_dir', [$this, 'filterUploadDir'], 20);
|
||||
add_filter('wp_get_attachment_url', [$this, 'filterAttachmentUrl'], 20, 2);
|
||||
add_filter('wp_get_attachment_metadata', [$this, 'filterAttachmentMetadata'], 20);
|
||||
add_filter('wp_get_original_image_path', [$this, 'filterOriginalImagePath'], 20);
|
||||
add_filter('wp_delete_file', [$this, 'handleDeleteFile'], 20);
|
||||
add_action('delete_attachment', [$this, 'handleDeleteAttachment'], 20);
|
||||
|
||||
add_action('switch_blog', function () {
|
||||
$this->filesystem = null;
|
||||
$this->streamRegistered = false;
|
||||
$this->settings = get_option('flysystem_offload_settings', []);
|
||||
$this->registerStreamWrapper();
|
||||
});
|
||||
|
||||
if (is_admin()) {
|
||||
(new SettingsPage(self::$pluginFile))->boot();
|
||||
}
|
||||
|
||||
if (defined('WP_CLI') && WP_CLI) {
|
||||
\WP_CLI::add_command('flysystem-offload health-check', [Admin\HealthCheck::class, 'run']);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFilesystem(): FilesystemOperator
|
||||
{
|
||||
if (!$this->filesystem) {
|
||||
$factory = new FilesystemFactory($this->settings);
|
||||
$result = $factory->make();
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
throw new \RuntimeException($result->get_error_message());
|
||||
}
|
||||
|
||||
$this->filesystem = $result;
|
||||
}
|
||||
|
||||
return $this->filesystem;
|
||||
}
|
||||
|
||||
private function registerStreamWrapper(): void
|
||||
{
|
||||
if ($this->streamRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
FlysystemStreamWrapper::register($this->getFilesystem(), 'fly', PathHelper::normalizePrefix($this->settings['base_prefix'] ?? ''));
|
||||
$this->streamRegistered = true;
|
||||
} catch (\Throwable $e) {
|
||||
error_log('[Flysystem Offload] No se pudo registrar el stream wrapper: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function filterUploadDir(array $dirs): array
|
||||
{
|
||||
$remoteBase = $this->getRemoteUrlBase();
|
||||
$prefix = PathHelper::normalizePrefix($this->settings['base_prefix'] ?? '');
|
||||
$subdir = $dirs['subdir'] ?? '';
|
||||
|
||||
$dirs['path'] = "fly://{$prefix}{$subdir}";
|
||||
$dirs['basedir'] = "fly://{$prefix}";
|
||||
$dirs['url'] = trailingslashit($remoteBase) . ltrim($subdir, '/');
|
||||
$dirs['baseurl'] = $remoteBase;
|
||||
|
||||
return $dirs;
|
||||
}
|
||||
|
||||
public function filterAttachmentUrl(string $url, int $postId): string
|
||||
{
|
||||
$localBase = trailingslashit(wp_get_upload_dir()['baseurl']);
|
||||
$remoteBase = trailingslashit($this->getRemoteUrlBase());
|
||||
|
||||
return str_replace($localBase, $remoteBase, $url);
|
||||
}
|
||||
|
||||
public function filterAttachmentMetadata(array $metadata): array
|
||||
{
|
||||
if (!empty($metadata['file'])) {
|
||||
$metadata['file'] = PathHelper::stripProtocol($metadata['file']);
|
||||
}
|
||||
|
||||
if (!empty($metadata['sizes'])) {
|
||||
foreach ($metadata['sizes'] as &$size) {
|
||||
if (!empty($size['file'])) {
|
||||
$size['file'] = ltrim($size['file'], '/');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
public function filterOriginalImagePath(string $path): string
|
||||
{
|
||||
return PathHelper::ensureFlyProtocol($path);
|
||||
}
|
||||
|
||||
public function handleDeleteFile(string $file): string|false
|
||||
{
|
||||
$flyPath = PathHelper::stripProtocol($file);
|
||||
|
||||
try {
|
||||
$this->getFilesystem()->delete($flyPath);
|
||||
} catch (\Throwable $e) {
|
||||
error_log('[Flysystem Offload] Error al borrar archivo: ' . $flyPath . ' - ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleDeleteAttachment(int $postId): void
|
||||
{
|
||||
$files = PathHelper::collectFilesFromAttachment($postId);
|
||||
|
||||
foreach ($files as $relativePath) {
|
||||
try {
|
||||
$this->getFilesystem()->delete($relativePath);
|
||||
} catch (\Throwable $e) {
|
||||
error_log('[Flysystem Offload] Error al borrar attachment: ' . $relativePath . ' - ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getRemoteUrlBase(): string
|
||||
{
|
||||
$adapterKey = $this->settings['adapter'] ?? 'local';
|
||||
$config = $this->settings['adapters'][$adapterKey] ?? [];
|
||||
|
||||
return (new FilesystemFactory($this->settings))->resolvePublicBaseUrl($adapterKey, $config);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue