Lines
90.59%
106 / 117
Methods
77.77%
7 / 9
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| setRootDir | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| createAnonymousUser | 0.00% | 0 / 8 | 0.00% | 0 / 1 | 2 | ||
| checkDirs | 78.57% | 11 / 14 | 0.00% | 0 / 1 | 9.80 | ||
| createDatabaseFile | 100.00% | 44 / 44 | 100.00% | 1 / 1 | 5 | ||
| escapeForSingleQuotedPhpString | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| createLdapFile | 100.00% | 20 / 20 | 100.00% | 1 / 1 | 1 | ||
| createElasticsearchFile | 100.00% | 14 / 14 | 100.00% | 1 / 1 | 2 | ||
| createOpenSearchFile | 100.00% | 14 / 14 | 100.00% | 1 / 1 | 2 | ||
| 31 | class Setup | |
| 32 | { | |
| 33 | private string $rootDir; | |
| 34 | ||
| 35 | /** | |
| 36 | * Setup constructor. | |
| 37 | */ | |
| 38 | public function __construct() | |
| 39 | { | |
| 40 | $this->setRootDir(PMF_SRC_DIR); | |
| 41 | } | |
| 42 | ||
| 43 | /** | |
| 44 | * Sets the root directory of the phpMyFAQ instance. | |
| 45 | */ | |
| 46 | public function setRootDir(string $rootDir): void | |
| 47 | { | |
| 48 | $this->rootDir = $rootDir; | |
| 49 | } | |
| 50 | ||
| 51 | /** | |
| 52 | * Creates the anonymous default user. | |
| 53 | * | |
| 54 | * @throws Exception | |
| 55 | */ | |
| 56 | public function createAnonymousUser(Configuration $configuration): void | |
| 57 | { | |
| 58 | $user = new User($configuration); | |
| 59 | $user->createUser('anonymous', '', '', -1); | |
| 60 | $user->setStatus('protected'); | |
| 61 | ||
| 62 | $anonymousData = [ | |
| 63 | 'display_name' => 'Anonymous User', | |
| 64 | 'email' => '', | |
| 65 | ]; | |
| 66 | $user->setUserData($anonymousData); | |
| 67 | } | |
| 68 | ||
| 69 | /** | |
| 70 | * Checks basic folders and creates them if necessary. | |
| 71 | * | |
| 72 | * @param string[] $dirs | |
| 73 | * @return string[] | |
| 74 | */ | |
| 75 | public function checkDirs(array $dirs): array | |
| 76 | { | |
| 77 | $failedDirs = []; | |
| 78 | ||
| 79 | foreach ($dirs as $dir) { | |
| 80 | if (false === is_dir($this->rootDir . $dir)) { | |
| 81 | // If the folder does not exist, try to create it | |
| 82 | if (false === mkdir($this->rootDir . $dir)) { | |
| 83 | // If the folder creation fails | |
| 84 | $failedDirs[] = 'Folder [' . $dir . '] could not be created.'; | |
| 85 | } | |
| 86 | ||
| 87 | if (is_dir($this->rootDir . $dir) && false === chmod($this->rootDir . $dir, permissions: 0o775)) { | |
| 88 | $failedDirs[] = 'Folder [' . $dir . '] could not be given correct permissions (775).'; | |
| 89 | } | |
| 90 | } | |
| 91 | ||
| 92 | if (false === is_dir($this->rootDir . $dir)) { | |
| 93 | continue; | |
| 94 | } | |
| 95 | ||
| 96 | if (false === is_writable($this->rootDir . $dir)) { | |
| 97 | // The folder exists, check permissions | |
| 98 | // If the folder exists but is not writeable | |
| 99 | $failedDirs[] = 'Folder [' . $dir . '] exists but is not writable.'; | |
| 100 | } | |
| 101 | ||
| 102 | if ([] === $failedDirs) { | |
| 103 | // if no failed dirs exist | |
| 104 | copy($this->rootDir . '/setup/index.html', $this->rootDir . $dir . '/index.html'); | |
| 105 | } | |
| 106 | } | |
| 107 | ||
| 108 | return $failedDirs; | |
| 109 | } | |
| 110 | ||
| 111 | /** | |
| 112 | * Creates the file /content/core/config/database.php. | |
| 113 | * | |
| 114 | * @param array<string, mixed> $data Array with database credentials | |
| 115 | * @param string $folder Folder | |
| 116 | * @throws Exception | |
| 117 | */ | |
| 118 | public function createDatabaseFile(array $data, string $folder = '/content/core/config'): int|bool | |
| 119 | { | |
| 120 | if (!file_exists($this->rootDir . $folder)) { | |
| 121 | throw new Exception('File [' . $this->rootDir . $folder . '] does not exist.'); | |
| 122 | } | |
| 123 | ||
| 124 | if (!is_writable($this->rootDir . $folder)) { | |
| 125 | throw new Exception('File [' . $this->rootDir . $folder . '] is not writable.'); | |
| 126 | } | |
| 127 | ||
| 128 | $schema = (string) ($data['dbSchema'] ?? ''); | |
| 129 | if ($schema !== '' && !preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $schema)) { | |
| 130 | throw new Exception('Invalid database schema name.'); | |
| 131 | } | |
| 132 | ||
| 133 | $dbServer = $this->escapeForSingleQuotedPhpString((string) ($data['dbServer'] ?? '')); | |
| 134 | $dbPort = $this->escapeForSingleQuotedPhpString((string) ($data['dbPort'] ?? '')); | |
| 135 | $dbUser = $this->escapeForSingleQuotedPhpString((string) ($data['dbUser'] ?? '')); | |
| 136 | $dbPassword = $this->escapeForSingleQuotedPhpString((string) ($data['dbPassword'] ?? '')); | |
| 137 | $dbDatabaseName = $this->escapeForSingleQuotedPhpString((string) ($data['dbDatabaseName'] ?? '')); | |
| 138 | $dbPrefix = $this->escapeForSingleQuotedPhpString((string) ($data['dbPrefix'] ?? '')); | |
| 139 | $dbType = $this->escapeForSingleQuotedPhpString((string) ($data['dbType'] ?? '')); | |
| 140 | $dbSchema = $this->escapeForSingleQuotedPhpString($schema); | |
| 141 | ||
| 142 | return file_put_contents( | |
| 143 | $this->rootDir . $folder . '/database.php', | |
| 144 | '<?php | |
| 145 | $DB[\'server\'] = \'' | |
| 146 | . $dbServer | |
| 147 | . "';\n" | |
| 148 | . "\$DB['port'] = '" | |
| 149 | . $dbPort | |
| 150 | . "';\n" | |
| 151 | . "\$DB['user'] = '" | |
| 152 | . $dbUser | |
| 153 | . "';\n" | |
| 154 | . "\$DB['password'] = '" | |
| 155 | . $dbPassword | |
| 156 | . "';\n" | |
| 157 | . "\$DB['db'] = '" | |
| 158 | . $dbDatabaseName | |
| 159 | . "';\n" | |
| 160 | . "\$DB['prefix'] = '" | |
| 161 | . $dbPrefix | |
| 162 | . "';\n" | |
| 163 | . "\$DB['type'] = '" | |
| 164 | . $dbType | |
| 165 | . "';\n" | |
| 166 | . "\$DB['schema'] = '" | |
| 167 | . $dbSchema | |
| 168 | . "';", | |
| 169 | LOCK_EX, | |
| 170 | ); | |
| 171 | } | |
| 172 | ||
| 173 | private function escapeForSingleQuotedPhpString(string $value): string | |
| 174 | { | |
| 175 | return str_replace(['\\', "'"], ['\\\\', "\\'"], $value); | |
| 176 | } | |
| 177 | ||
| 178 | /** | |
| 179 | * Creates the file /content/core/config/ldap.php. | |
| 180 | * | |
| 181 | * @param array<string, mixed> $data Array with LDAP credentials | |
| 182 | * @param string $folder Folder | |
| 183 | */ | |
| 184 | public function createLdapFile(array $data, string $folder = '/content/core/config'): int|bool | |
| 185 | { | |
| 186 | return file_put_contents( | |
| 187 | $this->rootDir . $folder . '/config/ldap.php', | |
| 188 | '<?php | |
| 189 | $PMF_LDAP[\'ldap_server\'] = \'' | |
| 190 | . (string) ($data['ldapServer'] ?? '') | |
| 191 | . "';\n" | |
| 192 | . "\$PMF_LDAP['ldap_port'] = '" | |
| 193 | . (string) ($data['ldapPort'] ?? '') | |
| 194 | . "';\n" | |
| 195 | . "\$PMF_LDAP['ldap_user'] = '" | |
| 196 | . (string) ($data['ldapUser'] ?? '') | |
| 197 | . "';\n" | |
| 198 | . "\$PMF_LDAP['ldap_password'] = '" | |
| 199 | . (string) ($data['ldapPassword'] ?? '') | |
| 200 | . "';\n" | |
| 201 | . "\$PMF_LDAP['ldap_base'] = '" | |
| 202 | . (string) ($data['ldapBase'] ?? '') | |
| 203 | . "';", | |
| 204 | LOCK_EX, | |
| 205 | ); | |
| 206 | } | |
| 207 | ||
| 208 | /** | |
| 209 | * Creates the file /content/core/config/elasticsearch.php | |
| 210 | * | |
| 211 | * @param array<string, mixed> $data Array with Elasticsearch credentials | |
| 212 | * @param string $folder Folder | |
| 213 | */ | |
| 214 | public function createElasticsearchFile(array $data, string $folder = '/content/core/config'): int|bool | |
| 215 | { | |
| 216 | return file_put_contents( | |
| 217 | $this->rootDir . $folder . '/config/elasticsearch.php', | |
| 218 | '<?php | |
| 219 | $PMF_ES[\'hosts\'] = [\'' | |
| 220 | . implode("'], ['", array_map( | |
| 221 | static fn(mixed $host): string => (string) $host, | |
| 222 | is_array($data['hosts'] ?? null) ? $data['hosts'] : [], | |
| 223 | )) | |
| 224 | . "'];\n" | |
| 225 | . "\$PMF_ES['index'] = '" | |
| 226 | . (string) ($data['index'] ?? '') | |
| 227 | . "';\n", | |
| 228 | LOCK_EX, | |
| 229 | ); | |
| 230 | } | |
| 231 | ||
| 232 | /** | |
| 233 | * Creates the file /content/core/config/opensearch.php | |
| 234 | * | |
| 235 | * @param array<string, mixed> $data Array with OpenSearch credentials | |
| 236 | * @param string $folder Folder | |
| 237 | */ | |
| 238 | public function createOpenSearchFile(array $data, string $folder = '/content/core/config'): int|bool | |
| 239 | { | |
| 240 | return file_put_contents( | |
| 241 | $this->rootDir . $folder . '/config/opensearch.php', | |
| 242 | '<?php | |
| 243 | $PMF_OS[\'hosts\'] = [\'' | |
| 244 | . implode("'], ['", array_map( | |
| 245 | static fn(mixed $host): string => (string) $host, | |
| 246 | is_array($data['hosts'] ?? null) ? $data['hosts'] : [], | |
| 247 | )) | |
| 248 | . "'];\n" | |
| 249 | . "\$PMF_OS['index'] = '" | |
| 250 | . (string) ($data['index'] ?? '') | |
| 251 | . "';\n", | |
| 252 | LOCK_EX, | |
| 253 | ); | |
| 254 | } | |
| 255 | } |