Часть 1. Немного лирики
Чаще всего в сети публикуются материалы по начальному уровню работы с Wordpress. В лучшем случае обсуждаются документированные возможности самого Wordpress и его различных плагинов. Я стою на позиции, что работа с документацией и использованием документированных возможностей — инструментами, которые вам предоставил разработчик — является приоритетной в разработке. Однако иногда документированных возможностей не хватает и как ответ на этот случай появилась эта статья.
Advanced Custom Fields (ACF) – один из популярных плагинов Wordpress. Основная задача — создание блоков дополнительной информации к Постам, Страницам и Товарам. Плагин настолько популярен, что вопросы по нему входят в список MustKnow на различных собеседованиях.
Ничего не имею против самого плагина — это очень удобный инструмент, с широкими возможностями. Имеет встроенную возможность выводить редактирование статей во фронтенд. Позволяет создавать поля по условию и связывает поля с нужными постами. Например, для новостного сайта вы решили в блоке спортивных новостей создать дополнительный тег с указанием вида спорта, чтобы не забывать это делать, вы создаете поле типа select, которое будет появляться при выборе категории «Спорт» и требуете его обязательного заполнения.
Конечно, чтобы описать стандартные возможности ACF мало приведенного примера. Используют ACF в самых различных случаях, документацию плагина вы сможете найти на официальном сайте. Для тех, кто ещё не освоил иностранные языки есть неплохой сайт с документацией на русском языке.
В моем случае не нашлось достаточных документированных инструментов и пришлось разбираться с устройством ACF.
Часть 2. Получаем ACF поля
Итак, от прелюдии к делу. Постановка задачи — выводим редактирование товаров во фронтенд, при этом редактирование должно включать в себя возможность редактирования ACF полей связанных с товаром по условию категории. То есть, менеджер добавляя товар должен иметь возможность (или обязанность) заполнить сопутствующую категории товара информацию. Например, в категории «Фрукты» появляется поле «Сорт», а категории «Телефоны» - поле «Бренд» и так далее. Если вы работаете через административную панель, то задача тривиальная. Но у вашего менеджера есть ограничения — пускать его в административную панель никто не собирался. Поэтому функционал административной панели для вас отрезан.
Стандартный функционал ACF не предлагает возможности запроса по условиям. Вывод полей происходит в связке с ID поста. Это связано с особенностями сохранения в базе данных. Условие «Категория товара» не привязывается к сохраняемой информации. Поэтому начинаем искать поля и условия.
Самая востребованная таблица базы данных posts, что связано с широким набором инструментов разработанных для данной таблицы. Именно в ней и хранятся наши поля. Для полей ACF зарезервированы два типа записей — в колонке ’post_type’ мы находим поля типов ’acf-field-group’ и ’acf-field’. Первый тип записей, как следует из его названия, отвечает за группу полей, второй тип записей отвечает непосредственно за поле. Связка между ними происходит по полю ’post_parent’.
Теперь, когда мы знаем где находятся наши поля, необходимо разобраться с условиями. Мы же не планировали выдавать поля списком, тем более, что это и есть наша основная задача — выдавать поля по условию. Всю необходимую нам информацию содержит колонка ’post_content’.
В ней в формате сериализованного массива сохранены условия и значения. Причем условия выдачи привязаны к группе полей, поэтому для разбора условий вам необходимо получить данные по группе, которые выглядят примерно так:
a:12:{s:8:"location";a:1:
{i:0;a:1:
{i:0;a:3
{s:5:"param";s:13:"post_taxonomy";s:8:"operator";s:2:"==";s:5:"value";s:27:"product_cat:fruit";}
}
}
s:8:"position";s:6:"normal";s:5:"style";s:7:"default";s:15:"label_placement";s:4:"left";s:21:"instruction_placement";s:5:"label";s:14:"hide_on_screen";s:0:"";s:11:"description";s:0:"";s:18:"acfe_display_title";s:0:"";s:13:"acfe_autosync";s:0:"";s:9:"acfe_form";i:0;s:9:"acfe_meta";s:0:"";s:9:"acfe_note";s:0:"";
}
Вы будете проверять по своим условиям, для понимания всей этой белиберды выделю пункты, которые важны по данному полю:
s:5:"param";s:13:"post_taxonomy";s:8:"operator";s:2:"==";s:5:"value";s:27:"product_cat:fruit";
Здесь содержится вся нужная нам информация:
параметр условия "post_taxonomy";
значение по условию должно быть "==";
ну и само значение "product_cat:fruit";
Теперь мы знаем какую группу полей нам необходимо использовать, можно переходить к самим полям. Выборку полей производим по колонке ’post_parent’. У нас есть названия и ID полей, но пока мы не знаем типы полей и связанные с ними условия. Вновь переходим к данным поля ’post_content’, теперь наши данные выглядят немного иначе:
a:10:
{s:4:"type";s:4:"text";s:12:"instructions";s:0:"";s:8:"required";i:1;s:17:"conditional_logic";i:0;s:7:"wrapper";a:3:
{s:5:"width";s:0:"";s:5:"class";s:0:"";s:2:"id";s:0:"";}
s:13:"default_value";s:0:"";s:11:"placeholder";s:0:"";s:7:"prepend";s:0:"";s:6:"append";s:0:"";s:9:"maxlength";s:0:"";}
Здесь для нас упакованы сведения связанные с выводимым полем:
тип поля — "text";
обязательное для заполнения — "required";
класс, длина, значение по-умолчанию, плейсхолдер и т. д.
Теперь получив эту информацию мы можем приступить к созданию своего запроса и передаче полей во фронтенд. То есть при выборе категории отправляем запрос в базу данных, находим группу полей по условиям, выбираем поля и подготавливаем форму.
Часть 3. Сохраняем информацию
Но остался ещё один вопрос — что делать с полученной информацией? Поэтому нам необходимо разобраться как сохраняется информация ACF.
Для дополнительной информации, возможных настроек постов в Wordpress предусмотрена специальная таблица postmeta. В ней хранится самая различная информация и, конечно, разработчики ACF использовали эту возможность. Но следует учесть, что использовали они не прямой подход.
Обычная запись в таблице postmeta состоит из 4 полей — уникальный ключ в БД (порядковый номер записи), ID поста с которым связано поле, идентификатор (по которому разработчик получает поле функцией get_post_meta () ) и значение.
В основном этого достаточно, чтобы иметь связанную информацию. Но ACF разработчики разбили задачу на две составляющие:
при сохранении данных ACF вносятся запись с именем поля и со значением.
ключ _sort содержит ссылку на post_name поля ACF из таблицы posts, а запись с ключом sort (без подчеркивания) сохраняется значение поля.
Вот и всё. Надеюсь, что полученные знания помогут вам в разработке. Всем удачи!