ILIAS  trunk Revision v11.0_alpha-1715-g7fc467680fb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilDclContentExporter.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
26 {
27  public const SOAP_FUNCTION_NAME = 'exportDataCollectionContent';
28  public const EXPORT_EXCEL = 'xlsx';
29  public const IN_PROGRESS_POSTFIX = '.prog';
33  protected int $ref_id;
37  protected ?int $table_id;
41  protected array $filter;
42 
44 
45  protected ilLanguage $lng;
46 
47  protected ilDclTable $table;
49  protected array $tables;
50 
51  public function __construct(int $ref_id, ?int $table_id, array $filter = [])
52  {
53  global $DIC;
54  $this->main_tpl = $DIC->ui()->mainTemplate();
55  $lng = $DIC['lng'];
56 
57  $this->ref_id = $ref_id;
58  $this->table_id = $table_id;
59  $this->filter = $filter;
60 
61  $this->dcl = new ilObjDataCollection($ref_id);
62  $this->tables = ($table_id) ? [$this->dcl->getTableById($table_id)] : $this->dcl->getTables();
63 
64  $lng->loadLanguageModule('dcl');
65  $this->lng = $lng;
66  }
67 
72  public function sanitizeFilename(string $filename): string
73  {
74  $dangerous_filename_characters = [" ", '"', "'", "&", "/", "\\", "?", "#", "`"];
75 
76  return str_replace($dangerous_filename_characters, "_", iconv("utf-8", "ascii//TRANSLIT", $filename));
77  }
78 
82  public function getExportContentPath(string $format): string
83  {
84  return ilExport::_getExportDirectory($this->dcl->getId(), $format, 'dcl') . '/';
85  }
86 
90  protected function fillRowExcel(
91  ilDclTable $table,
92  ilExcel $worksheet,
93  ilDclBaseRecordModel $record,
94  int $row
95  ): void {
96  $col = 0;
97  foreach ($table->getFields() as $field) {
98  if ($field->getExportable()) {
99  $record->fillRecordFieldExcelExport($worksheet, $row, $col, $field->getId());
100  }
101  }
102  }
103 
107  protected function fillHeaderExcel(ilDclTable $table, ilExcel $worksheet, int $row): void
108  {
109  $col = 0;
110 
111  foreach ($table->getFields() as $field) {
112  if ($field->getExportable()) {
113  $field->fillHeaderExcel($worksheet, $row, $col);
114  }
115  }
116  }
117 
121  protected function fillMetaExcel(ilDclTable $table, ilExcel $worksheet, int $row): void
122  {
123  }
124 
130  public function export(string $format = self::EXPORT_EXCEL, ?string $filepath = null, bool $send = false)
131  {
132  if (count($this->tables) == 0) {
133  return;
134  }
135 
136  if (empty($filepath)) {
137  $filepath = $this->getExportContentPath($format);
138  ilFileUtils::makeDirParents($filepath);
139 
140  $basename = (isset($this->table_id)) ? $this->tables[0]->getTitle() : 'complete';
141  $filename = time() . '__' . $basename . "_" . date("Y-m-d_H-i");
142 
143  $filepath .= $this->sanitizeFilename($filename);
144  } else {
145  $filename = pathinfo($filepath, PATHINFO_FILENAME);
146  }
147 
148  $in_progress_file = $filepath . self::IN_PROGRESS_POSTFIX;
149  file_put_contents($in_progress_file, "");
150 
151  $data_available = false;
152  $fields_available = false;
153  $adapter = new ilExcel();
154  if ($format == self::EXPORT_EXCEL) {
155  foreach ($this->tables as $table) {
157 
158  $list = $table->getPartialRecords((string) $this->dcl->getRefId(), 'id', 'asc', null, 0, $this->filter);
159  $data_available = $data_available || ($list['total'] > 0);
160  $fields_available = $fields_available || (count($table->getExportableFields()) > 0);
161  if ($list['total'] > 0 && count($table->getExportableFields()) > 0) {
162  // only 31 character-long table-titles are allowed
163  $title = substr($table->getTitle(), 0, 31);
164  $adapter->addSheet($title);
165  $row = 1;
166 
167  $this->fillMetaExcel($table, $adapter, $row);
168 
169  // #14813
170  $this->fillHeaderExcel($table, $adapter, $row);
171  $row++;
172 
173  foreach ($list['records'] as $set) {
174  $this->fillRowExcel($table, $adapter, $set, $row);
175  $row++; // #14760
176  }
177 
178  $data_available = true;
179  }
180  }
181  }
182 
183  if (file_exists($in_progress_file)) {
184  unlink($in_progress_file);
185  }
186 
187  if (!$data_available) {
188  $this->main_tpl->setOnScreenMessage('info', $this->lng->txt('dcl_no_export_content_available'));
189 
190  return false;
191  }
192 
193  if (!$fields_available) {
194  global $ilCtrl;
195  $this->main_tpl->setOnScreenMessage('info', sprintf(
196  $this->lng->txt('dcl_no_export_fields_available'),
197  $ilCtrl->getLinkTargetByClass(
198  ['ilDclTableListGUI', 'ilDclFieldListGUI'],
199  'listFields'
200  )
201  ));
202  return false;
203  }
204 
205  if ($send) {
206  $adapter->sendToClient($filename);
207  } else {
208  $adapter->writeToFile($filepath);
209  }
210  return true;
211  }
212 
213  public function exportAsync(string $format = self::EXPORT_EXCEL, ?string $filepath = null): mixed
214  {
215  global $DIC;
216  $ilLog = $DIC['ilLog'];
217 
218  $method = self::SOAP_FUNCTION_NAME;
219 
220  $soap_params = [$this->dcl->getRefId()];
221  array_push($soap_params, $this->table_id, $format, $filepath);
222 
223  $new_session_id = ilSession::_duplicate($_COOKIE[session_name()]);
224  $client_id = $_COOKIE['ilClientId'];
225 
226  // Start cloning process using soap call
227  $soap_client = new ilSoapClient();
228  $soap_client->setResponseTimeout(5);
229  $soap_client->enableWSDL(true);
230 
231  $ilLog->write(__METHOD__ . ': Trying to call Soap client...');
232 
233  array_unshift($soap_params, $new_session_id . '::' . $client_id);
234 
235  if ($soap_client->init()) {
236  $ilLog->info('Calling soap ' . $method . ' method with params ' . print_r($soap_params, true));
237  $res = $soap_client->call($method, $soap_params);
238  } else {
239  $ilLog->warning('SOAP clone call failed. Calling clone method manually');
240  if (method_exists('ilSoapFunctions', $method)) {
241  $res = ilSoapFunctions::$method(
242  $new_session_id . '::' . $client_id,
243  $this->dcl->getRefId(),
245  $format,
246  $filepath
247  );
248  } else {
249  throw new ilDclException("SOAP call " . $method . " does not exists!");
250  }
251  }
252 
253  return $res;
254  }
255 }
$res
Definition: ltiservices.php:66
static _duplicate(string $a_session_id)
Duplicate session.
getExportContentPath(string $format)
Return export path.
ilGlobalTemplateInterface $main_tpl
getFields()
Returns all fields of this table including the standard fields.
loadLanguageModule(string $a_module)
Load language module.
array $filter
Array with filters.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static _getExportDirectory(int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
Get export directory for an repository object
fillMetaExcel(ilDclTable $table, ilExcel $worksheet, int $row)
Fill Excel meta-data.
__construct(int $ref_id, ?int $table_id, array $filter=[])
static resetCache()
Resets all the cache fields.
int $table_id
Table-Id for export.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
fillRowExcel(ilDclTable $table, ilExcel $worksheet, ilDclBaseRecordModel $record, int $row)
Fill a excel row.
fillHeaderExcel(ilDclTable $table, ilExcel $worksheet, int $row)
Fill Excel header.
global $DIC
Definition: shib_login.php:22
exportAsync(string $format=self::EXPORT_EXCEL, ?string $filepath=null)
sanitizeFilename(string $filename)
Sanitize the given filename The ilUtil::_sanitizeFilename() does not clean enough.
export(string $format=self::EXPORT_EXCEL, ?string $filepath=null, bool $send=false)
Creates an export of a specific data collection table.
$filename
Definition: buildRTE.php:78
fillRecordFieldExcelExport(ilExcel $worksheet, int &$row, int &$col, $field_id)
int $ref_id
Ref-ID of DataCollection.
$client_id
Definition: ltiauth.php:66
Hook-Class for exporting data-collections (used in SOAP-Class) This Class avoids duplicated code by r...
filter(string $filter_id, $class_path, string $cmd, bool $activated=true, bool $expanded=true)
$_COOKIE[session_name()]
Definition: xapitoken.php:54