ReadyScript предоставляет готовую подсистему для быстрой разработки схем импорта/экспорта данных в форматах CSV, XLS, XLSX, ODS.
Посмотреть, как работает импорт/экспорт можно практически в любом разделе административной панели. Соответствующая кнопка есть в правой верхней части различных страниц, например в разделе Товары -> Каталог товаров.
Нажав на кнопку Экспорт товаров, запускается диалог выбора колонок для соответствующей схемы экспорта. Выбрав состав и порядок следования колонок можно нажать на кнопку "Экспорт" и файл начнет скачиваться.
Любой файл, сформированный через инструмент экспорта, можно импортировать обратно в систему и тем самым либо создать, либо обновить объекты в системе. Для импорта файла, следует выбрать пункт, например, Импорт товаров и затем выбрать файл. После анализа данных первой строки загружаемого файла, система автоматически предложит сопоставление имеющихся в файле колонок с колонками, которые известны системе. Сопоставив колонки, нужно нажать на кнопку "Начать импорт", после чего начнется загрузка данных из файла.
Схема экспорта - это потомок класса RS::Csv::AbstractSchema. Схема экспорта обеспечивает выполнение экспорта, запрашивая поочередно у пресетов данные слева-направо (если смотреть на итоговую таблицу файла). Каждый пресет подготавливает данные для одной или нескольких колонок. Первым всегда отрабатывает базовый пресет, затем все дополнительные.
В случае выполнения импорта данных, запуск функции импорта данных происходит у пресетов справа-налево (если смотреть на таблицу файла), базовый пресет в данном случае получает управление самым последним.
Схемы импорта/экспорта должны располагаться в следующих папках: /modules/ИМЯ-МОДУЛЯ/model/csvschema/
Рассмотрим аргументы конструктора схемы импорта/экспорта.
В системных модулях существует большое количество классов, описывающих схемы импорта/экспорта, которые можно изучать как пример, вот некоторые их них:
Пресет - это потомок класса RS::Csv::Preset::AbstractPreset, привносящий в схему экспорта одну или несколько колонок для импорта/экспорта. Рекомендуемый путь для размещения файла с классом: /modules/ИМЯ-МОДУЛЯ/model/csvpreset/
Рассмотрим абстрактный пример реализации пресета.
Каждый пресет содержит 3 обязательных метода для реализации:
В ReadyScript есть набор базовых классов-пресетов, которые покрывают основные сценарии организации экспорта/импорта:
Примеры использования данных пресетов можно найти в многочисленных схемах в системных модулях.
В некоторых случаях может понадобиться формировать CSV-экспортный файл не из административной панели, а через PHP-скрипт.
Рассмотрим пример вызова механизма экспорта данных о товаре в CSV из PHP-скрипта "export.php", созданного в корне сайта.
Также рассмотрим пример импорта CSV файла из PHP-скрипта "import.php", созданного в корне сайта.
Вызывается после выполнения стандартного конструктора схемы
Тип входящего параметра: | array |
Описание входящего параметра: | Элементы массива:
|
ReadyScript позволяет из сторонних модулей расширять любые схемы экспорта, имеющиеся в системе. Например, можно добавить свой набор колонок в существующую схему экспорта товаров в разделе Товары -> Каталог товаров.
Для этого следует создать обработчик события csv.scheme.afterconstruct.КОРОТКОЕ-ИМЯ-СХЕМЫ, где КОРОТКОЕ-ИМЯ-СХЕМЫ формируется путем исключения из полного наименования класса в нижнем регистре секции и замены обратных слешей на знак "-", с обрезкой минусов по краям.
Например, короткое имя схемы для класса будет выглядеть так: shop-orderitems. А полный идентификатор события будет соответственно выглядеть так: csv.scheme.afterconstruct.shop-orderitems
Рассмотрим пример добавления собственного пресета (набора колонок) из условного модуля Custom в системную схему экспорта заказанных товаров.
Файл /modules/custom/config/handlers.inc.php
Файл /modules/custom/model/csvpreset/orderwarehouse.inc.php
Вызывается перед экспортом одной строки данных
Тип входящего параметра: | array |
Описание входящего параметра: | Элементы массива:
|
Вызывается перед началом импорта одного файла
Тип входящего параметра: | array |
Описание входящего параметра: | Элементы массива:
|
Вызывается перед началом импорта одной строки данных. Если событие будет остановлено, то импорт строки будет пропущен
Тип входящего параметра: | array |
Описание входящего параметра: | Элементы массива:
|
Вызывается после импорта одной строки данных
Тип входящего параметра: | array |
Описание входящего параметра: | Элементы массива:
|
Вызывается после импорта одной порции данных. Одна порция - это объем импортированных строк данных, который успел загрузиться за время до истечения timeout (обычно 20 секунд).
Тип входящего параметра: | array |
Описание входящего параметра: | Элементы массива:
|
Иногда очень удобно связывать экспорт данных с фильтрами, установленными в административной панели в момент запуска экспорта. Например, вы отфильтровали заказы по статусу "Завершено", нажимаете экспорт заказов в CSV и получаете в CSV файле только те заказы, которые видели в административной панели после применения фильтров.
Для того, чтобы установить такую связь, достаточно в классе схемы экспорта установить у базового пресета через параметр savedRequest передать уже инициализированный фильтрами объект RS::Orm::Request.
Рассмотрим на примере класса схемы экспорта валют:
Если для вывода списка объектов используются стандартные для ReadyScript подходы, т.е. список объектов отображается с помощью контроллера-потомка класса RS::Controller::Admin::Crud, то получить объект последней выборки RS::Orm::Request со всеми условиями этой выборки можно из DAO-объекта, связанного с контроллером. В нашем примере - это Catalog::Model::CurrencyApi ,потомок RS::Module::AbstractModel::EntityList.
Метод getSavedRequest($key, $default = null), есть у всех потомков RS::Module::AbstractModel::EntityList, он принимает два аргумента на вход:
Если вы создаете стандартный контроллер административной панели, построенный на базе класса RS::Controller::Admin::Crud, то для добавления кнопки Импорт/Экспорт достаточно воспользоваться методом addCsvButton у класса RS::Controller::Admin::Helper::CrudCollection, с помощью которого вы настраиваете состав элементов страницы.
Пример: