Версия: 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
composer require letoceiling-coder/media
php artisan migrateГотово! Пакет работает автоматически. Подробнее в QUICK_START.md
⚠️ Важно: Если используете Vue компоненты, обязательно выполните шаги "Полная установка" ниже!
См. подробную инструкцию: INSTALLATION_STEPS.md
Кратко:
composer require letoceiling-coder/mediaphp artisan migratephp artisan vendor:publish --tag=media-componentsphp artisan vendor:publish --tag=media-styles- Подключите
@import './vendor/media.css';вresources/css/app.css npm install vue@^3.5.0 vue-router@^4.6.0 fslightbox-vue@^3.0.1 sweetalert2@^11.26.3
Установите пакет напрямую:
composer require letoceiling-coder/mediaКоманда автоматически установит последнюю стабильную версию пакета.
После установки через 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 установка, роуты)
--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
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
Если вы не использовали команду php artisan media:install, выполните следующие шаги вручную:
Публикация конфигурации нужна только для кастомизации. Пакет работает с настройками по умолчанию:
php artisan vendor:publish --provider="LetoceilingCoder\Media\MediaServiceProvider" --tag="media-config"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 для авторизации
ВАЖНО: Для корректного визуального отображения компонента необходимо опубликовать CSS стили:
php artisan vendor:publish --tag=media-stylesЗатем подключите стили в вашем главном CSS файле (resources/css/app.css):
@import './vendor/media.css';Или в app.js:
import '../css/vendor/media.css'npm install vue@^3.5.0 vue-router@^4.6.0 fslightbox-vue@^3.0.1 sweetalert2@^11.26.3Подробнее о использовании Vue компонентов см. VUE_COMPONENTS.md
php artisan vendor:publish --tag=media-assetsЭто опубликует иконки папок в public/img/system/media/ для использования в компоненте.
Пакет работает "из коробки" без дополнительной настройки. Все настройки имеют оптимальные значения по умолчанию.
Пакет автоматически определяет, какой middleware использовать:
- Если установлен Laravel Sanctum → использует
auth:sanctum - Если настроен
auth.guards.api→ используетauth:api - Можно переопределить через конфигурацию или
.env
Директория для загрузки файлов (public/upload) создается автоматически при первой загрузке файла или при загрузке ServiceProvider.
Если нужно изменить настройки, можно:
-
Использовать переменные окружения (рекомендуется, без публикации конфига):
MEDIA_MIDDLEWARE_API=auth:sanctum MEDIA_MAX_SIZE=10240 MEDIA_UPLOAD_PATH=upload MEDIA_USER_SCOPING=true
-
Опубликовать и редактировать конфигурацию:
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Пакет автоматически регистрирует следующие роуты:
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- Обновить позиции папок
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- Очистить корзину
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,
// ...
]);После публикации компонента, импортируйте его в ваше приложение:
<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>id- ID папкиname- Название папкиslug- URL-слагsrc- Иконка папкиparent_id- ID родительской папкиposition- Позиция для сортировкиprotected- Защищена ли папка от удаленияis_trash- Является ли папка корзинойuser_id- ID пользователя (для мультипользовательского режима)created_at,updated_at,deleted_at
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