WordPress: Делаем свои меню, переезжаем на HTTPS/хостинг и сортируем картинки в комменариях

Число просмотров: 2 088 

Всякие фишечки для моего блога: верхний баннер-меню, переезд на HTTPS, перетряхивание картинок в комментариях

Всякие фишечки для моего блога: верхний баннер-меню, переезд на HTTPS, перетряхивание картинок в комментариях

Йо! Я неожиданно для себя попробовал — и перевёл блог на HTTPS. В основном — ради вас, потому что сейчас трендом всех браузеров стало вываливать на все сайты без HTTPS предупреждение вида «Ваши данные могут своровать, не вводите тут пароли». Многие даже и правда верят и пугаются! Вторая причина — это такая же фигня с поисковиками: все сайты без HTTPS сейчас сваливаются вниз поиска, а мне этого не хочется.

Кода сайт, которому аж 10 лет, переезжает, то хипстерские руководства, которыми забиты поисковики (типа «ну, поменяйте тут и там — и всё будет хорошо»), не годятся: они не всё учитывают. Поэтому мне пришлось вчера знатно покопаться руками в базе и её полях и составить кучку удобных SQL-запросов. Но, хех, потом возникла классная наколочка с заебавшими меня картинками в комментариях: просто так заменить в их ссылках «HTTP» на «HTTPS» не прокатило! И пришлось мне писать скрипт для их обработки. Сегодня весь день писал и отлаживал.

Попутно мы запустили парочку проектов (сайт подруги и сайт для Кирича), которые до этого валялись у меня на хостинге на тестовых поддоменах. И вот тут-то у меня тоже набрался опыт переездов сайтов на WordPress и то, что надо делать, чтобы исправить ошибку «Извините, вам не разрешено просматривать эту страницу» на входе в админку блога, который перенесли на другую базу.

А ещё я всё грожусь переписать все правила… грожусь, грожусь… а вместо этого переписал верхнее меню блога так, чтобы оно состояло из трёх отдельных частей: «Контакты», «Услуги», «Дополнительное». А ещё я придумал, как сделать слайдер лучших работ вверху блога без грёбаных плагинов!

Вот сегодня я сделаю сборный пост и расскажу про все эти фишки. Я приношу огромные извинения за то, что некоторые вставки SQL- и PHP-кода у меня не будут отформатированы. Я честно поискал плагин для подсветки синтаксиса, нашёл один простой — и после описания «Пост можно редактировать только в режиме голого текста, иначе всё сломается» стёр этот плагин нахуй к ебеням. Простите! Все длинные куски кода выложу на хостинг текстовыми файлами!

1. Делаем новые меню для темы и верхний баннер с удобной настройкой через меню.

Начинаем со слайдера. Это меня подруга и Кирич подговорили! Они все сделали себе эти слайдеры… а я думал-думал — и тоже решил заморочиться и сделать блог чуток попривлекательней для клиентов. Вообще, моя основная задумка — это перетряхнуть меню таким образом, чтобы все ссылки стояли там так, как мне удобно — по группам. Я это уже начал делать и сейчас расскажу то, что я для этого придумал!

Основной концепт моего нового меню такой: я захотел вытащить контакты (Мои, ЮТуб и будущий Инстаграм) в шапку блога, чтобы они были на виду. А потом я захотел разделить остальные пункты меню на две строки так, чтобы в первой было всё, что относится к работе (сборка щитов, сценосвет, консультации), а во второй — остальные ссылки (правила блога, сообщество, коллеги и прочие). Самый жЫр потом будет в пункте меню «Что я могу?» — там я хочу выписать все идеи и решения, которые можно запихать в или автоматику со ссылками на посты, где про это рассказывалось. Хочу, чтобы мои новые заказчики не читали 10 постов про щитосборки, а читали так: «Управлять светом можно через ОВЕН так-то. В этом случае нужно то, то и то — и вот щиты, которые так работают».

Верхний баннер моего блога (на слайдере Slick)

Верхний баннер моего блога (на слайдере Slick)

Ну, это теория! А практика как? Шо делать? В моей старой теме верхнее «меню» генерировалось автоматически из всех страниц (Pages), которые были созданы. Каждая страница блога автоматически становилась новым пунктом меню, а поменять можно было только порядок их следования. С камрадом, который помогает мне по блогу, мы подкрутили CSS так, чтобы меню переносилось на несколько строк. Но это было уёбищно! Но и хрен бы с ним, если бы в этом перенесённом на несколько строк меню списке страниц можно было бы разобраться, а не искать ссылку на контакты где-то слева на второй строке…

Слышал я что-то о том, что в WordPress есть штатный функционал меню и что тема должна его поддерживать. И что это меню можно программировать самому. Разобрался — и рассказываю теперь вам.

Задумка с меню в WordPress следующая:

  • Прежде, чем что-то делать, надо врубить поддержку меню в теме. Это делается через вызов функции: add_theme_support(‘menus’). Всё, теперь тема поддерживает меню! =)
  • «Меню» — это набор пунктов. Каждый пункт может быть ссылкой на страницы, посты, рубрики или произвольные URL. Важно понимать, что меню в данный момент — просто набор этих ссылок, и всё. Оно нигде не будет показываться, если не привязать его к нужной области темы.
  • «Область» — это название (ID) места, где будет выводиться какое-нибудь меню. Области создаёт программист-разработчик темы блога. Называть их можно любыми именами, типа «Верхнее», «Услуги», «В товарах» и так далее. В админке WordPress для каждой из областей можно назначить одно из заранее созданных меню и в любой момент это назначение поменять.
  • В том месте темы блога, где нужно вывести меню, надо сделать вызов штатной функции WordPress — «wp_nav_menu()«, указав ID области нашего меню. То есть, примерно так: wp_nav_menu(‘menu=TopContacts’);.

На этом простой штатный функционал WordPress и тех, кто про него пишет, заканчивается. Функция wp_nav_menu() позволяет указать CSS-классы для текущего меню, чтобы вы могли прописать его внешний вид и оформление — и всё.

А мне надо БОЛЬШЕ, потому что я хочу сделать:

  • Специальное верхнее меню, в котором будут автоматически пихаться ссылки на регистрацию, вход и выход на блог.
  • Более правильно выводить обычные меню со своим форматированием.
  • Сделать так, чтобы пункты верхнего баннера тоже выглядели как меню: не хочу я админку для баннера писать!

И вот во всех этих требованиях я натолкнулся на главную жопу: wp_nav_menu() выводит меню в законченном виде! Оно начинается с <UL> и закрывается тоже тэгом </UL>. А ведь у меня стоит задача дописать в это меню свои пункты! И как быть? Тэг <UL> уже закрыт, пиздец! Писать меню, вложенное в имитацию меню? Это уже вёрстка с ума сойдёт!

Стал я копать дальше и наткнулся на более глубокие и зверские функции: «wp_get_nav_menu_object()» / «wp_get_nav_menu_items()«. Первая из них возвращает ссылку на объект выбранного для указанной области меню, а вторая умеет доставать из этого меню данные его пунктов (название, ссылка, подсказка). Вот когда у нас на руках будут голые данные — то тогда-то мы оторвёмся с вёрсткой как хотим!

Первое, с чего мы начинаем — это херачим поддержку меню и регистрируем свои области в теме:

if (function_exists(‘add_theme_support’)){ add_theme_support(‘menus’); }
if(function_exists(‘register_nav_menus’))
{
register_nav_menus( array(
‘csm_hdr’ => ‘CS: В заголовке’,
‘csm_main’ => ‘CS: Основное’,
‘csm_smain’ => ‘CS: Дополнительное’,
‘csm_topb’ => ‘CS: Слайдер сверху’
));

Штучки с названиями «csm_xxxx» — это ID областей. А текст — это понятные человеку названия. Теперь наша тема сразу же всё поддерживает:

Меню, которые теперь поддерживает моя тема (после того, как я допрограммировал её)

Меню, которые теперь поддерживает моя тема (после того, как я допрограммировал её)

Ну а дальше мне оставалось получить свои меню, вытащить из них пункты и в цикле сверстать и вывести мои меню так, как мне хочется. Вот примерно так выглядит этот код:

Код для вывода меню WordPress при помощи своего алгоритма

Код для вывода меню WordPress при помощи своего алгоритма

Дальше в нужных местах темы я вызываю свою функцию, которая генерирует мне готовый HTML-код для моих меню! Ура!

Теперь будем колдовать над верхним слайдером-баннером! Смысл колдовства следующий: ежели поискать в инете, то вы найдёте кучу ёбаных (да-да!) плагинов для слайдеров, баннеров, галерей и ещё хер знает чего. Эти плагины хороши, если вы вставляете по дохера слайдеров в каждый пост: тогда их мощный функционал и то, как они засирают собой базу данных и метаданные, будет хотя бы оправдан. Мне же нужен один-единственный слайдер сверху — и всё!

Стал я искать — и нашёл, что почти все эти плагины юзают один-единственный мощный скрипт слайдера — Slick.js (вот ссылка на его страницу). Он вызывается простым и понятным кодом типа такого (показать сразу три слайда, прокручивать по одному):

$(‘.multiple-items’).slick({
infinite: true,
slidesToShow: 3,
slidesToScroll: 1
});

Но это ж просто скрипт! А всё остальное — подключать его к теме, писать сами слайды, надо делать с нуля руками! И вот я долго ломал голову с тем, как быть с админкой моего баннера. Сначала я думал, что мне понадобится писать какой-то интерфейс чуть ли не на Ajax в виде кнопок «Добавить слайд», «Удалить слайд», делать обработку перетаскивания их между собой, сохранения этих настроек… Но я же совсем не умею это делать! Как быть?

И тут я снова вспомнил про функцию «wp_get_nav_menu_items()«, которая умеет отдавать необработанные внутренние значения для каждого пункта меню (у меня он находится в переменной «$menu_item»). Если порыть докуму, то мы найдём следующие поля:

  • $menu_item->title. В WP зовётся как «Текст ссылки» = навание слайда;
  • $menu_item->url. В WP зовётся как «URL» = URL, куда идти с баннера;
  • $menu_item->post_excerpt. В WP зовётся как «Атрибут title» = URL картинки слайда (RAW).

ВАУ! УРА! И теперь мой слайдер-баннер тоже настраивается через штатные менюшки WordPress через пункт «Произвольная ссылка» вот так:

Настройка верхнего баннера через виртуальное меню блога

Настройка верхнего баннера через виртуальное меню блога

Вот и готова админка для баннера! =) Ничего писать не надо, а надо считать пункты меню и выдать их в виде <DIV>-кондейнеров для слайда таким же образом, как мы пункты меню выводили — в цикле!

Но это ещё не всё! =)) Дальше, казалось бы, уже конец: осталось подключить скрипты самого слайдера Slick.js, сделать красивый его вызов… и хуй там! Если делать всё по инструкциям разработчика, то на WordPress или любом другом сайте, где уже используется библиотека «jQuery» будут грёбаные конфликты. А на WordPress ещё и будут конфликты с тем, что сначала будет грузиться скрипт слайдера, вываливаться в ошибки, а потом подгружаться остальные скрипты WordPress и тот самый jQuery…

Поэтому мне в моей теме понадобилось переписать загрузку скриптов так, чтобы скрипты имели приоритет загрузки. Для этого надо сделать обработчик на «wp_enqueue_scripts» так: add_action( ‘wp_enqueue_scripts’, ‘cs_theme_scripts’ );

А потом в функции «cs_theme_scripts()» нахерачить зависимые вызовы скриптов:

Пример вызовов загрузки скриптов так, чтобы они зависели друг от друга

Пример вызовов загрузки скриптов так, чтобы они зависели друг от друга

Здесь используются зависимости. Они показаны красными стрелками: в функции wp_enqueue_script мы передаём название (ID) скрипта, который грузим и список скриптов, от которых он должен зависеть. После этого скрипты будут грузиться в нужном порядке и косяков не будет.

Однако всё равно есть ещё один косяк! =)) Это то, что Google Chrome нагло кеширует все JS- и CSS-файлы по умолчанию так, что даже Ctrl+F5 не помогает! И я минут 10 не понимал, почему у меня на компе на FireFox слайдер поменял свой тип работы (после того, как я подкрутил slick-init.js), а на WEB-панели от ОВЕНа (где есть Хром) — ни хера.

Оказалось, что чтобы заставить хром перезагрузить JS- или CSS-файл, надо поменять его имя… или добавить какой-нить незначащий параметр так, чтобы сам URL файла поменялся. Вот я и добавил «v=1» в конце: «/js/slick-init.js?v=1». Тогда заработало! Я знаю, что некоторые разработчики из-за этого вообще херачат сюда случайное число, чтобы важные скрипты каждый раз загружались заново.

И ещё фишка. Если у вас стоит jQuery (а на WordPress он всегда стоит), то писать строку инициализации Slick.js надо не как в инструкции, а так: jQuery( document ).ready(function( $ ){ …

После этих фишек у меня всё заработало на ура, а мне не понадобилось писать админку баннера или ставить плагины! ^_^ Код для этого всего я выложил в этом файле: WP-Menu-Functions.txt.

2. Если блог переезжает в другое место (хостинг, база, HTTPS): что и где менять?

Теперь сделаю небольшую заметку про то, сколько всего надо НЕ забыть, когда вы переносите блог на другой хостинг и другую базу данных. Мой блог никуда не переезжал, а вот блоги моих камрадов — да! Конечно же, переездом занимался я, и поэтому придумал для этого свои фишки и технологии.

Если надо перенести блог WordPress на другой хостинг, то менять надо вот чего (мы НЕ говорим про обычные параметры, которые меняются в config.php):

  • Привязку к базе данных и именам таблиц. Кое-где прямо в самой же базе в именах ключей используется префикс таблиц (стандартный — «wp_», например «wp_posts»). А этот префикс в целях безопасности я люблю менять! Поэтому надо не забывать менять все ссылки на него прямо внутри базы данных!
  • Привязку к базовому URL: внутри WordPress ВСЕ ссылки составляются в виде полного пути (http://lalala.ru/bla-bla-post). И если ваш сайт переезжает с «lalala.ru» на «meow.net», то ВЕЗДЕ — в постах, комментариях, вложениях, медиабибиотеке, настройках — ВЕЗДЕ надо менять ссылки.
  • Привязку к полным путям хостинга. Иногда кое-где (в скриптах или загруженных файлах вложений) сохраняются полные внутренние пути хостинга типа «/home/u479543/cs-cs-net/www/wp-content/uploads/file.jpg». На другом хостинге эти пути могут отличаться и быть чем-то типа «/var/vh4146/f/funt8290/wp-content/uploads/file.jpg».
  • Контакты! =)) Да-да! Я знаю, что многие любят писать свои контакты прямо в текстах постов, типа «по всем вопросам пишите на мыло info@lalala.ru». И это ТОЖЕ надо менять при переезде на другой домен! =)

Конечно же для замены всего этого есть плагины. Они обычно зовутся примерно как «WB Database Search / Replace». Бля! Я подобный только вчера тестил, чтобы везде HTTP на HTTPS поменять! Плагин честно похлопал глазками и показал мне «выполнено 0 замен». Пошли нахуй они! =)

Я пользуюсь более злым способом. Когда мы что-то глобально меняем? А когда блог переезжает! А когда блог переезжает, то мы по любому скачиваем со старого хостинга всю базу данных в виде ZIP-архива SQL-файлов, так? Значит если открыть эти файлы и херакнуть по ним полнотекстовый поиск и замену… ООО! =)))

Меняю таким способом я следующее:

  • Префиксы таблиц. В SQL все названия таблиц начинаются с обратного апострофа «`», а сами префиксы таблиц отделяются от таблиц подчёркиванием. Поэтому если поискать «`old_» и заменить на «`new_» — то везде прям в SQL-командах обращения к таблицам (команды создания и заполнения таблиц данными) все названия таблиц поменяются!
  • Ключи метаданных и настроек WordPress (про это будет следующий раздел — там я расскажу подробно). ОЧЕНЬ ВАЖНАЯ ВЕЩЬ! Если вы меняли названия таблиц, то смените и ключи полей настроек WordPress! Так как названия полей перечисляются в командах SQL через запятую и указываются уже в прямых апострофах, то надо заменить «,’old_» на «,’new_».
  • Домен и URL всех ссылок, мыл, контактов. Тут просто делаем полноценный поиск, например «info@lalala.ru» на «info@meow.net» и не паримся.

После этого я снова ZIP-ую все SQL-файлы базы и уже этот архив загружаю на новый хостинг в новую базу данных. Можно пользоваться!

Всё это хорошо, когда мы переносим сайт и можем слить всю базу и поковырять её так, как я только описал. А что делать, если надо поменять всё (например HTTP на HTTPS) на живой базе (прям в тот момент, когда кто-то может отправить новый коммент на блоге)?

В этом случае нам поможет язык SQL-запросов к базе и встроенная функция SQL «REPLACE()». Replace делает обычный поиск с заменой. Если написать что-то типа `field` = REPLACE(`table`.`field`, ‘old’, ‘new’), то MySQL автоматически заменит «old» на «new» во всех местах всех записей этого поля.

Наша универсальная команда будет такой:

UPDATE `wp_tablle` SET `field` = REPLACE(
`wp_tablle`.`field`,
«old»,
«new»
);

А вот чего надо менять для того, чтобы сменились все ссылки и зависимые от домена/протокола опции:

  • wp_users, поле «user_url» — URL регистрации пользователей;
  • wp_usermeta, поле «meta_value» — метаданные пользователей (тут плагины хранят свои параметры);
  • wp_posts, поле «post_excerpt» — краткая часть поста (анонс) или ссылка на картинку моего слайдера-меню;
  • wp_posts, поле «post_content» — сам текст поста;
  • wp_posts, поле «guid» — ссылка на пост или вложение;
  • wp_postmeta, поле «meta_value» — метаданные поста (тут плагины хранят свои параметры);
  • wp_options, поле «option_name» — название опции WordPress (иногда привязано к домену или протоколу);
  • wp_options, поле «option_value» — значение опции WordPress;
  • wp_comments, поле «comment_author_url» — URL автора комментария;
  • wp_comments, поле «comment_content» — текст комментария к постам;
  • wp_commentmeta, поле «meta_value» — метаданные комментариев. ВАЖНО! Если есть плагин Comment Images Reloaded — то сначала читать пост дальше и юзать мой скрипт, а потом менять поле! Иначе будет пиздец! =)

У меня всё это превратилось в текстик с несколькими SQL-инструкциями, шаблон которой я показал выше. Я его сделал и разом прогнал в базе. Блог сразу на HTTPS и перешёл! =) Ещё мне понадобилось исправить URL, которые я кое-где жёстко прописал прямо в файлах темы, и всё! Кроме плагина Comment Images Reloaded, про который я ещё порасскажу! Вот он крови попил прилично!

3. Известная ошибка входа в админку после переноса блога: «Извините, вам не разрешено просматривать эту страницу».

А теперь расскажу вам сказочку. Значится, перенесли вы блог WordPress на новый хостинг и новую базу данных. База данных новая, хостинг новый — и вам (мне) хочется ещё и все таблицы WordPress переименовать с таким префиксом, чтобы это было красиво (или никто не догадался).

Тут надо сделать небольшую заметку в плане безопасности. Сейчас на блоги WordPress охотятся уже не злые хакеры, а огромные ботнеты. Они постоянно долбятся во все известные дыры (о, как это пошло прозвучало) с тем, чтобы попытаться скачать самый главный файл — «wp-config.php», в котором есть настройки базы данных. Иногда для взлома боты пытаются задействовать плагины работы с фотками, галереями (их может и не быть, но боты долбятся — вдруг да прокатит).

Вот зацените эти логи с моего блога:

Примеры того, как боты пытаются заполучить файл wp-config.php всеми способами и через все известные им плагины

Примеры того, как боты пытаются заполучить файл wp-config.php всеми способами и через все известные им плагины

У меня для защиты от этого сделан хитрый финт. Штатный файл просто к хуям переименован в рандомные буквы и цифры (типа «Umf8SJvqfYoy.php») и грузится вместо обычного. А в обычном написано что-то типа «Fuck Die!» =)) Поэтому даже если боты его скачают — хрен что они оттуда достанут.

Переименовывание стандартного префикса таблиц — это тоже защитная мера. Обычно таблицы имеют префикс «wp_», и поэтому можно пробовать делать SQL-инъекции — вдруг да прокатит стандартный префикс, а разработчик какого-нить плагина не все данные экранировал?

Шуточки на тему SQL-инъекций в систему распознавания номеров автомашин

Шуточки на тему SQL-инъекций в систему распознавания номеров автомашин

Итак, вы переименовываете все таблицы в базе, например с «wp_» на «wfp_» (и это для вас значит «WordPress For Powerlines» — вам так удобно отличать разные движки)… заходите в вашу админку и получате хуй в виде лаконичного сообщения «Извините, вам не разрешено просматривать эту страницу«.

Дальше вы идёте на хипстерские блоги или форумы, где все советуют одно и то же: найти какие-то «wp_capabilities» и вписать там «administrator», так как почему-то у администратора потерялись права доступа к блогу. Кое-кто предлагает создать при помощи PHP-кода нового пользователя с правами админа и заходить через него (вот ссылка на такой ответ)… Нового пользователя пускают, а всех старых — нет. И снова жопа!

А дело-то решается интереснее! Помните, я вам говорил про то, что иногда некоторые ключи параметров (meta_key, option_name) в базе зависят от домена, мыла или — о, находка, — префикса таблиц?! Зацените таблицу «wp_usermeta» (мои префиксы потёрты):

Ключи настроек WordPress в базе данных, которые зависят от префикса таблиц базы MySQL

Ключи настроек WordPress в базе данных, которые зависят от префикса таблиц базы MySQL

Положим, таблица зовётся как «wp_usermeta». Тогда и значения некоторых записей поля «meta_key» будут тоже содержать этот же префикс всех таблиц wordpress («wp_«), например «wp_usersettings» или «wp_capabilities». Когда мы меняем префикс таблиц в другой базе, то WordPress просто не может найти эти записи и ругается.

Эта фишка используется в двух таблицах:

  • wp_options, поле «option_name»
  • wp_usermeta, поле «meta_key»

Все такие записи можно отобрать по началу префикса (условием LIKE ‘%wp_%’) и переименовать на новый префикс. Тогда всё будет работать!

4. Грёбаные картинки в комментариях! Издеваемся над Comment Images Reloaded!

У меня же технический блог? Ага! И иногда нам, технарям, надо прицепить к комментарию схемку, скриншот или фотку. Поискал я плагины для этого — и нашёл плагин «Comment Images Reloaded». Я использую его уже несколько лет и начинал с первой версии, когда он умел подключать только одну картинку. Позже его поправили так, чтобы он поддерживал максимум три картинки — и этого хватает.

Картинки в комментариях, сделанные через плагин Comment Images Reloaded

Картинки в комментариях, сделанные через плагин Comment Images Reloaded

Я немного подкрутил вёрстку так, чтобы картинки шли не в столбик, а в линию (поменял CSS-свойство «flex») — и радовался… Хех, ровно до тех пор, пока не столкнулся с двумя вещами, первая из которых была вчера — переезд блога на HTTPS!

Переехал я, запустил — и смотрю, что браузер у меня ругается на то, что все фотки и картинки грузятся у меня по HTTP и, типа, теперь небезопасны. Обожаю я это переодевание на ходу! Десять лет всё было отлично и вдруг эти же фотки, которые десять лет лежат, стали небезопасными. Ага, прям вот протухли за ночь, бля, мгновенно!

Но вы же только сегодня прочитали мои фишки для полнотекстовой замены HTTP на HTTPS по всей базе данных. Ага, да! Я позавчера ночью прогнал по всей базе данных свой файлик SQL-запросов, поменял ссылки у всех вложений (attach) к постам на HTTPS, посмотрел на то, что браузер перестал ругаться на главную страницу блога — и пошёл спать.

А утром получил комментарий от Caesarion про «а в последнем комментарии PA3JlUBHOE пропала картинка. Совсем пропала, даже в HTML-коде никакого намёка нет, что она была». Вспоминаем Быкова из Интернов: «Чё эта?» ©. Иду, смотрю на плагин — плагин загружен и настроен. Смотрю на файлы — файлы есть и даже в базе данных упоминаются… Странно!

И тут открылась вся глубина наших глубин! Щча я вам расскажу, как этот Comment Images Reloaded хранит свои картинки для комментариев и какие косяки будут с полнотекстовой заменой базы, если он у вас установлен и вовсю используется!

Сам движок WordPress поддерживает медиа-библиотеку файлов, которые в него можно загрузить или удалить. Эти функции есть в ядре движка WordPress и их не надо писать самому:

  • media_handle_upload() — добавляет загруженный (через форму и метод POST) файл в медиа-библиотеку WordPress, привязывая его к посту;
  • wp_get_attachment_image() — получает изображение нужного размера из медиа-библиотеки;
  • wp_delete_attachment() — удаляет изображение из медиа-библиотеки в корзину или навсегда.

Вот чтобы не париться с загрузкой файлов на хостинг, разработчики плагина взяли эти функции. Поэтому любая картинка, которую вы мне цепляете в комментарии к посту, привязывается к нему и хранится в медиа-баблиотеке WordPress. Вот зацените скриншот поста в редакторе:

Картинки к комментариями выглядят в WordPress как вложения к медиа-библиотеке поста

Картинки к комментариями выглядят в WordPress как вложения к медиа-библиотеке поста

Зашибись! Лезем в медиа-библиотеку, отбирая посты по условию SQL: SELECT * FROM `wp_posts` WHERE `post_type` = ‘attachment’:

Вложения (attach) картинок к комментариям (медиа-библиотека WordPress)

Вложения (attach) картинок к комментариям (медиа-библиотека WordPress)

В поле GUID мы видим полный URL к файлу. Дальше вы скажете «О! Надо написать SQL-запрос, который будет выдирать ID комментариев, из них — ID вложений и менять там HTTP на HTTPS». ХУЙ ТАМ! Потому что это именно медиа-библиотека самого WordPress, которой Comment Images Reloaded пользуется как хранилкой файлов. Если что-то поменять здесь, то новые файлы увидит только сам WordPress, но не Comment Images Reloaded. WordPress сможет их корректно видеть как вложения к постам (хехе, кому они нахер нужны), а плагин — нет.

Идём глубже в нору, выебанную кроликом и охуеваем! Настоящие данные о картинках в комментариях плагин Comment Images Reloaded хранит в метаданных самого комментария в виде массива, закодированного в строку. Про кодирование не пугайтесь — это делается обычной функцией PHP serialize(), а раскодирование — unserialize().

Угар ситуации в следующем. В их массиве содержатся настоящие URL картинок, которые надо переводить на HTTPS. Но прямой поиск и замена по wp_commentsmeta.meta_value НЕ ПРОКАТИТ, так как у нас тут массив, закодированный в строку с указанием длины строк!

Как хранит данные о картинках в комментариях плагин Comment Images Reloaded

Как хранит данные о картинках в комментариях плагин Comment Images Reloaded

Я на скриншоте пометил стрелкой этот момент. Там есть кусочек такого вида: ;s:132:»<img width =. Вот 132 — это длина этого кусочка в символах. Как только мы меняем HTTP на HTTPS, строка начинает занимать уже 133 символа. Но текстовый поиск по базе этого не поменяет и не учтёт — для него это не описание массива, а просто текст. В итоге массивы не загрузятся и Comment Images Reloaded не увидит свои блядские картинки.

Заебала эта логика! Иногда мне хочется всё нахер посносить, но я не сделаю этого никогда, так как в комментариях сейчас есть такие картинки, от которых напрямую зависит логика обсуждения. А некоторые просто полезны всем, кто читает блог. Поэтому будем жить с такими извратами и костылями как есть. Если кто найдёт пост с этим исследованием плагина — пишите, вместе будем плакать над ним!

Теперь кратко подбиваем итоги:

  • Настоящие данные по картинкам лежат в виде массива в метаданных комментария. Именно оттуда плагин извлекает картинки и показывает их нам. Полнотекстовая замена HTTP на HTTPS ломает этот массив напрочь. И пиздец (почти, я написал скрипт)!
  • Для хранения картинок он пользуется библиотекой WordPress, чтобы не писать свои механизмы загрузки и удаления файлов.
  • Библиотека WordPress тупая и ебанутая: для каждого вложения она старается задать кучу параметров (типа описания, размеров, подписей, кода вставки в блог, страницы просмотра этого вложения) и тем самым засирает базу.
  • Библиотека WordPress ещё более тупая и ебанутая: в таблице posts она хранит полный URL файла (в поле «guid»), но, блядь, не пользуется им, а пользуется огрызком типа «2020/02/Image.jpg», всегда прикручивая к нему стандартную папку медиа-библиотеки. Нахуй тогда полный URL хранить?!

Сел я думать, что делать… А что, мать твою, делать? Писать PHP-скрипт, который пройдётся по всем метаданным комментариев, распакует строки назад в массивы, поменяет в массивах HTTP на HTTPS, заново запакует их и обновит базу! И когда мои руки уже потянулись к кодингу, я вспомнил про ещё один момент, который меня всегда дьявольски бесил.

Вот поглядите на то, как я называю свои файлы к постам:

Какие красивые файлы я загружаю на блог к постам

Какие красивые файлы я загружаю на блог к постам

Красиво? А вот какая помойка из ваших прицепленных картинок:

Какие файлы картинок вы назагрузили мне на блог (некрасивые названия)

Какие файлы картинок вы назагрузили мне на блог (некрасивые названия)

Этот лютый пиздец меня постоянно бесил до жути! Иногда мне надо перезалить какую-то фотку к посту, я захожу на FTP, а там такой вот мусор и полная помойка! С год назад я думал написать скрипт, который находит в этой помойке именно вложения в комментарии и переносит их в отдельную папку на хостинге (на скриншотах выше как раз и показано то, как отделилось одно от другого в результате работы скрипта).

Тогда я думал, что мне достаточно будет поменять поле «guid» в таблице «wp_posts» и всё разом заработает. А хер там, не заработало и не получилось. Но сейчас-то я знаю про массивы картинок в метаданных комментариев! И как раз буду эти массивы править на HTTPS! Короче, сел я вчера днём и начал кодить. Ну и накодил и сейчас покажу.

Вот расшифровка массива одного из комментариев поста:

Расшифровка массива массивов картинок одного из комментариев Comment Images Reloaded

Расшифровка массива массивов картинок одного из комментариев Comment Images Reloaded

Там оказался аж массив массивов: массив первого уровня — это массив самих картинок (по одному элементу на картинку), а массив второго уровня — это все возможные размеры каждой картинки и прямыми URL на их файлы. Скрипт я написал! Самая ебанутая строка у него, наверное, эта: «$NewMetaValue = mysql_real_escape_string(serialize($arrMetaData), $php_DBConnection);» =)

Сам скрипт лежит тут: WP-Move-Comm-Images.txt. Он уже пиздец опасный, потому что жёстко правит базу данных и файлы. Делайте бэкапы и используйте его только в случае, если вы сами программист и готовы к пиздецам!

Он умеет править префиксы ссылок (можно переехать на HTTPS, а можно — на другой домен) и переносить картинки от Comment Images Reloaded в другое место на хостинге. Вот его настройки.

Настройки моего скрипта для перемещения картинок комментариев и правки их на HTTPS

Настройки моего скрипта для перемещения картинок комментариев и правки их на HTTPS

А вот так он выводит всякие сообщения:

Работа моего скрипта переноса картинок Comment Images Reloaded в другую папку

Работа моего скрипта переноса картинок Comment Images Reloaded в другую папку

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

После работы этого скрипта (и когда я причесал папки), у меня на хостинга появилась такая вот структура папочек:

Структура папок с картинками к постам и картинками к комментариям

Структура папок с картинками к постам и картинками к комментариям

«wp-uploads» — для штатных фоток к постам, а «wp-uplocmi» — для комментариев. Скрипт только переносит уже загруженные картинки, поэтому я буду прогонять его раз в полгода и наводить порядок на хостинге! Сейчас (на момент поста) вы накидали мне картинок на 500 мегабайт, а мои фотки занимают 1,5 гигабайта! Вау! =)

А хуйня всей ситуации в том, что WordPres всё равно, падла лютая, упорно пытается загрузить эти файлы из wp-uploads. Поэтому, скорее всего, удаление картинок при удалении комментариев не будет работать. Мне на данный момент пофигу (а потом я, может быть, это всё доработаю, когда изучу работу медиа-библиотеки).

На этом всё! Итак, мы на HTTPS и с разделёнными по папкам фотками постов и картинками комментариев! Ура! Ну а открытый Киричев сайт лежит тут: http://funt8290.net/ (и я поменял все ссылки у себя в контактах). А подругин пока не покажу — команды не было! =)

16 Отзывов на “WordPress: Делаем свои меню, переезжаем на HTTPS/хостинг и сортируем картинки в комменариях”


  • 1 Caesarion  [Новосибирск]

    CS, в RSS повторно пришло всё (и посты, и комментарии) с 5 мая, а в последнем комментарии PA3JlUBHOE (https://cs-cs.net/logicheskie-rele-siemens-logo-programmirovanie-logo-web-editor#comment-40398) пропала картинка. Совсем пропала, даже в HTML-коде никакого намёка нет, что она была.

    А ещё перестала работать твоя запрещалка однострочных комментариев. Или так и должно быть?

  • 2 CS  [Москва]

    Caesarion Блядь! Пиздец! Это означает, что слетели ВСЕ настройки ВСЕХ плагинов! Песдец! Ёбаный HTTPS блядский! Нахуя я только его сделал!
    Ща буду соображать, что не так.

    UPD. Блядь!!! Картинки… сука! Там строковые массивы лежат в serialize… бля! Надо руками на каждую делать замену на HTTPS и ещё и длину строк править! ПЕСДЕЦ!

    UPD2. Ща нахер сяду писать скрипт, который будет автоматически все комменты переделывать. Руками херачить 1067 строк — я ебанусь! ЫЫЫЫ!!!
    Там надо:
    * Прочитать из базы поле, в котором есть упакованный в строку массив картинок к комментарию (даже если одна картинка — всё равно массив)
    * Распаковать строку в нормальный массив
    * Заменить в нём все «http://cs-cs» на «https:/cs-cs»
    * Запаковать назад
    * Вернуть в базу

  • 3 CS  [Москва]

    Caesarion УРА! Картинки в комментариях поправил!
    Охрененно! Потратил день — дописал хитрый скрипт, который не только базу правильно поправил с http на https, а ещё и перенёс мне все картинки из комментов в другую папку! На днях (или ща по горячим следам) напишу пост про это решение — мало ли кому сгодится хитрость!

    UPD: У меня на FireFox проверка на длинный коммент без перевода строк пашет, всё норм!
    Напиши, с какого устройства не работало и работает ли щас?

  • 4 Caesarion  [Новосибирск]

    А, я понял: чтобы комментарий не прошёл, он должен быть не только в одну строчку, но и длинный. А короткие и должны проходить. Тогда всё в порядке.

  • 5 CS  [Москва]

    Caesarion А, да! Теперь я понял, про чего ты говорил! =)
    Я сделал там от 250 символов (могу ошибаться, на память пишу)! =)

  • 6 EngineTech.

    А почему не стал делать сертификат от LetsEncrypt?
    Смысл платить за сертификат при наличии альтернативы?

  • 7 CS  [Москва]

    EngineTech По двум причинам.
    Во-первых, стрёмно: он же ненадёжный. Мало ли закроют его или всех как-то обломают с ними. А я в этот момент буду вовсю щитами заниматься, на блог заходить не буду и не буду знать, что там всё сдохло.
    Во-вторых, этот сертификат автоматом подключается к хостингу. А остальные надо подключать самому. Хрен ли — тыща в год, фигня!

  • 8 Caesarion  [Новосибирск]

    CS, что у тебя за редактор кода? И как ты относишься к Notepad++?

    И чтобы два раза не вставать: какой программой ты делаешь скриншоты?

  • 9 CS  [Москва]

    Caesarion Notepad когда-то в 2000ные я видел, посмотрел и забил, потому что тогда он был просто редактором с подсветкой кода. Ща глянул фотку по ссылке — ни хрена он не изменился с тех пор… =)
    Я ввёл себе жёсткое правило, которого стараюсь придерживаться: использовать IDE под языки, потому что IDE заточены под язык и умеют подсказывать, имеют справку по функциям языка, подсказки по переменным, типам (когда начинаешь набирать переменную, и тебе подсказываются варианты).
    Сейчас для HTML/CSS/PHP я использую Rapid PHP (у меня старая 2007 версия). Там и подсказки есть, и подсветки кода, и сразу все тэги, стили CSS.

    Скриншоты я делаю не программой, а кнопкой Print Screen на клаве =) А обрабатываю (стрелки, копирайты) в ACDSee 5. Про сами фотки на блоге и то, как я их быстро вставляю в посты, есть вот тута у меня целый пост.

    А! Ещё допишу тебе (надеюсь, прочитаешь). Ещё качество скриншота зависит от формата, который используешь:
    * JPEG для скриншотов не годится, потому что он сохраняет сжатое и поделённое на куски изображение (как звук в MP3). Из-за этого чёткость пикселей будет теряться. Зато фотка может быть большой по размеру, но немного занимать.
    * GIF/PNG сохраняют пиксели как есть, поэтому для скриншотов они идеальны: всё будет точно и чётко, без смазанности.

  • 10 mf

    Формально говоря, есть lossless jpeg, а конверсия в gif/png часто делается с потерями. Но суть это не меняет.

    PS. Примерно с середины 90х и до середины нулевых программисты, осваивавшие c с использованием IDE (особенно Visual Studio), получались очень сильно недоделанными и плохо переобучаемыми. Тогда это было хорошим тестовым вопросом — изучался ли c с использованием visual studio или без, при положительном ответе проще было задать еще пару вопросов для приличия и звать следующего. Богатый опыт работы на visual basic был таким же негативным маркером, переучивать кого-то добровольно с vb на c/c — редкой силы мазохизм.

    Но в дальнейщем генерация кода визардами резко потеряла в популярности, а именно подсаживание на визарды было одной из основных причин такого эффекта. Так что теперь IDE просто ускоряет работу, а не отупляет. Но зато подоспели новые маркеры, вроде увлечения nodejs. Если фанатизм ярко выражен — поступаем как в прошлом с любителями визардов.

  • 11 CS  [Москва]

    Гммм… а при чём тут IDE и визарды? У CodeSys есть IDE, у 1Ски есть IDE, у Atmel есть IDE, у Ардуинок есть IDE, у Logo есть IDE…
    Чего-то я тебя не понял. Это плохой стиль, что ли? И для Logo надо рыть toolchain и через make компилироваться?

  • 12 mf

    На стадии обучения желательно рыть и компилироваться через make. Это закрывает пробелы в понимании. Потом уже при активном применении можно использовать более эффективные инструменты.

    Это тема, статьей по которой я думаю разродиться давно, но т.к. 100 лет больших текстов не писал, воз и ныне там.

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

    Если основной инструмент будущей работы — IDE, то для эффективной работы надо вначале (не обязательно как самый первый шаг, но как можно ближе к началу обучения) освоить также toolchain на 1-3 уровня ниже. Сюда точно попадает make, где он есть. В плане оптимизации сюда также попадает понимание, в каком порядке доступ к памяти производится быстрее, что такое кеш процессора и каких уровней он бывает, а вот ассемблер и машинные коды уже находятся в спорной зоне и нужны гораздо меньше, чем в прошлом.

    Одновременно нужны абстракции нескольких более высоких уровней. Алгоритмы, структуры данных — вне зависимости от языка. Особенности апи мапов в яве или в другом языке не делают их принципиально разными конструкциями. Алгоритм сложностью N^2-N^3 на большом объеме данных в общем случае никогда не будет быстрым, поэтому оценку сложности алгоритма необходимо уметь делать, рано или поздно это прилетает всем.

    Освоение всех этих вещей часто тормозится и херится об колено, если человек с самого начала начинает работать в инструментах, ориентированных на срезание углов и на максимальную продуктивность, таких как визарды или IDE. Нет мотивации к развитию, сложные задачи просто объявляются слишком сложными и не берутся в работу.

    Как думаешь, какой процент опытных программистов в звании ведущих способен разглядеть N^3 алгоритм в блоке кода из трех вложенных циклов строчек на 15-20 ?

  • 13 CS  [Москва]

    Угу… сраный make, где каждый файл надо прописывать вручную, где нет окошка, куда все ошибки выводятся и нельзя два раза кликнуть мышкой по строчке и сразу же перейти на неё в нужном файле.
    Кому и зачем нужны навыки вручную рыться в makefile, чтобы прописать там очередной исходник или опции компилятора? Это гадость, неудобно — и те же опции проще галочками задать.
    Суть моего циничного вопроса была ещё и в том, что под определённые вещи make и toolchain вообще нее существует в природе — только готовые IDE. Например Siemens Logo.

    Дочитал про доступ к памяти и кэш процессора и затупил. Мы про одно и то же говорим вообще? Как работа через toolchain и работа через IDE, которая тот же makefile создаёт отличается?
    Вот прогал я на Visual Studio 6. Создаю я проект на C++. Добавляю файлы, ресурсы, библиотеки. Иду в окно настроек проекта и там ставлю разные опции компилятора типа «статически слинковать библиотеки», «оптимизировать скорость, на размер кода похер».
    В итоге Visual Studio делает мне такой же makefile и по F7 запускает всю toolchain. Но с выводом в окно проекта, с удобной обвязкой. Но компилятор и линковщик — один и тот же-то. И ему похер, как его вызовут — через IDE или напрямую.
    Как тогда IDE будет влиять на скорость доступа к памяти процессора? Шо-то я не понял.

    Кажется, мы о разном, раз ты про визарды всё повторяешь сто раз. Поэтому подведу итог:
    а) Если ты говоришь про IDE в плане «Это хуйня, это развращает и каждый должен через кровавую боль ручками описывать весь toolchain для каждого cpp-файла, иначе он не поймёт как оптимизировать работу с указателями» — то я против и в гробастом аду я видел такой подход.
    б) Если ты говоришь про какую-то часть IDE, которую называешь визардами и что она отупляет — то я здесь с тобой полностью согласен и в этом плане я люто ненавижу Delphi, потому что там на каждый чих была «компонента» — даже на то, что быстрее и короче делалось через вызов функций WinAPI, блядь.

    Но позволю себе напомнить, что в сфере умных домов, считай, сейчас одни визарды. Типа «включите устройство, нажмите кнопку, приложение его увидит и настроит за вас». Причём прикол в том, что сейчас это тренд и многие устройства просто даже не купят, если у них нет такого визарда настройки.
    Как, не бесит тебя это? Не развращает мозги?

  • 14 mf

    Это хуйня, это развращает и каждый должен через кровавую боль ручками описывать весь toolchain для каждого cpp-файла, иначе он не поймёт как оптимизировать работу с указателями

    Такой опыт крайне желателен в самом начале обучения (при возможности). Но совершенно ни к чему в дальнейшем работать именно таким способом.

    С памятью интереснее. Вот у нас есть база данных, из нее по условиям задачи надо все вчитать в память и использовать как справочник (алгоритм почти невозможно заставить работать быстро, если данные не зачитаны все заранее,
    и даже при кешировании всей базы sql сервером запросы к нему будут слишком многочисленны). Что сделает обычный разработчик ? Будет добавлять кучу железа, так как старт приложения в 40 минут — дико дорого. Или разведет руками. Выбьет бюджет на хадуп кластер. Что сделает разработчик со стажем? Обнаружит, что sql сервер может удивительно быстро дампить всю базу в виде plain text/csv, который считывается потом в память приложением буквально за секунды (вместо 40 минут). И который можно эффективно расположить в памяти, если выкинуть из головы все ООП и перейти на использование компактных массивов примитивов с минимумом нужных индексов. Какая ситуация, такие и методы. Но если в голове одно только ООП и распределенная обработка на кластере, то получить эффективное решение шансов нет.

  • 15 CS  [Москва]

    Такс. Про опыт разобрались. Значит на IDE не гоним, а будем гнать на уебанов-тупых-программистов =)
    Ага, про базу данных. Я про них в курсе только про MySQL. Пишу тезисно:
    а) Твой пример совсем не про «эти ёбаные IDE, всех за make надо сажать и носом тыкать»
    б) ООП или не ООП не отменяют главного косяка реализации: грузить весь спраочник разом. А если база будет в 5 гигабайт? А в 10? Это оно сожрёт столько оперативки ради того, чтобы из справочника выбрать одну строчку?
    в) ИМХО разработчик без стажа, но с не шаблонным мышлением сделает динамическую подгрузку нужных огрызков справочника на лету (в 1С 7.7 это давно с 90ых было, а в 1С 8 уже даже ревервирование товаров на складе на лету по мере того, как ты их в накладную вбиваешь есть).
    А, да! И ещё … даже в Win 95 уже были динамические списки (весь Office на них построен): когда грузится только то, что отображается.

  • 16 mf

    А если база будет в 5 гигабайт? А в 10?

    Тогда sql сервер закеширует ее в памяти сам для более быстрых запросов, иименно так они и работают. Только сделает это неэффективно, т.к. заточен на общий случай, а не под частное конкретное применение. И при этом его придется «прогревать» запросами, чтобы все было в кеше, на это часто выделяют целый день или оба выходных после рестарта. И все равно, если число обращений велико, производительность упрется в неуменьшаемый оверхед на каждое конкретное обращение.

    Памяти с sql сервером перестанет хватать намного быстрее. В случае же, когда ее перестанет хватать в оптимизированном кастомном варианте, можно увеличить компактность расположения, либо сделать кастомный кластер из 4-5 типовых машин (вместо 40-50). Разница в стоимости — на порядки. Технологии, как это делать, преподавались студентам третьих курсов еще 20 лет назад и не вызывали особых сложностей в освоении.

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

    Еще один пример из прошлого — биллинг на московские кафе и рестораны, по-моему его делает преимущественно одна или несколько контор, в одну из которых я однажды собеседовался. И там та же проблема, sql сервер (не конкретно mssql, может быть и mysql сейчас) держит в памяти несколько сотен гигов кеша. Тогда не довелось влезь в код и посмотреть, но сильно подозреваю, что в сервере можно было оставить справочные данные и мастер-копию изменяемых данных, а кеш для оперативных расчетов можно было ужать до нескольких гигабайт, или даже сотен мегабайт. А потом отжать неактуальные за текущий период данные и выкинуть из кеша еще 90% оставшегося.

    При классической полноценной подготовке видно намного больше вариантов решения сложных проблем, чем после онлайновых экспресс-курсов переподготовки, тут вроде спорить не с чем.

    А, да! И ещё … даже в Win 95 уже были динамические списки (весь Office на них построен): когда грузится только то, что отображается.

    При этом стоимость операции «подгрузить все заранее» при эффективной организации хранения данных может быть приблизительно такая же, как при загрузке только 10% элементов, а стоимость операции определения, что именно точно понадобится, может ее превысить. :) Работа со списками богата такими сюрпризами.

Оставить отзыв

Вы должны войти на блог, чтобы оставить комментарий.