ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilWebLinkXmlParser.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
28 {
29  protected const int MODE_UNDEFINED = 0;
30  public const int MODE_UPDATE = 1;
31  public const int 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_element_handler($a_xml_parser, $this->handlerBeginTag(...), $this->handlerEndTag(...));
146  xml_set_character_data_handler($a_xml_parser, $this->handlerCharacterData(...));
147  }
148 
149  public function handlerBeginTag(
150  $a_xml_parser,
151  string $a_name,
152  array $a_attribs
153  ): void {
154  global $DIC;
155  $a_attribs = $this->trimAndStripAttribs($a_attribs);
156  if ($this->in_metadata) {
157  parent::handlerBeginTag($a_xml_parser, $a_name, $a_attribs);
158  return;
159  }
160 
161  switch ($a_name) {
162  case "MetaData":
163  $this->in_metadata = true;
164 
165  // Delete old meta data
166  $md = new ilMD($this->getWebLink()->getId(), 0, 'webr');
167  $md->deleteAll();
168 
169  parent::handlerBeginTag($a_xml_parser, $a_name, $a_attribs);
170  break;
171 
172  case 'WebLink':
173 
174  $this->current_sorting_position = (int) ($a_attribs['position'] ?: 0);
175  $this->resetStoredValues();
176 
177  if (
178  $this->getMode() == self::MODE_CREATE ||
179  ($a_attribs['action'] ?? null) === 'Create'
180  ) {
181  $this->current_item_create = true;
182  } else {
183  if (!($a_attribs['id'] ?? false)) {
184  throw new ilWebLinkXmlParserException(
185  'Updating or deleting not possible, no id was given for element "Weblink"'
186  );
187  }
188  if (
189  $this->getMode() == self::MODE_UPDATE &&
190  ($a_attribs['action'] ?? null) === 'Delete'
191  ) {
192  $this->current_item_delete = true;
193  $this->web_link_repo->deleteItemByLinkId($a_attribs['id']);
194  break;
195  } elseif (
196  $this->getMode() == self::MODE_UPDATE &&
197  (!isset($a_attribs['action']) || $a_attribs['action'] == 'Update')
198  ) {
199  $this->current_link_id = $a_attribs['id'];
200  $this->current_item_update = true;
201  } else {
202  throw new ilWebLinkXmlParserException(
203  'Invalid action given for element "Weblink"'
204  );
205  }
206  }
207 
208  // Active
209  $this->current_active = (bool) $a_attribs['active'];
210 
211  // internal
212  if (isset($a_attribs['internal'])) {
213  $this->current_internal = (bool) $a_attribs['internal'];
214  }
215  break;
216 
217  case 'Sorting':
218 
219  $sort = new ilContainerSortingSettings(
220  $this->getWebLink()->getId()
221  );
222  $sort->delete();
223 
224  switch ($a_attribs['type'] ?? null) {
225  case 'Manual':
226  $sort->setSortMode(ilContainer::SORT_MANUAL);
227  break;
228 
229  case 'Title':
230  default:
231  $sort->setSortMode(ilContainer::SORT_TITLE);
232  }
233  $sort->save();
234  break;
235 
236  case 'WebLinks':
237  $this->sorting_positions = array();
238  // no break
239  case 'Title':
240  case 'Description':
241  case 'Target':
242  case 'ListTitle':
243  case 'ListDescription':
244  // Nothing to do
245  break;
246 
247  case 'DynamicParameter':
248  if (!($a_attribs['name'] ?? false)) {
249  throw new ilWebLinkXmlParserException(
250  'No attribute "name" given for element "Dynamic parameter". Aborting'
251  );
252  }
253  $name = $a_attribs['name'] ?? null;
254 
255  switch ($a_attribs['type'] ?? null) {
256  case 'userName':
257  $value = ilWebLinkBaseParameter::VALUES['login'];
258  break;
259 
260  case 'userId':
261  $value = ilWebLinkBaseParameter::VALUES['user_id'];
262  break;
263 
264  case 'matriculation':
265  $value = ilWebLinkBaseParameter::VALUES['matriculation'];
266  break;
267 
268  default:
269  throw new ilWebLinkXmlParserException(
270  'Invalid attribute "type" given for element "Dynamic parameter". Aborting'
271  );
272  }
273 
274  $param = new ilWebLinkDraftParameter($value, $name);
275  if ($this->current_item_update && ($a_attribs['id'] ?? null)) {
276  $item = $this->web_link_repo->getItemByLinkId($this->current_link_id);
277  $old_param = $this->web_link_repo->getParameterinItemByParamId(
278  $item,
279  $a_attribs['id']
280  );
281  $param->replaces($old_param);
282  }
283  $this->current_parameters[] = $param;
284 
285  break;
286 
287  case 'ListSettings':
288  $this->is_list = true;
289  break;
290  }
291  }
292 
293  public function handlerEndTag($a_xml_parser, string $a_name): void
294  {
295  $this->cdata = $this->trimAndStrip((string) $this->cdata);
296 
297  if ($this->in_metadata) {
298  parent::handlerEndTag($a_xml_parser, $a_name);
299  }
300 
301  switch ($a_name) {
302  case 'MetaData':
303  $this->in_metadata = false;
304  parent::handlerEndTag($a_xml_parser, $a_name);
305  break;
306 
307  case 'WebLinks':
308  if ($this->is_list || !$this->web_link_repo->doesOnlyOneItemExist()) {
309  $list_draft = new ilWebLinkDraftList(
310  $this->list_title ?? $this->getWebLink()->getTitle(),
311  $this->list_description ?? $this->getWebLink()->getDescription()
312  );
313 
314  if (!$this->web_link_repo->doesListExist()) {
315  $this->web_link_repo->createList($list_draft);
316  } else {
317  $this->web_link_repo->updateList(
318  $this->web_link_repo->getList(),
319  $list_draft
320  );
321  }
322  }
323 
324  // save sorting
326  $this->getWebLink()->getId()
327  );
328  $sorting->savePost($this->sorting_positions);
329  ilLoggerFactory::getLogger('webr')->dump(
330  $this->sorting_positions
331  );
332  break;
333 
334  case 'WebLink':
335 
336  if ($this->current_item_delete) {
337  //Deletion is already handled in the begin tag.
338  break;
339  }
340  if (!$this->current_item_create && !$this->current_item_update) {
341  throw new ilSaxParserException(
342  'Invalid xml structure given. Missing start tag "WebLink"'
343  );
344  }
345  if (!$this->current_title || !$this->current_target) {
346  throw new ilWebLinkXmlParserException(
347  'Missing required elements "Title, Target"'
348  );
349  }
350 
351  if ($this->current_item_update) {
352  $item = $this->web_link_repo->getItemByLinkId($this->current_link_id);
353  $draft = new ilWebLinkDraftItem(
354  $this->current_internal ?? $item->isInternal(),
355  $this->current_title ?? $item->getTitle(),
356  $this->current_description ?? $item->getDescription(),
357  $this->current_target ?? $item->getTarget(),
358  $this->current_active ?? $item->isActive(),
360  );
361 
362  $this->web_link_repo->updateItem($item, $draft);
363  } else {
364  $draft = new ilWebLinkDraftItem(
365  $this->current_internal ?? ilLinkInputGUI::isInternalLink($this->current_target),
366  $this->current_title,
367  $this->current_description ?? null,
368  $this->current_target,
369  $this->current_active,
370  $this->current_parameters
371  );
372  $item = $this->web_link_repo->createItem($draft);
373  }
374 
375  // store positions
376  $this->sorting_positions[$item->getLinkId()] = $this->current_sorting_position;
377 
378  $this->resetStoredValues();
379  break;
380 
381  case 'Title':
382  $this->current_title = trim($this->cdata);
383  if (!isset($this->first_item_title)) {
384  $this->first_item_title = $this->current_title;
385  }
386  break;
387 
388  case 'Description':
389  $this->current_description = trim($this->cdata);
390  if (!isset($this->first_item_description)) {
391  $this->first_item_description = $this->current_description;
392  }
393  break;
394 
395  case 'Target':
396  $this->current_target = trim($this->cdata);
397  break;
398 
399  case 'ListTitle':
400  $this->list_title = trim($this->cdata);
401  break;
402 
403  case 'ListDescription':
404  $this->list_description = trim($this->cdata);
405  break;
406  }
407 
408  // Reset cdata
409  $this->cdata = '';
410  }
411 
412  public function handlerCharacterData($a_xml_parser, string $a_data): void
413  {
414  if ($this->in_metadata) {
415  parent::handlerCharacterData($a_xml_parser, $a_data);
416  }
417 
418  if ($a_data != "\n") {
419  // Replace multiple tabs with one space
420  $a_data = preg_replace("/\t+/", " ", $a_data);
421  $this->cdata .= $a_data;
422  }
423  }
424 }
XML parser for weblink xml.
setThrowException(bool $throw_exception)
Draft class for creating and updating a parameter attached to Web Link items.
static getLogger(string $a_component_id)
Get component logger.
trimAndStrip(string $input)
deleteAll()
Definition: class.ilMD.php:302
trimAndStripAttribs(array $attribs)
handlerEndTag($a_xml_parser, string $a_name)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setWebLink(ilObjLinkResource $webl)
__construct(ilObjLinkResource $webr, string $xml)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$general
SECTIONS.
const array VALUES
TODO Once the GUI is updated, undefined can be dropped.
$param
Definition: xapitoken.php:46
global $DIC
Definition: shib_login.php:22
handlerBeginTag( $a_xml_parser, string $a_name, array $a_attribs)
handlerCharacterData($a_xml_parser, string $a_data)
Draft class for creating or updating a Web Link list.
static isInternalLink(string $a_value)
__construct(Container $dic, ilPlugin $plugin)
static _getInstance(int $a_obj_id)
ilWebLinkRepository $web_link_repo
Draft class for creating and updating a Web Link item.
Class ilObjLinkResource.
setXMLContent(string $a_xml_content)