Перейти к содержимому
davidka.net > 💻 🧠 Код 1001 > 📖 Гайды > Как сделать мультиязычный сайт на поддоменах в WordPress. > Как настроить общую медиабиблиотеку в WordPress Multisite: Пошаговое решение проблемы

Как настроить общую медиабиблиотеку в WordPress Multisite: Пошаговое решение проблемы

  • автор:

При работе с WordPress Multisite часто возникает необходимость использовать одну медиабиблиотеку для всех подсайтов сети. По умолчанию каждый подсайт имеет собственную изолированную папку для медиафайлов (/wp-content/uploads/sites/{blog_id}/), что создает дублирование и усложняет управление контентом.

Проблема

В стандартной настройке WordPress Multisite:

  • Основной сайт использует папку /wp-content/uploads/
  • Подсайты используют /wp-content/uploads/sites/{site_id}/
  • Каждый сайт имеет отдельные таблицы для медиа: wp_posts, wp_2_posts, wp_3_posts и т.д.

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

Решение 1: Символические ссылки

ln -s /path/to/wp-content/uploads /path/to/wp-content/uploads/sites/2

Решение 2: плагин для исправления URL

Основная проблема заключается в том, что WordPress генерирует неправильные URL для медиафайлов на подсайтах. Создайте плагин для исправления этой проблемы:

<?php
/*
Plugin Name: Fix Multisite Media URLs
Description: Исправляет URL медиафайлов на подсайтах Multisite
Version: 1.0.0
Network: true
*/
if (!defined('ABSPATH')) {
    exit;
}
class FixMultisiteMediaUrls {
    
    public function __construct() {
        if (!is_multisite()) {
            return;
        }
        
        add_filter('wp_get_attachment_url', [$this, 'fix_attachment_url'], 10, 2);
        add_filter('wp_get_attachment_image_src', [$this, 'fix_attachment_image_src'], 10, 4);
        add_filter('upload_dir', [$this, 'fix_upload_dir']);
        add_filter('the_content', [$this, 'fix_content_urls']);
        add_filter('rest_prepare_attachment', [$this, 'fix_rest_api_urls'], 10, 3);
    }
    
    /**
     * Исправляет URL вложений, убирая /sites/{blog_id}/ из путей
     */
    public function fix_attachment_url(string $url, int $post_id): string {
        if (is_main_site() || defined('WPM_TRANSLATION_PROCESSING')) {
            return $url;
        }
        
        $blog_id = get_current_blog_id();
        $pattern = '/\/sites\/' . $blog_id . '\//';
        return preg_replace($pattern, '/', $url);
    }
    
    /**
     * Исправляет источники изображений
     */
    public function fix_attachment_image_src($image, int $attachment_id, $size, bool $icon) {
        if (is_main_site() || !$image || defined('WPM_TRANSLATION_PROCESSING')) {
            return $image;
        }
        
        if (is_array($image) && isset($image[0])) {
            $image[0] = $this->fix_attachment_url($image[0], $attachment_id);
        }
        
        return $image;
    }
    
    /**
     * Направляет загрузку файлов в общую папку
     */
    public function fix_upload_dir(array $dirs): array {
        if (is_main_site() || defined('WPM_TRANSLATION_PROCESSING')) {
            return $dirs;
        }
        
        switch_to_blog(1);
        $main_dirs = wp_upload_dir();
        restore_current_blog();
        
        return $main_dirs;
    }
    
    /**
     * Исправляет URL в контенте постов
     */
    public function fix_content_urls($content) {
        if (is_main_site() || defined('WPM_TRANSLATION_PROCESSING')) {
            return $content;
        }
        
        $blog_id = get_current_blog_id();
        $pattern = '/\/wp-content\/uploads\/sites\/' . $blog_id . '\//';
        $replacement = '/wp-content/uploads/';
        
        return preg_replace($pattern, $replacement, $content);
    }
    
    /**
     * Исправляет URL в REST API для Gutenberg
     */
    public function fix_rest_api_urls($response, $post, $request) {
        if (is_main_site() || defined('WPM_TRANSLATION_PROCESSING')) {
            return $response;
        }
        
        $data = $response->get_data();
        
        if (isset($data['source_url'])) {
            $blog_id = get_current_blog_id();
            $pattern = '/\/sites\/' . $blog_id . '\//';
            $data['source_url'] = preg_replace($pattern, '/', $data['source_url']);
        }
        
        if (isset($data['media_details']['sizes'])) {
            foreach ($data['media_details']['sizes'] as $size => $details) {
                if (isset($details['source_url'])) {
                    $blog_id = get_current_blog_id();
                    $pattern = '/\/sites\/' . $blog_id . '\//';
                    $data['media_details']['sizes'][$size]['source_url'] = 
                        preg_replace($pattern, '/', $details['source_url']);
                }
            }
        }
        
        $response->set_data($data);
        return $response;
    }
}
new FixMultisiteMediaUrls();

Плагин перехватывает генерацию URL медиафайлов на подсайтах и исправляет их:

До:

https://ru.yoursite.com/wp-content/uploads/<strong>sites/2</strong>/2025/01/image.jpg

После:

https://ru.yoursite.com/wp-content/uploads/2025/01/image.jpg

Диагностика проблем

Если медиафайлы не отображаются, проверьте:

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

-- Проверьте существование подсайтов
SELECT blog_id, domain, path FROM wp_blogs;

-- Проверьте наличие медиа в таблицах
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'attachment';
SELECT COUNT(*) FROM wp_2_posts WHERE post_type = 'attachment';

2. Пути к файлам

-- Проверьте пути в метаданных
SELECT post_id, meta_key, meta_value 
FROM wp_2_postmeta 
WHERE meta_key = '_wp_attached_file' 
LIMIT 5;

Символические ссылки

Для продвинутых пользователей можно создать symlink:

ln -s /path/to/wp-content/uploads /path/to/wp-content/uploads/sites/2

Ограничения и рекомендации

  1. Безопасность: Создавайте резервные копии базы данных перед внесением изменений
  2. Совместимость: Плагин учитывает работу с WP Multilang и другими мультиязычными решениями
  3. Производительность: При большом количестве медиафайлов рекомендуется поэтапная миграция
  4. Обновления: Следите за совместимостью при обновлении WordPress

Заключение

Данное решение позволяет использовать единую медиабиблиотеку для всех сайтов в сети WordPress Multisite, избежав дублирования файлов и упростив управление контентом. Плагин автоматически исправляет URL и обеспечивает корректное отображение медиафайлов на всех подсайтах.

Решение протестировано на WordPress версий 5.0+ и совместимо с современными редакторами, включая Gutenberg.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *