ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilWACPath.php
Go to the documentation of this file.
1 <?php
18 // declare(strict_types=1);
25 class ilWACPath
26 {
27  public const DIR_DATA = "data";
28  public const DIR_SEC = "sec";
32  public const REGEX = "(?<prefix>.*?)(?<path>(?<path_without_query>(?<secure_path_id>(?<module_path>\/data\/(?<client>[\w\-\.]*)\/(?<sec>sec\/|)(?<module_type>.*?)\/(?<module_identifier>.*\/|)))(?<appendix>[^\?\n]*)).*)";
36  protected static array $image_suffixes = [
37  'png',
38  'jpg',
39  'jpeg',
40  'gif',
41  'svg',
42  ];
46  protected static array $video_suffixes = [
47  'mp4',
48  'm4v',
49  'mov',
50  'wmv',
51  'webm',
52  ];
56  protected static array $audio_suffixes = [
57  'mp3',
58  'aiff',
59  'aif',
60  'm4a',
61  'wav',
62  ];
63 
64  protected string $client = '';
68  protected array $parameters = [];
69  protected bool $in_sec_folder = false;
70  protected string $token = '';
71  protected int $timestamp = 0;
72  protected int $ttl = 0;
73  protected string $secure_path = '';
74  protected string $secure_path_id = '';
75  protected string $original_request = '';
76  protected string $file_name = '';
77  protected string $query = '';
78  protected string $suffix = '';
79  protected string $prefix = '';
80  protected string $appendix = '';
81  protected string $module_path = '';
82  protected string $path = '';
83  protected string $module_type = '';
84  protected string $module_identifier = '';
85  protected string $path_without_query = '';
86 
87  public function __construct(string $path, bool $normalize = true)
88  {
89  if ($normalize) {
90  $path = $this->normalizePath($path);
91  }
92 
93  $this->setOriginalRequest($path);
94  $re = '/' . self::REGEX . '/';
95  preg_match($re, $path, $result);
96 
97  $result['path_without_query'] = strstr(
98  parse_url($path)['path'],
99  '/data/',
100  false
101  );
102 
103 
104  foreach (array_keys($result) as $k) {
105  if (is_numeric($k)) {
106  unset($result[$k]);
107  }
108  }
109 
110  $moduleId = strstr(
111  !isset($result['module_identifier']) || is_null($result['module_identifier']) ? '' : $result['module_identifier'],
112  '/',
113  true
114  );
115  $moduleId = $moduleId === false ? '' : $moduleId;
116 
117  $this->setPrefix(!isset($result['prefix']) || is_null($result['prefix']) ? '' : $result['prefix']);
118  $this->setClient(!isset($result['client']) || is_null($result['client']) ? '' : $result['client']);
119  $this->setAppendix(!isset($result['appendix']) || is_null($result['appendix']) ? '' : $result['appendix']);
120  $this->setModuleIdentifier($moduleId);
121  $this->setModuleType(!isset($result['module_type']) || is_null($result['module_type']) ? '' : $result['module_type']);
122 
123  if ($this->getModuleIdentifier() !== '' && $this->getModuleIdentifier() !== '0') {
124  $module_path = strstr(
125  !isset($result['module_path']) || is_null($result['module_path']) ? '' : $result['module_path'],
126  $this->getModuleIdentifier(),
127  true
128  );
129  $module_path = '.' . ($module_path === false ? '' : $module_path);
130  } else {
131  $module_path = ('.' . (!isset($result['module_path']) || is_null($result['module_path']) ? '' : $result['module_path']));
132  }
133 
134  $this->setModulePath($module_path);
135  $this->setInSecFolder(isset($result['sec']) && $result['sec'] === 'sec/');
136  $this->setPathWithoutQuery(
137  '.' . (!isset($result['path_without_query']) || is_null($result['path_without_query']) ? '' : $result['path_without_query'])
138  );
139  $this->setPath('.' . (!isset($result['path']) || is_null($result['path']) ? '' : $result['path']));
140  $this->setSecurePath(
141  '.' . (!isset($result['secure_path_id']) || is_null($result['secure_path_id']) ? '' : $result['secure_path_id'])
142  );
143  $this->setSecurePathId(!isset($result['module_type']) || is_null($result['module_type']) ? '' : $result['module_type']);
144  // Pathinfo
145  $parts = parse_url($path);
146  $this->setFileName(basename($parts['path']));
147  if (isset($parts['query'])) {
148  $parts_query = $parts['query'];
149  $this->setQuery($parts_query);
150  parse_str($parts_query, $query);
151  $this->setParameters($query);
152  }
153  $this->setSuffix(pathinfo($parts['path'], PATHINFO_EXTENSION));
154  $this->handleParameters();
155  }
156 
157  protected function handleParameters(): void
158  {
159  $param = $this->getParameters();
161  $this->setToken($param[ilWACSignedPath::WAC_TOKEN_ID]);
162  }
164  $this->setTimestamp((int) $param[ilWACSignedPath::WAC_TIMESTAMP_ID]);
165  }
166  if (isset($param[ilWACSignedPath::WAC_TTL_ID])) {
167  $this->setTTL((int) $param[ilWACSignedPath::WAC_TTL_ID]);
168  }
169  }
170 
174  public function getParameters(): array
175  {
176  return $this->parameters;
177  }
178 
182  public function setParameters(array $parameters): void
183  {
184  $this->parameters = $parameters;
185  }
186 
190  public static function getAudioSuffixes(): array
191  {
192  return self::$audio_suffixes;
193  }
194 
198  public static function setAudioSuffixes(array $audio_suffixes): void
199  {
200  self::$audio_suffixes = $audio_suffixes;
201  }
202 
206  public static function getImageSuffixes(): array
207  {
208  return self::$image_suffixes;
209  }
210 
214  public static function setImageSuffixes(array $image_suffixes): void
215  {
216  self::$image_suffixes = $image_suffixes;
217  }
218 
222  public static function getVideoSuffixes(): array
223  {
224  return self::$video_suffixes;
225  }
226 
230  public static function setVideoSuffixes(array $video_suffixes): void
231  {
232  self::$video_suffixes = $video_suffixes;
233  }
234 
235  protected function normalizePath(string $path): string
236  {
237  $path = ltrim($path, '.');
238  $path = rawurldecode($path);
239 
240  // cut everything before "data/" (for installations using a subdirectory)
241  $path = strstr($path, '/' . self::DIR_DATA . '/');
242 
243  $original_path = parse_url($path, PHP_URL_PATH);
244  $query = parse_url($path, PHP_URL_QUERY);
245 
246  $real_data_dir = realpath("./" . self::DIR_DATA);
247  $realpath = realpath("." . $original_path);
248 
249  if (!str_starts_with($realpath, $real_data_dir)) {
250  throw new ilWACException(ilWACException::NOT_FOUND, "Path is not in data directory");
251  }
252 
253  $normalized_path = ltrim(
254  str_replace(
255  $real_data_dir,
256  '',
257  $realpath
258  ),
259  '/'
260  );
261 
262  return "/" . self::DIR_DATA . '/' . $normalized_path . (empty($query) ? '' : '?' . $query);
263  }
264 
265  public function getPrefix(): string
266  {
267  return $this->prefix;
268  }
269 
270  public function setPrefix(string $prefix): void
271  {
272  $this->prefix = $prefix;
273  }
274 
275  public function getAppendix(): string
276  {
277  return $this->appendix;
278  }
279 
280  public function setAppendix(string $appendix): void
281  {
282  $this->appendix = $appendix;
283  }
284 
285  public function getModulePath(): string
286  {
287  return $this->module_path;
288  }
289 
290  public function setModulePath(string $module_path): void
291  {
292  $this->module_path = $module_path;
293  }
294 
295  public function getDirName(): string
296  {
297  return dirname($this->getPathWithoutQuery());
298  }
299 
300  public function getPathWithoutQuery(): string
301  {
303  }
304 
305  public function setPathWithoutQuery(string $path_without_query): void
306  {
307  $this->path_without_query = $path_without_query;
308  }
309 
310  public function isImage(): bool
311  {
312  return in_array(strtolower($this->getSuffix()), self::$image_suffixes);
313  }
314 
315  public function getSuffix(): string
316  {
317  return $this->suffix;
318  }
319 
320  public function setSuffix(string $suffix): void
321  {
322  $this->suffix = $suffix;
323  }
324 
325  public function isStreamable(): bool
326  {
327  if ($this->isAudio()) {
328  return true;
329  }
330  return $this->isVideo();
331  }
332 
333  public function isAudio(): bool
334  {
335  return in_array(strtolower($this->getSuffix()), self::$audio_suffixes);
336  }
337 
338  public function isVideo(): bool
339  {
340  return in_array(strtolower($this->getSuffix()), self::$video_suffixes);
341  }
342 
343  public function fileExists(): bool
344  {
345  return is_file($this->getPathWithoutQuery());
346  }
347 
348  public function hasToken(): bool
349  {
350  return ($this->token !== '');
351  }
352 
353  public function hasTimestamp(): bool
354  {
355  return ($this->timestamp !== 0);
356  }
357 
358  public function hasTTL(): bool
359  {
360  return ($this->ttl !== 0);
361  }
362 
363  public function getToken(): string
364  {
365  return $this->token;
366  }
367 
368  public function setToken(string $token): void
369  {
370  $this->parameters[ilWACSignedPath::WAC_TOKEN_ID] = $token;
371  $this->token = $token;
372  }
373 
374  public function getTimestamp(): int
375  {
376  return $this->timestamp;
377  }
378 
379  public function setTimestamp(int $timestamp): void
380  {
381  $this->parameters[ilWACSignedPath::WAC_TIMESTAMP_ID] = $timestamp;
382  $this->timestamp = $timestamp;
383  }
384 
385  public function getTTL(): int
386  {
387  return $this->ttl;
388  }
389 
390  public function setTTL(int $ttl): void
391  {
392  $this->parameters[ilWACSignedPath::WAC_TTL_ID] = $ttl;
393  $this->ttl = $ttl;
394  }
395 
396  public function getClient(): string
397  {
398  return $this->client;
399  }
400 
401  public function setClient(string $client): void
402  {
403  $this->client = $client;
404  }
405 
406  public function getSecurePathId(): string
407  {
408  return $this->secure_path_id;
409  }
410 
411  public function setSecurePathId(string $secure_path_id): void
412  {
413  $this->secure_path_id = $secure_path_id;
414  }
415 
416  public function getPath(): string
417  {
418  return $this->path;
419  }
420 
424  public function getCleanURLdecodedPath(): string
425  {
426  return rawurldecode($this->getPathWithoutQuery());
427  }
428 
429  public function setPath(string $path): void
430  {
431  $this->path = $path;
432  }
433 
434  public function getQuery(): string
435  {
436  return $this->query;
437  }
438 
439  public function setQuery(string $query): void
440  {
441  $this->query = $query;
442  }
443 
444  public function getFileName(): string
445  {
446  return $this->file_name;
447  }
448 
449  public function setFileName(string $file_name): void
450  {
451  $this->file_name = $file_name;
452  }
453 
454  public function getOriginalRequest(): string
455  {
457  }
458 
459  public function setOriginalRequest(string $original_request): void
460  {
461  $this->original_request = $original_request;
462  }
463 
464  public function getSecurePath(): string
465  {
466  return $this->secure_path;
467  }
468 
469  public function setSecurePath(string $secure_path): void
470  {
471  $this->secure_path = $secure_path;
472  }
473 
474  public function isInSecFolder(): bool
475  {
476  return $this->in_sec_folder;
477  }
478 
479  public function setInSecFolder(bool $in_sec_folder): void
480  {
481  $this->in_sec_folder = $in_sec_folder;
482  }
483 
484  public function getModuleType(): string
485  {
486  return $this->module_type;
487  }
488 
489  public function setModuleType(string $module_type): void
490  {
491  $this->module_type = $module_type;
492  }
493 
494  public function getModuleIdentifier(): string
495  {
497  }
498 
499  public function setModuleIdentifier(string $module_identifier): void
500  {
501  $this->module_identifier = $module_identifier;
502  }
503 }
static array $video_suffixes
setOriginalRequest(string $original_request)
setClient(string $client)
bool $in_sec_folder
setPath(string $path)
static setAudioSuffixes(array $audio_suffixes)
__construct(string $path, bool $normalize=true)
string $suffix
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:64
string $module_identifier
string $prefix
array $parameters
static setVideoSuffixes(array $video_suffixes)
setTTL(int $ttl)
string $module_type
string $secure_path_id
string $secure_path
setParameters(array $parameters)
setModulePath(string $module_path)
static array $audio_suffixes
setPathWithoutQuery(string $path_without_query)
string $path_without_query
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $appendix
static getAudioSuffixes()
setSecurePath(string $secure_path)
string $original_request
string $file_name
string $module_path
setTimestamp(int $timestamp)
setSuffix(string $suffix)
$param
Definition: xapitoken.php:46
string $client
static getVideoSuffixes()
static setImageSuffixes(array $image_suffixes)
normalizePath(string $path)
static getImageSuffixes()
setAppendix(string $appendix)
setInSecFolder(bool $in_sec_folder)
setPrefix(string $prefix)
setQuery(string $query)
const REGEX
Copy this without to regex101.com and test with some URL of files.
setSecurePathId(string $secure_path_id)
getCleanURLdecodedPath()
Returns a clean (everything behind ? is removed and rawurldecoded path.
setToken(string $token)
setModuleIdentifier(string $module_identifier)
setModuleType(string $module_type)
static array $image_suffixes
setFileName(string $file_name)