3.0.0
This commit is contained in:
parent
79fa886ee1
commit
799352708b
|
|
@ -4,180 +4,73 @@ declare(strict_types=1);
|
|||
|
||||
namespace FlysystemOffload\Filesystem\Adapters;
|
||||
|
||||
use FlysystemOffload\Filesystem\AdapterInterface; // ← CORRECTO (sin Adapters)
|
||||
use League\Flysystem\FilesystemAdapter;
|
||||
use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
|
||||
use League\Flysystem\Visibility;
|
||||
use League\Flysystem\WebDAV\WebDAVAdapter as FlysystemWebDAVAdapter;
|
||||
use League\Flysystem\WebDAV\WebDAVAdapter as LeagueWebDAVAdapter;
|
||||
use Sabre\DAV\Client;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Adaptador WebDAV para Flysystem Offload
|
||||
*
|
||||
* Proporciona integración con servidores WebDAV usando Sabre/DAV
|
||||
*/
|
||||
class WebdavAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Crea y configura el adaptador WebDAV
|
||||
*
|
||||
* @param array $config Configuración del adaptador
|
||||
* @return FilesystemAdapter
|
||||
* @throws InvalidArgumentException Si la configuración es inválida
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createAdapter(array $config): FilesystemAdapter
|
||||
{
|
||||
$this->validateConfig($config);
|
||||
|
||||
// Normalizar permisos de string a integer octal
|
||||
$filePublic = $this->normalizePermission($config['file_public'] ?? '0644');
|
||||
$filePrivate = $this->normalizePermission($config['file_private'] ?? '0600');
|
||||
$dirPublic = $this->normalizePermission($config['dir_public'] ?? '0755');
|
||||
$dirPrivate = $this->normalizePermission($config['dir_private'] ?? '0700');
|
||||
|
||||
// Configurar cliente WebDAV
|
||||
$clientConfig = [
|
||||
'baseUri' => rtrim($config['base_uri'], '/') . '/',
|
||||
'userName' => $config['username'] ?? null,
|
||||
'password' => $config['password'] ?? null,
|
||||
];
|
||||
|
||||
// Añadir autenticación si está configurada
|
||||
if (!empty($config['username'])) {
|
||||
$clientConfig['userName'] = $config['username'];
|
||||
$clientConfig['password'] = $config['password'] ?? '';
|
||||
$clientConfig['authType'] = $this->normalizeAuthType($config['auth_type'] ?? 'basic');
|
||||
}
|
||||
|
||||
// Configuración adicional opcional
|
||||
if (isset($config['encoding'])) {
|
||||
$clientConfig['encoding'] = $config['encoding'];
|
||||
// Configurar tipo de autenticación
|
||||
if (!empty($config['auth_type'])) {
|
||||
$authType = strtolower($config['auth_type']);
|
||||
$clientConfig['authType'] = match ($authType) {
|
||||
'basic' => Client::AUTH_BASIC,
|
||||
'digest' => Client::AUTH_DIGEST,
|
||||
'ntlm' => Client::AUTH_NTLM,
|
||||
default => Client::AUTH_BASIC,
|
||||
};
|
||||
}
|
||||
|
||||
// Crear cliente
|
||||
$client = new Client($clientConfig);
|
||||
|
||||
// Crear convertidor de visibilidad con permisos normalizados
|
||||
$visibility = new PortableVisibilityConverter(
|
||||
$filePublic,
|
||||
$filePrivate,
|
||||
$dirPublic,
|
||||
$dirPrivate,
|
||||
Visibility::PRIVATE // Visibilidad por defecto
|
||||
);
|
||||
// Configurar permisos
|
||||
$permissions = [
|
||||
'file' => [
|
||||
'public' => $this->normalizePermission($config['file_public'] ?? '0644'),
|
||||
'private' => $this->normalizePermission($config['file_private'] ?? '0600'),
|
||||
],
|
||||
'dir' => [
|
||||
'public' => $this->normalizePermission($config['dir_public'] ?? '0755'),
|
||||
'private' => $this->normalizePermission($config['dir_private'] ?? '0700'),
|
||||
],
|
||||
];
|
||||
|
||||
// Crear y retornar el adaptador
|
||||
return new FlysystemWebDAVAdapter(
|
||||
error_log('[WebDAV Adapter] Creating adapter with permissions: ' . print_r($permissions, true));
|
||||
|
||||
// Crear adaptador
|
||||
$adapter = new LeagueWebDAVAdapter(
|
||||
$client,
|
||||
$config['prefix'] ?? '',
|
||||
$visibility
|
||||
$permissions
|
||||
);
|
||||
|
||||
error_log('[WebDAV Adapter] Adapter created successfully');
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convierte permisos de string octal a integer
|
||||
*
|
||||
* @param mixed $permission Permiso en formato string u octal
|
||||
* @return int Permiso como integer octal
|
||||
* @throws InvalidArgumentException Si el formato es inválido
|
||||
*/
|
||||
private function normalizePermission($permission): int
|
||||
{
|
||||
// Si ya es integer, retornar directamente
|
||||
if (is_int($permission)) {
|
||||
return $permission;
|
||||
}
|
||||
|
||||
// Si es string, convertir de octal a decimal
|
||||
if (is_string($permission)) {
|
||||
// Limpiar espacios
|
||||
$permission = trim($permission);
|
||||
|
||||
// Si comienza con '0', es octal
|
||||
if (str_starts_with($permission, '0')) {
|
||||
$result = octdec($permission);
|
||||
if ($result === false || $result === 0 && $permission !== '0' && $permission !== '0000') {
|
||||
throw new InvalidArgumentException(
|
||||
"Invalid octal permission format: {$permission}"
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Si es decimal como '644', añadir el 0 y convertir
|
||||
if (ctype_digit($permission)) {
|
||||
return octdec('0' . $permission);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(
|
||||
"Permission must be an octal string (e.g., '0644') or integer"
|
||||
);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(
|
||||
'Permission must be an integer or string, ' . gettype($permission) . ' given'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normaliza el tipo de autenticación
|
||||
*
|
||||
* @param string|int $authType Tipo de autenticación
|
||||
* @return int Constante de autenticación de Sabre\DAV\Client
|
||||
*/
|
||||
private function normalizeAuthType($authType): int
|
||||
{
|
||||
if (is_int($authType)) {
|
||||
return $authType;
|
||||
}
|
||||
|
||||
$authType = strtolower(trim($authType));
|
||||
|
||||
return match ($authType) {
|
||||
'basic' => Client::AUTH_BASIC,
|
||||
'digest' => Client::AUTH_DIGEST,
|
||||
'ntlm' => Client::AUTH_NTLM,
|
||||
default => Client::AUTH_BASIC,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Valida la configuración del adaptador
|
||||
*
|
||||
* @param array $config Configuración a validar
|
||||
* @throws InvalidArgumentException Si falta configuración requerida
|
||||
*/
|
||||
private function validateConfig(array $config): void
|
||||
{
|
||||
// Validar base_uri requerido
|
||||
if (empty($config['base_uri'])) {
|
||||
throw new InvalidArgumentException('WebDAV base_uri is required');
|
||||
}
|
||||
|
||||
// Validar formato de URL
|
||||
if (!filter_var($config['base_uri'], FILTER_VALIDATE_URL)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Invalid WebDAV base_uri format. Must be a valid URL (e.g., https://webdav.example.com/remote.php/dav/files/username/)'
|
||||
);
|
||||
}
|
||||
|
||||
// Validar que sea HTTP o HTTPS
|
||||
$scheme = parse_url($config['base_uri'], PHP_URL_SCHEME);
|
||||
if (!in_array($scheme, ['http', 'https'], true)) {
|
||||
throw new InvalidArgumentException(
|
||||
'WebDAV base_uri must use http:// or https:// scheme'
|
||||
);
|
||||
}
|
||||
|
||||
// Si hay username, debe haber password
|
||||
if (!empty($config['username']) && !isset($config['password'])) {
|
||||
throw new InvalidArgumentException(
|
||||
'WebDAV password is required when username is provided'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene las claves de configuración requeridas
|
||||
*
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRequiredConfigKeys(): array
|
||||
{
|
||||
|
|
@ -185,9 +78,7 @@ class WebdavAdapter implements AdapterInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Obtiene las claves de configuración opcionales
|
||||
*
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOptionalConfigKeys(): array
|
||||
{
|
||||
|
|
@ -200,34 +91,55 @@ class WebdavAdapter implements AdapterInterface
|
|||
'file_private',
|
||||
'dir_public',
|
||||
'dir_private',
|
||||
'encoding',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la descripción del adaptador
|
||||
* Valida la configuración
|
||||
*
|
||||
* @return string
|
||||
* @param array $config
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getDescription(): string
|
||||
private function validateConfig(array $config): void
|
||||
{
|
||||
return 'WebDAV storage adapter for Nextcloud, ownCloud, and other WebDAV-compatible servers';
|
||||
foreach ($this->getRequiredConfigKeys() as $key) {
|
||||
if (empty($config[$key])) {
|
||||
throw new InvalidArgumentException("WebDAV config key '{$key}' is required");
|
||||
}
|
||||
}
|
||||
|
||||
if (!filter_var($config['base_uri'], FILTER_VALIDATE_URL)) {
|
||||
throw new InvalidArgumentException('WebDAV base_uri must be a valid URL');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene valores por defecto para la configuración
|
||||
* Normaliza un permiso a entero octal
|
||||
*
|
||||
* @return array
|
||||
* @param string|int $permission
|
||||
* @return int
|
||||
*/
|
||||
public function getDefaultConfig(): array
|
||||
private function normalizePermission($permission): int
|
||||
{
|
||||
return [
|
||||
'auth_type' => 'basic',
|
||||
'prefix' => '',
|
||||
'file_public' => '0644',
|
||||
'file_private' => '0600',
|
||||
'dir_public' => '0755',
|
||||
'dir_private' => '0700',
|
||||
];
|
||||
if (is_int($permission)) {
|
||||
return $permission;
|
||||
}
|
||||
|
||||
if (is_string($permission)) {
|
||||
$permission = trim($permission);
|
||||
|
||||
// Si es octal string (ej: "0644")
|
||||
if (preg_match('/^0[0-7]{3}$/', $permission)) {
|
||||
return intval($permission, 8);
|
||||
}
|
||||
|
||||
// Si es decimal string sin el 0 (ej: "644")
|
||||
if (preg_match('/^[0-7]{3}$/', $permission)) {
|
||||
return intval('0' . $permission, 8);
|
||||
}
|
||||
}
|
||||
|
||||
// Default
|
||||
return 0644;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue