|
23 | 23 | use Gibbon\Module\DataAdmin\ParseCSV;
|
24 | 24 | use Gibbon\Tables\DataTable;
|
25 | 25 | use Gibbon\Domain\DataSet;
|
| 26 | +use Gibbon\Services\Format; |
26 | 27 |
|
27 | 28 | // Module Bootstrap
|
28 | 29 | require __DIR__ . '/module.php';
|
|
55 | 56 | $checkUserPermissions = getSettingByScope($connection2, 'Data Admin', 'enableUserLevelPermissions');
|
56 | 57 |
|
57 | 58 | if ($checkUserPermissions == 'Y' && $importType->isImportAccessible($guid, $connection2) == false) {
|
58 |
| - echo "<div class='error'>" ; |
59 |
| - echo __('You do not have access to this action.') ; |
60 |
| - echo "</div>" ; |
| 59 | + echo Format::alert(__('You do not have access to this action.')); |
61 | 60 | return;
|
62 | 61 | } elseif (empty($importType)) {
|
63 |
| - echo "<div class='error'>" ; |
64 |
| - echo __('Your request failed because your inputs were invalid.') ; |
65 |
| - echo "</div>" ; |
| 62 | + echo Format::alert(__('Your request failed because your inputs were invalid.')); |
66 | 63 | return;
|
67 | 64 | } elseif (!$importType->isValid()) {
|
68 |
| - echo "<div class='error'>"; |
69 |
| - echo __('Import cannot proceed, there was an error reading the import file type {type}.', ['type' => $type]); |
70 |
| - echo "<br/></div>"; |
| 65 | + echo Format::alert(__('Import cannot proceed, there was an error reading the import file type {type}.', ['type' => $type])); |
71 | 66 | return;
|
72 | 67 | }
|
73 | 68 |
|
|
97 | 92 | ORDER BY gibbonLog.timestamp DESC LIMIT 1" ;
|
98 | 93 | $importLog = $pdo->selectOne($sql, $data);
|
99 | 94 |
|
100 |
| - echo '<div class="message">'; |
101 |
| - echo __("Always backup your database before performing any imports. You will have the opportunity to review the data on the next step, however there's no guarantee the import won't change or overwrite important data."); |
102 |
| - echo '</div>'; |
| 95 | + echo Format::alert(__("Always backup your database before performing any imports. You will have the opportunity to review the data on the next step, however there's no guarantee the import won't change or overwrite important data."), 'message'); |
103 | 96 |
|
104 | 97 | $form = Form::create('importStep1', $_SESSION[$guid]['absoluteURL'].'/index.php?q=/modules/'.$_SESSION[$guid]['module'].'/import_run.php&type='.$type.'&step=2');
|
105 | 98 |
|
|
149 | 142 | $row->addSubmit();
|
150 | 143 |
|
151 | 144 | echo $form->getOutput();
|
152 |
| - |
153 |
| - |
154 |
| - echo '<h4>'; |
155 |
| - echo __('Notes'); |
156 |
| - echo '</h4>'; |
157 |
| - |
158 |
| - echo '<ol>'; |
159 |
| - echo '<li style="color: #c00; font-weight: bold">'.__('Always include a header row in the uploaded file.').'</li>'; |
160 |
| - echo '<li>'.__('Imports cannot be run concurrently (e.g. make sure you are the only person importing at any one time).').'</li>'; |
161 |
| - echo '</ol>'; |
162 | 145 |
|
163 |
| - if (isActionAccessible($guid, $connection2, "/modules/Data Admin/export_run.php")) { |
164 |
| - echo "<div class='linkTop'>" ; |
165 |
| - echo "<a href='" . $_SESSION[$guid]["absoluteURL"] . "/modules/" . $_SESSION[$guid]["module"] . "/export_run.php?type=$type'>" . __('Export Columns') . "<img style='margin-left: 5px' title='" . __('Export Columns'). "' src='./themes/" . $_SESSION[$guid]["gibbonThemeName"] . "/img/download.png'/></a>" ; |
166 |
| - echo "</div>" ; |
| 146 | + $importSpecification = array_reduce($importType->getTableFields(), function ($group, $fieldName) use ($importType) { |
| 147 | + if (!$importType->isFieldHidden($fieldName)) { |
| 148 | + $group[] = [ |
| 149 | + 'count' => count($group) + 1, |
| 150 | + 'name' => __($importType->getField($fieldName, 'name')) |
| 151 | + .($importType->isFieldRequired($fieldName)? ' <strong class="highlight">*</strong>' : ''), |
| 152 | + 'desc' => __($importType->getField($fieldName, 'desc')), |
| 153 | + 'type' => $importType->readableFieldType($fieldName), |
| 154 | + ]; |
| 155 | + } |
| 156 | + return $group; |
| 157 | + }, []); |
| 158 | + |
| 159 | + $notes = '<ol>'; |
| 160 | + $notes .= '<li style="color: #c00; font-weight: bold">'.__('Always include a header row in the uploaded file.').'</li>'; |
| 161 | + $notes .= '<li>'.__('Imports cannot be run concurrently (e.g. make sure you are the only person importing at any one time).').'</li>'; |
| 162 | + $notes .= '</ol>'; |
| 163 | + |
| 164 | + $table = DataTable::create('notes'); |
| 165 | + $table->setTitle(__('Notes')); |
| 166 | + $table->setDescription($notes); |
| 167 | + |
| 168 | + if (isActionAccessible($guid, $connection2, '/modules/Data Admin/export_run.php')) { |
| 169 | + $table->addHeaderAction('export', __('Export Columns')) |
| 170 | + ->setURL('/modules/Data Admin/export_run.php') |
| 171 | + ->addParam('type', $type) |
| 172 | + ->addParam('sidebar', 'false') |
| 173 | + ->setIcon('download') |
| 174 | + ->isDirect() |
| 175 | + ->displayLabel(); |
167 | 176 | }
|
168 | 177 |
|
169 |
| - echo "<table class='smallIntBorder fullWidth colorOddEven' cellspacing='0'>" ; |
170 |
| - echo "<tr class='head'>" ; |
171 |
| - echo "<th style='width: 20px;'>" ; |
172 |
| - echo "</th>" ; |
173 |
| - echo "<th style='width: 180px;'>" ; |
174 |
| - echo __("Name") ; |
175 |
| - echo "</th>" ; |
176 |
| - echo "<th >" ; |
177 |
| - echo __("Description") ; |
178 |
| - echo "</th>" ; |
179 |
| - echo "<th style='width: 200px;'>" ; |
180 |
| - echo __("Type") ; |
181 |
| - echo "</th>" ; |
182 |
| - echo "</tr>" ; |
183 |
| - |
184 |
| - if (!empty($importType->getTableFields())) { |
185 |
| - $count = 0; |
186 |
| - foreach ($importType->getTableFields() as $fieldName) { |
187 |
| - $count++; |
188 |
| - |
189 |
| - if ($importType->isFieldHidden($fieldName)) { |
190 |
| - continue; |
191 |
| - } |
| 178 | + $table->addColumn('count', '#'); |
| 179 | + $table->addColumn('name', __('Name')); |
| 180 | + $table->addColumn('desc', __('Description')); |
| 181 | + $table->addColumn('type', __('Type')); |
192 | 182 |
|
193 |
| - echo "<tr>" ; |
194 |
| - echo "<td>" . $count. "</td>" ; |
195 |
| - echo "<td>"; |
196 |
| - echo __($importType->getField($fieldName, 'name')); |
197 |
| - if ($importType->isFieldRequired($fieldName) == true) { |
198 |
| - echo " <strong class='highlight'>*</strong>"; |
199 |
| - } |
200 |
| - echo "</td>" ; |
201 |
| - echo "<td><em>" . __($importType->getField($fieldName, 'desc')). "</em></td>" ; |
202 |
| - echo "<td>"; |
203 |
| - echo $importType->readableFieldType($fieldName); |
204 |
| - echo "</td>" ; |
205 |
| - echo "</tr>" ; |
206 |
| - } |
207 |
| - } |
208 |
| - echo "</table><br/>" ; |
| 183 | + echo $table->render(new DataSet($importSpecification)); |
209 | 184 | }
|
210 | 185 |
|
211 | 186 | //STEP 2, CONFIG -----------------------------------------------------------------------------------
|
|
214 | 189 |
|
215 | 190 | //Check file type
|
216 | 191 | if ($importer->isValidMimeType($_FILES['file']['type']) == false) {
|
217 |
| - echo "<div class='error'>"; |
218 |
| - printf(__('Import cannot proceed, as the submitted file has a MIME-TYPE of %1$s, and as such does not appear to be a valid file.'), $_FILES['file']['type']); |
219 |
| - echo "<br/></div>"; |
| 192 | + echo Format::alert(__('Import cannot proceed, as the submitted file has a MIME-TYPE of %1$s, and as such does not appear to be a valid file.', ['%1$s' => $_FILES['file']['type']])); |
220 | 193 | } elseif (empty($_POST["fieldDelimiter"]) or empty($_POST["stringEnclosure"])) {
|
221 |
| - echo "<div class='error'>"; |
222 |
| - echo __('Import cannot proceed, as the "Field Delimiter" and/or "String Enclosure" fields have been left blank.'); |
223 |
| - echo "<br/></div>"; |
| 194 | + echo Format::alert(__('Import cannot proceed, as the "Field Delimiter" and/or "String Enclosure" fields have been left blank.')); |
224 | 195 | } elseif ($mode != "sync" and $mode != "insert" and $mode != "update") {
|
225 |
| - echo "<div class='error'>"; |
226 |
| - echo __('Import cannot proceed, as the "Mode" field have been left blank.'); |
227 |
| - echo "<br/></div>"; |
| 196 | + echo Format::alert(__('Import cannot proceed, as the "Mode" field have been left blank.')); |
228 | 197 | } else {
|
229 | 198 | $proceed=true ;
|
230 | 199 | $columnOrder=(isset($_POST['columnOrder']))? $_POST['columnOrder'] : 'guess';
|
|
249 | 218 | $firstLine = $importer->getFirstRow();
|
250 | 219 |
|
251 | 220 | if (empty($csvData) || empty($headings) || empty($firstLine)) {
|
252 |
| - echo "<div class='error'>"; |
253 |
| - echo __('Import cannot proceed, the file type cannot be read.'); |
254 |
| - echo "<br/></div>"; |
| 221 | + echo Format::alert(__('Import cannot proceed, there was an error reading the import file type {type}.', ['type' => $_FILES['file']['name']])); |
255 | 222 | return;
|
256 | 223 | }
|
257 | 224 |
|
|
289 | 256 |
|
290 | 257 | $form->toggleVisibilityByClass('syncDetails')->onRadio('syncField')->when('Y');
|
291 | 258 | $row = $table->addRow()->addClass('syncDetails');
|
292 |
| - $row->addLabel('syncColumn', __('Primary Key ID'))->description(sprintf(__("Sync field %s with CSV column:"), '<code>'.$importType->getPrimaryKey().'</code>')); |
293 |
| - $row->addSelect('syncColumn')->fromArray($headings)->selected($lastColumnValue)->placeholder()->isRequired(); |
294 |
| - } |
295 |
| - |
296 |
| - $form->addRow()->addContent(' '); |
297 |
| - |
298 |
| - // IMPORT RESTRICTIONS |
299 |
| - $importRestrictions = $importType->getImportRestrictions(); |
300 |
| - |
301 |
| - if (!empty($importRestrictions)) { |
302 |
| - $table = $form->addRow()->addTable()->setClass('smallIntBorder fullWidth'); |
303 |
| - $table->addHeaderRow()->addContent(__('Import Restrictions')); |
304 |
| - |
305 |
| - foreach ($importRestrictions as $count => $restriction) { |
306 |
| - $table->addRow()->addContent(($count+1).'. '.$restriction); |
307 |
| - } |
| 259 | + $row->addLabel('syncColumn', __('Primary Key')) |
| 260 | + ->description($importType->getPrimaryKey()); |
| 261 | + $row->addSelect('syncColumn') |
| 262 | + ->fromArray($headings) |
| 263 | + ->selected($lastColumnValue) |
| 264 | + ->placeholder() |
| 265 | + ->isRequired(); |
308 | 266 | }
|
309 | 267 |
|
310 | 268 | $form->addRow()->addContent(' ');
|
|
447 | 405 | $ignoreErrors = $_POST['ignoreErrors'] ?? false;
|
448 | 406 |
|
449 | 407 | if (empty($csvData) || empty($columnOrder)) {
|
450 |
| - echo "<div class='error'>"; |
451 |
| - echo __("Your request failed because your inputs were invalid.") ; |
452 |
| - echo "<br/></div>"; |
| 408 | + echo Format::alert('Your request failed because your inputs were invalid.'); |
453 | 409 | return;
|
454 | 410 | } elseif ($mode != "sync" and $mode != "insert" and $mode != "update") {
|
455 |
| - echo "<div class='error'>"; |
456 |
| - echo __('Import cannot proceed, as the "Mode" field has been left blank.'); |
457 |
| - echo "<br/></div>"; |
| 411 | + echo Format::alert(__('Import cannot proceed, as the "Mode" field has been left blank.')); |
458 | 412 | } elseif (($mode == 'sync' || $mode == 'update') && (!empty($syncField) && $syncColumn < 0)) {
|
459 |
| - echo "<div class='error'>"; |
460 |
| - echo __("Your request failed because your inputs were invalid.") ; |
461 |
| - echo "<br/></div>"; |
| 413 | + echo Format::alert(__("Your request failed because your inputs were invalid.")); |
462 | 414 | return;
|
463 | 415 | } elseif (empty($fieldDelimiter) or empty($stringEnclosure)) {
|
464 |
| - echo "<div class='error'>"; |
465 |
| - echo __('Import cannot proceed, as the "Field Delimiter" and/or "String Enclosure" fields have been left blank.'); |
466 |
| - echo "<br/></div>"; |
| 416 | + echo Format::alert(__('Import cannot proceed, as the "Field Delimiter" and/or "String Enclosure" fields have been left blank.')); |
467 | 417 | } else {
|
468 | 418 | $importer->mode = $mode;
|
469 | 419 | $importer->syncField = ($syncField == 'Y');
|
470 | 420 | $importer->syncColumn = $syncColumn;
|
471 | 421 | $importer->fieldDelimiter = (!empty($fieldDelimiter))? stripslashes($fieldDelimiter) : ',';
|
472 | 422 | $importer->stringEnclosure = (!empty($stringEnclosure))? stripslashes($stringEnclosure) : '"';
|
473 | 423 |
|
474 |
| - // Load the CSV Data |
475 |
| - |
476 |
| - // Loop through and validate |
477 |
| - |
478 |
| - // If sync, check for how many updates |
479 |
| - // If import, check how many inserts |
480 |
| - |
481 |
| - // Check for duplicates within current data set |
482 |
| - // Check for database duplicates using unique keys |
483 |
| - |
484 | 424 | $importSuccess = $buildSuccess = $databaseSuccess = false;
|
485 | 425 | $importSuccess = $importer->readCSVString($csvData);
|
486 | 426 |
|
|
496 | 436 |
|
497 | 437 | if ($overallSuccess) {
|
498 | 438 | if ($step == 3) {
|
499 |
| - echo "<div class='message'>"; |
500 |
| - echo __('The data was successfully validated. This is a <b>DRY RUN!</b> No changes have been made to the database. If everything looks good here, you can click submit to complete this import.'); |
501 |
| - echo "</div>"; |
| 439 | + echo Format::alert(__('The data was successfully validated. This is a <b>DRY RUN!</b> No changes have been made to the database. If everything looks good here, you can click submit to complete this import.'), 'message'); |
502 | 440 | } else {
|
503 |
| - echo "<div class='success'>"; |
504 |
| - echo __('The import completed successfully and all relevant database fields have been created and/or updated.'); |
505 |
| - echo "</div>"; |
| 441 | + echo Format::alert(__('The import completed successfully and all relevant database fields have been created and/or updated.'), 'success'); |
506 | 442 | }
|
507 | 443 | } elseif ($ignoreErrors) {
|
508 |
| - echo "<div class='warning'>"; |
509 |
| - echo __('The import completed successfully, with the following errors ignored.'); |
510 |
| - echo "</div>"; |
| 444 | + echo Format::alert(__('Imported with errors ignored.'), 'warning'); |
511 | 445 | } else {
|
512 |
| - echo "<div class='error'>"; |
513 |
| - echo $importer->getLastError(); |
514 |
| - echo "</div>"; |
| 446 | + echo Format::alert($importer->getLastError()); |
515 | 447 | }
|
516 | 448 |
|
517 | 449 | $logs = $importer->getLogs();
|
|
537 | 469 | $memoryUsage = readableFileSize(max(0, memory_get_usage() - $memoryStart));
|
538 | 470 |
|
539 | 471 | $results = array(
|
540 |
| - 'importSuccess' => $importSuccess, |
541 |
| - 'buildSuccess' => $buildSuccess, |
542 |
| - 'databaseSuccess' => $databaseSuccess, |
543 |
| - 'rows' => $importer->getRowCount(), |
544 |
| - 'rowerrors' => $importer->getErrorRowCount(), |
545 |
| - 'errors' => $importer->getErrorCount(), |
546 |
| - 'warnings' => $importer->getWarningCount(), |
547 |
| - 'inserts' => $importer->getDatabaseResult('inserts'), |
548 |
| - 'inserts_skipped' => $importer->getDatabaseResult('inserts_skipped'), |
549 |
| - 'updates' => $importer->getDatabaseResult('updates'), |
550 |
| - 'updates_skipped' => $importer->getDatabaseResult('updates_skipped'), |
551 |
| - 'executionTime' => $executionTime, |
552 |
| - 'memoryUsage' => $memoryUsage, |
553 |
| - 'ignoreErrors' => $ignoreErrors, |
| 472 | + 'step' => $step, |
| 473 | + 'importSuccess' => $importSuccess, |
| 474 | + 'buildSuccess' => $buildSuccess, |
| 475 | + 'databaseSuccess' => $databaseSuccess, |
| 476 | + 'rows' => $importer->getRowCount(), |
| 477 | + 'rowerrors' => $importer->getErrorRowCount(), |
| 478 | + 'errors' => $importer->getErrorCount(), |
| 479 | + 'warnings' => $importer->getWarningCount(), |
| 480 | + 'inserts' => $importer->getDatabaseResult('inserts'), |
| 481 | + 'inserts_skipped' => $importer->getDatabaseResult('inserts_skipped'), |
| 482 | + 'updates' => $importer->getDatabaseResult('updates'), |
| 483 | + 'updates_skipped' => $importer->getDatabaseResult('updates_skipped'), |
| 484 | + 'executionTime' => $executionTime, |
| 485 | + 'memoryUsage' => $memoryUsage, |
| 486 | + 'ignoreErrors' => $ignoreErrors, |
554 | 487 | );
|
555 | 488 |
|
556 | 489 | echo $page->fetchFromTemplate('importer.twig.html', $results);
|
|
592 | 525 |
|
593 | 526 | // Output passwords if generated
|
594 | 527 | if (!empty($importer->outputData['passwords'])) {
|
595 |
| - echo '<h4>'; |
596 |
| - echo __('Generated Passwords'); |
597 |
| - echo '</h4>'; |
598 |
| - echo '<p>'; |
599 |
| - echo __('These passwords have been generated by the import process. They have <b>NOT</b> been recorded anywhere: please copy & save them now if you wish to record them.'); |
600 |
| - echo '</p>'; |
601 |
| - |
602 | 528 | $table = DataTable::create('output');
|
| 529 | + $table->setTitle(__('Generated Passwords')); |
| 530 | + $table->setDescription(__('These passwords have been generated by the import process. They have <b>NOT</b> been recorded anywhere: please copy & save them now if you wish to record them.')); |
603 | 531 |
|
604 | 532 | $table->addColumn('username', __('Username'));
|
605 | 533 | $table->addColumn('password', __('Password'));
|
|
610 | 538 | $columnOrder['syncField'] = $syncField;
|
611 | 539 | $columnOrder['syncColumn'] = $syncColumn;
|
612 | 540 |
|
613 |
| - |
614 |
| - |
615 | 541 | $importer->createImportLog($_SESSION[$guid]['gibbonPersonID'], $type, $results, $columnOrder);
|
616 | 542 | }
|
617 | 543 | }
|
|
0 commit comments