ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
PublicAssetManager.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
27{
28 public const REGEXP = '%^/[A-Za-z0-9_]+(?:[.-][A-Za-z0-9_]+)*(?:/[A-Za-z0-9_]+(?:[.-][A-Za-z0-9_]+)*)*$%';
29
30 public const DONT_PURGE = ["data", "Customizing"];
31
32 protected $assets = [];
33
34
35 public function addAssets(PublicAsset ...$assets): void
36 {
37 foreach ($assets as $asset) {
38 $this->insertInto($this->assets, explode("/", $asset->getTarget()), $asset);
39 }
40 }
41
42 protected function insertInto(array &$assets, array $path, PublicAsset $asset): void
43 {
44 $key = array_shift($path);
45 $key_exists = array_key_exists($key, $assets);
46 $target_reached = count($path) === 0;
47
48 if (!$key_exists && $target_reached) {
49 $assets[$key] = $asset;
50 return;
51 }
52
53 if (!$target_reached && (!$key_exists || is_array($assets[$key]))) {
54 if (!$key_exists) {
55 $assets[$key] = [];
56 }
57 $this->insertInto($assets[$key], $path, $asset);
58 return;
59 }
60
61 $first_asset = $assets[$key];
62 while (!$first_asset instanceof PublicAsset) {
63 $first_asset = array_shift($first_asset);
64 }
65
66 throw new \LogicException(
67 "There are (at least) two assets for the same target '{$asset->getTarget()}': " .
68 "'{$first_asset->getSource()}' and '{$asset->getSource()}'"
69 );
70 }
71
72
73
78 public function buildPublicFolder(string $ilias_base, string $target): void
79 {
80 if (!preg_match(self::REGEXP, $ilias_base)) {
81 throw new \InvalidArgumentException(
82 "'{$ilias_base}' is not a valid path to ILIAS base folder."
83 );
84 }
85 if (!preg_match(self::REGEXP, $target)) {
86 throw new \InvalidArgumentException(
87 "'{$target}' is not a valid target path for public assets."
88 );
89 }
90
91 $this->purge($target, array_map(fn(string $v): string => $target . "/" . $v, self::DONT_PURGE));
92 $this->makeDir($target);
93 $this->buildPublicFolderRecursivelyArray($ilias_base, $target, $this->assets);
94 }
95
96 protected function buildPublicFolderRecursively(string $ilias_base, string $target, PublicAsset|array $asset): void
97 {
98 if (is_array($asset)) {
99 $this->makeDir("$target");
100 $this->buildPublicFolderRecursivelyArray($ilias_base, $target, $asset);
101 } else {
102 $targets = explode("/", $asset->getTarget());
103 $this->copy("$ilias_base/{$asset->getSource()}", "$target");
104 }
105 }
106
107 protected function buildPublicFolderRecursivelyArray(string $ilias_base, string $target, array $assets): void
108 {
109 foreach ($assets as $key => $asset) {
110 $this->buildPublicFolderRecursively($ilias_base, "$target/$key", $asset);
111 }
112 }
113
114 protected function copy(string $source, string $target): void
115 {
116 if (is_file($source)) {
117 copy($source, $target);
118 } elseif (is_dir($source)) {
119 $dir = new \RecursiveDirectoryIterator($source, \FilesystemIterator::SKIP_DOTS);
120 $this->makeDir($target);
121 foreach ($dir as $d) {
122 $name = $d->getBasename();
123 $this->copy("$source/$name", "$target/$name");
124 }
125 } else {
126 throw new \RuntimeException(
127 "Cannot copy $source, not a file or directory."
128 );
129 }
130 }
131
132 protected function purge(string $path, array $dont_purge): bool
133 {
134 if (in_array($path, $dont_purge)) {
135 return false;
136 }
137
138 if (!file_exists($path)) {
139 return true;
140 }
141
142 if (is_file($path)) {
143 unlink($path);
144 return true;
145 }
146
147 if (is_dir($path)) {
148 $purged = true;
149 foreach (array_diff(scandir($path), ['.', '..']) as $item) {
150 $purged = $this->purge($path . "/" . $item, $dont_purge) && $purged;
151 }
152 if ($purged) {
153 rmdir($path);
154 }
155 return $purged;
156 }
157
158 throw new \LogicException("Don't know how to purge $path");
159 }
160
161 protected function makeDir(string $path): void
162 {
163 if (!file_exists($path)) {
164 mkdir($path, 0755);
165 }
166 }
167}
Will take care of the public assets, just like a good manager does.
buildPublicFolder(string $ilias_base, string $target)
insertInto(array &$assets, array $path, PublicAsset $asset)
buildPublicFolderRecursivelyArray(string $ilias_base, string $target, array $assets)
purge(string $path, array $dont_purge)
buildPublicFolderRecursively(string $ilias_base, string $target, PublicAsset|array $asset)
An public asset is a file or folder that should be served via the web.
Definition: PublicAsset.php:27
$path
Definition: ltiservices.php:30