admsys/azure-blob-storage-octobercms

Package para subir archivos a Azure Blob Storage compatible con Laravel y October CMS

v1.2.1 2025-03-27 23:41 UTC

This package is auto-updated.

Last update: 2025-03-31 18:46:13 UTC


README

Configuración del disco en config/filesystems.php

'disks' => [
    // Otros discos...

    'azure' => [
        'driver' => 'azure',
        'account_name' => Settings::get('account_name'),
        'account_key' => Settings::get('account_key'),
        'container_name' => Settings::get('container_name'),
        'endpoint' => Settings::get('endpoint'),
        'url' => Settings::get('url'),
    ],
],

Uso en controladores y componentes de October CMS

use Storage;

// En un controlador o componente
public function onUpload()
{
    $file = Input::file('archivo');
    $path = Storage::disk('azure')->putFile('carpeta', $file);

    // O usar el facade directamente
    $url = \AzureBlobStorage::upload($file, 'carpeta/' . $file->getClientOriginalName());

    return [
        'path' => $path,
        'url' => $url
    ];
}

Uso en un formulario de backend

// En fields.yaml de un modelo
fields:
    document:
        label: Documento
        type: fileupload
        mode: file
        span: full
        fileTypes: pdf,doc,docx
        useCaption: true
        thumbOptions:
            mode: crop
            extension: auto
        disk: azure

Uso con el Media Manager de October CMS

Para usar el disco de Azure con el Media Manager, debes configurar el siguiente valor en tu archivo config/cms.php:

'storage' => [
    'media' => [
        'disk'   => 'azure',
        'folder' => 'media',
        'path'   => '/media',
    ],
],

Esto permitirá que el Media Manager use Azure Blob Storage para almacenar los archivos multimedia.

Compatibilidad con múltiples versiones de Flysystem

Este package utiliza una estrategia de fallback que detecta automáticamente la versión de Flysystem en tu proyecto y utiliza el adaptador adecuado:

  • Flysystem v1: Utilizado en Laravel 6-7 y algunas versiones de October CMS v2
  • Flysystem v2: Utilizado en Laravel 8-9 y versiones tempranas de October CMS v3
  • Flysystem v3: Utilizado en Laravel 10+ y versiones recientes de October CMS v3

Esta detección automática garantiza la compatibilidad sin necesidad de configuración adicional.

Solución de problemas

El driver "azure" no es soportado

Si encuentras el error "Driver [azure] is not supported", intenta lo siguiente:

  1. Asegúrate de que el plugin está correctamente instalado y activado:

    php artisan plugin:refresh Admsys.AzureBlobStorageOctobercms
  2. Verifica que las variables de entorno estén correctamente configuradas:

    AZURE_STORAGE_ACCOUNT_NAME=tucuentaazure
    AZURE_STORAGE_ACCOUNT_KEY=tuclavedeacceso
    AZURE_STORAGE_CONTAINER=tucontenedor
    
  3. Comprueba los logs del sistema en storage/logs/system.log para identificar errores específicos.

  4. Si el problema persiste, puedes intentar registrar manualmente el driver en tu archivo config/app.php:

    'providers' => [
        // Otros proveedores
        Admsys\AzureBlobStorage\AzureBlobStorageServiceProvider::class,
    ],
    'aliases' => [
        // Otros aliases
        'AzureBlobStorage' => Admsys\AzureBlobStorage\Facades\AzureBlobStorage::class,
    ],

Contribuir

Las contribuciones son bienvenidas y serán completamente acreditadas.

Licencia

Este package está licenciado bajo la licencia MIT. Consulta el archivo LICENSE.md para más detalles.# Azure Blob Storage para October CMS

Este package proporciona una integración sencilla con Azure Blob Storage principalmente para October CMS v3, también compatible con aplicaciones Laravel 10+.

Características principales

  • Subir, descargar y gestionar archivos en Azure Blob Storage
  • Compatibilidad con múltiples versiones de Flysystem/Laravel/October CMS mediante detección automática
  • Integración con el panel de administración de October CMS
  • Soporte para disco personalizado en Laravel Filesystem
  • Fácil configuración de credenciales y opciones

Compatibilidad

Este package soporta:

  • October CMS v3.x
  • Laravel 8.x, 9.x, 10.x y 11.x
  • PHP 8.0 o superior

Instalación

Puedes instalar el package a través de Composer:

composer require admsys/azure-blob-storage-octobercms

Configuración en Laravel

Publicación de la configuración

Para publicar el archivo de configuración en Laravel, ejecuta:

php artisan vendor:publish --tag=azure-blob-storage-config

Esto creará el archivo config/azure-blob-storage-config.php en tu aplicación Laravel.

Configuración en el archivo .env

Configura tus credenciales de Azure Blob Storage en el archivo .env:

AZURE_STORAGE_ACCOUNT_NAME=tu-nombre-de-cuenta
AZURE_STORAGE_ACCOUNT_KEY=tu-clave
AZURE_STORAGE_CONTAINER=tu-contenedor
AZURE_STORAGE_URL=https://tu-cdn-o-url-personalizada.com/
AZURE_STORAGE_DEFAULT_VISIBILITY=public

Configuración en October CMS

Instalación como plugin

En October CMS, puedes instalar este package como un plugin:

  1. Descarga o clona este repositorio en la carpeta plugins/admsys/azureblobstorageoctobercms de tu instalación de October CMS.
  2. Desde la línea de comandos, navega a la carpeta raíz de tu instalación de October CMS y ejecuta:
    php artisan plugin:refresh Admsys.AzureBlobStorageOctobercms
  3. O instálalo a través de Composer:
    composer require admsys/azure-blob-storage-octobercms
  4. Luego ejecuta:
    php artisan october:migrate

Configuración en el panel de administración

Una vez instalado el plugin en October CMS, puedes configurarlo desde el panel de administración:

  1. Ve a Configuración (Settings) > Sistema > Azure Blob Storage
  2. Ingresa tu nombre de cuenta, clave de acceso y nombre del contenedor
  3. Opcionalmente, configura el endpoint personalizado, URL base y visibilidad predeterminada
  4. Guarda la configuración

Uso básico

Subir un archivo

use Admsys\AzureBlobStorage\Facades\AzureBlobStorage;

// Subir un archivo desde un formulario
$file = $request->file('document');
$url = AzureBlobStorage::upload($file);

// Subir un archivo con nombre personalizado
$url = AzureBlobStorage::upload($file, 'documentos/archivo.pdf');

// Subir un archivo con opciones adicionales
$url = AzureBlobStorage::upload($file, 'archivo.pdf', [
    'unique' => true, // Genera un nombre único
    'metadata' => [
        'descripcion' => 'Documento importante',
        'usuario_id' => auth()->id(),
    ],
    'cacheControl' => 'public, max-age=31536000',
    'visibility' => 'public', // o 'private'
]);

// También puedes subir desde una ruta de archivo
$url = AzureBlobStorage::upload(storage_path('app/archivo.pdf'));

Eliminar un archivo

if (AzureBlobStorage::delete('nombre-del-blob.pdf')) {
    // Archivo eliminado correctamente
}

Verificar si un archivo existe

if (AzureBlobStorage::exists('nombre-del-blob.pdf')) {
    // El archivo existe
}

Listar archivos

// Listar todos los archivos
$archivos = AzureBlobStorage::listBlobs();

// Listar archivos con un prefijo (como una carpeta)
$archivos = AzureBlobStorage::listBlobs('carpeta/');

// Limitar el número de resultados
$archivos = AzureBlobStorage::listBlobs(null, 100);

Descargar un archivo

$contenido = AzureBlobStorage::download('nombre-del-blob.pdf');
if ($contenido) {
    return response($contenido)
        ->header('Content-Type', 'application/pdf')
        ->header('Content-Disposition', 'attachment; filename="documento.pdf"');
}

Operaciones avanzadas

Para operaciones más avanzadas, puedes acceder directamente al cliente Azure:

$blobClient = AzureBlobStorage::getClient();
// Ahora puedes usar todas las funciones del SDK de Azure

Integración con Laravel Filesystem

Este package incluye un adaptador de sistema de archivos para Laravel, lo que te permite usar Azure Blob Storage como un disco de almacenamiento de Laravel.

Configuración del disco

Agrega la siguiente configuración en config/filesystems.php:

'disks' => [
    // Otros discos...

    'azure' => [
        'driver' => 'azure',
        'account_name' => env('AZURE_STORAGE_ACCOUNT_NAME'),
        'account_key' => env('AZURE_STORAGE_ACCOUNT_KEY'),
        'container_name' => env('AZURE_STORAGE_CONTAINER'),
        'endpoint' => env('AZURE_STORAGE_ENDPOINT', null),
        'url' => env('AZURE_STORAGE_URL', null),
    ],
],

Uso del disco

Una vez configurado, puedes usar el disco normalmente con la facade Storage:

use Illuminate\Support\Facades\Storage;

// Subir un archivo
Storage::disk('azure')->put('archivo.txt', 'Contenido del archivo');

// Subir un archivo desde una petición
$path = Storage::disk('azure')->putFile('carpeta', $request->file('archivo'));

// Obtener la URL
$url = Storage::disk('azure')->url('archivo.txt');

// Descargar un archivo
$contenido = Storage::disk('azure')->get('archivo.txt');

// Eliminar un archivo
Storage::disk('azure')->delete('archivo.txt');

// Verificar si existe
if (Storage::disk('azure')->exists('archivo.txt')) {
    // El archivo existe
}

// Listar archivos
$archivos = Storage::disk('azure')->files('carpeta');

Uso con Filament PHP

Si estás utilizando Filament PHP, puedes configurar un FileUpload personalizado:

use Filament\Forms\Components\FileUpload;
use Admsys\AzureBlobStorage\Facades\AzureBlobStorage;

FileUpload::make('documento')
    ->disk('azure') // Ahora puedes usar el disco 'azure' configurado
    ->directory('documentos')
    ->visibility('public')
    ->afterStateUpdated(function ($state) {
        // Personalizar la manipulación si es necesario
    })

Uso con October CMS

Configuración del disco en config/filesystems.php

'disks' => [
    // Otros discos...

    'azure' => [
        'driver' => 'azure',
        'account_name' => Settings::get('account_name'),
        'account_key' => Settings::get('account_key'),
        'container_name' => Settings::get('container_name'),
        'endpoint' => Settings::get('endpoint'),
        'url' => Settings::get('url'),
    ],
],

Uso en controladores y componentes de October CMS

use Storage;

// En un controlador o componente
public function onUpload()
{
    $file = Input::file('archivo');
    $path = Storage::disk('azure')->putFile('carpeta', $file);

    // O usar el facade directamente
    $url = \AzureBlobStorage::upload($file, 'carpeta/' . $file->getClientOriginalName());

    return [
        'path' => $path,
        'url' => $url
    ];
}

Uso en un formulario de backend

// En fields.yaml de un modelo
fields:
    document:
        label: Documento
        type: fileupload
        mode: file
        span: full
        fileTypes: pdf,doc,docx
        useCaption: true
        thumbOptions:
            mode: crop
            extension: auto
        disk: azure

Ejemplo completo de implementación

Aquí hay un ejemplo completo de cómo podrías usar este package en un controlador de Laravel:

<?php

namespace App\Http\Controllers;

use Admsys\AzureBlobStorage\Facades\AzureBlobStorage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class DocumentController extends Controller
{
    /**
     * Mostrar la lista de archivos
     */
    public function index()
    {
        // Usar la clase principal
        $files = AzureBlobStorage::listBlobs('documentos/');

        // O usar el sistema de archivos de Laravel
        $files = Storage::disk('azure')->files('documentos');

        return view('documents.index', compact('files'));
    }

    /**
     * Subir un nuevo archivo
     */
    public function store(Request $request)
    {
        $request->validate([
            'documento' => 'required|file|max:10240', // 10MB
        ]);

        // Método 1: Usando la clase principal directamente
        $file = $request->file('documento');
        $filename = 'documentos/' . time() . '_' . $file->getClientOriginalName();

        $url = AzureBlobStorage::upload($file, $filename, [
            'metadata' => [
                'usuario_id' => auth()->id(),
                'descripcion' => $request->input('descripcion', ''),
            ],
            'visibility' => 'public',
        ]);

        // Método 2: Usando el sistema de archivos de Laravel
        $path = Storage::disk('azure')->putFileAs(
            'documentos',
            $request->file('documento'),
            time() . '_' . $request->file('documento')->getClientOriginalName()
        );

        $url = Storage::disk('azure')->url($path);

        return redirect()->route('documents.index')
            ->with('success', 'Documento subido correctamente')
            ->with('file_url', $url);
    }

    /**
     * Descargar un archivo
     */
    public function download($filename)
    {
        // Método 1: Usando la clase principal directamente
        $content = AzureBlobStorage::download('documentos/' . $filename);

        if (!$content) {
            return back()->with('error', 'No se pudo descargar el archivo');
        }

        $extension = pathinfo($filename, PATHINFO_EXTENSION);
        $contentType = $this->getContentType($extension);

        return response($content)
            ->header('Content-Type', $contentType)
            ->header('Content-Disposition', 'attachment; filename="' . $filename . '"');

        // Método 2: Usando el sistema de archivos de Laravel
        if (!Storage::disk('azure')->exists('documentos/' . $filename)) {
            return back()->with('error', 'Archivo no encontrado');
        }

        return Storage::disk('azure')->download('documentos/' . $filename);
    }

    /**
     * Eliminar un archivo
     */
    public function destroy($filename)
    {
        // Método 1: Usando la clase principal directamente
        if (AzureBlobStorage::delete('documentos/' . $filename)) {
            return back()->with('success', 'Archivo eliminado correctamente');
        }

        // Método 2: Usando el sistema de archivos de Laravel
        if (Storage::disk('azure')->delete('documentos/' . $filename)) {
            return back()->with('success', 'Archivo eliminado correctamente');
        }

        return back()->with('error', 'No se pudo eliminar el archivo');
    }

    /**
     * Obtener el content type basado en la extensión
     */
    private function getContentType($extension)
    {
        $types = [
            'pdf' => 'application/pdf',
            'doc' => 'application/msword',
            'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'xls' => 'application/vnd.ms-excel',
            'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'jpg' => 'image/jpeg',
            'jpeg' => 'image/jpeg',
            'png' => 'image/png',
            'txt' => 'text/plain',
        ];

        return $types[strtolower($extension)] ?? 'application/octet-stream';
    }
}

Contribuir

Las contribuciones son bienvenidas y serán completamente acreditadas.

Licencia

Este package está licenciado bajo la licencia MIT. Consulta el archivo LICENSE.md para más detalles.