ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilComponentDefinitionReader.php
Go to the documentation of this file.
1 <?php
2 
20 declare(strict_types=1);
21 
23 {
27  protected array $processors;
28 
29  public function __construct(
30  ilComponentDefinitionProcessor ...$processor
31  ) {
32  $this->processors = $processor;
33  }
34 
39  public function purge(): void
40  {
41  foreach ($this->processors as $p) {
42  $p->purge();
43  }
44  }
45 
50  public function readComponentDefinitions(): void
51  {
52  foreach ($this->getComponents() as [$type, $component, $path]) {
53  $file = $this->readFile($path);
54  foreach ($this->processors as $processor) {
55  $processor->beginComponent($component, $type);
56  }
57  $this->parseComponentXML($type, $component, $file);
58  foreach ($this->processors as $processor) {
59  $processor->endComponent($component, $type);
60  }
61  }
62  }
63 
64  protected function readFile(string $path): string
65  {
66  if (!file_exists($path)) {
67  throw new \InvalidArgumentException(
68  "Cannot find file $path."
69  );
70  }
71  return file_get_contents($path);
72  }
73 
74  protected function parseComponentXML(string $type, string $component, string $xml): void
75  {
76  $xml_parser = null;
77  try {
78  $xml_parser = xml_parser_create("UTF-8");
79  xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
80  xml_set_object($xml_parser, $this);
81  xml_set_element_handler($xml_parser, 'beginTag', 'endTag');
82  if (!xml_parse($xml_parser, $xml)) {
83  $code = xml_get_error_code($xml_parser);
84  $line = xml_get_current_line_number($xml_parser);
85  $col = xml_get_current_column_number($xml_parser);
86  $msg = xml_error_string($code);
87  throw new \InvalidArgumentException(
88  "Error $code component xml of $type/$component, on line $line in column $col: $msg"
89  );
90  }
91  } finally {
92  if ($xml_parser) {
93  xml_parser_free($xml_parser);
94  }
95  }
96  }
97 
98  public function beginTag($_, string $name, array $attributes): void
99  {
100  foreach ($this->processors as $processor) {
101  $processor->beginTag($name, $attributes);
102  }
103  }
104 
105  public function endTag($_, string $name): void
106  {
107  foreach ($this->processors as $processor) {
108  $processor->endTag($name);
109  }
110  }
111 
115  protected function getComponents(): \Iterator
116  {
117  foreach ($this->getComponentInfo("components/ILIAS", "module.xml") as $i) {
118  yield $i;
119  }
120  foreach ($this->getComponentInfo("components/ILIAS", "service.xml") as $i) {
121  yield $i;
122  }
123  }
124 
128  protected function getComponentInfo(string $type, string $name): \Iterator
129  {
130  $dir = __DIR__ . "/../../../../" . $type;
131  foreach ($this->getComponentPaths($dir, $name) as $c) {
132  yield [
133  $type,
134  $c,
135  realpath($dir . "/" . $c . "/" . $name)
136  ];
137  }
138  }
139 
143  protected function getComponentPaths(string $root, string $name): \Iterator
144  {
145  $dir = opendir($root);
146  while ($sub = readdir($dir)) {
147  if ($sub === "." || $sub === "..") {
148  continue;
149  }
150  if (!is_dir($root . "/" . $sub)) {
151  continue;
152  }
153  if (!is_file($root . "/" . $sub . "/" . $name)) {
154  continue;
155  }
156  yield $sub;
157  }
158  }
159 }
An ilComponentDefinitionProcessor processes some attributes from a component.xml (i.e.
purge()
This methods is supposed to purge existing data in the registered processor.
$c
Definition: deliver.php:9
parseComponentXML(string $type, string $component, string $xml)
$path
Definition: ltiservices.php:30
readComponentDefinitions()
This reads the component.xml of all components in the core and processes them with the provided proce...
beginTag($_, string $name, array $attributes)
__construct(ilComponentDefinitionProcessor ... $processor)