mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
Add required fields + validation step, headers checkbox can be toggled
This commit is contained in:
parent
f99f838faf
commit
5a40c54f3c
@ -5,6 +5,7 @@ use Backend\Classes\ControllerBehavior;
|
||||
use League\Csv\Writer as CsvWrtier;
|
||||
use League\Csv\Reader as CsvReader;
|
||||
use ApplicationException;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Import/Export Controller Behavior
|
||||
@ -79,8 +80,61 @@ class ImportExportController extends ControllerBehavior
|
||||
// TBA
|
||||
}
|
||||
|
||||
//
|
||||
// Importing AJAX
|
||||
//
|
||||
|
||||
public function onImport()
|
||||
{
|
||||
// traceLog(post());
|
||||
}
|
||||
|
||||
public function onImportLoadForm()
|
||||
{
|
||||
try {
|
||||
$this->checkRequiredImportColumns();
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
$this->controller->handleError($ex);
|
||||
}
|
||||
|
||||
return $this->importExportMakePartial('import_form');
|
||||
}
|
||||
|
||||
public function onImportLoadColumnSampleForm()
|
||||
{
|
||||
if (($columnId = post('file_column_id', false)) === false) {
|
||||
throw new ApplicationException('Missing column identifier');
|
||||
}
|
||||
|
||||
$columns = $this->getImportFileColumns();
|
||||
if (!array_key_exists($columnId, $columns)) {
|
||||
throw new ApplicationException('Unknown column');
|
||||
}
|
||||
|
||||
$path = $this->getImportFilePath();
|
||||
$reader = CsvReader::createFromPath($path);
|
||||
|
||||
if (post('first_row_titles')) {
|
||||
$reader->setOffset(1);
|
||||
}
|
||||
|
||||
$data = $reader->setLimit(20)->fetchColumn((int) $columnId);
|
||||
|
||||
/*
|
||||
* Clean up data
|
||||
*/
|
||||
foreach ($data as $index => $sample) {
|
||||
$data[$index] = Str::limit($sample, 100);
|
||||
if (!strlen($data[$index])) {
|
||||
unset($data[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->vars['columnName'] = array_get($columns, $columnId);
|
||||
$this->vars['columnData'] = $data;
|
||||
|
||||
return $this->importExportMakePartial('column_sample_form');
|
||||
}
|
||||
|
||||
//
|
||||
@ -173,40 +227,34 @@ class ImportExportController extends ControllerBehavior
|
||||
return $file->getLocalPath();
|
||||
}
|
||||
|
||||
public function onImportLoadColumnSamplePopup()
|
||||
public function importIsColumnRequired($columnName)
|
||||
{
|
||||
if (($columnId = post('file_column_id', false)) === false) {
|
||||
throw new ApplicationException('Missing column identifier');
|
||||
$model = $this->importGetModel();
|
||||
return $model->isAttributeRequired($columnName);
|
||||
}
|
||||
|
||||
protected function checkRequiredImportColumns()
|
||||
{
|
||||
if (!$matches = post('column_match', [])) {
|
||||
throw new ApplicationException('Please match some columns first.');
|
||||
}
|
||||
|
||||
$columns = $this->getImportFileColumns();
|
||||
if (!array_key_exists($columnId, $columns)) {
|
||||
throw new ApplicationException('Unknown column');
|
||||
}
|
||||
$dbColumns = $this->getImportDbColumns();
|
||||
foreach ($dbColumns as $column => $label) {
|
||||
if (!$this->importIsColumnRequired($column)) continue;
|
||||
|
||||
$path = $this->getImportFilePath();
|
||||
$reader = CsvReader::createFromPath($path);
|
||||
$found = false;
|
||||
foreach ($matches as $matchedColumns) {
|
||||
if (in_array($column, $matchedColumns)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (post('first_row_titles')) {
|
||||
$reader->setOffset(1);
|
||||
}
|
||||
|
||||
$data = $reader->setLimit(20)->fetchColumn((int) $columnId);
|
||||
|
||||
/*
|
||||
* Clean up data
|
||||
*/
|
||||
foreach ($data as $index => $sample) {
|
||||
$data[$index] = Str::limit($sample, 100);
|
||||
if (!strlen($data[$index])) {
|
||||
unset($data[$index]);
|
||||
if (!$found) {
|
||||
throw new ApplicationException('Please specify a match for the required field '.$label.'.');
|
||||
}
|
||||
}
|
||||
|
||||
$this->vars['columnName'] = array_get($columns, $columnId);
|
||||
$this->vars['columnData'] = $data;
|
||||
|
||||
return $this->importExportMakePartial('column_sample_popup');
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -62,6 +62,9 @@
|
||||
.import-behavior .import-db-columns > ul > li:hover .column-icon {
|
||||
color: #4da7e8;
|
||||
}
|
||||
.import-behavior .import-db-columns > ul > li.is-required .column-icon {
|
||||
color: #ab2a1c;
|
||||
}
|
||||
.import-behavior .import-file-columns > ul > li:before,
|
||||
.import-behavior .import-file-columns > ul > li:after {
|
||||
content: " ";
|
||||
@ -70,7 +73,7 @@
|
||||
.import-behavior .import-file-columns > ul > li:after {
|
||||
clear: both;
|
||||
}
|
||||
.import-behavior .import-file-columns > ul > li.column-ignored {
|
||||
.import-behavior .import-file-columns > ul > li.is-ignored {
|
||||
display: none;
|
||||
}
|
||||
.import-behavior .import-file-columns > ul > li .column-success-icon {
|
||||
@ -79,10 +82,10 @@
|
||||
left: -2px;
|
||||
width: 15px;
|
||||
}
|
||||
.import-behavior .import-file-columns > ul > li.column-matched .column-success-icon {
|
||||
.import-behavior .import-file-columns > ul > li.is-matched .column-success-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
.import-behavior .import-file-columns > ul > li.column-matched .column-ignore-button {
|
||||
.import-behavior .import-file-columns > ul > li.is-matched .column-ignore-button {
|
||||
display: none !important;
|
||||
}
|
||||
.import-behavior .import-file-columns > ul div.import-column-name {
|
||||
|
@ -69,19 +69,19 @@
|
||||
|
||||
this.toggleMatchState = function ($container) {
|
||||
var hasItems = !!$('.import-column-bindings li', $container).length
|
||||
$container.toggleClass('column-matched', hasItems)
|
||||
$container.toggleClass('is-matched', hasItems)
|
||||
}
|
||||
|
||||
this.ignoreFileColumn = function(el) {
|
||||
var $el = $(el),
|
||||
$column = $el.closest('[data-column-id]')
|
||||
|
||||
$column.addClass('column-ignored')
|
||||
$column.addClass('is-ignored')
|
||||
$('#showIgnoredColumnsButton').removeClass('disabled')
|
||||
}
|
||||
|
||||
this.showIgnoredColumns = function(el) {
|
||||
$('#importFileColumns li.column-ignored').removeClass('column-ignored')
|
||||
$('#importFileColumns li.is-ignored').removeClass('is-ignored')
|
||||
$('#showIgnoredColumnsButton').addClass('disabled')
|
||||
}
|
||||
|
||||
@ -91,12 +91,18 @@
|
||||
columnId = $column.data('column-id')
|
||||
|
||||
$el.popup({
|
||||
handler: 'onImportLoadColumnSamplePopup',
|
||||
handler: 'onImportLoadColumnSampleForm',
|
||||
extraData: {
|
||||
file_column_id: columnId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.processImport = function () {
|
||||
var $form = $('#importFileColumns').closest('form')
|
||||
|
||||
$form.request('onImport')
|
||||
}
|
||||
}
|
||||
|
||||
$.oc.importBehavior = new ImportBehavior;
|
||||
|
@ -79,6 +79,12 @@
|
||||
&:hover .column-icon {
|
||||
color: #4da7e8;
|
||||
}
|
||||
|
||||
&.is-required {
|
||||
.column-icon {
|
||||
color: #ab2a1c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +92,7 @@
|
||||
> li {
|
||||
.clearfix;
|
||||
|
||||
&.column-ignored {
|
||||
&.is-ignored {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -97,7 +103,7 @@
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
&.column-matched {
|
||||
&.is-matched {
|
||||
.column-success-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
<div class="import-db-columns" id="importDbColumns">
|
||||
<ul>
|
||||
<?php foreach ($importDbColumns as $column => $label): ?>
|
||||
<li data-column-name="<?= e($column) ?>">
|
||||
<?php
|
||||
$isRequired = $this->importIsColumnRequired($column);
|
||||
$iconName = $isRequired ? 'icon-asterisk' : 'icon-link';
|
||||
?>
|
||||
<li
|
||||
class="<?= $isRequired ? 'is-required' : '' ?>"
|
||||
data-column-name="<?= e($column) ?>">
|
||||
<span>
|
||||
<i class="column-icon icon-link"></i>
|
||||
<i class="column-icon <?= $iconName ?>"></i>
|
||||
<?= e($label) ?>
|
||||
</span>
|
||||
<input type="hidden" data-column-match-input />
|
||||
|
@ -0,0 +1,51 @@
|
||||
<div id="importFormPopup">
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?= Form::open(['id' => 'importForm']) ?>
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Import progress</h4>
|
||||
</div>
|
||||
|
||||
<div id="importContainer">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="loading-indicator-container">
|
||||
<p> </p>
|
||||
<div class="loading-indicator transparent">
|
||||
<div>Processing</div>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<p> </p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= Form::close() ?>
|
||||
|
||||
<script>
|
||||
$('#importFormPopup').on('popupComplete', function() {
|
||||
$.oc.importBehavior.processImport()
|
||||
})
|
||||
</script>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title">Import error</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.close')) ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php endif ?>
|
||||
</div>
|
@ -33,13 +33,14 @@ fields:
|
||||
label: File columns
|
||||
type: partial
|
||||
path: ~/modules/backend/behaviors/importexportcontroller/partials/_import_file_columns.htm
|
||||
dependsOn: import_file
|
||||
dependsOn: [import_file, first_row_titles]
|
||||
span: left
|
||||
|
||||
import_db_columns:
|
||||
label: Database fields
|
||||
type: partial
|
||||
path: ~/modules/backend/behaviors/importexportcontroller/partials/_import_db_columns.htm
|
||||
dependsOn: [import_file, first_row_titles]
|
||||
span: right
|
||||
|
||||
step3_section:
|
||||
|
Loading…
x
Reference in New Issue
Block a user