Баг з переміщенням папки 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:
Після переміщення ядра 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 запит:
UPDATE wp_posts SET post_content = REPLACE (post_content, 'http://example.com/uploads/', 'http://example.com/content/uploads/');
І про всяк випадок перейменував всі поля guid у вкладень, для цього я зробив міні-плагін .
Навіщо це все?
До того, що якщо ви раптом будите на старому сайті переміщати базові папки WordPress, то зайдіть у всі опції: http://ВАШСАЙТ/wp-admin/options.php
і перевірте, чи не встановлені у вас опції upload_path
і upload_url_path
вони в 99% випадків не потрібні з версії WP 3.0+ і їх можна просто видалити. До речі, на цьому блозі вони теж були і я їх видалив…
У тих випадках, коли вони потрібні, ви швидше за все знатимете про це і ця стаття буде вам не цікава
Також не намагайтеся перенести папку 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 буде основний, а не поточного сайту, на який переключилися.