DB Structure Viewer для Cotonti

Гибкий комбинированный экспорт в CSV для Excel, просмотр таблиц БД прямо в админке — всё это реализует плагин DB Structure Viewer для администраторов сайтов на CMF Cotonti.

Руководство пользователя плагина «DB Structure Viewer» для Cotonti Siena

1. Общие сведения

Плагин DB Structure Viewer предназначен для администраторов сайтов на CMF Cotonti Siena (версия 0.9.26) и предоставляет удобный интерфейс для:

  • просмотра структуры таблиц базы данных (список таблиц, поля, типы, ключи);
  • просмотра содержимого таблиц с возможностью фильтрации по ID записи;
  • экспорта структуры и данных таблиц в форматы JSON, SQL, CSV, PHP;
  • комбинированного экспорта данных из нескольких связанных таблиц в единый CSV‑файл с гибкой настройкой соответствий (маппингом) и автоматическим или ручным определением связей (JOIN);
  • логирования всех операций экспорта;
  • упаковки экспортированных файлов в ZIP‑архив;
  • сохранения настроек комбинированного экспорта в браузере для повторного использования.

Плагин работает на PHP 8.4+ и MySQL 8.0+, полностью интегрируется в административную панель Cotonti. Он не требует специальных знаний SQL для выполнения большинства операций, однако понимание структуры базы данных вашего сайта существенно расширит его возможности.


2. Установка и активация

  1. Скопируйте папку dbviewstructure в каталог plugins вашего сайта.
  2. Перейдите в Панель управления → «Расширения».
  3. Найдите в списке «DB Structure Viewer» и нажмите «Установить».
  4. После установки в таблице cot_dbviewstructure_logs будет создана структура для хранения логов экспорта.

Примечание: если плагин был обновлён с более ранней версии, возможно, потребуется повторное применение SQL‑запроса из файла dbviewstructure.install.sql.


3. Конфигурация плагина

Настройки плагина доступны сразу после установки через кнопку «Конфигурация» в списке расширений. Рассмотрим каждый параметр.

3.1. Путь к папке экспорта (export_path)

По умолчанию: plugins/dbviewstructure/export/.

Определяет директорию на сервере, в которую будут сохраняться все экспортированные файлы (CSV, JSON, SQL, PHP, ZIP).
Важно: указанная папка должна существовать и иметь права на запись (755 или 777 в зависимости от конфигурации хостинга). Если папка отсутствует, файлы не смогут быть сохранены, и вы получите сообщение об ошибке.

3.2. Включить логирование (log_enabled)

По умолчанию: выключено (0).

При включении (1) каждая операция экспорта (как обычного, так и комбинированного) будет записываться в таблицу cot_dbviewstructure_logs базы данных. Логи содержат имя файла, формат, количество задействованных таблиц, признак наличия данных и временную метку. Логи доступны для просмотра в соответствующей вкладке плагина.

3.3. Одновременный экспорт в браузер (export_to_browser)

По умолчанию: выключено (0).

  • Если включено (1), после завершения экспорта файл будет сразу же отправлен в браузер для скачивания (появится диалог сохранения).
  • Если выключено (0), файл остаётся только на сервере в папке экспорта, и вы можете скачать его позже через вкладку «Логи».

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

3.4. Записей на страницу (max_rows_per_page)

По умолчанию: 10. Доступные варианты: 5, 6, 7, 8, 9, 10, 15, 20.

Определяет, сколько записей логов отображается на одной странице во вкладке «Логи». При большом количестве логов страница будет разбиваться на части с постраничной навигацией.

3.5. Упаковывать в ZIP (pack_to_zip)

По умолчанию: выключено (0).

  • Если включено (1), все экспортируемые файлы будут автоматически упаковываться в ZIP‑архив. Имя архива формируется по шаблону db_export_bundle_ГГГГММДД_ЧЧММСС.zip для обычного экспорта и db_export_combined_... для комбинированного. Оригинальный файл (CSV/JSON/…) после упаковки может быть удалён (если export_to_browser = 0) или сохранён вместе с архивом.
  • Если выключено (0), файлы экспортируются в исходном формате без архивации.

4. Интерфейс плагина

После установки плагин добавляет пункт «DB Structure Viewer» в раздел «Инструменты» админ‑панели Cotonti (путь: admin/other?p=dbviewstructure). Интерфейс состоит из четырёх вкладок:

  • Структура — просмотр таблиц и их содержимого.
  • Экспорт — обычный экспорт одной или нескольких таблиц.
  • Комбинированный CSV — настраиваемый экспорт из нескольких связанных таблиц.
  • Логи — история экспорта (отображается только при включённом логировании).

Каждая вкладка описана далее.


5. Вкладка «Структура»

Вкладка предназначена для быстрого ознакомления со списком таблиц, имеющих префикс Cotonti (по умолчанию cot_, но может быть изменён в config.php как $cfg['db_x']). Выводится таблица со следующими колонками:

  • Таблица — имя таблицы без префикса.
  • Поля — список полей через запятую.
  • Движок — тип хранилища (InnoDB, MyISAM и т.п.).
  • Строк — примерное количество строк (данные из SHOW TABLE STATUS).

Вкладка имеет два подраздела, переключаемых через вложенные табы:

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

5.1. Просмотр строк

Форма содержит:

  • выпадающий список таблиц (заполняется всеми таблицами с префиксом Cotonti);
  • необязательное поле «ID строки» — целое число;
  • кнопку «Показать».

При нажатии «Показать» происходит запрос к выбранной таблице. Если ID указан, выполняется SELECT * FROM таблица WHERE первичный_ключ = ID LIMIT 1. Если ID не указан, выбираются первые 10 записей (LIMIT 10). Результат отображается в виде двух таблиц:

  • Поля таблицы — список всех полей с их характеристиками (Имя, Тип, NULL, Ключ, По умолчанию, Extra). Эта информация извлекается через SHOW FULL COLUMNS.
  • Данные — строки, соответствующие запросу. Каждая строка представлена в виде набора ячеек, заголовками служат имена полей.

Таким образом, можно быстро проверить содержимое любой таблицы, не прибегая к phpMyAdmin или командной строке.


6. Вкладка «Экспорт»

Эта вкладка позволяет экспортировать структуру и/или данные одной или нескольких таблиц в выбранном формате. Она подходит для быстрого получения дампа конкретных таблиц.

6.1. Интерфейс

  • Формат: выпадающий список с вариантами SQL, CSV, JSON, PHP Array.
  • Режим данных: переключатели (радиокнопки):
    • Только структура — экспортируются только описания полей (для SQL — CREATE TABLE, для JSON/PHP/CSV — информация о полях без самих данных).
    • Включить данные (10 строк) — к структуре добавляются первые 10 строк каждой выбранной таблицы.
    • Все строки — экспортируются все строки таблиц (может быть долго для больших таблиц).
  • Кнопка «Экспорт» — запускает процесс.
  • Список таблиц с чекбоксами и кнопкой «Выделить все» — выбор таблиц для экспорта.

6.2. Процесс экспорта

  1. Выберите нужные таблицы галочками.
  2. Выберите формат и режим данных.
  3. Нажмите «Экспорт».

В зависимости от настроек export_to_browser и pack_to_zip:

  • Если export_to_browser = 1, браузер начнёт скачивание файла. Если при этом pack_to_zip = 1, скачан будет ZIP‑архив, иначе — файл выбранного формата.
  • Если export_to_browser = 0, файл будет сохранён в папке export_path. При pack_to_zip = 1 будет создан архив, а оригинальный файл удалён (если упаковка прошла успешно).

При включённом логировании в таблицу cot_dbviewstructure_logs будет добавлена запись с именем файла, форматом и количеством таблиц.

6.3. Особенности форматов

  • SQL: генерируется скрипт, содержащий DROP TABLE IF EXISTS и CREATE TABLE для каждой таблицы. При включении данных добавляются INSERT INTO. Удобен для переноса структуры между серверами.
  • CSV: для режима «Только структура» формируется таблица с полями: Table, Field, Type, Null, Key, Default, Extra. Для данных CSV содержит непосредственно строки таблиц с заголовками.
  • JSON: структура и данные упаковываются в многоуровневый JSON‑объект. Удобен для машинной обработки.
  • PHP Array: экспортируется в виде PHP‑кода, возвращающего массив. Подходит для включения в код Cotonti.

7. Вкладка «Комбинированный CSV»

Это наиболее мощная и гибкая часть плагина. Она позволяет сформировать CSV‑файл, строки которого соответствуют записям из базовой таблицы, а колонки могут содержать данные из самой базовой таблицы и из любых других таблиц, связанных с ней через механизм JOIN (объединения).

7.1. Назначение и концепция

Предположим, у вас есть интернет‑магазин на Cotonti с модулем market. Товары хранятся в таблице cot_market, но описания товаров на разных языках лежат в отдельной таблице cot_i18n4marketpro_pages, а изображения — в cot_attacher. Чтобы выгрузить все товары с их названиями, описаниями на нужном языке и списком картинок, обычного экспорта недостаточно — разные таблицы нужно объединять по идентификатору товара. Именно это и делает «Комбинированный экспорт».

Вы определяете:

  • Базовую таблицу — её записи станут строками CSV.
  • Набор колонок — для каждой вы задаёте:
    • название колонки в CSV;
    • таблицу, откуда брать данные;
    • поле этой таблицы;
    • (опционально) способ агрегации для множественных значений (например, для картинок);
    • режим связи с базовой таблицей (автоматический или ручной выбор поля‑связи).

Плагин автоматически строит SQL‑запрос с нужными LEFT JOIN и GROUP BY, выполняет его и записывает результат в CSV. Пути к картинкам (из таблицы attacher) преобразуются в абсолютные URL вашего сайта.

7.2. Описание интерфейса

Форма состоит из:

  • Выбор базовой таблицы: обязательный выпадающий список всех таблиц с префиксом Cotonti. Выберите таблицу, которая будет источником строк. Обычно это market, pages, users и т.п.
  • Динамические колонки: контейнер, в который вы добавляете строки конфигурации колонок. Каждая строка содержит:
    • поле ввода названия колонки в CSV (произвольный текст);
    • селектор таблицы (все таблицы Cotonti);
    • селектор поля (загружается динамически после выбора таблицы через AJAX);
    • селектор агрегации (необязательный) — опции: «Без агрегации», «Первая картинка (MIN)», «Остальные картинки (через запятую)»;
    • блок настройки JOIN (появляется после выбора таблицы):
      • селектор режима: «JOIN: авто» или «JOIN: вручную»;
      • селектор поля связи (показывается только при ручном режиме) — содержит все поля выбранной таблицы, позволяя указать, какое именно поле должно использоваться для соединения с базовой таблицей.
    • кнопка удаления строки (×).
  • Кнопки управления:
    • «+ Добавить колонку» — создаёт новую пустую строку.
    • «Очистить поля» — удаляет все строки колонок и сбрасывает базовую таблицу; сохранённая в localStorage конфигурация также очищается.
  • Кнопка «Экспорт» — запускает комбинированный экспорт.

7.3. Принцип работы маппинга колонок

Каждая добавленная колонка определяет, какое значение попадёт в соответствующую ячейку CSV для каждой строки базовой таблицы. Возможны три случая:

  1. Поле из самой базовой таблицы. Выбирается таблица, совпадающая с базовой. В SQL это просто поле без JOIN.
  2. Поле из другой таблицы, связанной с базовой. В этом случае плагин определяет, как именно эта таблица связана с базовой (условие JOIN). Вы можете положиться на автоматическое определение или указать поле связи вручную.
  3. Специальные агрегации для картинок (attacher). Для таблицы attacher (из плагина attacher, широко используемого в Cotonti) доступны две агрегации:
    • Первая картинка (MIN): возвращает путь к изображению с наименьшим att_id (самая ранняя загруженная картинка). В CSV попадёт абсолютный URL.
    • Остальные картинки (через запятую): возвращает строку, состоящую из абсолютных URL всех изображений товара, кроме первой, разделённых запятой и пробелом.

Агрегации работают только для полей типа att_path (путь к файлу). Если выбрано другое поле, агрегация игнорируется.

7.4. Автоматическое определение JOIN (режим «авто»)

Когда для колонки выбрана таблица, отличная от базовой, и включён режим «JOIN: авто», плагин пытается угадать условие связи. Алгоритм (функция dbview_detect_join_condition):

  1. Если присоединяемая таблица — cot_attacher, используется фиксированное условие: att_item = ID_базовой_таблицы AND att_area = 'имя_модуля' (например, 'market'). Это стандартный способ связи в attacher.
  2. Ищется поле, точное имя которого совпадает с baseIdField (первичный ключ базовой таблицы, обычно оканчивается на _id).
  3. Ищется поле, заканчивающееся на _id или _item и содержащее в названии имя базовой таблицы (без префикса). Например, для базовой таблицы market будет искаться market_id, market_item и т.п.
  4. Если ничего не найдено, берётся любое поле, оканчивающееся на _id (первое попавшееся) — запасной вариант.

Если и это не помогло, экспорт прерывается с ошибкой «Cannot detect JOIN condition».

Пример: базовая таблица x92374_market, ID‑поле fieldmrkt_id. Присоединяемая x92374_i18n4marketpro_pages. Алгоритм найдёт поле ipage_id (заканчивается на _id) и создаст условие ipage_id = fieldmrkt_id. Этого достаточно для корректной связи.

7.5. Ручное указание поля связи (режим «JOIN: вручную»)

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

Например, для таблицы i18n4marketpro_pages вы можете вручную выбрать ipage_id (даже если авто‑алгоритм уже нашёл это поле). Для таблицы attacher ручной режим также доступен, но будет проигнорирован — всегда используется стандартная связка att_item + att_area.

Этот подход даёт полную гибкость: можно связывать даже таблицы, вообще не имеющие очевидных связей по имени, если вы знаете, какое поле использовать.

7.6. Сохранение формы между сеансами

Чтобы не потерять тщательно настроенную конфигурацию колонок при случайной перезагрузке страницы или переходе по другим вкладкам, плагин использует localStorage браузера. При любом изменении полей (ввод текста, выбор значений) текущее состояние формы автоматически сохраняется. При следующем открытии вкладки «Комбинированный CSV» данные восстанавливаются.

Сохранение происходит под ключом dbv_combined_form и содержит выбранную базовую таблицу и массив колонок с их параметрами. Кнопка «Очистить поля» удаляет эту запись из localStorage и сбрасывает форму к трём пустым строкам по умолчанию.

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

Задача: получить CSV всех товаров с артикулом, названием на украинском, описанием на украинском и списком всех изображений.

Шаги:

  1. На вкладке «Комбинированный CSV» выберите базовую таблицу market.
  2. Нажмите «+ Добавить колонку» и настройте строки:
    • Колонка «Артикул»: таблица market, поле fieldmrkt_pcod, агрегация не нужна, JOIN авто.
    • Колонка «Назва»: таблица i18n4marketpro_pages, поле ipage_title, JOIN авто (или вручную выбрать ipage_id).
    • Колонка «Опис»: та же таблица i18n4marketpro_pages, поле ipage_text, JOIN аналогично.
    • Колонка «Фото»: таблица attacher, поле att_path, агрегация «Остальные картинки (через запятую)», JOIN авто.
  3. Проверьте, что все поля корректно загружены (селекторы заполнены).
  4. Нажмите «Экспорт».

В зависимости от настроек плагина вы получите либо CSV, либо ZIP‑архив с CSV внутри. В полученном файле каждая строка будет соответствовать одному товару, а колонки заполнены соответствующими данными. Пути к картинкам будут начинаться с https://ваш_сайт/.

7.8. Технические детали комбинированного экспорта

  • SQL‑запрос строится с использованием LEFT JOIN для всех задействованных таблиц (кроме базовой). Чтобы избежать дублирования строк при связях «один‑ко‑многим», применяется GROUP BY по ID базовой таблицы.
  • Для агрегаций first_image и rest_images используются коррелированные подзапросы с LIMIT 1 и GROUP_CONCAT соответственно. Это обеспечивает корректный выбор первой и последующих картинок.
  • Абсолютные URL для изображений формируются на основе Cot::$sys['abs_url'] (или $cfg['mainurl']), что даёт правильный протокол и домен.
  • ZIP‑упаковка встроена прямо в функцию экспорта и включает проверки на каждом этапе, чтобы исключить повреждение архива.

8. Вкладка «Логи»

Если в конфигурации включено логирование, эта вкладка показывает историю всех операций экспорта (как обычного, так и комбинированного).

8.1. Просмотр логов

Каждая запись лога отображает:

  • ID — порядковый номер записи.
  • Файл — имя файла (отображается вместе с путём из конфигурации). Если файл физически существует на сервере, имя выводится как код; иначе показывается красный текст «Файл отсутствует на сервере».
  • Загрузка — ссылка для скачивания (активна только при существующем файле).
  • Формат — тип файла (SQL, CSV, JSON, PHP, ZIP) в виде цветного бейджа.
  • Таблиц — количество таблиц, участвовавших в экспорте.
  • Данные — «Да» или «Нет», показывающее, были ли включены строки данных (а не только структура).
  • Дата — временная метка экспорта в локальном формате.

Логи отображаются постранично; количество записей на странице задаётся в настройке max_rows_per_page. Внизу таблицы находится стандартная навигация пагинации Cotonti.

8.2. Очистка логов

Кнопка «Очистить все логи» (красная, справа от заголовка) позволяет одним нажатием полностью удалить все записи из таблицы cot_dbviewstructure_logs. При нажатии появляется подтверждение. Очистка происходит через SQL‑команду TRUNCATE TABLE.

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


9. Загрузка ранее экспортированных файлов

Любой файл, созданный плагином (и отображённый в логах), можно скачать двумя способами:

  • На вкладке «Логи» кликнуть по ссылке «Скачать файл экспорта», если файл существует.
  • Использовать прямую ссылку, формируемую плагином: admin/other?p=dbviewstructure&a=download&file=имя_файла. Этот механизм обходит возможные проблемы с NGINX (405 ошибка) и отдаёт файл с корректными заголовками.

10. Сценарии использования

10.1. Резервное копирование структуры избранных таблиц

  • Перейдите на вкладку «Экспорт».
  • Отметьте нужные таблицы.
  • Выберите формат SQL и режим «Только структура».
  • Нажмите «Экспорт». Полученный SQL‑файл можно использовать для восстановления структуры на другом сервере.

10.2. Выгрузка товаров для маркетплейса

  • На вкладке «Комбинированный CSV» настройте колонки в соответствии с требованиями площадки (артикул, название, цена, описание, ссылки на изображения).
  • Используйте ручной выбор JOIN для нестандартных таблиц.
  • Экспортируйте в CSV (или ZIP, если включена архивация). Файл готов к загрузке в маркетплейс.

10.3. Анализ данных в Excel

  • Скомбинируйте данные из нескольких таблиц (например, пользователи + их заказы + профили) в единый CSV.
  • Откройте файл в Excel (благодаря BOM в начале файла кодировка UTF‑8 распознаётся корректно). Постройте сводные таблицы, диаграммы.

10.4. Миграция части данных

  • Экспортируйте нужные таблицы в формате SQL с данными. Используйте фильтр по ID (через вкладку «Структура») для предварительного просмотра, затем выгружайте всю таблицу через «Экспорт» с режимом «Все строки».

11. Безопасность и права доступа

Плагин доступен только пользователям с правами администратора (cot_auth('plug', 'dbviewstructure', 'A')). Все операции (просмотр таблиц, экспорт, очистка логов) требуют подтверждения прав.

Файлы экспорта сохраняются в защищённой директории, недоступной для прямого скачивания извне (если сервер правильно настроен). Для скачивания используется внутренний обработчик Cotonti, проверяющий авторизацию.

Тем не менее, рекомендуется ограничить доступ к папке plugins/dbviewstructure/export/ через .htaccess или правила nginx, чтобы предотвратить прямое обращение к файлам.


12. Устранение неполадок

12.1. Ошибка «Cannot detect JOIN condition for ...»

Возникает при комбинированном экспорте, когда автоматическое определение связи не смогло найти подходящее поле. Решение:

  • Переключите соответствующую колонку в режим «JOIN: вручную» и выберите поле связи самостоятельно.
  • Убедитесь, что в присоединяемой таблице есть поле, которое можно сопоставить с ID базовой таблицы.

12.2. Файл экспорта не создаётся / ошибка записи

Проверьте права на папку, указанную в export_path. Она должна существовать и быть доступной для записи (обычно 755 или 777).

12.3. ZIP‑архив повреждён

  • Убедитесь, что на сервере установлено расширение PHP zip (класс ZipArchive).
  • При использовании export_to_browser = 1 иногда проблема решается отключением архивации или увеличением лимитов памяти.
  • В последней версии плагина функция упаковки встроена в комбинированный экспорт и содержит многократные проверки целостности. Если архив всё же битый, попробуйте временно отключить pack_to_zip и экспортировать чистый CSV.

12.4. Не загружаются поля в селекторах комбинированного экспорта

Убедитесь, что AJAX‑запросы отрабатывают корректно. Проверьте консоль браузера на наличие ошибок. Запрос к index.php?r=dbviewstructure&a=get_columns&table=... должен возвращать JSON со списком полей.

12.5. Пропадают настройки комбинированного экспорта при перезагрузке

Настройки сохраняются в localStorage браузера. Если они не восстанавливаются, возможно, в вашем браузере отключён localStorage или вы используете режим инкогнито. Очистка localStorage (через кнопку «Очистить поля») также сбрасывает сохранённые данные.


13. Примечания по совместимости и кастомизации

  • Плагин разработан для Cotonti Siena 0.9.26 и протестирован на PHP 8.4+ с MySQL 8.0.
  • Префикс таблиц Cotonti определяется автоматически из $cfg['db_x'] или из Cot::$db_x. Если вы используете нестандартный префикс, плагин будет работать с ним.
  • Пути к изображениям формируются с использованием Cot::$sys['abs_url']. Если ваш сайт доступен по нескольким доменам, URL будет соответствовать тому, с которого был выполнен экспорт.
  • Шаблон вкладок можно изменить в файле dbviewstructure.tools.tpl. Например, настроить внешний вид кнопок или таблиц.
  • Логи пишутся в дополнительный файл plugins/dbviewstructure/logs/export.log, если включено логирование и установлена соответствующая настройка в functions.php. Файл логов может пригодиться для детальной отладки.

14. Заключение

Плагин DB Structure Viewer значительно упрощает работу с базой данных Cotonti, предоставляя интуитивно понятные инструменты для просмотра, экспорта и гибкого связывания таблиц. Возможность комбинированного экспорта с автоматическим или ручным управлением JOIN делает его незаменимым при подготовке данных для внешних систем, аналитики или миграций.

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

Если вы столкнулись с ошибками или у вас есть предложения по улучшению, обратитесь к автору через GitHub‑репозиторий (https://github.com/webitproff/cot-dbviewstructure) или официальный форум Cotonti.


 

Полное руководство по вкладке «Комбинированный CSV» плагина DB Structure Viewer

Данное руководство посвящено единственной вкладке плагина DB Structure Viewer — «Комбинированный CSV». Оно рассчитано на начинающих администраторов Cotonti, которые хотят научиться выгружать данные сразу из нескольких таблиц базы данных в один CSV-файл, не написав ни строчки кода.

Мы пройдём весь путь: от понимания, зачем это нужно, до создания сложных выгрузок с изображениями и мультиязычными описаниями. Каждое действие объясняется предельно подробно, с аналогиями и примерами.


1. Введение: зачем нужен комбинированный экспорт?

В Cotonti данные редко хранятся в одной таблице. Например, товары в модуле market лежат в cot_market, их описания на разных языках — в cot_i18n4marketpro_pages, а картинки — в cot_attacher. Если вы захотите выгрузить все товары в Excel, вам придётся как-то «склеить» эти таблицы, чтобы в одной строке оказались и название товара, и его описание на нужном языке, и список изображений.

Обычный экспорт (вкладка «Экспорт») умеет выгружать только отдельные таблицы. Комбинированный CSV делает именно «склейку»: вы сами решаете, какие колонки будут в итоговом файле, из каких таблиц брать данные и как эти таблицы связаны между собой.

Результат — CSV-файл, который можно открыть в Excel, Google Sheets или загрузить в другой сервис (например, маркетплейс). Каждая строка в нём соответствует одной записи из базовой таблицы (например, одному товару), а колонки заполняются данными из всех таблиц, которые вы подключите.


2. Основные понятия

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

Базовая таблица (Base Table)

Это главная таблица, которая определяет количество строк в итоговом CSV. Если в базовой таблице 150 товаров, то в CSV будет 150 строк (по одной на каждый товар). Обычно в качестве базовой выбирают таблицу модуля: market — для товаров, pages — для статей, users — для пользователей и т.д.

JOIN (связь между таблицами)

JOIN — это механизм, который объединяет строки из двух таблиц на основе какого-то общего поля. Например, у каждого товара есть уникальный идентификатор (ID). В таблице cot_attacher хранятся изображения, и у каждого изображения есть поле att_item, которое говорит, к какому товару оно относится. Если att_item равен ID товара, то мы можем «присоединить» изображения к товару.

В нашем плагине JOIN'ы создаются автоматически (или вручную) для каждой колонки, которая берёт данные не из базовой таблицы.

Маппинг (Mapping)

Маппинг — это процесс сопоставления: вы говорите, что в первой колонке CSV должно быть «Название товара», которое берётся из таблицы market, поле fieldmrkt_title. А во второй колонке — «Цена» из той же таблицы, поле fieldmrkt_costdflt. И так далее.

Агрегация (Aggregation)

Иногда одному товару соответствует несколько записей в другой таблице. Например, у товара может быть 5 картинок. Если мы просто присоединим таблицу attacher, товар продублируется 5 раз. Чтобы этого избежать, используются агрегации:

  • Первая картинка (MIN) — берёт только одну (самую раннюю) картинку.
  • Остальные картинки (через запятую) — собирает все остальные картинки в одну ячейку, разделяя их запятой.

Агрегации доступны только для таблицы attacher и поля att_path.


3. Интерфейс вкладки «Комбинированный CSV»

Когда вы переходите на вкладку «Комбинированный CSV» (кнопка в верхней панели, рядом с «Экспорт» и «Структура»), вы видите:

  1. Заголовок «Комбинированный экспорт в CSV» и краткое описание.
  2. Выпадающий список «Базовая таблица (строки)».
  3. Контейнер с динамическими колонками (изначально пустой или с тремя пустыми строками, если вы зашли впервые).
  4. Кнопки «+ Добавить колонку» и «Очистить поля».
  5. Кнопку «Экспорт».

Разберём каждый элемент детально.

3.1. Выбор базовой таблицы

Это обязательный элемент. Щёлкнув по нему, вы увидите список всех таблиц вашей базы данных, которые начинаются с префикса Cotonti (обычно cot_, но у вас может быть другой). Имена отображаются без префикса для удобства, но в обработку идёт полное имя (например, x92374_market).

Вы должны выбрать одну таблицу. Именно её строки станут строками CSV. Если вы передумаете, просто выберите другую таблицу из списка.

Пример: вы хотите выгрузить товары. Выбираете market. Если нужны пользователи — users, статьи — pages.

3.2. Динамические колонки (контейнер #columns-container)

Это центральная часть формы. Здесь вы добавляете, настраиваете и удаляете колонки будущего CSV. Каждая колонка представлена строкой, содержащей несколько элементов управления. По умолчанию при первом заходе создаётся 3 пустые строки, но вы можете добавить сколько угодно.

Каждая строка колонки содержит:

  • Поле ввода названия колонки (слева) — произвольный текст. Это будет заголовок в CSV. Например, «Название товара», «Цена», «Первая картинка». Можно использовать любые символы, включая кириллицу и пробелы.
  • Селектор таблицы — выпадающий список всех таблиц с префиксом Cotonti. Выбрав таблицу, вы указываете, откуда брать данные для этой колонки.
  • Селектор поля — становится активным после выбора таблицы. Содержит все поля выбранной таблицы. Загружается через AJAX. Выберите нужное поле (например, fieldmrkt_title).
  • Селектор агрегации — необязательный, активен после выбора таблицы. Содержит три варианта:
    • «— Без агрегации —» (по умолчанию)
    • «Первая картинка (MIN)»
    • «Остальные картинки (через запятую)»
  • Блок настройки JOIN (правее) — появляется после выбора таблицы. Состоит из:
    • Селектора режима: «JOIN: авто» (по умолчанию) или «JOIN: вручную».
    • Селектора «поле связи» (показывается только при выборе «JOIN: вручную») — содержит все поля выбранной таблицы. Здесь вы указываете, какое поле использовать для соединения с базовой таблицей.
  • Кнопка «×» (красная) — удаляет эту строку колонки.

Если для колонки выбрана та же таблица, что и базовая, блок JOIN не нужен и будет скрыт (остаётся только выбор поля). Если таблица отличается — блок JOIN становится обязательным (вы должны либо довериться автоматике, либо указать поле связи вручную).

3.3. Кнопки управления

  • «+ Добавить колонку» — создаёт новую строку колонки внизу контейнера. Вы можете нажать её много раз, чтобы добавить нужное количество колонок.
  • «Очистить поля» — удаляет все строки колонок, сбрасывает базовую таблицу (выбор становится пустым) и очищает сохранённую в браузере конфигурацию. После очистки автоматически создаются 3 пустые строки, чтобы вы могли начать заново.

3.4. Кнопка «Экспорт»

Запускает процесс формирования CSV-файла и, в зависимости от настроек плагина, либо сохраняет его на сервере, либо сразу отдаёт браузеру для скачивания (возможно, в виде ZIP-архива). При нажатии кнопки форма отправляется на сервер, где происходит вся «магия»: строятся SQL-запросы, выполняются, результат пишется в файл.


4. Пошаговое руководство: ваш первый комбинированный экспорт

Давайте представим, что у нас есть интернет-магазин с модулем market. Мы хотим получить CSV всех товаров с тремя колонками: «Артикул», «Название», «Цена». Все эти данные лежат в самой таблице market, так что JOIN'ы нам не понадобятся. Этот пример — разминка перед более сложными задачами.

Шаг 1. Откройте вкладку «Комбинированный CSV»

В админ-панели Cotonti перейдите: Инструменты → DB Structure Viewer → вкладка «Комбинированный CSV».

Шаг 2. Выберите базовую таблицу

В выпадающем списке «Базовая таблица (строки)» найдите market. Нажмите на него. Теперь наш CSV будет содержать по одной строке на каждый товар из этой таблицы.

Шаг 3. Настройте первую колонку

Под заголовком «Динамические колонки» вы увидите одну или несколько строк. Если строк нет, нажмите «+ Добавить колонку». В первой строке:

  1. В поле ввода названия колонки напишите «Артикул».
  2. В селекторе таблиц выберите market (ту же, что базовая).
  3. После загрузки полей (произойдёт автоматически через мгновение) в селекторе поля выберите fieldmrkt_pcod (обычно это код товара).
  4. Агрегацию оставьте «Без агрегации».
  5. Блок JOIN не появится, так как таблица совпадает с базовой.

Шаг 4. Добавьте вторую колонку

Нажмите «+ Добавить колонку». В новой строке:

  1. Название: «Название».
  2. Таблица: снова market.
  3. Поле: fieldmrkt_title.
  4. Остальное по умолчанию.

Шаг 5. Добавьте третью колонку

Аналогично: название «Цена», таблица market, поле fieldmrkt_costdflt.

Шаг 6. Проверьте результат

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

Шаг 7. Экспортируйте

Нажмите «Экспорт». В зависимости от настроек плагина (см. основной конфиг) файл либо сразу скачается, либо сохранится в папке экспорта. Откройте полученный CSV в Excel или текстовом редакторе. Вы увидите три колонки с вашими заголовками, а под ними — данные товаров.

Поздравляю! Это был простейший экспорт. Теперь переходим к более интересным вещам.


5. Работа с динамическими колонками: подробности

5.1. Добавление колонок

Кнопка «+ Добавить колонку» создаёт новую строку внизу списка. Вы можете добавить сколько угодно колонок — в CSV они пойдут в том порядке, в котором вы их расположили. Порядок можно изменить только удалением и повторным добавлением (плагин не поддерживает перетаскивание, но это не критично).

Каждая новая колонка сразу получает уникальный индекс (в атрибутах name полей формы). Индексы не обновляются при удалении средних колонок, но это не влияет на обработку — сервер принимает массив и обрабатывает только те элементы, у которых заполнены обязательные поля (название, таблица, поле).

5.2. Настройка колонки

После создания строки вы должны заполнить как минимум три поля: название, таблицу и поле. Пока таблица не выбрана, селекторы поля и агрегации неактивны (серые). Как только вы выбираете таблицу, происходит AJAX-запрос к серверу, который возвращает JSON-список всех полей этой таблицы. Этот список подставляется в селекторы поля и, при необходимости, в селектор «поле связи» (если включён ручной JOIN).

Важно: если вы смените таблицу, уже выбранное поле сбросится, потому что поля в разных таблицах разные.

5.3. Удаление колонки

Красная кнопка «×» в правой части строки удаляет её. При удалении колонки из середины списка индексы не пересчитываются, но это нормально. Сервер проигнорирует «дырки» в нумерации.

5.4. Очистка всех колонок

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


6. Автоматическое и ручное определение связей (JOIN)

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

6.1. Режим «JOIN: авто»

Это режим по умолчанию. Вы просто выбираете таблицу и поле, а плагин сам пытается «догадаться», какое поле в выбранной таблице соответствует ID базовой таблицы.

Алгоритм автоопределения (упрощённо):

  1. Если выбранная таблица — attacher, условие фиксированное: att_item = <ID базовой таблицы> AND att_area = '<имя модуля>'. Имя модуля извлекается из названия базовой таблицы (например, market, pages). Это покрывает 90% случаев работы с изображениями.
  2. Иначе ищется поле, точное имя которого совпадает с именем ID-поля базовой таблицы (например, fieldmrkt_id в таблице market, и точно такое же fieldmrkt_id в другой таблице).
  3. Если точного совпадения нет, ищется поле, заканчивающееся на _id или _item, и при этом содержащее в названии имя базовой таблицы. Например, для базовой market будет искаться market_id, market_item и т.п.
  4. Если и этого нет, берётся любое поле, заканчивающееся на _id (первое попавшееся).
  5. Если ничего не найдено, экспорт прерывается с ошибкой.

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

6.2. Режим «JOIN: вручную»

Если автоматика не сработала или вы хотите явно контролировать связь, переключите селектор режима в положение «JOIN: вручную». После этого появится дополнительный селектор «поле связи», в котором перечислены все поля выбранной таблицы. Выберите то поле, которое содержит идентификатор, соответствующий ID базовой таблицы.

Пример: базовая таблица — market, ID-поле — fieldmrkt_id. Вы хотите добавить колонку с украинским названием товара из таблицы i18n4marketpro_pages. Автоопределение может сработать (найдёт ipage_id), но вы для надёжности включаете ручной режим и в селекторе «поле связи» выбираете ipage_id. Теперь плагин точно знает, что ipage_id из i18n4marketpro_pages соответствует fieldmrkt_id из market.

Обратите внимание: для таблицы attacher ручной режим также доступен, но он будет проигнорирован — всегда используется стандартная связка att_item + att_area. Сделано это для того, чтобы неопытный пользователь случайно не сломал логику работы с изображениями.

6.3. Как проверить, правильно ли определился JOIN?

К сожалению, в интерфейсе нет прямой индикации. Но если экспорт завершился успешно, и данные в колонках соответствуют ожидаемым — связь определилась верно. Если вы получили ошибку «Cannot detect JOIN condition for ...», значит, автоопределение не смогло найти подходящее поле. Тогда включите ручной режим и укажите поле явно.


7. Агрегации для изображений (подробный разбор)

Таблица attacher используется для хранения любых прикреплённых файлов, но чаще всего — изображений товаров и страниц. У одного товара может быть много картинок. Если мы просто сделаем LEFT JOIN к таблице attacher, то для товара с 5 картинками получим 5 строк в CSV, что испортит всю выгрузку. Чтобы этого избежать, используются агрегации.

7.1. «Первая картинка (MIN)»

Выбирая эту агрегацию, вы говорите плагину: «Для каждого товара возьми только одну, самую первую загруженную картинку». Технически это реализовано через подзапрос с сортировкой по att_order и att_id и LIMIT 1. В результате в ячейке CSV окажется абсолютный URL этой картинки (например, https://vash-sait.ru/attacher/market/123/att_456.webp).

Когда это использовать: когда вам нужна только главная картинка товара (например, для загрузки в маркетплейс, где требуется одно основное фото).

7.2. «Остальные картинки (через запятую)»

Эта агрегация собирает все картинки, кроме первой, и объединяет их в одну строку через запятую и пробел. Например: https://vash-sait.ru/attacher/market/123/att_457.webp, https://vash-sait.ru/attacher/market/123/att_458.webp.

Если у товара только одна картинка, в этой колонке будет пусто. Если две — попадёт только вторая. Если пять — все, кроме первой.

Когда использовать: когда площадка позволяет загрузить несколько дополнительных изображений.

7.3. «Без агрегации»

Если вы уверены, что у каждого товара строго одна картинка (или вас не волнует дублирование строк), можно оставить «Без агрегации». Тогда при наличии нескольких картинок товар продублируется, и каждая строка будет с одной картинкой. Не рекомендуется для большинства случаев.

7.4. Какое поле выбирать для картинок?

Всегда используйте поле att_path. Оно содержит относительный путь к файлу, например attacher/market/2336/att_2788.webp. Плагин автоматически преобразует его в абсолютный URL, добавляя домен вашего сайта. Поле att_filename содержит оригинальное имя загруженного файла, но оно не гарантирует доступность файла (оригинал может быть удалён). Поэтому для получения рабочих ссылок на изображения используйте att_path.


8. Сохранение и восстановление формы

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

8.1. Как это работает?

При любом изменении в форме (ввод текста, выбор значения в селекторе, добавление/удаление колонки) вызывается функция saveFormToStorage(). Она собирает текущие значения базовой таблицы и всех колонок (название, таблицу, поле, агрегацию, режим JOIN, поле связи) и сохраняет в localStorage под ключом dbv_combined_form.

При загрузке страницы (событие DOMContentLoaded) плагин проверяет, есть ли сохранённые данные, и если есть — восстанавливает их: заполняет базовую таблицу и создаёт колонки с теми же настройками, включая выбранные таблицы и поля (с задержкой для подгрузки полей через AJAX). Если сохранённых данных нет, создаются три пустые строки по умолчанию.

8.2. Когда данные удаляются?

  • При нажатии кнопки «Очистить поля».
  • При ручной очистке localStorage браузера.
  • Если вы используете браузер в режиме инкогнито — данные могут не сохраняться между сеансами.

8.3. Ручное управление

Вы не можете напрямую управлять сохранёнными данными из интерфейса, кроме как очистить их кнопкой. Но вы можете открыть консоль разработчика (F12), перейти в раздел «Application» → «Local Storage» и найти ключ dbv_combined_form, чтобы просмотреть или удалить его вручную.


9. Обработка ошибок и их решение

При работе с комбинированным экспортом могут возникать различные ошибки. Рассмотрим самые частые и способы их устранения.

9.1. «Invalid base table» или «Cannot determine ID field for table»

Эта ошибка появляется, если вы не выбрали базовую таблицу или если в выбранной таблице нет поля, оканчивающегося на _id (например, fieldmrkt_id, page_id и т.п.). Плагин ожидает, что у базовой таблицы есть первичный ключ с таким окончанием. Решение:

  • Убедитесь, что вы выбрали таблицу в списке «Базовая таблица».
  • Проверьте структуру таблицы (вкладка «Структура»), есть ли там поле с _id на конце. Если нет, выберите другую таблицу или добавьте нужное поле вручную через phpMyAdmin (но это для продвинутых).

9.2. «Cannot detect JOIN condition for ...»

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

  • Переключите эту колонку в режим «JOIN: вручную» и выберите поле связи самостоятельно (см. раздел 6.2).

9.3. «No columns defined»

Означает, что вы не настроили ни одной колонки (или во всех строках не заполнено одно из обязательных полей: название, таблица, поле). Проверьте, что в каждой колонке заполнены все три поля.

9.4. Ошибка экспорта (общая)

Если появляется сообщение «Ошибка экспорта» без уточнений, причиной может быть:

  • Отсутствие прав на запись в папке экспорта (plugins/dbviewstructure/export/). Установите права 755 или 777.
  • Ошибка в SQL-запросе. Включите логирование в конфиге и проверьте файл plugins/dbviewstructure/logs/export.log. Там будет записан полный SQL и сообщение об ошибке.
  • Нехватка памяти или времени выполнения скрипта. Попробуйте уменьшить количество колонок или выбрать меньше данных (например, если базовая таблица очень большая).

9.5. ZIP-архив повреждён

Если включена упаковка в ZIP, но архив не открывается, проверьте:

  • Установлено ли расширение PHP zip. Создайте файл info.php с <?php phpinfo(); и найдите раздел zip.
  • Попробуйте временно отключить pack_to_zip в настройках плагина и экспортировать чистый CSV. Если CSV создаётся нормально, проблема именно в упаковке.
  • Убедитесь, что на сервере достаточно свободного места.

10. Практические примеры

Рассмотрим несколько реальных сценариев, чтобы закрепить понимание.

Пример 1. Экспорт товаров с основными полями и первой картинкой

Задача: получить CSV товаров с колонками: «Код товара», «Название», «Описание», «Цена», «Главное фото».

Настройка:

  • Базовая таблица: market.
  • Колонка 1: название «Код товара», таблица market, поле fieldmrkt_pcod.
  • Колонка 2: название «Название», таблица market, поле fieldmrkt_title.
  • Колонка 3: название «Описание», таблица market, поле fieldmrkt_text.
  • Колонка 4: название «Цена», таблица market, поле fieldmrkt_costdflt.
  • Колонка 5: название «Главное фото», таблица attacher, поле att_path, агрегация «Первая картинка (MIN)», JOIN авто.

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

Пример 2. Экспорт товаров с мультиязычными описаниями и всеми картинками

Задача: получить CSV с колонками: «Артикул», «Название (укр)», «Описание (укр)», «Все фото (кроме главного)».

Настройка:

  • Базовая таблица: market.
  • Колонка 1: название «Артикул», таблица market, поле fieldmrkt_pcod.
  • Колонка 2: название «Название (укр)», таблица i18n4marketpro_pages, поле ipage_title. Поскольку это не базовая таблица, нужно определить JOIN. Если авто не срабатывает, включите «JOIN: вручную» и выберите поле связи ipage_id.
  • Колонка 3: название «Описание (укр)», та же таблица i18n4marketpro_pages, поле ipage_text, JOIN аналогично.
  • Колонка 4: название «Все фото (кроме главного)», таблица attacher, поле att_path, агрегация «Остальные картинки (через запятую)», JOIN авто.

Результат: в CSV каждая строка — товар. Название и описание взяты из таблицы переводов (предполагаем, что там записи с нужной локалью). В последней колонке — список дополнительных картинок через запятую, каждая с полным URL.

Пример 3. Экспорт пользователей с их последними заказами (продвинутый)

Допустим, у вас есть таблица payordersmarket (заказы). Базовая таблица — users. Вы хотите выгрузить пользователей и их последние заказы. Так как у одного пользователя может быть много заказов, а строки CSV должны быть уникальными по пользователю, вы можете использовать агрегацию, аналогичную картинкам, но такой встроенной агрегации в плагине пока нет. В этом случае комбинированный экспорт не совсем подходит для подобных «один-ко-многим» без потери данных. Лучше экспортировать заказы отдельно или написать кастомный скрипт.

Однако, если вам нужно просто получить пользователей с количеством заказов (агрегированным значением), можно было бы добавить поддержку COUNT через модификацию плагина, но это уже программирование.


11. Советы и лучшие практики

  1. Всегда проверяйте результат на небольшом количестве данных. Прежде чем экспортировать всю базу, можно временно ограничить базовую таблицу (например, через фильтр во вкладке «Структура»), но плагин не имеет встроенного ограничения для комбинированного экспорта. Поэтому начинайте с тестового экспорта, чтобы убедиться, что связи работают верно.
  2. Используйте осмысленные названия колонок. Они станут заголовками CSV и должны быть понятны тем, кто будет с файлом работать. Избегайте слишком длинных названий, но и не делайте их слишком краткими (например, «Цена, руб» лучше, чем просто «Цена», если у вас несколько валют).
  3. Проверяйте связи через ручной режим, если сомневаетесь. Даже если автоопределение сработало, можно временно переключиться в ручной режим и посмотреть, какое поле выбрано по умолчанию в селекторе «поле связи» (он заполняется автоматически при загрузке страницы, если были сохранены данные). Это поможет понять, как плагин «видит» связь.
  4. Не забывайте про папку экспорта. Периодически очищайте её от старых файлов, чтобы не засорять сервер. Логи можно очистить специальной кнопкой.
  5. При работе с большими таблицами может потребоваться увеличение лимитов PHP (max_execution_time, memory_limit). Если экспорт обрывается, проверьте настройки сервера.
  6. Следите за обновлениями плагина. Разработчик может добавить новые агрегации или улучшить автоопределение JOIN.

Заключение

Вкладка «Комбинированный CSV» плагина DB Structure Viewer — мощный и гибкий инструмент, позволяющий даже новичкам создавать сложные выборки данных из базы Cotonti. Понимание базовых концепций (таблицы, JOIN, агрегации) и внимательное следование инструкциям помогут вам успешно решать задачи экспорта товаров, пользователей, статей и любых других сущностей.

Надеемся, это руководство было для вас полезным. Если у вас остались вопросы, ищите поддержку на форуме разработчика или в сообществе Cotonti. Удачного экспорта!

Вы можете нанять меня для выполнения задания, написав мне в телеграм.



Rating based on reviews:
Stars received: 0
Total reviews: 0
Average rating: 0
30 minutes read

Reviews to products

No reviews yet


Add to Cart

Product has no downloadable file

 

Category Extentions
Administration and management, Import, export, and data exchange, Marketplaces, Utilities and tools
Availability
Free

Page Discussion in Telegram

Content author

webitproff

Offline

webitproff

Last logged: 2026-07-11 19:44

  • Чем могу помочь?

    Оказываю весь спектр услуг по CMF Cotonti. Разработка открытых и закрытых корпоративных интернет порталов, небольших социальных сетей, торговые площадки, маркетплейсы, биржи фриланса, каталоги товаров оптовых поставщиков, интернет-магазин под заказ, чтобы делать совместные покупки и групповые совместные продажи от имени нескольких продавцов.

  • Разработки на GitHub бесплатно
    • 2026-07-01 18:40
    • 2026-07-05 18:58

    Featured Products and Services

    Cotonti CMF: Plugin Installation, Integration, and Adaptation

    Cotonti CMF: Plugin Installation, Integration, and Adaptation

    professional services for the installation, deep integration and adaptation of plug-ins for Cotonti

    Market PRO Showcase

    CMS, Script and Engine for an online storefront, infoproduct shop and digital goods store. Different prices in different currencies. Online cryptocurrency payments for goods and services.