point111
Для экспорта только выбранных записей пришлось сделать отдельную кнопку, при этом выбрать экспортируемые поля у пользователя возможности нет, только те, что заданы заранее в коде.
Делал по этой инструкции (там ещё работа с фильтрами, но мне они не нужны)
https://talk.octobercms.com/t/export-records-base-on-filterscope-to-csv-json/1308
Список отмеченных записей можно получить из
поведения ListController
а он объявлен в контроллере модели в
\plugins\OctoClub\Tutorial\controllers\Items.php
Поэтому и вся кухня будет организована там и ItemExport будет вызван оттуда.
1.
Добавляем новую кнопку в _list_toolbar.htm
<button
class="btn btn-default"
data-request-data="{filename:'export_selected.json'}"
data-list-checked-request
data-request-success="window.location = data.fileUrl; setTimeout(function(){ window.location.reload() },500)"
data-stripe-load-indicator
data-request="onExportSelectRecords">
Экспортировать выбранное
</button>
что тут:
data-request-data="{filename:'export_selected.json'}"
имя файла для экспорта, далее из него будет извлекаться расширение для указания в каком формате экспортировать
data-request-success="window.location = data.fileUrl; setTimeout(function(){ window.location.reload() },500)"
чтобы очистить чекбоксы после экспорта
data-list-checked-request
- передает список выбранных записей
data-request="onExportSelectRecords"
функция в контролеере \plugins\OctoClub\Tutorial\controllers\Items.php
которая примет данные и отправит дальше на экспорт
2.
В \plugins\OctoClub\Tutorial\controllers\Items.php добавляем функцию
public function onExportSelectRecords()
{
$listWidget = $this->asExtension('ListController')->listGetWidget(); // получаем записи списка
$checkedIds = post('checked'); // массив айдишников выбранных записей
$filename = post('filename'); // имя файла которое указано в коде кнопки
$query = $listWidget->prepareQuery(); // подготовка к запросу (что то там про PDO , инъекции...)
$columnList = ['title', 'slug', 'content']; // список полей которые будут экспортироваться, id я сюда не включаю, у меня автоинкремент
if (isset($checkedIds)) {
$query->whereIn('id', $checkedIds); // выбираем из списка записей только отмеченные
} else {
Flash::error(Lang::get('backend::lang.form.preview_no_record_message'));
return; // намекаем пользователю, что он забыл выбрать записи. Не забудьте use Flash; и use Lang; в начало файла
}
$records = $query->get(); // окончательно получаем выбранные записи
$modelExport = new \OctoClub\Tutorial\Models\ItemExport(); // создаем эксземпляр экспорта
# set records to process export
// отправляем в метод setModelRecords выбранные записи,
// этот метод объявим в модели экспорта
$modelExport->setModelRecords($records);
# need know file extension
# отделяем расширение файла от
$ext = pathinfo($filename, PATHINFO_EXTENSION);
# set extension to model Export
$exportOptions['fileFormat'] = $ext;
# set file format
# задаем тип экспортируемого файла
$modelExport->file_format = $exportOptions['fileFormat'];
# need create file reference to download
$reference = $modelExport->export($columnList, $exportOptions);
# create download full link to file
$fileUrl = $this->actionUrl('download', $reference . '/' . $filename);
return [
'fileUrl' => $fileUrl
];
}
3.
Модификация импорта для полей имеющих в базе метку UNIQUE KEY,
у меня это поле ‘slug’
public function importData($results, $sessionKey = null)
{
// $firstRow = reset($results); // хз зачем - в коде не используется
foreach ($results as $row => $data) {
try {
// Retrieve the existing slugs
// Извлекаем существующие слаги
$slugs = is_array($data['slug']) ? $data['slug'] : [$data['slug']];
$existingSlugs = Page::whereIn('slug', $slugs)->pluck('slug');
// Check for duplicate slugs
// Проверяем дубликаты слагов
$slug = $data['slug'];
while ($existingSlugs->contains($slug)) {
$slug = $data['slug'] . '_' . Str::random(5);
// Generate a random string
// если находим дубль записи, генерим случайную строку и коннектим её к дублю, снова проверяем дубль
// use Illuminate\Support\Str; не забываем в начало файла
}
// Создаем новую запись
$item = Page::make();
// Исключить из цикла
$except = ['id']; // В этом массиве мы исключаем те переменные, которые не нужно обрабатывать в автоматическом цикле foreach ниже
// Цикл заполнения
foreach (array_except($data, $except) as $attribute => $value) {
// $item->{$attribute} = $value ?: null; // Присваивание значения в столбец по атрибуту
// Изменение заполнения записи для полей имеющих метку NOT NULL но имеющих значение 0 (например флаг публикации)
if ($value !== '' or $value !== null) {
$item->{$attribute} = $value;
} else {
$item->{$attribute} = null;
}
}
$item->slug = $slug; // заменяем найденный дубль слага
// Сохранение
// $item->forceSave(); //запись без проверки изменения модели
$item->save(); //запишет модель только если были её изменения
$this->logCreated();
} catch (\Exception $ex) {
// Ошибка
// $this->logError($row, $ex);
$this->logError($row, $ex->getMessage());
}
}
}