Merge branch 'origin/master' into Weblate.
[phpmyadmin.git] / src / Scripts.php
blobe2cee28d30569eee2bb6a4b608bb701d3481da19
1 <?php
3 declare(strict_types=1);
5 namespace PhpMyAdmin;
7 use function defined;
8 use function md5;
9 use function str_contains;
11 /**
12 * Collects information about which JavaScript
13 * files and objects are necessary to render
14 * the page and generates the relevant code.
16 class Scripts
18 /**
19 * An array of SCRIPT tags
21 * @var array<string, array<string, int|string|array<string, string>>>
22 * @psalm-var array<string, array{has_onload: 0|1, filename: non-empty-string, params: array<string, string>}>
24 private array $files = [];
25 /**
26 * A string of discrete javascript code snippets
28 private string $code = '';
30 /**
31 * Generates new Scripts objects
33 public function __construct(private readonly Template $template)
37 /**
38 * Adds a new file to the list of scripts
40 * @param string $filename The name of the file to include
41 * @param array<string, string> $params Additional parameters to pass to the file
43 public function addFile(
44 string $filename,
45 array $params = [],
46 ): void {
47 $hash = md5($filename);
48 if (! empty($this->files[$hash]) || $filename === '') {
49 return;
52 $hasOnload = $this->hasOnloadEvent($filename);
53 $this->files[$hash] = ['has_onload' => (int) $hasOnload, 'filename' => $filename, 'params' => $params];
56 /**
57 * Add new files to the list of scripts
59 * @param string[] $filelist The array of file names
61 public function addFiles(array $filelist): void
63 foreach ($filelist as $filename) {
64 $this->addFile($filename);
68 /**
69 * Determines whether to fire up an onload event for a file
71 * @param string $filename The name of the file to be checked against the exclude list.
73 * @return bool true to fire up the event, false not to
75 private function hasOnloadEvent(string $filename): bool
77 return ! str_contains($filename, 'vendor')
78 && ! str_contains($filename, 'runtime.js')
79 && ! str_contains($filename, 'name-conflict-fixes.js')
80 && ! str_contains($filename, 'index.php')
81 && ! str_contains($filename, 'shared.js')
82 && ! str_contains($filename, 'datetimepicker.js')
83 && ! str_contains($filename, 'validator-messages.js');
86 /**
87 * Adds a new code snippet to the code to be executed
89 * @param string $code The JS code to be added
91 public function addCode(string $code): void
93 $this->code .= $code . "\n";
96 /**
97 * Returns a list with filenames and a flag to indicate
98 * whether to register onload events for this file
100 * @return array<int, array<string, int|string>>
101 * @psalm-return list<array{name: non-empty-string, fire: 0|1}>
103 public function getFiles(): array
105 $retval = [];
106 foreach ($this->files as $file) {
107 //If filename contains a "?", continue.
108 if (str_contains($file['filename'], '?')) {
109 continue;
112 $retval[] = ['name' => $file['filename'], 'fire' => $file['has_onload']];
115 return $retval;
119 * Renders all the JavaScript file inclusions, code and events
121 public function getDisplay(): string
123 $baseDir = defined('PMA_PATH_TO_BASEDIR') ? PMA_PATH_TO_BASEDIR : '';
125 return $this->template->render('scripts', [
126 'base_dir' => $baseDir,
127 'files' => $this->files,
128 'version' => Version::VERSION,
129 'code' => $this->code,