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