Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 53f4345

Browse files
committed
Update import type syntax to allow for multiple-table imports
1 parent 026492a commit 53f4345

File tree

7 files changed

+378
-224
lines changed

7 files changed

+378
-224
lines changed

Data Admin/export_run.php

Lines changed: 99 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -81,33 +81,13 @@
8181

8282
$excel->setActiveSheetIndex(0) ;
8383

84-
$tableName = $importType->getDetail('table');
85-
$primaryKey = $importType->getPrimaryKey();
84+
$count = 0;
8685

86+
$rowData = [];
8787
$queryFields = [];
88-
$columnFields = [];
89-
90-
foreach ($importType->getTableFields() as $fieldName) {
91-
if ($importType->isFieldHidden($fieldName)) {
92-
continue; // Skip hidden fields
93-
}
94-
95-
$columnFields[] = $fieldName;
96-
97-
if ($importType->isFieldReadOnly($fieldName) && $dataExport == true) {
98-
continue; // Skip readonly fields when exporting data
99-
}
100-
101-
$queryFields[] = $fieldName;
102-
}
103-
104-
if ($dataExport && !empty($primaryKey)) {
105-
$queryFields = array_merge(array($primaryKey), $queryFields);
106-
$columnFields = array_merge(array($primaryKey), $columnFields);
107-
}
88+
$columnFields = $importType->getAllFields();
10889

10990
// Create the header row
110-
$count = 0;
11191
foreach ($columnFields as $fieldName) {
11292
$excel->getActiveSheet()->setCellValue(num2alpha($count).'1', $importType->getField($fieldName, 'name', $fieldName));
11393
$excel->getActiveSheet()->getStyle(num2alpha($count).'1')->applyFromArray($style_head_fill);
@@ -131,106 +111,130 @@
131111
$count++;
132112
}
133113

134-
135-
if ($dataExport) {
136-
// Get the data
137-
$data = [];
138-
$sql = "SELECT ".implode(', ', $queryFields)." FROM `{$tableName}`" ;
114+
foreach ($importType->getTables() as $index => $tableName) {
115+
116+
$importType->switchTable($tableName);
117+
$primaryKey = $importType->getPrimaryKey();
139118

140-
if ($dataExportAll == false) {
141-
// Optionally limit all exports to the current school year by default, to avoid massive files
142-
$gibbonSchoolYearID = $importType->getField('gibbonSchoolYearID', 'name', null);
119+
foreach ($importType->getTableFields() as $fieldName) {
120+
if ($importType->isFieldHidden($fieldName)) {
121+
continue; // Skip hidden fields
122+
}
143123

144-
if ($gibbonSchoolYearID != null && $importType->isFieldReadOnly('gibbonSchoolYearID') == false) {
145-
$data['gibbonSchoolYearID'] = $_SESSION[$guid]['gibbonSchoolYearID'];
146-
$sql .= " WHERE gibbonSchoolYearID=:gibbonSchoolYearID ";
124+
if ($importType->isFieldReadOnly($fieldName) && $dataExport == true) {
125+
continue; // Skip readonly fields when exporting data
147126
}
127+
128+
$queryFields[$tableName][] = $fieldName;
148129
}
149130

150-
$sql.= " ORDER BY $primaryKey ASC";
151-
$result = $pdo->executeQuery($data, $sql);
131+
if ($dataExport && !empty($primaryKey)) {
132+
$queryFields[$tableName] = array_merge(array($primaryKey), $queryFields[$tableName]);
133+
// $columnFields = array_merge(array($primaryKey), $columnFields);
134+
}
135+
136+
if ($dataExport) {
137+
// Get the data
138+
$data = [];
139+
$sql = "SELECT ".implode(', ', $queryFields[$tableName])." FROM `{$tableName}`" ;
140+
141+
if ($dataExportAll == false) {
142+
// Optionally limit all exports to the current school year by default, to avoid massive files
143+
$gibbonSchoolYearID = $importType->getField('gibbonSchoolYearID', 'name', null);
144+
145+
if ($gibbonSchoolYearID != null && $importType->isFieldReadOnly('gibbonSchoolYearID') == false) {
146+
$data['gibbonSchoolYearID'] = $_SESSION[$guid]['gibbonSchoolYearID'];
147+
$sql .= " WHERE gibbonSchoolYearID=:gibbonSchoolYearID ";
148+
}
149+
}
150+
151+
$sql.= " ORDER BY $primaryKey ASC";
152+
$result = $pdo->executeQuery($data, $sql);
152153

153-
// Continue if there's data
154-
if ($result && $result->rowCount() > 0) {
154+
// Continue if there's data
155+
if ($result && $result->rowCount() > 0) {
155156

156-
// Build some relational data arrays, if needed (do this first to avoid duplicate queries per-row)
157-
$relationalData = [];
157+
// Build some relational data arrays, if needed (do this first to avoid duplicate queries per-row)
158+
$relationalData = [];
158159

159-
foreach ($columnFields as $fieldName) {
160-
if ($importType->isFieldRelational($fieldName)) {
161-
$join = $on = '';
162-
extract($importType->getField($fieldName, 'relationship'));
163-
$queryFields = (is_array($field))? implode(',', $field) : $field;
160+
foreach ($importType->getTableFields() as $fieldName) {
161+
if ($importType->isFieldRelational($fieldName)) {
162+
$join = $on = '';
163+
extract($importType->getField($fieldName, 'relationship'));
164+
$queryFieldsRelational = (is_array($field))? implode(',', $field) : $field;
164165

165-
// Build a query to grab data from relational tables
166-
$relationalSQL = "SELECT `{$table}`.`{$key}` id, {$queryFields} FROM `{$table}`";
166+
// Build a query to grab data from relational tables
167+
$relationalSQL = "SELECT `{$table}`.`{$key}` id, {$queryFieldsRelational} FROM `{$table}`";
167168

168-
if (!empty($join) && !empty($on)) {
169-
if (is_array($on) && count($on) == 2) {
170-
$relationalSQL .= " JOIN {$join} ON ({$join}.{$on[0]}={$table}.{$on[1]})";
169+
if (!empty($join) && !empty($on)) {
170+
if (is_array($on) && count($on) == 2) {
171+
$relationalSQL .= " JOIN {$join} ON ({$join}.{$on[0]}={$table}.{$on[1]})";
172+
}
171173
}
172-
}
173174

174-
$resultRelation = $pdo->executeQuery([], $relationalSQL);
175+
$resultRelation = $pdo->executeQuery([], $relationalSQL);
175176

176-
if ($resultRelation->rowCount() > 0) {
177+
if ($resultRelation->rowCount() > 0) {
177178

178-
// Fetch into an array as: id => array( field => value, field => value, ... )
179-
$relationalData[$fieldName] = $resultRelation->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE);
179+
// Fetch into an array as: id => array( field => value, field => value, ... )
180+
$relationalData[$fieldName] = $resultRelation->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE);
181+
}
180182
}
181183
}
182-
}
183-
184-
$rowCount = 2;
185-
while ($row = $result->fetch()) {
186-
187-
// Work backwards, so we can potentially fill in any relational read-only fields
188-
for ($i=count($columnFields)-1; $i >= 0; $i--) {
189-
$fieldName = $columnFields[$i];
190-
191-
$value = (isset($row[ $fieldName ]))? $row[ $fieldName ] : null;
192184

193-
// Handle relational fields
194-
if ($importType->isFieldRelational($fieldName)) {
195-
extract($importType->getField($fieldName, 'relationship'));
196-
$filter = $importType->getField($fieldName, 'filter');
197-
198-
$values = $filter == 'csv' ? array_map('trim', explode(',', $value)) : [$value];
199-
$relationalValue = [];
200-
201-
foreach ($values as $value) {
202-
// Single key relational field -- value is the ID from other table
203-
$relationalField = (is_array($field))? $field[0] : $field;
204-
$relationalValue[] = @$relationalData[$fieldName][$value][$relationalField];
205-
206-
// Multi-key relational field (fill in backwards, slightly hacky but works)
207-
if (is_array($field) && count($field) > 1) {
208-
for ($n=1; $n < count($field); $n++) {
209-
$relationalField = $field[$n];
210-
211-
// Does the field exist in the import definition but not in the current table?
212-
// Add the value to the row to fill-in the link between read-only relational fields
213-
if ($importType->isFieldReadOnly($relationalField)) {
214-
$row[ $relationalField ] = @$relationalData[$fieldName][$value][$relationalField];
185+
$rowCount = 2;
186+
while ($row = $result->fetch()) {
187+
188+
// Work backwards, so we can potentially fill in any relational read-only fields
189+
for ($i=count($columnFields)-1; $i >= 0; $i--) {
190+
$fieldName = $columnFields[$i];
191+
192+
$value = (isset($row[ $fieldName ]))? $row[ $fieldName ] : null;
193+
194+
// Handle relational fields
195+
if ($importType->isFieldRelational($fieldName)) {
196+
extract($importType->getField($fieldName, 'relationship'));
197+
$filter = $importType->getField($fieldName, 'filter');
198+
199+
$values = $filter == 'csv' ? array_map('trim', explode(',', $value)) : [$value];
200+
$relationalValue = [];
201+
202+
foreach ($values as $value) {
203+
// Single key relational field -- value is the ID from other table
204+
$relationalField = (is_array($field))? $field[0] : $field;
205+
$relationalValue[] = @$relationalData[$fieldName][$value][$relationalField];
206+
207+
// Multi-key relational field (fill in backwards, slightly hacky but works)
208+
if (is_array($field) && count($field) > 1) {
209+
for ($n=1; $n < count($field); $n++) {
210+
$relationalField = $field[$n];
211+
212+
// Does the field exist in the import definition but not in the current table?
213+
// Add the value to the row to fill-in the link between read-only relational fields
214+
if ($importType->isFieldReadOnly($relationalField)) {
215+
$row[ $relationalField ] = @$relationalData[$fieldName][$value][$relationalField];
216+
}
215217
}
216218
}
217219
}
220+
221+
// Replace the relational ID value with the actual value
222+
$value = implode(',', $relationalValue);
223+
}
224+
225+
if (!empty($value)) {
226+
// Set the cell value
227+
$excel->getActiveSheet()->setCellValue(num2alpha($i).$rowCount, (string)$value);
218228
}
219-
220-
// Replace the relational ID value with the actual value
221-
$value = implode(',', $relationalValue);
222229
}
223230

224-
// Set the cell value
225-
$excel->getActiveSheet()->setCellValue(num2alpha($i).$rowCount, $value);
231+
$rowCount++;
226232
}
227-
228-
$rowCount++;
229233
}
230234
}
231235
}
232236

233-
$filename = ($dataExport)? __("DataExport", 'Data Admin').'-'.$tableName : __("DataStructure", 'Data Admin').'-'.$type;
237+
$filename = ($dataExport) ? 'DataExport'.'-'.$type : 'DataStructure'.'-'.$type;
234238

235239
$exportFileType = getSettingByScope($connection2, 'Data Admin', 'exportDefaultFileType');
236240
if (empty($exportFileType)) {

Data Admin/import_run.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143

144144
echo $form->getOutput();
145145

146-
$importSpecification = array_reduce($importType->getTableFields(), function ($group, $fieldName) use ($importType) {
146+
$importSpecification = array_reduce($importType->getAllFields(), function ($group, $fieldName) use ($importType) {
147147
if (!$importType->isFieldHidden($fieldName)) {
148148
$group[] = [
149149
'count' => count($group) + 1,
@@ -178,7 +178,7 @@
178178
$table->addColumn('count', '#');
179179
$table->addColumn('name', __('Name'));
180180
$table->addColumn('desc', __('Description'));
181-
$table->addColumn('type', __('Type'));
181+
$table->addColumn('type', __('Type'))->width('20%');
182182

183183
echo $table->render(new DataSet($importSpecification));
184184
}
@@ -268,7 +268,7 @@
268268
$form->addRow()->addContent('&nbsp;');
269269

270270
// COLUMN SELECTION
271-
if (!empty($importType->getTableFields())) {
271+
if (!empty($importType->getAllFields())) {
272272
$table = $form->addRow()->addTable()->setClass('colorOddEven fullWidth');
273273

274274
$header = $table->addHeaderRow();
@@ -314,7 +314,7 @@
314314
return $output;
315315
};
316316

317-
foreach ($importType->getTableFields() as $fieldName) {
317+
foreach ($importType->getAllFields() as $fieldName) {
318318
if ($importType->isFieldHidden($fieldName)) {
319319
$columnIndex = Importer::COLUMN_DATA_HIDDEN;
320320
if ($importType->isFieldLinked($fieldName)) {
@@ -421,15 +421,21 @@
421421
$importer->fieldDelimiter = (!empty($fieldDelimiter))? stripslashes($fieldDelimiter) : ',';
422422
$importer->stringEnclosure = (!empty($stringEnclosure))? stripslashes($stringEnclosure) : '"';
423423

424-
$importSuccess = $buildSuccess = $databaseSuccess = false;
424+
425+
$importSuccess = $buildSuccess = $databaseSuccess = true;
425426
$importSuccess = $importer->readCSVString($csvData);
426427

427-
if ($importSuccess || $ignoreErrors) {
428-
$buildSuccess = $importer->buildTableData($importType, $columnOrder, $columnText);
429-
}
428+
foreach ($importType->getTables() as $tableName) {
429+
430+
$importType->switchTable($tableName);
430431

431-
if ($buildSuccess || $ignoreErrors) {
432-
$databaseSuccess = $importer->importIntoDatabase($importType, ($step == 4));
432+
if ($importSuccess || $ignoreErrors) {
433+
$buildSuccess &= $importer->buildTableData($importType, $columnOrder, $columnText);
434+
}
435+
436+
if ($buildSuccess || $ignoreErrors) {
437+
$databaseSuccess &= $importer->importIntoDatabase($importType, ($step == 4));
438+
}
433439
}
434440

435441
$overallSuccess = ($importSuccess && $buildSuccess && $databaseSuccess);
@@ -457,7 +463,7 @@
457463
$table->addColumn('row', __('Row'));
458464
$table->addColumn('field', __('Field'))
459465
->format(function ($log) {
460-
return $log['field_name'].($log['field'] >= 0 ? ' ('. $log['field'] .')' : '');
466+
return $log['field_name'].(!empty($log['field']) ? ' ('. $log['field'] .')' : '');
461467
});
462468
$table->addColumn('info', __('Message'));
463469

Data Admin/imports/markbookTargets.yml

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
details:
22
type: markbookTargets
3-
name: Markbook Targets
3+
name: Targets
44
desc: Student target marks (requires Target Scale set per class)
55
table: gibbonMarkbookTarget
66
modes: { update: true, insert: true, export: true }
77
access:
88
module: Markbook
99
action: Edit Markbook_everything
10-
primaryKey:
11-
gibbonMarkbookTargetID
12-
uniqueKeys:
13-
- [ gibbonCourseClassID, gibbonPersonIDStudent ]
14-
table:
10+
fields:
1511
gibbonSchoolYearID:
1612
name: "School Year"
1713
desc: "Must match an existing school year e.g. 2015-2016"
@@ -32,8 +28,35 @@ table:
3228
desc: "Username"
3329
args: { filter: string, required: true }
3430
relationship: { table: gibbonPerson, key: gibbonPersonID, field: username }
31+
gibbonScaleIDTarget:
32+
name: "Grade Scale"
33+
desc: "Short Name of the Grade Scale to use for student targets"
34+
args: { filter: string, required: true, custom: true }
35+
relationship: { table: gibbonScale, key: gibbonScaleID, field: nameShort }
3536
gibbonScaleGradeID:
3637
name: "Target Grade"
3738
desc: "Value of the target grade (actual value, not the descriptor)"
3839
args: { filter: string, required: true }
39-
relationship: { table: gibbonScaleGrade, key: gibbonScaleGradeID, field: value }
40+
relationship: { table: gibbonScaleGrade, key: gibbonScaleGradeID, field: value }
41+
tables:
42+
gibbonMarkbookTarget:
43+
primaryKey:
44+
gibbonMarkbookTargetID
45+
uniqueKeys:
46+
- [ gibbonCourseClassID, gibbonPersonIDStudent ]
47+
fields:
48+
- gibbonSchoolYearID
49+
- gibbonCourseID
50+
- gibbonCourseClassID
51+
- gibbonPersonIDStudent
52+
- gibbonScaleGradeID
53+
gibbonCourseClass:
54+
primaryKey:
55+
gibbonCourseClassID
56+
uniqueKeys:
57+
- [ gibbonCourseClassID ]
58+
fields:
59+
- gibbonSchoolYearID
60+
- gibbonCourseID
61+
- gibbonCourseClassID
62+
- gibbonScaleIDTarget

Data Admin/records_manage.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@
4141
// Get a list of available import options
4242
$importTypeList = ImportType::loadImportTypeList($pdo, false);
4343

44+
4445
// Get the unique tables used
4546
$importTables = array();
4647
foreach ($importTypeList as $importTypeName => $importType) {
47-
$table = $importType->getDetail('table');
4848
$modes = $importType->getDetail('modes');
4949

5050
if ((isset($modes['export']) && $modes['export'] == true) && $modes['update'] == true && $modes['insert'] == true) {
51-
$importTables[$table] = $importType;
51+
$importTables[$importTypeName] = $importType;
5252
}
5353
}
5454

@@ -109,7 +109,7 @@
109109
echo "<tr>" ;
110110
echo "<td>".$importType->getDetail('category'). "</td>" ;
111111

112-
echo "<td>".$importType->getDetail('table')."</td>" ;
112+
echo "<td>".$importType->getDetail('name')."</td>" ;
113113

114114
echo "<td>".$recordCount."</td>";
115115

0 commit comments

Comments
 (0)