ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilDclContentImporter.php
Go to the documentation of this file.
1 <?php
2 
20 {
21  //const SOAP_FUNCTION_NAME = 'exportDataCollectionContent';
22 
23  public const EXPORT_EXCEL = 'xlsx';
24  protected int $max_imports = 100;
25  protected array $supported_import_datatypes
26  = [
35  ];
36  protected array $warnings;
40  protected int $ref_id;
44  protected int $table_id;
45 
50  protected array $tables;
51 
52  protected ilLanguage $lng;
53  protected ilObjUser $user;
54 
55  public function __construct(int $ref_id, ?int $table_id = null)
56  {
57  global $DIC;
58 
59  $this->ref_id = $ref_id;
60  $this->table_id = $table_id;
61 
62  $this->lng = $DIC->language();
63  $this->user = $DIC->user();
64 
65  $this->dcl = new ilObjDataCollection($ref_id);
66  $this->tables = ($table_id) ? [$this->dcl->getTableById($table_id)] : $this->dcl->getTables();
67  }
68 
74  public function import(string $file, bool $simulate = false): array
75  {
76  $this->warnings = [];
77  try {
78  $excel = new ilExcel();
79  $excel->loadFromFile($file);
80  } catch (Exception $e) {
81  $this->warnings[] = $this->lng->txt("dcl_file_not_readable");
82  }
83 
84  $sheet_count = $excel->getSheetCount();
85  $excel->setActiveSheet(0);
86 
87  if ($sheet_count != count($this->tables)) {
88  $this->warnings[] = $this->lng->txt('dcl_file_not_readable');
89  }
90 
91  if (count($this->warnings)) {
92  return ['line' => 0, 'warnings' => $this->warnings];
93  }
94 
95  for ($sheet = 0; $sheet < $sheet_count; $sheet++) {
96  $excel->setActiveSheet($sheet);
97  $table = $this->tables[$sheet];
98 
99  // only 31 character-long table-titles are allowed
100  $sheet_title = substr($table->getTitle(), 0, 31);
101  if ($excel->getSheetTitle() != $sheet_title) {
102  $this->warnings[] = $this->lng->txt('dcl_table_title_not_matching');
103  continue;
104  }
105 
106  $field_names = [];
107  $sheet_data = $excel->getSheetAsArray();
108 
109  foreach ($sheet_data[0] as $column) {
110  $field_names[] = $column;
111  }
112  $fields = $this->getImportFieldsFromTitles($table, $field_names);
113 
114  $records_failed = 0;
115  for ($i = 2; $i <= count($sheet_data); $i++) {
116  $record = new ilDclBaseRecordModel();
117  $record->setOwner($this->user->getId());
118  $date_obj = new ilDateTime(time(), IL_CAL_UNIX);
119  $record->setCreateDate($date_obj);
120  $record->setLastUpdate($date_obj);
121  $record->setLastEditBy($this->user->getId());
122  $record->setTableId($table->getId());
123  if (!$simulate) {
124  $record->doCreate();
125  }
126  $fields_failed = 0;
127  foreach ($fields as $col => $field) {
128  try {
129  if ($field->isStandardField()) {
130  $record->setStandardFieldValueFromExcel($excel, $i, $col, $field);
131  } else {
132  $value = $record->getRecordFieldValueFromExcel($excel, $i, $col, $field);
133 
134  if (is_array($value) && isset($value['warning'])) {
135  $this->warnings[] = $value['warning'];
136  $value = '';
137  }
138 
139  $field->checkValidity($value, $record->getId());
140  if (!$simulate) {
141  $record->setRecordFieldValue($field->getId(), $value);
142  }
143  }
144  } catch (ilDclInputException $e) {
145  $fields_failed++;
146  $this->warnings[] = "(" . $i . ", " . ilDataCollectionImporter::getExcelCharForInteger($col + 1) . ") " . $e;
147  }
148  }
149 
150  if ($fields_failed < count($fields)) {
151  $record_imported = true;
152  } else {
153  $records_failed++;
154  $record_imported = false;
155  }
156 
157  if (!$simulate) {
158  if (!$record_imported) { // if no fields have been filled, delete the record again
159  $record->doDelete(true); // omit notification
160  } else {
161  $record->doUpdate();
162  }
163  }
164  if (($i - 1) - $records_failed > $this->max_imports) {
165  $this->warnings[] = $this->lng->txt("dcl_max_import") . (count($sheet_data) - 1) . " > " . $this->max_imports;
166  break;
167  }
168  }
169  }
170 
171  return array('line' => (($i ?? 2) - 2), 'warnings' => $this->warnings);
172  }
173 
174  protected function checkImportType(ilDclBaseFieldModel $field): bool
175  {
176  if (in_array($field->getDatatypeId(), $this->supported_import_datatypes)) {
177  return true;
178  } else {
179  $this->warnings[] = $field->getTitle() . ": " . $this->lng->txt("dcl_not_supported_in_import");
180 
181  return false;
182  }
183  }
184 
189  protected function getImportFieldsFromTitles(ilDclTable $table, array $titles): array
190  {
191  $fields = $table->getRecordFields();
192  $import_fields = array();
193  foreach ($fields as $field) {
194  if ($this->checkImportType($field)) {
195  // the fields will add themselves to $import_fields (at the correct position) if their title is in $titles
196  $field->checkTitlesForImport($titles, $import_fields);
197  }
198  }
199 
200  foreach ($titles as $key => $value) {
203  foreach ($importable_titles as $identifier => $values) {
204  if (in_array($value, $values)) {
205  $std_field = new ilDclStandardField();
206  $std_field->setId(substr($identifier, 4));
207  $import_fields[$key] = $std_field;
208  continue 2;
209  }
210  }
211  if (in_array($value, $not_importable_titles)) {
212  $this->warnings[] = "(1, " . ilDataCollectionImporter::getExcelCharForInteger($key) . ") \"" . $value . "\" " . $this->lng->txt("dcl_std_field_not_importable");
213  } else {
214  if (!isset($import_fields[$key])) {
215  $this->warnings[] = "(1, " . ilDataCollectionImporter::getExcelCharForInteger($key + 1) . ") \"" . $value . "\" " . $this->lng->txt("dcl_row_not_found");
216  }
217  }
218  }
219 
220  return $import_fields;
221  }
222 }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(int $ref_id, ?int $table_id=null)
const IL_CAL_UNIX
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const INPUTFORMAT_TEXT_SELECTION
const INPUTFORMAT_DATE_SELECTION
int $ref_id
Ref-ID of DataCollection.
global $DIC
Definition: feed.php:28
getImportFieldsFromTitles(ilDclTable $table, array $titles)
getRecordFields()
Returns all fields of this table which are NOT standard fields.
string $key
Consumer key/client ID value.
Definition: System.php:193
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
int $table_id
Table-Id for export.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
checkImportType(ilDclBaseFieldModel $field)
$i
Definition: metadata.php:41
getDatatypeId()
Get datatype_id.