Passed
Push — dependabot/composer/doctrine/d... ( bc1a80...bcc5a8 )
by
unknown
41:27 queued 36:06
created

src/Backend/Modules/Profiles/Actions/Import.php (1 issue)

1
<?php
2
3
namespace Backend\Modules\Profiles\Actions;
4
5
use Backend\Core\Engine\Base\ActionAdd as BackendBaseActionAdd;
6
use Backend\Core\Engine\Form as BackendForm;
7
use Backend\Core\Language\Language as BL;
8
use Backend\Core\Engine\Model as BackendModel;
9
use Backend\Modules\Profiles\Engine\Model as BackendProfilesModel;
10
use ForkCMS\Utility\Csv\Reader;
11
use ForkCMS\Utility\PhpSpreadsheet\Reader\Filter\ColumnsFilter;
12
use PhpOffice\PhpSpreadsheet\IOFactory;
13
14
/**
15
 * This is the add-action, it will display a form to add a new profile.
16
 */
17
class Import extends BackendBaseActionAdd
18
{
19
    public function execute(): void
20
    {
21
        parent::execute();
22
        $this->loadForm();
23
        $this->validateForm();
24
        $this->parse();
25
        $this->display();
26
    }
27
28
    private function loadForm(): void
29
    {
30
        // get group values for dropdown
31
        $ddmValues = BackendProfilesModel::getGroupsForDropDown(0);
32
33
        // create form and elements
34
        $this->form = new BackendForm('import');
35
        $this->form->addDropdown('group', $ddmValues);
36
        $this->form->addFile('file');
37
        $this->form->addCheckbox('overwrite_existing');
38
    }
39
40
    private function validateForm(): void
41
    {
42
        if (!$this->form->isSubmitted()) {
43
            return;
44
        }
45
        $this->form->cleanupFields();
46
47
        // get fields
48
        $ddmGroup = $this->form->getField('group');
49
        $fileFile = $this->form->getField('file');
50
51
        // validate input
52
        $ddmGroup->isFilled(BL::getError('FieldIsRequired'));
53
        if ($fileFile->isFilled(BL::err('FieldIsRequired'))) {
54
            if ($fileFile->isAllowedExtension(['csv'], sprintf(BL::getError('ExtensionNotAllowed'), 'csv'))) {
55
                $indexes = $this->get(Reader::class)->findColumnIndexes(
56
                    $fileFile->getTempFileName(),
57
                    ['email', 'display_name', 'password']
58
                );
59
                if (in_array(null, $indexes)) {
60
                    $fileFile->addError(BL::getError('InvalidCSV'));
61
                }
62
            }
63
        }
64
65
        if (!$this->form->isCorrect()) {
66
            return;
67
        }
68
69
        // import the profiles
70
        $overwrite = $this->form->getField('overwrite_existing')->isChecked();
71
72
        $csvData = $this->convertFileToArray($fileFile->getTempFileName(), array_flip($indexes));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $indexes does not seem to be defined for all execution paths leading up to this point.
Loading history...
73
74
        $statistics = BackendProfilesModel::importFromArray(
75
            $csvData,
76
            $ddmGroup->getValue(),
77
            $overwrite
78
        );
79
80
        // build redirect url with the right message
81
        $redirectUrl = BackendModel::createUrlForAction('index') . '&report=';
82
        $redirectUrl .= $overwrite ?
83
            'profiles-imported-and-updated' :
84
            'profiles-imported';
85
        $redirectUrl .= '&var[]=' . $statistics['count']['inserted'];
86
        $redirectUrl .= '&var[]=' . $statistics['count']['exists'];
87
88
        // everything is saved, so redirect to the overview
89
        $this->redirect($redirectUrl);
90
    }
91
92
    private function convertFileToArray(string $path, array $mapping): array
93
    {
94
        $dataToImport = [];
95
96
        $reader = IOFactory::createReader('Csv');
97
        $reader->setReadDataOnly(true);
98
        $reader->setReadFilter(new ColumnsFilter(array_keys($mapping)));
99
        $spreadSheet = $reader->load($path);
100
101
        foreach ($spreadSheet->getActiveSheet()->getRowIterator() as $row) {
102
            // skip the first row as it contains the headers
103
            if ($row->getRowIndex() === 1) {
104
                continue;
105
            }
106
107
            $dataToImport[] = $this->get(Reader::class)->convertRowIntoMappedArray(
108
                $row,
109
                $mapping
110
            );
111
        }
112
113
        return $dataToImport;
114
    }
115
}
116