Skip to content

letoceiling-coder/media

Repository files navigation

Laravel Media Package

Версия: 1.3.6
Лицензия: MIT

Полнофункциональный пакет для управления медиа-файлами в Laravel приложениях. Включает загрузку файлов, управление папками, корзину, фильтрацию, поиск и многое другое.

🚀 Новое в версии 1.2.3: Добавлен редактор изображений с функцией обрезки (crop) - при клике на кнопку редактирования открывается модальное окно! ✨ Добавлено в версии 1.2.2: Системные иконки папок для корректного отображения! 🐛 Исправлено в версии 1.2.1: Пути к иконкам, ошибка редактирования фото, улучшена обработка альтернативных путей!

Возможности

  • ✅ Загрузка файлов (изображения, видео, документы)
  • ✅ Управление папками с иерархической структурой
  • ✅ Корзина с возможностью восстановления
  • ✅ Фильтрация и поиск файлов
  • ✅ Пагинация
  • ✅ Сортировка
  • ✅ Drag & Drop для папок
  • ✅ Vue компонент для фронтенда
  • ✅ RESTful API
  • ✅ Защищенные папки
  • ✅ Мультипользовательская поддержка (scope по user_id)
  • ✅ Мягкое удаление
  • ✅ Автоматическая генерация превью для изображений

Требования

  • PHP >= 8.2
  • Laravel >= 10.0
  • MySQL/MariaDB или PostgreSQL

Быстрая установка

Минимальная установка (только API)

composer require letoceiling-coder/media
php artisan migrate

Готово! Пакет работает автоматически. Подробнее в QUICK_START.md

⚠️ Важно: Если используете Vue компоненты, обязательно выполните шаги "Полная установка" ниже!

Полная установка (с Vue компонентами)

См. подробную инструкцию: INSTALLATION_STEPS.md

Кратко:

  1. composer require letoceiling-coder/media
  2. php artisan migrate
  3. php artisan vendor:publish --tag=media-components
  4. php artisan vendor:publish --tag=media-styles
  5. Подключите @import './vendor/media.css'; в resources/css/app.css
  6. npm install vue@^3.5.0 vue-router@^4.6.0 fslightbox-vue@^3.0.1 sweetalert2@^11.26.3

Установка

1. Установка через Composer

Установите пакет напрямую:

composer require letoceiling-coder/media

Команда автоматически установит последнюю стабильную версию пакета.

2. Автоматическая установка пакета

После установки через Composer выполните команду автоматической установки:

php artisan media:install

Эта команда автоматически выполнит все необходимые шаги:

  • Публикует миграции в database/migrations/
  • Публикует конфигурацию в config/media.php
  • Публикует Vue компоненты в resources/js/vendor/media/
  • Публикует CSS стили в resources/css/vendor/media.css
  • Публикует системные иконки в public/img/system/media/
  • Проверяет подключение CSS стилей
  • Проверяет наличие роута для редактирования изображений
  • Обнаруживает проблемы с порядком роутов
  • Может автоматически исправить порядок роутов (с опцией --auto-fix-routes)
  • Показывает следующие шаги (миграции, npm установка, роуты)

Опции команды media:install:

  • --force - Перезаписать существующие файлы
  • --no-components - Не публиковать Vue компоненты
  • --no-styles - Не публиковать CSS стили
  • --no-assets - Не публиковать иконки

Примеры:

# Полная установка
php artisan media:install

# Установка с перезаписью существующих файлов
php artisan media:install --force

# Установка без Vue компонентов (только API)
php artisan media:install --no-components --no-styles --no-assets

Примечание: Если пакет не опубликован в Packagist, добавьте репозиторий в composer.json:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/letoceiling-coder/media.git"
        }
    ]
}

Затем установите пакет: composer require letoceiling-coder/media

3. Запуск миграций

php artisan migrate

Пакет автоматически:

  • ✅ Определит и подключит нужный middleware (auth:sanctum или auth:api)
  • ✅ Создаст директорию public/upload при первой загрузке файла
  • ✅ Настроит все необходимые роуты

Примечание: Если пакет не опубликован в Packagist, добавьте репозиторий в composer.json:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/letoceiling-coder/media.git"
        }
    ]
}

Затем установите пакет: composer require letoceiling-coder/media

Ручная публикация файлов (если не использовали media:install)

Если вы не использовали команду php artisan media:install, выполните следующие шаги вручную:

Публикация конфигурации (опционально)

Публикация конфигурации нужна только для кастомизации. Пакет работает с настройками по умолчанию:

php artisan vendor:publish --provider="LetoceilingCoder\Media\MediaServiceProvider" --tag="media-config"

Публикация Vue компонентов

php artisan vendor:publish --tag=media-components

Это опубликует:

  • resources/js/vendor/media/components/Media.vue - полнофункциональный медиа-менеджер
  • resources/js/vendor/media/utils/api.js - утилиты для API запросов
  • resources/js/vendor/media/composables/useAuthToken.js - composable для авторизации

5. Публикация CSS стилей (обязательно для Vue компонентов)

ВАЖНО: Для корректного визуального отображения компонента необходимо опубликовать CSS стили:

php artisan vendor:publish --tag=media-styles

Затем подключите стили в вашем главном CSS файле (resources/css/app.css):

@import './vendor/media.css';

Или в app.js:

import '../css/vendor/media.css'

6. Установка зависимостей для Vue компонентов

npm install vue@^3.5.0 vue-router@^4.6.0 fslightbox-vue@^3.0.1 sweetalert2@^11.26.3

Подробнее о использовании Vue компонентов см. VUE_COMPONENTS.md

7. Публикация изображений (иконки папок, системные изображения) (опционально)

php artisan vendor:publish --tag=media-assets

Это опубликует иконки папок в public/img/system/media/ для использования в компоненте.

Автоматические настройки

Пакет работает "из коробки" без дополнительной настройки. Все настройки имеют оптимальные значения по умолчанию.

Автоматическое определение middleware

Пакет автоматически определяет, какой middleware использовать:

  • Если установлен Laravel Sanctum → использует auth:sanctum
  • Если настроен auth.guards.api → использует auth:api
  • Можно переопределить через конфигурацию или .env

Автоматическое создание директорий

Директория для загрузки файлов (public/upload) создается автоматически при первой загрузке файла или при загрузке ServiceProvider.

Конфигурация

Если нужно изменить настройки, можно:

  1. Использовать переменные окружения (рекомендуется, без публикации конфига):

    MEDIA_MIDDLEWARE_API=auth:sanctum
    MEDIA_MAX_SIZE=10240
    MEDIA_UPLOAD_PATH=upload
    MEDIA_USER_SCOPING=true
  2. Опубликовать и редактировать конфигурацию:

    php artisan vendor:publish --tag=media-config

После публикации конфигурации, настройте файл config/media.php:

return [
    'upload' => [
        'max_size' => 10240, // Максимальный размер файла в KB (по умолчанию 10 MB)
        'allow_all_types' => false, // Разрешить загрузку всех типов файлов
        'allowed_mime_types' => [
            'image/jpeg',
            'image/png',
            'image/gif',
            'image/webp',
            'image/svg+xml',
            'video/mp4',
            // ...
        ],
        'path' => 'upload', // Путь для загрузки файлов
    ],
    
    'pagination' => [
        'per_page_default' => 20,
        'per_page_max' => 100,
    ],
    
    'user_scoping' => true, // Включить фильтрацию по user_id

    'middleware' => [
        // Автоматически определяется, если не указано
        // null = автопределение, 'auth:sanctum' = явно указать
        'api' => env('MEDIA_MIDDLEWARE_API', null),
        
        // Дополнительные middleware
        'additional' => env('MEDIA_MIDDLEWARE_ADDITIONAL', '') 
            ? explode(',', env('MEDIA_MIDDLEWARE_ADDITIONAL', '')) 
            : [],
    ],

    'auto_setup' => [
        // Автоматически создавать директорию для загрузки
        'create_upload_directory' => env('MEDIA_AUTO_CREATE_UPLOAD_DIR', true),
    ],
];

Также можно настроить через переменные окружения в .env:

MEDIA_MAX_SIZE=10240
MEDIA_ALLOW_ALL_TYPES=false
MEDIA_UPLOAD_PATH=upload
MEDIA_PER_PAGE_DEFAULT=20
MEDIA_PER_PAGE_MAX=100
MEDIA_USER_SCOPING=true

Использование

API Endpoints

Пакет автоматически регистрирует следующие роуты:

Folders

  • GET /api/v1/folders - Список папок
  • POST /api/v1/folders - Создать папку
  • GET /api/v1/folders/{id} - Показать папку
  • PUT /api/v1/folders/{id} - Обновить папку
  • DELETE /api/v1/folders/{id} - Удалить папку (переместить в корзину)
  • POST /api/v1/folders/{id}/restore - Восстановить папку из корзины
  • GET /api/v1/folders/tree/all - Получить дерево всех папок
  • POST /api/v1/folders/update-positions - Обновить позиции папок

Media

  • GET /api/v1/media - Список файлов
  • POST /api/v1/media - Загрузить файл
  • GET /api/v1/media/{id} - Показать файл
  • PUT /api/v1/media/{id} - Обновить файл (переместить в другую папку или заменить файл)
  • DELETE /api/v1/media/{id} - Удалить файл (переместить в корзину)
  • POST /api/v1/media/{id}/restore - Восстановить файл из корзины
  • DELETE /api/v1/media/trash/empty - Очистить корзину

Примеры использования API

Загрузка файла

const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('folder_id', folderId); // опционально

fetch('/api/v1/media', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer ' + token
    },
    body: formData
})
.then(response => response.json())
.then(data => console.log(data));

Получение списка файлов с фильтрацией

// Получить файлы из папки
fetch('/api/v1/media?folder_id=1&per_page=20&page=1&sort_by=created_at&sort_order=desc')
    .then(response => response.json())
    .then(data => console.log(data));

// Поиск файлов
fetch('/api/v1/media?search=photo&type=photo')
    .then(response => response.json())
    .then(data => console.log(data));

Создание папки

fetch('/api/v1/folders', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token
    },
    body: JSON.stringify({
        name: 'Новая папка',
        parent_id: null // null для корневой папки
    })
})
.then(response => response.json())
.then(data => console.log(data));

Использование моделей в коде

use LetoceilingCoder\Media\Models\Media;
use LetoceilingCoder\Media\Models\Folder;

// Получить все файлы текущего пользователя
$media = Media::all();

// Получить файлы из конкретной папки
$folder = Folder::find(1);
$files = $folder->files;

// Создать папку
$folder = Folder::create([
    'name' => 'Мои файлы',
    'parent_id' => null
]);

// Загрузить файл (обычно через контроллер)
$media = Media::create([
    'name' => 'filename.jpg',
    'original_name' => 'original.jpg',
    'extension' => 'jpg',
    'type' => 'photo',
    'size' => 1024000,
    'folder_id' => $folder->id,
    // ...
]);

Использование Vue компонента

После публикации компонента, импортируйте его в ваше приложение:

<template>
    <Media 
        v-if="showMediaManager"
        :selection-mode="false"
        :count-file="1"
        @file-selected="handleFileSelected"
    />
</template>

<script setup>
import Media from '@/vendor/media/Media.vue'

const showMediaManager = ref(true)

const handleFileSelected = (file) => {
    console.log('Выбран файл:', file)
}
</script>

Структура базы данных

Таблица folders

  • id - ID папки
  • name - Название папки
  • slug - URL-слаг
  • src - Иконка папки
  • parent_id - ID родительской папки
  • position - Позиция для сортировки
  • protected - Защищена ли папка от удаления
  • is_trash - Является ли папка корзиной
  • user_id - ID пользователя (для мультипользовательского режима)
  • created_at, updated_at, deleted_at

Таблица media

  • id - ID файла
  • name - Имя файла на сервере
  • original_name - Оригинальное имя файла
  • extension - Расширение файла
  • disk - Диск для хранения
  • width - Ширина изображения (для фото)
  • height - Высота изображения (для фото)
  • type - Тип файла (photo, video, document)
  • size - Размер файла в байтах
  • folder_id - ID папки
  • original_folder_id - ID оригинальной папки (для восстановления из корзины)
  • user_id - ID пользователя
  • telegram_file_id - ID файла в Telegram (если был загружен оттуда)
  • metadata - Дополнительные метаданные (JSON)
  • temporary - Временный ли файл
  • created_at, updated_at, deleted_at

Авторизация

По умолчанию API не защищено middleware авторизации. Для защиты добавьте middleware в контроллеры или через MediaServiceProvider:

// В MediaServiceProvider::boot()
Route::prefix('api/v1')
    ->middleware(['api', 'auth:sanctum']) // Добавьте middleware
    ->group(function () {
        // роуты...
    });

Фильтрация по пользователям

Пакет поддерживает автоматическую фильтрацию по user_id через scope. Это можно включить/выключить через конфигурацию:

'user_scoping' => true // или false для отключения

При включенной фильтрации:

  • Пользователи видят только свои файлы и папки
  • Системные папки (с user_id = NULL) доступны всем
  • Корзина общая для всех пользователей

Для обхода scope используйте:

// Получить все файлы без фильтрации по user_id
$allMedia = Media::withoutUserScope()->get();

// Получить файлы конкретного пользователя
$userMedia = Media::forUser($userId)->get();

// Получить файлы всех пользователей
$allUsersMedia = Media::allUsers()->get();

Расширение

Добавление кастомных фильтров

Создайте свой фильтр:

namespace App\Http\Filters;

use LetoceilingCoder\Media\Http\Filters\AbstractFilter;
use Illuminate\Database\Eloquent\Builder;

class MediaFilter extends AbstractFilter
{
    public const TYPE = 'type';
    
    protected function getCallbacks(): array
    {
        return [
            self::TYPE => [$this, 'type'],
        ];
    }
    
    public function type(Builder $builder, $value)
    {
        $builder->where('type', $value);
    }
}

Кастомизация моделей

Если нужно расширить функциональность моделей, создайте свои модели, наследуя от моделей пакета:

namespace App\Models;

use LetoceilingCoder\Media\Models\Media as BaseMedia;

class Media extends BaseMedia
{
    // Ваша кастомизация
}

Поддержка

Для вопросов и предложений создайте issue в репозитории: https://github.com/letoceiling-coder/media

Лицензия

MIT License

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published