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