WordPress как на ладони
wordpress jino

Баг с перемещением папки uploads

Похоже напоролся на баг в WordPress, который связан с каталогом загрузок wp-content/uploads. Хотя утверждать что это баг я не буду, но логика точно отсутствует...

По порядку, дело было так: есть у меня старый сайт, который работает еще с версии WP 2+. При его создании я переместил папку файлов uploads в корень сайта. Для этого определил константу в wp-config.php:

define('UPLOADS', 'uploads'); // значит что папка uploads должна лежать в корне сайта

Также, переименовал папку контента с wp-content на content. Для этого определил константы в том же wp-config.php:

define('WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'].'/content');
define('WP_CONTENT_URL', 'http://'. $_SERVER['HTTP_HOST'] .'/content');

Все работало до недавнего времени...

Недавно я переместил ядро WordPress в отдельную папку wp - это удобно. Теперь, получилось: ядро лежит в папке wp, плагины и т.д. в content и файлы в uploads и все это в корне сайта.

Для тех кто не знает, в WordPress можно логически разделить файлы содержимого (wp-contents) и файлы движка (wp-includes, wp-admin, ...). При этом в настройках устанавливаются 2 разных УРЛ: адрес сайта и адрес WordPress:

wpurls

После перемещения ядра WordPress, в медиатеке у меня пропали картинки. Посмотрев на УРЛ картинок я увидел что УРЛ изменился с /uploads на /wp/uploads при этом я не менял ранее установленную константу UPLOADS.

Заглянув в код _wp_upload_dir() (эта функцию лежит в основе получения всех ссылок на файлы) увидел, что ссылка (url) строиться из объединения UPLOADS с опцией siteurl, а путь (path) строиться так: ABSPATH . UPLOADS.

if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
	$dir = ABSPATH . UPLOADS;
	$url = trailingslashit( $siteurl ) . UPLOADS;
}

Это значит что за основу берется не корень сайта, а папка где находится ядро WordPress, и если это вложенный каталог, то UPLOADS будет относится уже к этому каталогу. Это не логично, потому что едва ли можно отнести папку с файлами сайта к понятию движок... Это контент сайта!

«OK», - сказал я, по-английски. А затем по русски: «раз нельзя определить константу UPLOADS так, чтобы файлы «смотрели» на корень сайта, а не корень движка, то будем удалять». И удалил константу UPLOADS из wp-config.php, а затем переместил папку uploads в папку контента - content.

В итоге общая структура получилась такая:

/wp/wp-admin
/wp/wp-includes
/content
/content/uploads

Далее, чтобы проверить все ли работает как надо, я попробовал загрузить картинку в медиатеку, но картинка загрузилась не в ожидаемую папку: /content/uploads/..., а все в туже подпапку движка: /wp/uploads/....

Расследование показало, что в настройках WP установлена опция upload_path, которая с версий 3.0 не является обязательной и по умолчанию не устанавливается. А у меня там было значение uploads тоже самое что я установил когда-то в константе UPLOADS.

Чтобы решить проблему, я просто удалил опцию upload_path. Заменил все старые ссылки в контенте на новые. Для этого использовал простой плагин SQL Executioner и такой запрос:

UPDATE wp_posts SET post_content = REPLACE (post_content, 'http://site.ru/uploads/', 'http://site.ru/content/uploads/');

И на всякий случай переименовал все поля guid у вложений, для этого я сделал мини-плагин, как раз недавно.

К чему это все?

К тому, что если вы вдруг будите на старом сайте перемещать базовые папки WordPress, то зайдите во все опции: http://ВАШСАЙТ/wp-admin/options.php и проверьте не установлены ли у вас опции upload_path и upload_url_path они в 99% случаев не нужны с версии WP 3.0+ и их можно просто удалить. К слову на этом блоге они тоже были и я их удалил...

В тех случаях, когда они нужны, вы скорее все будите знать об этом и эта статья будет вам не интересна smile

Также, не пытайтесь перенести папку uploads за пределы папки контента (по умолчанию wp-contents). Это у вас не получится, если WP вынесен в отдельную папку. Или это вызовет проблемы, если в будущем вы заходите вынести файлы движка в отдельную папку.

Выше упомянул что опции нужны в 99%, но есть 1% когда опция upload_url_path нужна - это когда у нас включен мультисайт и мы переместили папку контента или ядро ВП. В обоих случаях нам придется установить константу WP_CONTENT_URL. Далее, при переключении в одном блоге сети на другой с помощью switch_to_blog(). Мы поймаем баг, потому что во многих функциях, например получение URL картинки (см. wp_get_attachment_url() и _wp_upload_dir()) ВП использует константу WP_CONTENT_URL, а она при переключении будет относится к текущему блогу, а не к тому на который переключились. Вот для таких случаев нужна опция upload_url_path, потому что сначала проверяется её значение и только потом используется константа, если в опции пусто.

Обращу еще внимание на то, что Url на загруженные файлы даже при установленной константе WP_CONTENT_URL, все равно остается рабочим при переключении на другой блог. Только домен этого URL будет основной, а не текущего сайта на который переключились.

Баг с перемещением папки uploads 3 комментария
  • Роман

    Сперва:

    Недавно я переместил ядро WordPress в отдельную папку wp - это удобно. Теперь, получилось: ядро лежит в папке wp, плагины и т.д. в content и файлы в uploads и все это в корне сайта.

    Затем:

    Также, не пытайтесь перенести папку uploads за пределы папки контента (по умолчанию wp-contents). Это у вас не получится, если WP тоже вынесен в отдельную папку и вызовет проблемы, если в будущем вы заходите вынести WP.

    В итоге какой получилась структура?

    ./wp/wp-admin
    ./wp/wp-includes
    ./content
    ./uploads
    1
    Ответить1.9 года назад #
    • Kama4662

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

      /wp/wp-admin
      /wp/wp-includes
      /content
      /content/uploads
      1
      Ответить1.9 года назад #
  • Сергей cайт: newwebmaster.ru

    тоже считаю нелогичным.
    Баловался с разными вариантами установки, пришел к такому же как у тебя:
    правда у меня это папки
    /content
    и
    /core

    В результате многочисленных мучений так и не смог вынести папку uploads в корень, как раз в виду описанного тобой. Так и приходится держать ее в папке /content

    Ответитьгод назад #

Здравствуйте, !

Ваш комментарий