Passed
Push — master ( 4ed6bf...62427a )
by Thomas
12:01 queued 12s
created

ModelAdminExcelExtension::updateGridFieldConfig()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 17
c 2
b 0
f 0
dl 0
loc 28
rs 8.8333
cc 7
nc 8
nop 1
1
<?php
2
3
namespace LeKoala\ExcelImportExport\Extensions;
4
5
use SilverStripe\Forms\Form;
6
use SilverStripe\Core\Extension;
7
use SilverStripe\Admin\ModelAdmin;
8
use SilverStripe\Forms\CheckboxField;
9
use SilverStripe\Forms\OptionsetField;
10
use LeKoala\ExcelImportExport\ExcelBulkLoader;
11
use LeKoala\ExcelImportExport\ExcelImportExport;
12
use SilverStripe\Forms\GridField\GridFieldConfig;
13
use SilverStripe\Forms\GridField\GridFieldExportButton;
14
use SilverStripe\Forms\GridField\GridFieldImportButton;
15
use LeKoala\ExcelImportExport\ExcelGridFieldExportButton;
16
use LeKoala\ExcelImportExport\ExcelGridFieldImportButton;
17
18
/**
19
 * Extends {@link ModelAdmin}. to bind new forms and features
20
 *
21
 * @author Koala
22
 */
23
class ModelAdminExcelExtension extends Extension
24
{
25
    private static $allowed_actions = array(
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
26
        'downloadsample'
27
    );
28
29
    public function onAfterInit()
30
    {
31
        $this->updateModelImporters();
32
    }
33
34
    /**
35
     * Replace default model import with a predefined value
36
     *
37
     * @return void
38
     */
39
    protected function updateModelImporters()
40
    {
41
        /* @var $owner ModelAdmin */
42
        $owner = $this->owner;
43
        $config = $this->owner->config();
44
45
        // Overwrite model imports
46
        $importerClasses = $config->get('model_importers');
47
48
        if (is_null($importerClasses)) {
49
            $models = $owner->getManagedModels();
50
            foreach (array_keys($models) as $modelName) {
51
                $importerClasses[$modelName] = ExcelBulkLoader::class;
52
            }
53
54
            $config->set('model_importers', $importerClasses);
55
        }
56
    }
57
58
    public function downloadsample()
59
    {
60
        ExcelImportExport::sampleFileForClass($this->owner->modelClass);
61
    }
62
63
    public function updateGridFieldConfig(GridFieldConfig $config)
64
    {
65
        /** @var ModelAdmin $owner */
66
        $owner = $this->owner;
67
        $class = $owner->modelClass;
68
        $classConfig = $owner->config();
69
70
        // Add/remove csv export (hide by default)
71
        if ($classConfig->export_csv) {
72
            $GridFieldExportButton = $this->getGridFieldExportButton($config);
73
            $GridFieldExportButton->setExportColumns(ExcelImportExport::exportFieldsForClass($class));
74
        } else {
75
            $config->removeComponentsByType(GridFieldExportButton::class);
76
        }
77
78
        // Add/remove csv export (add by default)
79
        if ($classConfig->export_excel) {
80
            $ExcelGridFieldExportButton = new ExcelGridFieldExportButton('buttons-before-left');
81
            $config->addComponent($ExcelGridFieldExportButton);
82
        }
83
84
        // Rename import button
85
        $config->removeComponentsByType(GridFieldImportButton::class);
86
        if (is_bool($this->owner->showImportForm) && $this->owner->showImportForm || is_array($this->owner->showImportForm) && in_array($class, $this->owner->showImportForm)) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (is_bool($this->owner->s...>owner->showImportForm), Probably Intended Meaning: is_bool($this->owner->sh...owner->showImportForm))
Loading history...
87
            $ExcelGridFieldImportButton = new ExcelGridFieldImportButton('buttons-before-left');
88
            $ExcelGridFieldImportButton->setImportForm($this->owner->ImportForm());
89
            $ExcelGridFieldImportButton->setModalTitle(_t('ExcelImportExport.IMPORTFROMFILE', 'Import from a file'));
90
            $config->addComponent($ExcelGridFieldImportButton);
91
        }
92
    }
93
94
    /**
95
     * @param GridFieldConfig $config
96
     * @return GridFieldExportButton
97
     */
98
    protected function getGridFieldExportButton($config)
99
    {
100
        return $config->getComponentByType(GridFieldExportButton::class);
101
    }
102
103
    public function updateImportForm(Form $form)
104
    {
105
        /** @var ModelAdmin $owner */
106
        $owner = $this->owner;
107
        $class = $owner->modelClass;
108
        $classConfig = $owner->config();
109
110
        $modelSNG = singleton($class);
111
        $modelConfig = $modelSNG->config();
112
        $modelName = $modelSNG->i18n_singular_name();
113
114
        $fields = $form->Fields();
115
116
        $downloadSampleLink = $owner->Link(str_replace('\\', '-', $class) . '/downloadsample');
117
        $downloadSample = '<a href="' . $downloadSampleLink . '" class="no-ajax" target="_blank">' . _t(
118
            'ExcelImportExport.DownloadSample',
119
            'Download sample file'
120
        ) . '</a>';
121
122
        $file = $fields->dataFieldByName('_CsvFile');
123
        if ($file) {
124
            $csvDescription = ExcelImportExport::getValidExtensionsText();
125
            $csvDescription .= '. ' . $downloadSample;
126
            $file->setDescription($csvDescription);
127
            $file->getValidator()->setAllowedExtensions(ExcelImportExport::getValidExtensions());
128
        }
129
130
        // Hide by default, but allow on per class basis (opt-in)
131
        if ($classConfig->hide_replace_data && !$modelConfig->show_replace_data) {
132
            // This is way too dangerous and customers don't understand what this is most of the time
133
            $fields->removeByName("EmptyBeforeImport");
134
        }
135
        // If you cannot delete, you cannot empty
136
        if (!$modelSNG->canDelete()) {
137
            $fields->removeByName('EmptyBeforeImport');
138
        }
139
140
        // We moved the specs into a nice to use download sample button
141
        $fields->removeByName("SpecFor{$modelName}");
142
143
        // We can implement a custom handler
144
        $importHandlers = [];
145
        if ($modelSNG->hasMethod('listImportHandlers')) {
146
            $importHandlers = array_merge([
147
                'default' => _t('ExcelImportExport.DefaultHandler', 'Default import handler'),
148
            ], $modelSNG->listImportHandlers());
149
150
            $supportOnlyUpdate = [];
151
            foreach ($importHandlers as $class => $label) {
152
                if (class_exists($class) && method_exists($class, 'setOnlyUpdate')) {
153
                    $supportOnlyUpdate[] = $class;
154
                }
155
            }
156
157
            $form->Fields()->push($OnlyUpdateRecords = new CheckboxField("OnlyUpdateRecords", _t('ExcelImportExport.OnlyUpdateRecords', "Only update records")));
158
            $OnlyUpdateRecords->setAttribute("data-handlers", implode(",", $supportOnlyUpdate));
159
        }
160
        if (!empty($importHandlers)) {
161
            $form->Fields()->push($ImportHandler = new OptionsetField("ImportHandler", _t('ExcelImportExport.PleaseSelectImportHandler', "Please select the import handler"), $importHandlers));
162
            // Simply check of this is supported or not for the given handler (if not, disable it)
163
            $js = <<<JS
164
var cb=document.querySelector('#OnlyUpdateRecords');var accepted=cb.dataset.handlers.split(',');var item=([...this.querySelectorAll('input')].filter((input) => input.checked)[0]); cb.disabled=(item && accepted.includes(item.value)) ? '': 'disabled';
165
JS;
166
            $ImportHandler->setAttribute("onclick", $js);
167
        }
168
169
        $actions = $form->Actions();
170
171
        // Update import button
172
        $import = $actions->dataFieldByName('action_import');
173
        if ($import) {
174
            $import->setTitle(_t(
175
                'ExcelImportExport.ImportExcel',
176
                "Import from Excel"
177
            ));
178
            $import->removeExtraClass('btn-outline-secondary');
179
            $import->addExtraClass('btn-primary');
180
        }
181
    }
182
}
183