Открывается в новой вкладке

Как я перенёс 129 полей JetEngine из CPT в метабоксы и сохранил 1602 значения

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

Как я перенёс 129 полей JetEngine из CPT в метабоксы и сохранил 1602 значения

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

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

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

С чего всё началось

На сайте используется WordPress в связке с Elementor Pro и плагинами Crocoblock, в частности JetEngine.

Для управления услугами создан отдельный тип записи — «Услуги» (uslugy).

Со временем в нём накопилось 129 произвольных полей. Они использовались для самых разных блоков страниц: заголовков, описаний, изображений, стоимости услуг, преимуществ, этапов работ, FAQ и других элементов.

Сами поля были разделены по смыслу на два больших направления: разработка сайтов и SEO-продвижение.

Но все 129 определений находились непосредственно внутри настроек одного типа записи JetEngine.

Работать с такой структурой стало неудобно. Чтобы изменить одно поле, приходилось искать его среди большого количества других. Кроме того, в перспективе я планировал дальше расширять структуру услуг и добавлять новые блоки.

Решение напрашивалось само собой — перенести поля в отдельные метабоксы JetEngine.

В результате хотелось получить:

  • Отдельный метабокс для услуг разработки сайтов.
  • Отдельный метабокс для SEO-услуг.
  • Сохранение существующих названий и ключей полей.
  • Сохранение всех текстов, изображений, повторителей и других данных.
  • Возможность продолжать использовать существующие динамические шаблоны Elementor и JetEngine.

И всё это без ручного пересохранения каждой записи.

Первая неожиданность — поля и их значения хранятся отдельно

Первоначально задача казалась простой: скопировать определения полей из CPT в нужные метабоксы, сохранить их meta_key, после чего удалить старые определения.

Однако обнаружилась важная особенность.

У типа записи «Услуги» был включён режим Custom Meta Storage.

Это означает, что JetEngine хранил значения произвольных полей не в стандартной таблице WordPress wp_postmeta, а в отдельной таблице wp_uslugy_meta.

В то же время обычные метабоксы JetEngine используют стандартное хранилище метаданных WordPress.

Получилась интересная ситуация.

После копирования определений в новые метабоксы ранее заполненные данные ещё отображались. Но при удалении исходных определений из CPT значения в метабоксах становились пустыми.

Один из способов исправить это — открыть каждую услугу и пересохранить запись. Тогда значения записываются в новое хранилище.

Но делать это вручную для десятков записей и сотен значений мне совершенно не хотелось.

Стало понятно, что нужно переносить не только структуру полей, но и сами данные.

Собственный плагин для миграции JetEngine

Для решения задачи я использовал ChatGPT как помощника в разработке и анализе кода.

В результате появился собственный служебный WordPress-плагин — MRKT JetEngine Metabox Migrator.

Идея заключалась в том, чтобы сделать инструмент, который сможет работать непосредственно со структурой JetEngine и при этом минимизировать риск потери данных.

Плагин получил возможность выбирать нужный тип записи, отмечать поля через чекбоксы, выполнять массовое выделение, искать поля по meta_key, копировать определения в существующие метабоксы и предварительно показывать изменения.

Отдельно был реализован механизм переноса значений из Custom Meta Storage в wp_postmeta.

Причём обычного копирования оказалось недостаточно. Понадобились проверки фактического наличия столбцов в БД, сравнение значений, обнаружение конфликтов и создание резервных копий операций.

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

Разделение 129 полей по метабоксам

Сначала я изучил экспорт конфигурации JetEngine и определил, какие поля относятся к каждому направлению.

В итоге структура распределилась следующим образом:

НаправлениеКоличество полей
Разработка сайтов58
SEO-продвижение71
Всего129

При этом выяснилось, что 22 определения являются служебными элементами интерфейса — вкладками и аккордеонами.

Оставшиеся 107 — поля, которые действительно могут хранить значения: текст, изображения, списки, переключатели, повторители и другие данные.

Все исходные поля были скопированы в соответствующие метабоксы с сохранением ключей и параметров.

Это было особенно важно, поскольку Elementor и JetEngine используют meta_key при динамическом выводе контента. Сохранение существующих ключей позволяет избежать массового изменения привязок в шаблонах.

Массовый перенос значений между таблицами

Следующим этапом стала работа непосредственно с базой данных.

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

Предварительная диагностика показала:

ПоказательРезультат
Найдено строк Custom Storage38
Полей для проверки107
Непустых значений1602
Пустых значений2464
Конфликтов перед копированием0

Большое количество пустых значений оказалось нормальным: не все поля используются на каждой странице услуги.

Например, поля, относящиеся к SEO-продвижению, могут быть пустыми у услуг разработки сайтов и наоборот.

После предварительной проверки я выполнил массовое копирование значений непосредственно в wp_postmeta.

Но на этом история не закончилась.

Четыре конфликта, которые оказались самой интересной частью задачи

После копирования я повторно запустил проверку.

Большинство значений совпали, но плагин обнаружил четыре расхождения.

На первый взгляд было непонятно, почему они появились: новые значения уже находились в wp_postmeta, но отличались от исходных.

Пришлось разобраться подробнее.

В миграторе появилась отдельная диагностическая таблица, показывающая ID записи, meta_key, размеры значений и контрольные суммы SHA-256.

Затем я сравнил данные непосредственно в phpMyAdmin.

Три конфликта оказались связаны с HTML-разметкой заголовков.

В старой версии данных использовались теги <div> и <p>, а в актуальной — <span>.

Тут я вспомнил, что действительно когда-то переделывал HTML-разметку этих заголовков.

То есть в стандартной таблице WordPress сохранились старые варианты контента, а в Custom Meta Storage — новые.

Четвёртый конфликт оказался ещё интереснее.

Он возник в поле-повторителе nomer_zagolovok_opisanie, где хранился сериализованный PHP-массив.

В одной версии текста использовались символы • и неразрывные пробелы, а в другой — HTML-сущности &bull; и &nbsp;.

Внешне содержимое было практически одинаковым, но на уровне базы данных отличалось.

После проверки я определил, что актуальные значения находятся именно в wp_uslugy_meta.

Поэтому вместо глобальной перезаписи всех полей исправил четыре конкретных значения с помощью адресных SQL-запросов.

Это позволило сохранить нужный контент, не затрагивая остальные данные.

Финальная проверка: 1602 совпадения и ни одного конфликта

После устранения расхождений я снова запустил предпросмотр миграции.

На этот раз получил ожидаемый результат:

1602 значения совпадают с исходными, 0 конфликтов, 0 значений осталось скопировать.

Таким образом, все непустые значения из выбранных 107 полей были перенесены в стандартное хранилище WordPress и прошли проверку на совпадение.

Особенно важно, что значения переносились без ручного пересохранения каждой услуги. Исходная таблица Custom Meta Storage при этом сохранилась.

Проверка включала не только обычные текстовые поля, но и изображения, HTML-содержимое и сериализованные повторители.

После синхронизации данных можно переходить к заключительной очистке структуры CPT — удалению дублирующих определений полей. Эту операцию необходимо выполнять с резервной копией и контрольной проверкой динамического вывода Elementor и JetEngine.

Что получилось в результате

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

Вместо работы с одним огромным списком из 129 полей появилась более удобная структура, разделённая на разработку сайтов и SEO.

При этом удалось:

  • Сохранить существующие meta_key.
  • Перенести 1602 непустых значения.
  • Найти и устранить четыре расхождения между таблицами.
  • Избежать ручного пересохранения десятков услуг.
  • Подготовить безопасный механизм для дальнейшей очистки исходных полей.
  • Получить собственный инструмент миграции JetEngine с предпросмотром и диагностикой.

Отдельно о работе с ChatGPT

В этом кейсе ChatGPT был не просто инструментом для написания отдельных фрагментов PHP-кода.

ChatGPT помог: проанализировал устройства JetEngine, доработал плагин, в поиске причин ошибок, в подготовке диагностических SQL-запросов и проверке логики переноса.

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

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

Вывод

Этот случай ещё раз показал, что перенос произвольных полей WordPress — это не всегда простое копирование настроек.

Особенно когда используется JetEngine с Custom Meta Storage, а на сайте уже накопилось много динамического контента.

Важно понимать, где физически находятся значения, как они связаны с ключами полей и что произойдёт при изменении их определений.

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

И самое главное — все 1602 перенесённых значения совпали с исходными.

Стек: WordPress, Elementor Pro, JetEngine, Crocoblock, PHP, JavaScript, MySQL 8.0, phpMyAdmin, ChatGPT.

Сломался сайт?

Напишите, что случилось
— найду решение

Бесплатно предложу решение и отвечу на вопросы.

Обсудить проект ↗

Готовы обсудить
ваш проект?

Напишите мне — обсудим задачу, сроки и бюджет. Консультация бесплатна, без обязательств.

Бесплатно оценю задачу и предложу структуру сайта · Отвечу в течение 30 минут