Разработка системы медиа-библиотеки для CMS сайта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка системы медиа-библиотеки для CMS сайта
Средняя
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Разработка системы медиа-библиотеки для CMS сайта

Медиа-библиотека — централизованное хранилище и интерфейс управления файлами: изображениями, видео, документами. Вместо загрузки одного файла для каждой записи, редактор выбирает из уже загруженных — меньше дублей, меньше затрат на хранение.

Модель данных

media_files (
  id, original_name, file_name, disk, path,
  mime_type, size,
  width, height,        -- для изображений
  alt, title, caption,  -- SEO и доступность
  folder_id,
  uploaded_by,
  created_at, updated_at
)

media_folders (
  id, name, parent_id, created_at
)

media_conversions (
  id, media_id, name,  -- 'thumb', 'medium', 'large'
  file_name, width, height, size, created_at
)

Загрузка файлов через presigned URL

Загрузка напрямую с браузера на S3 — без нагрузки на сервер:

// Сервер генерирует presigned URL
$s3 = new S3Client([...]);
$cmd = $s3->getCommand('PutObject', [
    'Bucket'      => env('AWS_BUCKET'),
    'Key'         => "uploads/temp/{$uuid}/{$filename}",
    'ContentType' => $mimeType
]);
$presigned = $s3->createPresignedRequest($cmd, '+15 minutes');

return ['upload_url' => (string)$presigned->getUri(), 'key' => $key];
// Клиент загружает напрямую на S3
const { upload_url, key } = await getPresignedUrl(file);
await fetch(upload_url, { method: 'PUT', body: file, headers: { 'Content-Type': file.type } });

// Подтвердить загрузку серверу
await confirmUpload(key, { alt: '', title: file.name });

Генерация превью

После загрузки — асинхронная генерация версий через очередь:

class GenerateImageConversions implements ShouldQueue
{
    public function handle(): void
    {
        $conversions = [
            'thumb'  => ['width' => 150,  'height' => 150],
            'medium' => ['width' => 800,  'height' => null],
            'large'  => ['width' => 1920, 'height' => null],
            'webp'   => ['width' => null, 'height' => null, 'format' => 'webp']
        ];

        foreach ($conversions as $name => $params) {
            $image = Image::make(Storage::get($this->media->path));
            if ($params['width']) {
                $image->resize($params['width'], $params['height'], fn($c) => $c->aspectRatio());
            }
            if (isset($params['format'])) {
                $image->encode($params['format'], 85);
            }
            Storage::put("media/conversions/{$this->media->id}/{$name}", $image->stream());
        }
    }
}

Интерфейс медиа-библиотеки

Основные возможности UI:

  • Сетка файлов с превью (или список)
  • Фильтры: тип файла, папка, дата
  • Поиск по имени и alt-тексту
  • Загрузка drag-and-drop или кнопкой
  • Создание папок
  • Множественный выбор для массовых операций
  • Редактирование alt, title, caption прямо в библиотеке
  • Копирование URL в буфер обмена

Виджет выбора медиа для редактора

function MediaPickerButton({ onSelect, multiple = false }) {
    const [isOpen, setIsOpen] = useState(false);

    return (
        <>
            <Button onClick={() => setIsOpen(true)}>Выбрать из библиотеки</Button>
            <Dialog open={isOpen} onOpenChange={setIsOpen}>
                <DialogContent className="max-w-4xl h-[80vh]">
                    <MediaLibraryGrid
                        onSelect={(files) => {
                            onSelect(multiple ? files : files[0]);
                            setIsOpen(false);
                        }}
                        multiple={multiple}
                    />
                </DialogContent>
            </Dialog>
        </>
    );
}

Очистка неиспользуемых файлов

// Scheduled job: найти файлы без привязок
$unused = MediaFile::whereDoesntHave('usages')
    ->where('created_at', '<', now()->subDays(30))
    ->get();

foreach ($unused as $file) {
    Storage::delete($file->path);
    $file->delete();
}

Срок разработки: 3–4 недели для полной медиа-библиотеки с генерацией превью, папками и виджетом выбора.