From 799352708b59f81531437e53a542dd76b6e3005f Mon Sep 17 00:00:00 2001 From: Brasdrive Date: Sun, 9 Nov 2025 19:36:01 -0400 Subject: [PATCH] 3.0.0 --- src/Filesystem/Adapters/WebdavAdapter.php | 236 +++++++--------------- 1 file changed, 74 insertions(+), 162 deletions(-) diff --git a/src/Filesystem/Adapters/WebdavAdapter.php b/src/Filesystem/Adapters/WebdavAdapter.php index aa52c54..b15ea4d 100644 --- a/src/Filesystem/Adapters/WebdavAdapter.php +++ b/src/Filesystem/Adapters/WebdavAdapter.php @@ -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; } }