ILIAS  trunk Revision v11.0_alpha-1769-g99a433fe2dc
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ContentIdManager.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\COPage\ID;
22 
24 
29 {
30  protected const ID_ELEMENTS =
31  ["PageContent",
32  "TableRow",
33  "TableData",
34  "ListItem",
35  "FileItem",
36  "Section",
37  "Tab",
38  "ContentPopup",
39  "GridCell"];
40 
41  protected array $hier_ids = [];
42  protected \ilPageObject $page;
43  protected DomUtil $dom_util;
45 
46  public function __construct(
47  \ilPageObject $page,
48  ?ContentIdGeneratorInterface $generator = null
49  ) {
50  global $DIC;
51 
52  $this->dom_util = $DIC->copage()
53  ->internal()
54  ->domain()
55  ->domUtil();
56  $this->page = $page;
57  $this->generator = $generator ?? $DIC->copage()
58  ->internal()
59  ->domain()
60  ->contentIdGenerator();
61  }
62 
75  public function addHierIDsToDom(): void
76  {
77  $this->hier_ids = [];
78  $dom = $this->page->getDomDoc();
79 
80  $sep = $path = "";
81  foreach (self::ID_ELEMENTS as $el) {
82  $path .= $sep . "//" . $el;
83  $sep = " | ";
84  }
85 
86  $nodes = $this->dom_util->path($dom, $path);
87 
88  foreach ($nodes as $node) {
89  $cnode = $node;
90  $ctag = $cnode->nodeName;
91 
92  // get hierarchical id of previous sibling
93  $sib_hier_id = "";
94  while ($cnode = $cnode->previousSibling) {
95  if (($cnode->nodeType == XML_ELEMENT_NODE)
96  && $cnode->hasAttribute("HierId")) {
97  $sib_hier_id = $cnode->getAttribute("HierId");
98  break;
99  }
100  }
101 
102  if ($sib_hier_id != "") { // set id to sibling id "+ 1"
103  $node_hier_id = $this->incEdId($sib_hier_id);
104  $node->setAttribute("HierId", $node_hier_id);
105  $this->hier_ids[] = $node_hier_id;
106  } else { // no sibling -> node is first child
107  // get hierarchical id of next parent
108  $cnode = $node;
109  $par_hier_id = "";
110  while ($cnode = $cnode->parentNode) {
111  if (($cnode->nodeType == XML_ELEMENT_NODE)
112  && $cnode->hasAttribute("HierId")) {
113  $par_hier_id = $cnode->getAttribute("HierId");
114  break;
115  }
116  }
117  if (($par_hier_id != "") && ($par_hier_id != "pg")) { // set id to parent_id."_1"
118  $node_hier_id = $par_hier_id . "_1";
119  $node->setAttribute("HierId", $node_hier_id);
120  $this->hier_ids[] = $node_hier_id;
121  } else { // no sibling, no parent -> first node
122  $node_hier_id = "1";
123  $node->setAttribute("HierId", $node_hier_id);
124  $this->hier_ids[] = $node_hier_id;
125  }
126  }
127  }
128 
129  // set special hierarchical id "pg" for pageobject
130  $path = "//PageObject";
131  $nodes = $this->dom_util->path($dom, $path);
132  foreach ($nodes as $node) {
133  $node->setAttribute("HierId", "pg");
134  $this->hier_ids[] = "pg";
135  }
136  }
137 
141  public function getHierIds(): array
142  {
143  return $this->hier_ids;
144  }
145 
146  public function stripHierIDsFromDom(): void
147  {
148  $this->hier_ids = [];
149  $dom = $this->page->getDomDoc();
150 
151  if (is_object($dom)) {
152  $path = "//*[@HierId]";
153  $nodes = $this->dom_util->path($dom, $path);
154  foreach ($nodes as $node) {
155  if ($node->hasAttribute("HierId")) {
156  $node->removeAttribute("HierId");
157  }
158  }
159  }
160  }
161 
162 
168  protected function incEdId(string $ed_id): string
169  {
170  $id = explode("_", $ed_id);
171  $id[count($id) - 1]++;
172  return implode("_", $id);
173  }
174 
180  protected function decEdId(string $ed_id): string
181  {
182  $id = explode("_", $ed_id);
183  $id[count($id) - 1]--;
184  return implode("_", $id);
185  }
186 
187  public function generatePCId(): string
188  {
189  return $this->generator->generate();
190  }
191 
192  public function insertPCIds(): void
193  {
194  $this->page->buildDom();
195  $dom = $this->page->getDomDoc();
196 
197  // add missing ones
198  $sep = $path = "";
199  foreach (self::ID_ELEMENTS as $el) {
200  $path .= $sep . "//" . $el . "[not(@PCID)]";
201  $sep = " | ";
202  $path .= $sep . "//" . $el . "[@PCID='']";
203  $sep = " | ";
204  }
205  $nodes = $this->dom_util->path($dom, $path);
206  foreach ($nodes as $node) {
207  $id = $this->generatePCId();
208  $node->setAttribute("PCID", $id);
209  }
210  }
211 
212  public function getDuplicatePCIds(): array
213  {
214  $this->page->buildDom();
215  $dom = $this->page->getDomDoc();
216 
217  $pcids = [];
218  $duplicates = [];
219 
220  $sep = $path = "";
221  foreach (self::ID_ELEMENTS as $el) {
222  $path .= $sep . "//" . $el . "[@PCID]";
223  $sep = " | ";
224  }
225 
226  // get existing ids
227  $nodes = $this->dom_util->path($dom, $path);
228  foreach ($nodes as $node) {
229  $pc_id = $node->getAttribute("PCID");
230  if ($pc_id != "") {
231  if (isset($pcids[$pc_id])) {
232  $duplicates[] = $pc_id;
233  }
234  $pcids[$pc_id] = $pc_id;
235  }
236  }
237  return $duplicates;
238  }
239 
240  public function hasDuplicatePCIds(): bool
241  {
242  $duplicates = $this->getDuplicatePCIds();
243  return count($duplicates) > 0;
244  }
245 
246  public function stripPCIDs(): void
247  {
248  $dom = $this->page->getDomDoc();
249  if (is_object($dom)) {
250  $path = "//*[@PCID]";
251  $nodes = $this->dom_util->path($dom, $path);
252  foreach ($nodes as $node) {
253  if ($node->hasAttribute("PCID")) {
254  $node->removeAttribute("PCID");
255  }
256  }
257  }
258  }
259 
260  public function checkPCIds(): bool
261  {
262  $page = $this->page;
263  $page->buildDom();
264  $dom = $page->getDomDoc();
265 
266  $sep = $path = "";
267  foreach (self::ID_ELEMENTS as $el) {
268  $path .= $sep . "//" . $el . "[not(@PCID)]";
269  $sep = " | ";
270  $path .= $sep . "//" . $el . "[@PCID='']";
271  }
272  $nodes = $this->dom_util->path($dom, $path);
273  if (count($nodes) > 0) {
274  return false;
275  }
276  return true;
277  }
278 
279  public function getAllPCIds(): array
280  {
281  $page = $this->page;
282  $page->buildDom();
283  $dom = $page->getDomDoc();
284 
285  $pcids = array();
286 
287  $sep = $path = "";
288  foreach (self::ID_ELEMENTS as $el) {
289  $path .= $sep . "//" . $el . "[@PCID]";
290  $sep = " | ";
291  }
292 
293  // get existing ids
294  $nodes = $this->dom_util->path($dom, $path);
295  foreach ($nodes as $node) {
296  $pcids[] = $node->getAttribute("PCID");
297  }
298  return $pcids;
299  }
300 
301 
302  public function getHierIdsForPCIds(array $a_pc_ids): array
303  {
304  if (!is_array($a_pc_ids) || count($a_pc_ids) == 0) {
305  return array();
306  }
307  $ret = array();
308 
309  $dom = $this->page->getDomDoc();
310  if (is_object($dom)) {
311  $path = "//*[@PCID]";
312  $nodes = $this->dom_util->path($dom, $path);
313  foreach ($nodes as $node) {
314  $pc_id = $node->getAttribute("PCID");
315  if (in_array($pc_id, $a_pc_ids)) {
316  $ret[$pc_id] = $node->getAttribute("HierId");
317  }
318  }
319  }
320  return $ret;
321  }
322 
323  public function getHierIdForPcId(string $pcid): string
324  {
325  $hier_ids = $this->getHierIdsForPCIds([$pcid]);
326  return $hier_ids[$pcid] ?? "";
327  }
328 
329  public function getPCIdsForHierIds(array $hier_ids): array
330  {
331  $page = $this->page;
332  $dom = $page->getDomDoc();
333  if (!is_array($hier_ids) || count($hier_ids) == 0) {
334  return [];
335  }
336  $ret = [];
337  if (is_object($dom)) {
338  $page->addHierIDs();
339  $path = "//*[@HierId]";
340  $nodes = $this->dom_util->path($dom, $path);
341  foreach ($nodes as $node) {
342  $hier_id = $node->getAttribute("HierId");
343  if (in_array($hier_id, $hier_ids)) {
344  $ret[$hier_id] = $node->getAttribute("PCID");
345  }
346  }
347  }
348  return $ret;
349  }
350 
351  public function getPCIdForHierId(string $hier_id): string
352  {
353  $hier_ids = $this->getPCIdsForHierIds([$hier_id]);
354  return ($hier_ids[$hier_id] ?? "");
355  }
356 }
buildDom(bool $a_force=false)
addHierIDsToDom()
Add hierarchical ID (e.g.
getDomDoc()
Get dom doc (DOMDocument)
$path
Definition: ltiservices.php:29
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
Class ilPageObject Handles PageObjects of ILIAS Learning Modules (see ILIAS DTD)
decEdId(string $ed_id)
Decreases an hierarchical editing id at lowest level (last number)
incEdId(string $ed_id)
Increases an hierarchical editing id at lowest level (last number)
global $DIC
Definition: shib_login.php:22
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(\ilPageObject $page, ?ContentIdGeneratorInterface $generator=null)
getHierIds()
get all hierarchical ids