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