ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilWebLinkXmlParser.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
28 {
29  protected const MODE_UNDEFINED = 0;
30  public const MODE_UPDATE = 1;
31  public const MODE_CREATE = 2;
32 
35  private int $mode = self::MODE_UNDEFINED;
36  private bool $in_metadata = false;
37  private array $sorting_positions = [];
38  private string $cdata = '';
39 
40  private int $current_sorting_position = 0;
41  private bool $current_item_create = false;
42  private bool $current_item_update = false;
43  private bool $current_item_delete = false;
44 
45  private ?int $current_link_id;
46  private ?string $current_title;
47  private ?string $current_target;
48  private ?bool $current_active;
52  private array $current_parameters = [];
53  private ?string $current_description;
54  private ?bool $current_internal;
55 
56  private bool $is_list = false;
57  private string $list_title;
58  private string $list_description;
59  private string $first_item_title;
60  private string $first_item_description;
61 
62  public function __construct(ilObjLinkResource $webr, string $xml)
63  {
65  $this->setXMLContent($xml);
66  $this->setWebLink($webr);
67  $this->web_link_repo = new ilWebLinkDatabaseRepository(
68  $this->getWebLink()->getId()
69  );
70 
71  $this->setMDObject(
72  new ilMD(
73  $this->getWebLink()->getId(),
74  $this->getWebLink()->getId(),
75  'webr'
76  )
77  );
78  $this->setThrowException(true);
79  }
80 
81  public function startParsing(): void
82  {
83  parent::startParsing();
84 
85  // set title and description
86  $this->getWebLink()->setTitle($this->list_title ?? $this->first_item_title);
87  $this->getWebLink()->setDescription($this->list_description ?? $this->first_item_description);
88  $this->getWebLink()->update();
89 
90  // rewrite autogenerated entry
91  $general = $this->getMDObject()->getGeneral();
92  $identifier_ids = $general->getIdentifierIds();
93  if (!isset($identifier_ids[0])) {
94  return;
95  }
96  $identifier = $general->getIdentifier($identifier_ids[0]);
97  $identifier->setEntry(
98  'il__' . $this->getMDObject()->getObjType() . '_' . $this->getMDObject()->getObjId()
99  );
100  $identifier->update();
101  }
102 
103  public function setWebLink(ilObjLinkResource $webl): void
104  {
105  $this->webl = $webl;
106  }
107 
108  public function getWebLink(): ilObjLinkResource
109  {
110  return $this->webl;
111  }
112 
113  public function setMode(int $a_mode): void
114  {
115  $this->mode = $a_mode;
116  }
117 
118  public function getMode(): int
119  {
120  return $this->mode;
121  }
122 
123  protected function resetStoredValues(): void
124  {
125  $this->current_item_create = false;
126  $this->current_item_update = false;
127  $this->current_item_delete = false;
128 
129  $this->current_link_id = null;
130  $this->current_title = null;
131  $this->current_target = null;
132  $this->current_active = null;
133  $this->current_parameters = [];
134  $this->current_description = null;
135  $this->current_internal = null;
136  }
137 
138  public function start(): void
139  {
140  $this->startParsing();
141  }
142 
143  public function setHandlers($a_xml_parser): void
144  {
145  xml_set_object($a_xml_parser, $this);
146  xml_set_element_handler(
147  $a_xml_parser,
148  'handlerBeginTag',
149  'handlerEndTag'
150  );
151  xml_set_character_data_handler($a_xml_parser, 'handlerCharacterData');
152  }
153 
154  public function handlerBeginTag(
155  $a_xml_parser,
156  string $a_name,
157  array $a_attribs
158  ): void {
159  global $DIC;
160  $a_attribs = $this->trimAndStripAttribs($a_attribs);
161  if ($this->in_metadata) {
162  parent::handlerBeginTag($a_xml_parser, $a_name, $a_attribs);
163  return;
164  }
165 
166  switch ($a_name) {
167  case "MetaData":
168  $this->in_metadata = true;
169 
170  // Delete old meta data
171  $md = new ilMD($this->getWebLink()->getId(), 0, 'webr');
172  $md->deleteAll();
173 
174  parent::handlerBeginTag($a_xml_parser, $a_name, $a_attribs);
175  break;
176 
177  case 'WebLink':
178 
179  $this->current_sorting_position = (int) ($a_attribs['position'] ?: 0);
180  $this->resetStoredValues();
181 
182  if (
183  $this->getMode() == self::MODE_CREATE ||
184  ($a_attribs['action'] ?? null) === 'Create'
185  ) {
186  $this->current_item_create = true;
187  } else {
188  if (!($a_attribs['id'] ?? false)) {
189  throw new ilWebLinkXmlParserException(
190  'Updating or deleting not possible, no id was given for element "Weblink"'
191  );
192  }
193  if (
194  $this->getMode() == self::MODE_UPDATE &&
195  ($a_attribs['action'] ?? null) === 'Delete'
196  ) {
197  $this->current_item_delete = true;
198  $this->web_link_repo->deleteItemByLinkId($a_attribs['id']);
199  break;
200  } elseif (
201  $this->getMode() == self::MODE_UPDATE &&
202  (!isset($a_attribs['action']) || $a_attribs['action'] == 'Update')
203  ) {
204  $this->current_link_id = $a_attribs['id'];
205  $this->current_item_update = true;
206  } else {
207  throw new ilWebLinkXmlParserException(
208  'Invalid action given for element "Weblink"'
209  );
210  }
211  }
212 
213  // Active
214  $this->current_active = (bool) $a_attribs['active'];
215 
216  // internal
217  if (isset($a_attribs['internal'])) {
218  $this->current_internal = (bool) $a_attribs['internal'];
219  }
220  break;
221 
222  case 'Sorting':
223 
224  $sort = new ilContainerSortingSettings(
225  $this->getWebLink()->getId()
226  );
227  $sort->delete();
228 
229  switch ($a_attribs['type'] ?? null) {
230  case 'Manual':
231  $sort->setSortMode(ilContainer::SORT_MANUAL);
232  break;
233 
234  case 'Title':
235  default:
236  $sort->setSortMode(ilContainer::SORT_TITLE);
237  }
238  $sort->save();
239  break;
240 
241  case 'WebLinks':
242  $this->sorting_positions = array();
243  // no break
244  case 'Title':
245  case 'Description':
246  case 'Target':
247  case 'ListTitle':
248  case 'ListDescription':
249  // Nothing to do
250  break;
251 
252  case 'DynamicParameter':
253  if (!($a_attribs['name'] ?? false)) {
254  throw new ilWebLinkXmlParserException(
255  'No attribute "name" given for element "Dynamic parameter". Aborting'
256  );
257  }
258  $name = $a_attribs['name'] ?? null;
259 
260  switch ($a_attribs['type'] ?? null) {
261  case 'userName':
262  $value = ilWebLinkBaseParameter::VALUES['login'];
263  break;
264 
265  case 'userId':
266  $value = ilWebLinkBaseParameter::VALUES['user_id'];
267  break;
268 
269  case 'matriculation':
270  $value = ilWebLinkBaseParameter::VALUES['matriculation'];
271  break;
272 
273  default:
274  throw new ilWebLinkXmlParserException(
275  'Invalid attribute "type" given for element "Dynamic parameter". Aborting'
276  );
277  }
278 
279  $param = new ilWebLinkDraftParameter($value, $name);
280  if ($this->current_item_update && ($a_attribs['id'] ?? null)) {
281  $item = $this->web_link_repo->getItemByLinkId($this->current_link_id);
282  $old_param = $this->web_link_repo->getParameterinItemByParamId(
283  $item,
284  $a_attribs['id']
285  );
286  $param->replaces($old_param);
287  }
288  $this->current_parameters[] = $param;
289 
290  break;
291 
292  case 'ListSettings':
293  $this->is_list = true;
294  break;
295  }
296  }
297 
298  public function handlerEndTag($a_xml_parser, string $a_name): void
299  {
300  $this->cdata = $this->trimAndStrip((string) $this->cdata);
301 
302  if ($this->in_metadata) {
303  parent::handlerEndTag($a_xml_parser, $a_name);
304  }
305 
306  switch ($a_name) {
307  case 'MetaData':
308  $this->in_metadata = false;
309  parent::handlerEndTag($a_xml_parser, $a_name);
310  break;
311 
312  case 'WebLinks':
313  if ($this->is_list || !$this->web_link_repo->doesOnlyOneItemExist()) {
314  $list_draft = new ilWebLinkDraftList(
315  $this->list_title ?? $this->getWebLink()->getTitle(),
316  $this->list_description ?? $this->getWebLink()->getDescription()
317  );
318 
319  if (!$this->web_link_repo->doesListExist()) {
320  $this->web_link_repo->createList($list_draft);
321  } else {
322  $this->web_link_repo->updateList(
323  $this->web_link_repo->getList(),
324  $list_draft
325  );
326  }
327  }
328 
329  // save sorting
331  $this->getWebLink()->getId()
332  );
333  $sorting->savePost($this->sorting_positions);
334  ilLoggerFactory::getLogger('webr')->dump(
335  $this->sorting_positions
336  );
337  break;
338 
339  case 'WebLink':
340 
341  if ($this->current_item_delete) {
342  //Deletion is already handled in the begin tag.
343  break;
344  }
345  if (!$this->current_item_create && !$this->current_item_update) {
346  throw new ilSaxParserException(
347  'Invalid xml structure given. Missing start tag "WebLink"'
348  );
349  }
350  if (!$this->current_title || !$this->current_target) {
351  throw new ilWebLinkXmlParserException(
352  'Missing required elements "Title, Target"'
353  );
354  }
355 
356  if ($this->current_item_update) {
357  $item = $this->web_link_repo->getItemByLinkId($this->current_link_id);
358  $draft = new ilWebLinkDraftItem(
359  $this->current_internal ?? $item->isInternal(),
360  $this->current_title ?? $item->getTitle(),
361  $this->current_description ?? $item->getDescription(),
362  $this->current_target ?? $item->getTarget(),
363  $this->current_active ?? $item->isActive(),
365  );
366 
367  $this->web_link_repo->updateItem($item, $draft);
368  } else {
369  $draft = new ilWebLinkDraftItem(
370  $this->current_internal ?? ilLinkInputGUI::isInternalLink($this->current_target),
371  $this->current_title,
372  $this->current_description ?? null,
373  $this->current_target,
374  $this->current_active,
375  $this->current_parameters
376  );
377  $item = $this->web_link_repo->createItem($draft);
378  }
379 
380  // store positions
381  $this->sorting_positions[$item->getLinkId()] = $this->current_sorting_position;
382 
383  $this->resetStoredValues();
384  break;
385 
386  case 'Title':
387  $this->current_title = trim($this->cdata);
388  if (!isset($this->first_item_title)) {
389  $this->first_item_title = $this->current_title;
390  }
391  break;
392 
393  case 'Description':
394  $this->current_description = trim($this->cdata);
395  if (!isset($this->first_item_description)) {
396  $this->first_item_description = $this->current_description;
397  }
398  break;
399 
400  case 'Target':
401  $this->current_target = trim($this->cdata);
402  break;
403 
404  case 'ListTitle':
405  $this->list_title = trim($this->cdata);
406  break;
407 
408  case 'ListDescription':
409  $this->list_description = trim($this->cdata);
410  break;
411  }
412 
413  // Reset cdata
414  $this->cdata = '';
415  }
416 
417  public function handlerCharacterData($a_xml_parser, string $a_data): void
418  {
419  if ($this->in_metadata) {
420  parent::handlerCharacterData($a_xml_parser, $a_data);
421  }
422 
423  if ($a_data != "\n") {
424  // Replace multiple tabs with one space
425  $a_data = preg_replace("/\t+/", " ", $a_data);
426  $this->cdata .= $a_data;
427  }
428  }
429 }
XML parser for weblink xml.
setThrowException(bool $throw_exception)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getLogger(string $a_component_id)
Get component logger.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
trimAndStrip(string $input)
deleteAll()
Definition: class.ilMD.php:302
trimAndStripAttribs(array $attribs)
handlerEndTag($a_xml_parser, string $a_name)
SaxParserException thrown by ilSaxParser if property throwException is set.
setWebLink(ilObjLinkResource $webl)
__construct(ilObjLinkResource $webr, string $xml)
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...
$general
SECTIONS.
$param
Definition: xapitoken.php:44
global $DIC
Definition: shib_login.php:25
handlerBeginTag( $a_xml_parser, string $a_name, array $a_attribs)
handlerCharacterData($a_xml_parser, string $a_data)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static isInternalLink(string $a_value)
__construct(Container $dic, ilPlugin $plugin)
static _getInstance(int $a_obj_id)
ilWebLinkRepository $web_link_repo
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const VALUES
TODO Once the GUI is updated, undefined can be dropped.
Class ilObjLinkResource.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setXMLContent(string $a_xml_content)